From: kaf24@scramble.cl.cam.ac.uk Date: Thu, 10 Jun 2004 11:33:45 +0000 (+0000) Subject: bitkeeper revision 1.947 (40c84719Ozi8_o69nGYdNuJ6OQd4eQ) X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~18174 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=cce2235b0ff8d8a818b2a57c2a399afe388e2e34;p=xen.git bitkeeper revision 1.947 (40c84719Ozi8_o69nGYdNuJ6OQd4eQ) Cleanup domain stop/crash. Provide notification to DOM0 so that cleanup/postmortem can occur before domain is killed. --- diff --git a/extras/mini-os/h/hypervisor.h b/extras/mini-os/h/hypervisor.h index b1cfd60dc6..500dcdf99e 100644 --- a/extras/mini-os/h/hypervisor.h +++ b/extras/mini-os/h/hypervisor.h @@ -15,7 +15,7 @@ #include #include #include - +#include "../../../tools/xend/lib/domain_controller.h" /* * a placeholder for the start of day information passed up from the hypervisor @@ -155,25 +155,39 @@ static __inline__ int HYPERVISOR_block(void) return ret; } -static __inline__ int HYPERVISOR_exit(void) +static inline int HYPERVISOR_shutdown(void) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_sched_op), + "b" (SCHEDOP_stop | (STOPCODE_shutdown << SCHEDOP_reasonshift)) + : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_reboot(void) { int ret; __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_sched_op), - "b" (SCHEDOP_exit) : "memory" ); + "b" (SCHEDOP_stop | (STOPCODE_reboot << SCHEDOP_reasonshift)) + : "memory" ); return ret; } -static __inline__ int HYPERVISOR_stop(unsigned long srec) +static inline int HYPERVISOR_suspend(unsigned long srec) { int ret; /* NB. On suspend, control software expects a suspend record in %esi. */ __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_sched_op), - "b" (SCHEDOP_stop), "S" (srec) : "memory" ); + "b" (SCHEDOP_stop | (STOPCODE_suspend << SCHEDOP_reasonshift)), + "S" (srec) : "memory" ); return ret; } diff --git a/extras/mini-os/kernel.c b/extras/mini-os/kernel.c index 0afd864cf5..f1d46fbf7d 100644 --- a/extras/mini-os/kernel.c +++ b/extras/mini-os/kernel.c @@ -153,7 +153,7 @@ void start_kernel(start_info_t *si) void do_exit(void) { printk("do_exit called!\n"); - for ( ;; ) HYPERVISOR_exit(); + for ( ;; ) HYPERVISOR_shutdown(); } static void exit_handler(int ev, struct pt_regs *regs) { do_exit(); diff --git a/linux-2.4.26-xen-sparse/arch/xen/kernel/process.c b/linux-2.4.26-xen-sparse/arch/xen/kernel/process.c index 1ef8521fcb..aa59c37790 100644 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/process.c +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/process.c @@ -120,17 +120,23 @@ 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_exit(); + HYPERVISOR_reboot(); } void machine_halt(void) { - machine_restart(NULL); + /* We really want to get pending console data out before we die. */ + extern void xencons_force_flush(void); + xencons_force_flush(); + HYPERVISOR_shutdown(); } void machine_power_off(void) { - machine_restart(NULL); + /* We really want to get pending console data out before we die. */ + extern void xencons_force_flush(void); + xencons_force_flush(); + HYPERVISOR_shutdown(); } extern void show_trace(unsigned long* esp); diff --git a/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c b/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c index 1d1306df2b..a787a5c78c 100644 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c @@ -1205,7 +1205,7 @@ static void stop_task(void *unused) memcpy(&suspend_record->resume_info, &start_info, sizeof(start_info)); - HYPERVISOR_stop(virt_to_machine(suspend_record) >> PAGE_SHIFT); + HYPERVISOR_suspend(virt_to_machine(suspend_record) >> PAGE_SHIFT); suspending = 0; diff --git a/linux-2.4.26-xen-sparse/include/asm-xen/hypervisor.h b/linux-2.4.26-xen-sparse/include/asm-xen/hypervisor.h index 3ace0bae8a..c341fe5990 100644 --- a/linux-2.4.26-xen-sparse/include/asm-xen/hypervisor.h +++ b/linux-2.4.26-xen-sparse/include/asm-xen/hypervisor.h @@ -253,25 +253,39 @@ static inline int HYPERVISOR_block(void) return ret; } -static inline int HYPERVISOR_exit(void) +static inline int HYPERVISOR_shutdown(void) { int ret; __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_sched_op), - "b" (SCHEDOP_exit) : "memory" ); + "b" (SCHEDOP_stop | (STOPCODE_shutdown << SCHEDOP_reasonshift)) + : "memory" ); return ret; } -static inline int HYPERVISOR_stop(unsigned long srec) +static inline int HYPERVISOR_reboot(void) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_sched_op), + "b" (SCHEDOP_stop | (STOPCODE_reboot << SCHEDOP_reasonshift)) + : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_suspend(unsigned long srec) { int ret; /* NB. On suspend, control software expects a suspend record in %esi. */ __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_sched_op), - "b" (SCHEDOP_stop), "S" (srec) : "memory" ); + "b" (SCHEDOP_stop | (STOPCODE_suspend << SCHEDOP_reasonshift)), + "S" (srec) : "memory" ); return ret; } diff --git a/tools/xc/lib/xc_domain.c b/tools/xc/lib/xc_domain.c index 97a919f8d6..41c004ed6e 100644 --- a/tools/xc/lib/xc_domain.c +++ b/tools/xc/lib/xc_domain.c @@ -91,9 +91,14 @@ int xc_domain_getinfo(int xc_handle, if ( do_dom0_op(xc_handle, &op) < 0 ) break; info->domid = (u32)op.u.getdomaininfo.domain; - info->cpu = op.u.getdomaininfo.processor; - info->has_cpu = op.u.getdomaininfo.has_cpu; - info->stopped = (op.u.getdomaininfo.state == DOMSTATE_STOPPED); + + info->cpu = + (op.u.getdomaininfo.flags>>DOMFLAGS_CPUSHIFT) & DOMFLAGS_CPUMASK; + info->has_cpu = + (op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) == DOMSTATE_RUNNING; + info->stopped = + (op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) == DOMSTATE_STOPPED; + info->nr_pages = op.u.getdomaininfo.tot_pages; info->max_memkb = op.u.getdomaininfo.max_pages<<(PAGE_SHIFT-10); info->shared_info_frame = op.u.getdomaininfo.shared_info_frame; diff --git a/tools/xc/lib/xc_linux_build.c b/tools/xc/lib/xc_linux_build.c index 899d6c5329..c5329231c4 100644 --- a/tools/xc/lib/xc_linux_build.c +++ b/tools/xc/lib/xc_linux_build.c @@ -436,7 +436,7 @@ int xc_linux_build(int xc_handle, PERROR("Could not get info on domain"); goto error_out; } - if ( (op.u.getdomaininfo.state != DOMSTATE_STOPPED) || + if ( ((op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) != DOMSTATE_STOPPED) || (ctxt->pt_base != 0) ) { ERROR("Domain is already constructed"); diff --git a/tools/xc/lib/xc_netbsd_build.c b/tools/xc/lib/xc_netbsd_build.c index b3dfcc7314..991edb0634 100644 --- a/tools/xc/lib/xc_netbsd_build.c +++ b/tools/xc/lib/xc_netbsd_build.c @@ -258,7 +258,7 @@ int xc_netbsd_build(int xc_handle, PERROR("Could not get info on domain"); goto error_out; } - if ( (op.u.getdomaininfo.state != DOMSTATE_STOPPED) || + if ( ((op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) != DOMSTATE_STOPPED) || (op.u.getdomaininfo.ctxt->pt_base != 0) ) { ERROR("Domain is already constructed"); diff --git a/tools/xc/lib/xc_private.c b/tools/xc/lib/xc_private.c index c602a56630..23d30a464a 100644 --- a/tools/xc/lib/xc_private.c +++ b/tools/xc/lib/xc_private.c @@ -229,7 +229,8 @@ int xc_domain_stop_sync( int xc_handle, domid_t domid, goto out; } - if ( op->u.getdomaininfo.state == DOMSTATE_STOPPED ) + if ( (op->u.getdomaininfo.flags & DOMFLAGS_STATEMASK) == + DOMSTATE_STOPPED ) { printf("Domain %u stopped\n",domid); return 0; diff --git a/tools/xend/lib/domain_controller.h b/tools/xend/lib/domain_controller.h index 2bf01eff53..a21fdb2446 100644 --- a/tools/xend/lib/domain_controller.h +++ b/tools/xend/lib/domain_controller.h @@ -28,6 +28,16 @@ typedef struct { #define SIF_NET_BE_DOMAIN (1<<5) /* Is this a net backend domain? */ +/* + * Stop codes for SCHEDOP_stop. These are opaque to Xen but interpreted by + * control software to determine appropriate action. + */ + +#define STOPCODE_shutdown 0 /* Domain exited normally. Clean up and kill. */ +#define STOPCODE_reboot 1 /* Clean up, kill, and then restart. */ +#define STOPCODE_suspend 2 /* Clean up, save suspend info, kill. */ + + /* * CONTROLLER MESSAGING INTERFACE. */ diff --git a/xen/arch/i386/entry.S b/xen/arch/i386/entry.S index d7600ade07..3493ff641a 100644 --- a/xen/arch/i386/entry.S +++ b/xen/arch/i386/entry.S @@ -446,34 +446,34 @@ FAULT12:movl %eax,8(%esi) .section __ex_table,"a" .align 4 - .long FAULT1, kill_domain_fixup3 # Fault writing to ring-1 stack - .long FAULT2, kill_domain_fixup3 # Fault writing to ring-1 stack - .long FAULT3, kill_domain_fixup3 # Fault writing to ring-1 stack - .long FAULT4, kill_domain_fixup3 # Fault writing to ring-1 stack - .long FAULT5, kill_domain_fixup1 # Fault executing failsafe iret - .long FAULT6, kill_domain_fixup2 # Fault loading ring-1 stack selector - .long FAULT7, kill_domain_fixup2 # Fault writing to ring-1 stack - .long FAULT8, kill_domain_fixup2 # Fault writing to ring-1 stack - .long FAULT9, kill_domain_fixup2 # Fault loading ring-1 stack selector - .long FAULT10,kill_domain_fixup2 # Fault writing to ring-1 stack - .long FAULT11,kill_domain_fixup2 # Fault writing to ring-1 stack - .long FAULT12,kill_domain_fixup2 # Fault writing to ring-1 stack - .long FAULT13,kill_domain_fixup3 # Fault writing to ring-1 stack - .long FAULT14,kill_domain_fixup3 # Fault writing to ring-1 stack + .long FAULT1, crash_domain_fixup3 # Fault writing to ring-1 stack + .long FAULT2, crash_domain_fixup3 # Fault writing to ring-1 stack + .long FAULT3, crash_domain_fixup3 # Fault writing to ring-1 stack + .long FAULT4, crash_domain_fixup3 # Fault writing to ring-1 stack + .long FAULT5, crash_domain_fixup1 # Fault executing failsafe iret + .long FAULT6, crash_domain_fixup2 # Fault loading ring-1 stack selector + .long FAULT7, crash_domain_fixup2 # Fault writing to ring-1 stack + .long FAULT8, crash_domain_fixup2 # Fault writing to ring-1 stack + .long FAULT9, crash_domain_fixup2 # Fault loading ring-1 stack selector + .long FAULT10,crash_domain_fixup2 # Fault writing to ring-1 stack + .long FAULT11,crash_domain_fixup2 # Fault writing to ring-1 stack + .long FAULT12,crash_domain_fixup2 # Fault writing to ring-1 stack + .long FAULT13,crash_domain_fixup3 # Fault writing to ring-1 stack + .long FAULT14,crash_domain_fixup3 # Fault writing to ring-1 stack .previous # This handler kills domains which experience unrecoverable faults. .section .fixup,"ax" -kill_domain_fixup1: +crash_domain_fixup1: subl $4,%esp SAVE_ALL - jmp kill_domain -kill_domain_fixup2: + jmp crash_domain +crash_domain_fixup2: addl $4,%esp -kill_domain_fixup3: +crash_domain_fixup3: pushl %ss popl %ds - jmp kill_domain + jmp crash_domain .previous ALIGN diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 39847e58f1..666942301d 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -282,11 +282,12 @@ long do_dom0_op(dom0_op_t *u_dom0_op) case DOM0_GETDOMAININFO: { - struct task_struct *p; - u_long flags; - int i; + full_execution_context_t *c; + struct task_struct *p; + unsigned long flags; + int i; - read_lock_irqsave (&tasklist_lock, flags); + read_lock_irqsave(&tasklist_lock, flags); for_each_domain ( p ) { @@ -294,7 +295,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) break; } - if ( p == NULL ) + if ( (p == NULL) || (p->state == TASK_DYING) ) { ret = -ESRCH; goto gdi_out; @@ -302,12 +303,23 @@ long do_dom0_op(dom0_op_t *u_dom0_op) else { op->u.getdomaininfo.domain = p->domain; - strcpy (op->u.getdomaininfo.name, p->name); - op->u.getdomaininfo.processor = p->processor; - op->u.getdomaininfo.has_cpu = p->has_cpu; - op->u.getdomaininfo.state = DOMSTATE_ACTIVE; - if ( (p->state == TASK_STOPPED) || (p->state == TASK_DYING) ) - op->u.getdomaininfo.state = DOMSTATE_STOPPED; + strcpy(op->u.getdomaininfo.name, p->name); + + if ( p->state == TASK_RUNNING ) + op->u.getdomaininfo.flags = + p->has_cpu ? DOMSTATE_RUNNING : DOMSTATE_RUNNABLE; + else if ( (p->state == TASK_INTERRUPTIBLE) || + (p->state == TASK_UNINTERRUPTIBLE) ) + op->u.getdomaininfo.flags = DOMSTATE_BLOCKED; + else if ( p->state == TASK_PAUSED ) + op->u.getdomaininfo.flags = DOMSTATE_PAUSED; + else if ( p->state == TASK_CRASHED ) + op->u.getdomaininfo.flags = DOMSTATE_CRASHED; + else + op->u.getdomaininfo.flags = DOMSTATE_STOPPED; + op->u.getdomaininfo.flags |= p->processor << DOMFLAGS_CPUSHIFT; + op->u.getdomaininfo.flags |= p->stop_code << DOMFLAGS_GUESTSHIFT; + op->u.getdomaininfo.hyp_events = p->hyp_events; op->u.getdomaininfo.tot_pages = p->tot_pages; op->u.getdomaininfo.max_pages = p->max_pages; @@ -315,13 +327,12 @@ long do_dom0_op(dom0_op_t *u_dom0_op) op->u.getdomaininfo.shared_info_frame = __pa(p->shared_info) >> PAGE_SHIFT; - if ( p->state == TASK_STOPPED && op->u.getdomaininfo.ctxt ) + if ( (p->state == TASK_STOPPED) && + (op->u.getdomaininfo.ctxt != NULL) ) { - full_execution_context_t *c=NULL; - if ( (c = kmalloc(sizeof(*c), GFP_KERNEL)) == NULL ) { - ret= -ENOMEM; + ret = -ENOMEM; goto gdi_out; } @@ -373,12 +384,11 @@ long do_dom0_op(dom0_op_t *u_dom0_op) c->failsafe_callback_eip = p->failsafe_address; - if( copy_to_user(op->u.getdomaininfo.ctxt, c, sizeof(*c)) ) - { + if ( copy_to_user(op->u.getdomaininfo.ctxt, c, sizeof(*c)) ) ret = -EINVAL; - } - if (c) kfree(c); + if ( c != NULL ) + kfree(c); } } @@ -387,7 +397,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op) gdi_out: read_unlock_irqrestore(&tasklist_lock, flags); - } break; diff --git a/xen/common/domain.c b/xen/common/domain.c index 6c0dccc8ac..3da5d7913a 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -170,13 +170,6 @@ struct task_struct *find_last_domain(void) } -void kill_domain_with_errmsg(const char *err) -{ - printk("DOM%u FATAL ERROR: %s\n", current->domain, err); - kill_domain(); -} - - void __kill_domain(struct task_struct *p) { int i; @@ -245,7 +238,7 @@ long kill_other_domain(domid_t dom, int force) if ( (p = find_domain_by_id(dom)) == NULL ) return -ESRCH; - if ( p->state == TASK_STOPPED ) + if ( (p->state == TASK_STOPPED) || (p->state == TASK_CRASHED) ) __kill_domain(p); else if ( force ) send_hyp_event(p, _HYP_EVENT_DIE); @@ -256,8 +249,27 @@ long kill_other_domain(domid_t dom, int force) return 0; } -void stop_domain(void) + +void crash_domain(void) { + struct task_struct *p; + + set_current_state(TASK_CRASHED); + + p = find_domain_by_id(0); + send_guest_virq(p, VIRQ_DOM_EXC); + put_task_struct(p); + + __enter_scheduler(); + BUG(); +} + + +void stop_domain(u8 reason) +{ + struct task_struct *p; + + current->stop_code = reason; memcpy(¤t->shared_info->execution_context, get_execution_context(), sizeof(execution_context_t)); @@ -265,13 +277,9 @@ void stop_domain(void) wmb(); /* All CPUs must see saved info in state TASK_STOPPED. */ set_current_state(TASK_STOPPED); - /* OK, this is grim, but helps speed up live migrate. When a domain stops, - kick Dom0 */ - { - struct task_struct *p; - guest_schedule_to_run( p = find_domain_by_id(0ULL) ); - put_task_struct(p); - } + p = find_domain_by_id(0); + send_guest_virq(p, VIRQ_DOM_EXC); + put_task_struct(p); __enter_scheduler(); } diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 00929ffc93..116ee14574 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -244,7 +244,7 @@ long do_sched_op(unsigned long op) { long ret = 0; - switch( op ) + switch ( op & SCHEDOP_cmdmask ) { case SCHEDOP_yield: @@ -259,19 +259,9 @@ long do_sched_op(unsigned long op) break; } - case SCHEDOP_exit: - { - DPRINTK("DOM%u killed itself!\n", current->domain); - DPRINTK(" EIP == %08lx\n", get_execution_context()->eip); - kill_domain(); - break; - } - case SCHEDOP_stop: { - DPRINTK("DOM%u stopped itself!\n", current->domain); - DPRINTK(" EIP == %08lx\n", get_execution_context()->eip); - stop_domain(); + stop_domain((u8)(op >> SCHEDOP_reasonshift)); break; } @@ -284,9 +274,9 @@ long do_sched_op(unsigned long op) /* - * sched_pause_sync - synchronously pause a domain's execution - * XXXX This is horibly broken -- here just as a place holder at present, - * do not use. + * sched_pause_sync - synchronously pause a domain's execution. + * XXXX This is horribly broken -- here just as a place holder at present, + * do not use. */ void sched_pause_sync(struct task_struct *p) { diff --git a/xen/include/hypervisor-ifs/dom0_ops.h b/xen/include/hypervisor-ifs/dom0_ops.h index cb16d58afa..2693dcd566 100644 --- a/xen/include/hypervisor-ifs/dom0_ops.h +++ b/xen/include/hypervisor-ifs/dom0_ops.h @@ -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 0xAAAA000E +#define DOM0_INTERFACE_VERSION 0xAAAA000F #define MAX_DOMAIN_NAME 16 @@ -84,24 +84,33 @@ typedef struct { #define DOM0_GETDOMAININFO 12 typedef struct { /* IN variables. */ - domid_t domain; /* 0 */ - u32 __pad; - full_execution_context_t *ctxt; /* 8 */ - MEMORY_PADDING; + domid_t domain; /* 0 */ /* NB. IN/OUT variable. */ /* OUT variables. */ - u8 name[MAX_DOMAIN_NAME]; /* 16 */ - u32 processor; /* 32 */ - u32 has_cpu; /* 36 */ -#define DOMSTATE_ACTIVE 0 -#define DOMSTATE_STOPPED 1 - u32 state; /* 40 */ - u32 hyp_events; /* 44 */ - u32 tot_pages; /* 48 */ - u32 max_pages; /* 52 */ - u64 cpu_time; /* 56 */ - memory_t shared_info_frame; /* 64: MFN of shared_info struct */ +#define DOMSTATE_CRASHED 0 /* Crashed domain; frozen for postmortem. */ +#define DOMSTATE_STOPPED 1 /* Domain voluntarily halted it execution. */ +#define DOMSTATE_PAUSED 2 /* Currently paused (forced non-schedulable). */ +#define DOMSTATE_BLOCKED 3 /* Currently blocked pending a wake-up event. */ +#define DOMSTATE_RUNNABLE 4 /* Currently runnable. */ +#define DOMSTATE_RUNNING 5 /* Currently running. */ +#define DOMFLAGS_STATEMASK 7 /* One of the DOMSTATE_??? values. */ +#define DOMFLAGS_STATESHIFT 0 +#define DOMFLAGS_CPUMASK 255 /* CPU to which this domain is bound. */ +#define DOMFLAGS_CPUSHIFT 3 +#define DOMFLAGS_GUESTMASK 255 /* DOMSTATE_STOPPED -> Guest-supplied code. */ +#define DOMFLAGS_GUESTSHIFT 11 + u32 flags; /* 4 */ + u8 name[MAX_DOMAIN_NAME]; /* 8 */ + full_execution_context_t *ctxt; /* 24 */ /* NB. IN/OUT variable. */ + MEMORY_PADDING; + memory_t tot_pages; /* 32 */ + MEMORY_PADDING; + memory_t max_pages; /* 40 */ + MEMORY_PADDING; + memory_t shared_info_frame; /* 48: MFN of shared_info struct */ MEMORY_PADDING; -} PACKED dom0_getdomaininfo_t; /* 72 bytes */ + u64 cpu_time; /* 56 */ + u32 hyp_events; /* 64 */ +} PACKED dom0_getdomaininfo_t; /* 68 bytes */ #define DOM0_BUILDDOMAIN 13 typedef struct { @@ -314,7 +323,7 @@ typedef struct { u32 cmd; /* 0 */ u32 interface_version; /* 4 */ /* DOM0_INTERFACE_VERSION */ union { /* 8 */ - u32 dummy[14]; /* 56 bytes */ + u32 dummy[18]; /* 72 bytes */ dom0_createdomain_t createdomain; dom0_startdomain_t startdomain; dom0_stopdomain_t stopdomain; @@ -341,6 +350,6 @@ typedef struct { dom0_setdomainmaxmem_t setdomainmaxmem; dom0_getpageframeinfo2_t getpageframeinfo2; } PACKED u; -} PACKED dom0_op_t; /* 64 bytes */ +} PACKED dom0_op_t; /* 80 bytes */ #endif /* __DOM0_OPS_H__ */ diff --git a/xen/include/hypervisor-ifs/hypervisor-if.h b/xen/include/hypervisor-ifs/hypervisor-if.h index 3e9aa19d07..0c41fd71b5 100644 --- a/xen/include/hypervisor-ifs/hypervisor-if.h +++ b/xen/include/hypervisor-ifs/hypervisor-if.h @@ -59,19 +59,20 @@ * * Virtual interrupts that a guest OS may receive from the hypervisor. */ -#define VIRQ_BLKDEV 0 /* A block device response has been queued. */ +#define VIRQ_BLKDEV 0 /* (OBS) A block device response has been queued. */ #define VIRQ_TIMER 1 /* A timeout has been updated. */ -#define VIRQ_DIE 2 /* OS is about to be killed. Clean up please! */ +#define VIRQ_DIE 2 /* (OBS) OS is about to be killed. Clean up! */ #define VIRQ_DEBUG 3 /* Request guest to dump debug info (gross!) */ -#define VIRQ_NET 4 /* There are packets for transmission. */ -#define VIRQ_PS2 5 /* PS/2 keyboard or mouse event(s) */ -#define VIRQ_STOP 6 /* Prepare for stopping and possible pickling */ +#define VIRQ_NET 4 /* (OBS) There are packets for transmission. */ +#define VIRQ_PS2 5 /* (OBS) PS/2 keyboard or mouse event(s) */ +#define VIRQ_STOP 6 /* (OBS) Prepare for stopping and pickling */ #define VIRQ_EVTCHN 7 /* Event pending on an event channel */ -#define VIRQ_VBD_UPD 8 /* Event to signal VBDs should be reprobed */ -#define VIRQ_CONSOLE 9 /* This is only for domain-0 initial console. */ -#define VIRQ_PHYSIRQ 10 /* Event to signal pending physical IRQs. */ +#define VIRQ_VBD_UPD 8 /* (OBS) Event to signal VBDs should be reprobed */ +#define VIRQ_CONSOLE 9 /* (DOM0) bytes received on master console. */ +#define VIRQ_PHYSIRQ 10 /* Pending physical IRQs. */ #define VIRQ_MISDIRECT 11 /* Catch-all virtual interrupt. */ -#define NR_VIRQS 12 +#define VIRQ_DOM_EXC 12 /* (DOM0) Exceptional event for some domain. */ +#define NR_VIRQS 13 /* * MMU-UPDATE REQUESTS @@ -169,8 +170,9 @@ */ #define SCHEDOP_yield 0 /* Give up the CPU voluntarily. */ #define SCHEDOP_block 1 /* Block until an event is received. */ -#define SCHEDOP_exit 3 /* Exit and kill this domain. */ #define SCHEDOP_stop 4 /* Stop executing this domain. */ +#define SCHEDOP_cmdmask 255 /* 8-bit command. */ +#define SCHEDOP_reasonshift 8 /* 8-bit stop code. (SCHEDOP_stop only) */ /* * Commands to HYPERVISOR_console_io(). diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index a9464415fc..4df8980444 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -123,6 +123,7 @@ struct task_struct struct list_head run_list; int has_cpu; int state; /* current run state */ + int stop_code; /* stop code from OS (if TASK_STOPPED). */ int cpupinned; /* true if pinned to curent CPU */ s_time_t lastschd; /* time this domain was last scheduled */ s_time_t lastdeschd; /* time this domain was last descheduled */ @@ -207,6 +208,7 @@ struct task_struct #define TASK_STOPPED 4 #define TASK_DYING 8 #define TASK_PAUSED 16 +#define TASK_CRASHED 32 #include /* for KERNEL_DS */ @@ -255,9 +257,8 @@ struct task_struct *find_last_domain(void); extern void release_task(struct task_struct *); extern void __kill_domain(struct task_struct *p); extern void kill_domain(void); -extern void kill_domain_with_errmsg(const char *err); extern long kill_other_domain(domid_t dom, int force); -extern void stop_domain(void); +extern void stop_domain(u8 reason); extern long stop_other_domain(domid_t dom); /* arch/process.c */