mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Clean up sched_op() hypercall interface. One particular
change to watch out for is that the suspend record, on save/restore, is now passed via register %edx not %esi (both i386 and x86/64). Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
1 parent
92f5a40578
commit
1872f40d78
17 files changed
+90
-216
No files matched your search
@@ -106,7 +106,8 @@ void xen_idle(void)
|
||||
local_irq_enable();
|
||||
} else {
|
||||
stop_hz_timer();
|
||||
HYPERVISOR_block(); /* implicit local_irq_enable() */
|
||||
/* Blocking includes an implicit local_irq_enable(). */
|
||||
HYPERVISOR_sched_op(SCHEDOP_block, 0);
|
||||
start_hz_timer();
|
||||
}
|
||||
}
|
||||
@@ -122,7 +123,7 @@ static inline void play_dead(void)
|
||||
{
|
||||
/* Death loop */
|
||||
while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
|
||||
HYPERVISOR_yield();
|
||||
HYPERVISOR_sched_op(SCHEDOP_yield, 0);
|
||||
|
||||
__flush_tlb_all();
|
||||
/*
|
||||
|
||||
@@ -1784,7 +1784,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
static int
|
||||
xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
|
||||
{
|
||||
HYPERVISOR_crash();
|
||||
HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_crash);
|
||||
/* we're never actually going to get here... */
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ void machine_restart(char * __unused)
|
||||
/* We really want to get pending console data out before we die. */
|
||||
extern void xencons_force_flush(void);
|
||||
xencons_force_flush();
|
||||
HYPERVISOR_reboot();
|
||||
HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_reboot);
|
||||
}
|
||||
|
||||
void machine_halt(void)
|
||||
@@ -39,7 +39,7 @@ void machine_power_off(void)
|
||||
/* We really want to get pending console data out before we die. */
|
||||
extern void xencons_force_flush(void);
|
||||
xencons_force_flush();
|
||||
HYPERVISOR_shutdown();
|
||||
HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_poweroff);
|
||||
}
|
||||
|
||||
int reboot_thru_bios = 0; /* for dmi_scan.c */
|
||||
|
||||
@@ -96,7 +96,8 @@ void xen_idle(void)
|
||||
local_irq_enable();
|
||||
} else {
|
||||
stop_hz_timer();
|
||||
HYPERVISOR_block(); /* implicit local_irq_enable() */
|
||||
/* Blocking includes an implicit local_irq_enable(). */
|
||||
HYPERVISOR_sched_op(SCHEDOP_block, 0);
|
||||
start_hz_timer();
|
||||
}
|
||||
}
|
||||
@@ -114,7 +115,7 @@ static inline void play_dead(void)
|
||||
* it "work" for testing purposes. */
|
||||
/* Death loop */
|
||||
while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
|
||||
HYPERVISOR_yield();
|
||||
HYPERVISOR_sched_op(SCHEDOP_yield, 0);
|
||||
|
||||
local_irq_disable();
|
||||
__flush_tlb_all();
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#define __HYPERCALL_H__
|
||||
|
||||
#include <asm-xen/xen-public/xen.h>
|
||||
#include <asm-xen/xen-public/sched.h>
|
||||
|
||||
#define _hypercall0(type, name) \
|
||||
({ \
|
||||
@@ -160,41 +161,10 @@ HYPERVISOR_fpu_taskswitch(
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_yield(
|
||||
void)
|
||||
HYPERVISOR_sched_op(
|
||||
int cmd, unsigned long arg)
|
||||
{
|
||||
return _hypercall2(int, sched_op, SCHEDOP_yield, 0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_block(
|
||||
void)
|
||||
{
|
||||
return _hypercall2(int, sched_op, SCHEDOP_block, 0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_shutdown(
|
||||
void)
|
||||
{
|
||||
return _hypercall2(int, sched_op, SCHEDOP_shutdown |
|
||||
(SHUTDOWN_poweroff << SCHEDOP_reasonshift), 0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_reboot(
|
||||
void)
|
||||
{
|
||||
return _hypercall2(int, sched_op, SCHEDOP_shutdown |
|
||||
(SHUTDOWN_reboot << SCHEDOP_reasonshift), 0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_crash(
|
||||
void)
|
||||
{
|
||||
return _hypercall2(int, sched_op, SCHEDOP_shutdown |
|
||||
(SHUTDOWN_crash << SCHEDOP_reasonshift), 0);
|
||||
return _hypercall2(int, sched_op, cmd, arg);
|
||||
}
|
||||
|
||||
static inline long
|
||||
@@ -326,19 +296,8 @@ static inline int
|
||||
HYPERVISOR_suspend(
|
||||
unsigned long srec)
|
||||
{
|
||||
int ret;
|
||||
unsigned long ign1, ign2;
|
||||
|
||||
/* On suspend, control software expects a suspend record in %esi. */
|
||||
__asm__ __volatile__ (
|
||||
TRAP_INSTR
|
||||
: "=a" (ret), "=b" (ign1), "=S" (ign2)
|
||||
: "0" (__HYPERVISOR_sched_op),
|
||||
"1" (SCHEDOP_shutdown | (SHUTDOWN_suspend <<
|
||||
SCHEDOP_reasonshift)),
|
||||
"2" (srec) : "memory", "ecx");
|
||||
|
||||
return ret;
|
||||
return _hypercall3(int, sched_op, SCHEDOP_shutdown,
|
||||
SHUTDOWN_suspend, srec);
|
||||
}
|
||||
|
||||
#endif /* __HYPERCALL_H__ */
|
||||
|
||||
@@ -29,7 +29,9 @@
|
||||
|
||||
#ifndef __HYPERCALL_H__
|
||||
#define __HYPERCALL_H__
|
||||
|
||||
#include <asm-xen/xen-public/xen.h>
|
||||
#include <asm-xen/xen-public/sched.h>
|
||||
|
||||
/* FIXME: temp place to hold these page related macros */
|
||||
#include <asm/page.h>
|
||||
@@ -184,77 +186,9 @@ HYPERVISOR_fpu_taskswitch(
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_yield(
|
||||
void)
|
||||
HYPERVISOR_sched_op(
|
||||
int cmd, unsigned long arg)
|
||||
{
|
||||
#if 0
|
||||
int ret;
|
||||
unsigned long ign;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
TRAP_INSTR
|
||||
: "=a" (ret), "=b" (ign)
|
||||
: "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield)
|
||||
: "memory" );
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_block(
|
||||
void)
|
||||
{
|
||||
#if 0
|
||||
int ret;
|
||||
unsigned long ign1;
|
||||
__asm__ __volatile__ (
|
||||
TRAP_INSTR
|
||||
: "=a" (ret), "=b" (ign1)
|
||||
: "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block)
|
||||
: "memory" );
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_shutdown(
|
||||
void)
|
||||
{
|
||||
#if 0
|
||||
int ret;
|
||||
unsigned long ign1;
|
||||
__asm__ __volatile__ (
|
||||
TRAP_INSTR
|
||||
: "=a" (ret), "=b" (ign1)
|
||||
: "0" (__HYPERVISOR_sched_op),
|
||||
"1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
|
||||
: "memory" );
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_reboot(
|
||||
void)
|
||||
{
|
||||
#if 0
|
||||
int ret;
|
||||
unsigned long ign1;
|
||||
__asm__ __volatile__ (
|
||||
TRAP_INSTR
|
||||
: "=a" (ret), "=b" (ign1)
|
||||
: "0" (__HYPERVISOR_sched_op),
|
||||
"1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
|
||||
: "memory" );
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -262,39 +196,6 @@ static inline int
|
||||
HYPERVISOR_suspend(
|
||||
unsigned long srec)
|
||||
{
|
||||
#if 0
|
||||
int ret;
|
||||
unsigned long ign1, ign2;
|
||||
|
||||
/* NB. On suspend, control software expects a suspend record in %esi. */
|
||||
__asm__ __volatile__ (
|
||||
TRAP_INSTR
|
||||
: "=a" (ret), "=b" (ign1), "=S" (ign2)
|
||||
: "0" (__HYPERVISOR_sched_op),
|
||||
"b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)),
|
||||
"S" (srec) : "memory");
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_crash(
|
||||
void)
|
||||
{
|
||||
#if 0
|
||||
int ret;
|
||||
unsigned long ign1;
|
||||
__asm__ __volatile__ (
|
||||
TRAP_INSTR
|
||||
: "=a" (ret), "=b" (ign1)
|
||||
: "0" (__HYPERVISOR_sched_op),
|
||||
"1" (SCHEDOP_shutdown | (SHUTDOWN_crash << SCHEDOP_reasonshift))
|
||||
: "memory" );
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#define __HYPERCALL_H__
|
||||
|
||||
#include <asm-xen/xen-public/xen.h>
|
||||
#include <asm-xen/xen-public/sched.h>
|
||||
|
||||
#define __syscall_clobber "r11","rcx","memory"
|
||||
|
||||
@@ -165,33 +166,10 @@ HYPERVISOR_fpu_taskswitch(
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_yield(
|
||||
void)
|
||||
HYPERVISOR_sched_op(
|
||||
int cmd, unsigned long arg)
|
||||
{
|
||||
return _hypercall2(int, sched_op, SCHEDOP_yield, 0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_block(
|
||||
void)
|
||||
{
|
||||
return _hypercall2(int, sched_op, SCHEDOP_block, 0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_shutdown(
|
||||
void)
|
||||
{
|
||||
return _hypercall2(int, sched_op, SCHEDOP_shutdown |
|
||||
(SHUTDOWN_poweroff << SCHEDOP_reasonshift), 0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_reboot(
|
||||
void)
|
||||
{
|
||||
return _hypercall2(int, sched_op, SCHEDOP_shutdown |
|
||||
(SHUTDOWN_reboot << SCHEDOP_reasonshift), 0);
|
||||
return _hypercall2(int, sched_op, cmd, arg);
|
||||
}
|
||||
|
||||
static inline long
|
||||
@@ -325,8 +303,8 @@ static inline int
|
||||
HYPERVISOR_suspend(
|
||||
unsigned long srec)
|
||||
{
|
||||
return _hypercall2(int, sched_op, SCHEDOP_shutdown |
|
||||
(SHUTDOWN_suspend << SCHEDOP_reasonshift), srec);
|
||||
return _hypercall3(int, sched_op, SCHEDOP_shutdown,
|
||||
SHUTDOWN_suspend, srec);
|
||||
}
|
||||
|
||||
#endif /* __HYPERCALL_H__ */
|
||||
|
||||
@@ -500,13 +500,13 @@ int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns,
|
||||
}
|
||||
|
||||
/* Uncanonicalise the suspend-record frame number and poke resume rec. */
|
||||
pfn = ctxt.user_regs.esi;
|
||||
pfn = ctxt.user_regs.edx;
|
||||
if ( (pfn >= nr_pfns) || (pfn_type[pfn] != NOTAB) )
|
||||
{
|
||||
ERR("Suspend record frame number is bad");
|
||||
goto out;
|
||||
}
|
||||
ctxt.user_regs.esi = mfn = pfn_to_mfn_table[pfn];
|
||||
ctxt.user_regs.edx = mfn = pfn_to_mfn_table[pfn];
|
||||
start_info = xc_map_foreign_range(
|
||||
xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
|
||||
start_info->nr_pages = nr_pfns;
|
||||
|
||||
@@ -978,9 +978,9 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
|
||||
goto out;
|
||||
}
|
||||
|
||||
DPRINTF("SUSPEND shinfo %08lx eip %08u esi %08u\n",
|
||||
DPRINTF("SUSPEND shinfo %08lx eip %08u edx %08u\n",
|
||||
info.shared_info_frame,
|
||||
ctxt.user_regs.eip, ctxt.user_regs.esi);
|
||||
ctxt.user_regs.eip, ctxt.user_regs.edx);
|
||||
}
|
||||
|
||||
if ( xc_shadow_control( xc_handle, dom,
|
||||
@@ -1048,7 +1048,7 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
|
||||
}
|
||||
|
||||
/* Canonicalise the suspend-record frame number. */
|
||||
if ( !translate_mfn_to_pfn(&ctxt.user_regs.esi) )
|
||||
if ( !translate_mfn_to_pfn(&ctxt.user_regs.edx) )
|
||||
{
|
||||
ERR("Suspend record is not in range of pseudophys map");
|
||||
goto out;
|
||||
|
||||
@@ -25,6 +25,7 @@ typedef int64_t s64;
|
||||
#include <xen/dom0_ops.h>
|
||||
#include <xen/version.h>
|
||||
#include <xen/event_channel.h>
|
||||
#include <xen/sched.h>
|
||||
#include <xen/sched_ctl.h>
|
||||
#include <xen/acm.h>
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ typedef uint64_t u64;
|
||||
|
||||
#include <xen/xen.h>
|
||||
#include <xen/dom0_ops.h>
|
||||
#include <xen/sched.h>
|
||||
#include <xen/version.h>
|
||||
|
||||
/* Opaque handles */
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@
|
||||
#if CONFIG_PAGING_LEVELS >= 3
|
||||
#include <asm/shadow_64.h>
|
||||
#endif
|
||||
|
||||
#include <public/sched.h>
|
||||
#include <public/io/ioreq.h>
|
||||
|
||||
int hvm_enabled;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <xen/domain_page.h>
|
||||
#include <asm/debugger.h>
|
||||
#include <public/dom0_ops.h>
|
||||
#include <public/sched.h>
|
||||
#include <public/vcpu.h>
|
||||
|
||||
/* Both these structures are protected by the domlist_lock. */
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <xen/softirq.h>
|
||||
#include <xen/trace.h>
|
||||
#include <xen/mm.h>
|
||||
#include <public/sched.h>
|
||||
#include <public/sched_ctl.h>
|
||||
|
||||
extern void arch_getdomaininfo_ctxt(struct vcpu *,
|
||||
@@ -270,11 +271,11 @@ static long do_yield(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long do_sched_op(unsigned long op, unsigned long arg)
|
||||
long do_sched_op(int cmd, unsigned long arg)
|
||||
{
|
||||
long ret = 0;
|
||||
|
||||
switch ( op & SCHEDOP_cmdmask )
|
||||
switch ( cmd )
|
||||
{
|
||||
case SCHEDOP_yield:
|
||||
{
|
||||
@@ -291,9 +292,8 @@ long do_sched_op(unsigned long op, unsigned long arg)
|
||||
case SCHEDOP_shutdown:
|
||||
{
|
||||
TRACE_3D(TRC_SCHED_SHUTDOWN,
|
||||
current->domain->domain_id, current->vcpu_id,
|
||||
(op >> SCHEDOP_reasonshift));
|
||||
domain_shutdown((u8)(op >> SCHEDOP_reasonshift));
|
||||
current->domain->domain_id, current->vcpu_id, arg);
|
||||
domain_shutdown((u8)arg);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* This makes sure that old versions of dom0 tools will stop working in a
|
||||
* well-defined way (rather than crashing the machine, for instance).
|
||||
*/
|
||||
#define DOM0_INTERFACE_VERSION 0xAAAA1010
|
||||
#define DOM0_INTERFACE_VERSION 0xAAAA1011
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/******************************************************************************
|
||||
* sched.h
|
||||
*
|
||||
* Scheduler state interactions
|
||||
*
|
||||
* Copyright (c) 2005, Keir Fraser <keir@xensource.com>
|
||||
*/
|
||||
|
||||
#ifndef __XEN_PUBLIC_SCHED_H__
|
||||
#define __XEN_PUBLIC_SCHED_H__
|
||||
|
||||
/*
|
||||
* Prototype for this hypercall is:
|
||||
* int sched_op(int cmd, unsigned long arg)
|
||||
* @cmd == SCHEDOP_??? (scheduler operation).
|
||||
* @arg == Operation-specific extra argument(s).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Voluntarily yield the CPU.
|
||||
* @arg == 0.
|
||||
*/
|
||||
#define SCHEDOP_yield 0
|
||||
|
||||
/*
|
||||
* Block execution of this VCPU until an event is received for processing.
|
||||
* If called with event upcalls masked, this operation will atomically
|
||||
* reenable event delivery and check for pending events before blocking the
|
||||
* VCPU. This avoids a "wakeup waiting" race.
|
||||
* @arg == 0.
|
||||
*/
|
||||
#define SCHEDOP_block 1
|
||||
|
||||
/*
|
||||
* Halt execution of this domain (all VCPUs) and notify the system controller.
|
||||
* @arg == SHUTDOWN_??? (reason for shutdown).
|
||||
*/
|
||||
#define SCHEDOP_shutdown 2
|
||||
|
||||
/*
|
||||
* Reason codes for SCHEDOP_shutdown. These may be interpreted by controller
|
||||
* software to determine the appropriate action. For the most part, Xen does
|
||||
* not care about the shutdown code.
|
||||
*/
|
||||
#define SHUTDOWN_poweroff 0 /* Domain exited normally. Clean up and kill. */
|
||||
#define SHUTDOWN_reboot 1 /* Clean up, kill, and then restart. */
|
||||
#define SHUTDOWN_suspend 2 /* Clean up, save suspend info, kill. */
|
||||
#define SHUTDOWN_crash 3 /* Tell controller we've crashed. */
|
||||
|
||||
#endif /* __XEN_PUBLIC_SCHED_H__ */
|
||||
@@ -195,25 +195,6 @@ struct mmuext_op {
|
||||
#define UVMF_LOCAL (0UL<<2) /* Flush local TLB. */
|
||||
#define UVMF_ALL (1UL<<2) /* Flush all TLBs. */
|
||||
|
||||
/*
|
||||
* Commands to HYPERVISOR_sched_op().
|
||||
*/
|
||||
#define SCHEDOP_yield 0 /* Give up the CPU voluntarily. */
|
||||
#define SCHEDOP_block 1 /* Block until an event is received. */
|
||||
#define SCHEDOP_shutdown 2 /* Stop executing this domain. */
|
||||
#define SCHEDOP_cmdmask 255 /* 8-bit command. */
|
||||
#define SCHEDOP_reasonshift 8 /* 8-bit reason code. (SCHEDOP_shutdown) */
|
||||
|
||||
/*
|
||||
* Reason codes for SCHEDOP_shutdown. These may be interpreted by control
|
||||
* software to determine the appropriate action. For the most part, Xen does
|
||||
* not care about the shutdown code (SHUTDOWN_crash excepted).
|
||||
*/
|
||||
#define SHUTDOWN_poweroff 0 /* Domain exited normally. Clean up and kill. */
|
||||
#define SHUTDOWN_reboot 1 /* Clean up, kill, and then restart. */
|
||||
#define SHUTDOWN_suspend 2 /* Clean up, save suspend info, kill. */
|
||||
#define SHUTDOWN_crash 3 /* Tell controller we've crashed. */
|
||||
|
||||
/*
|
||||
* Commands to HYPERVISOR_console_io().
|
||||
*/
|
||||
|
||||