ia64/xen-unstable
changeset 1447:a956305055ae
bitkeeper revision 1.947 (40c84719Ozi8_o69nGYdNuJ6OQd4eQ)
Cleanup domain stop/crash. Provide notification to DOM0 so that
cleanup/postmortem can occur before domain is killed.
Cleanup domain stop/crash. Provide notification to DOM0 so that
cleanup/postmortem can occur before domain is killed.
line diff
1.1 --- a/extras/mini-os/h/hypervisor.h Wed Jun 09 16:36:08 2004 +0000 1.2 +++ b/extras/mini-os/h/hypervisor.h Thu Jun 10 11:33:45 2004 +0000 1.3 @@ -15,7 +15,7 @@ 1.4 #include <hypervisor-ifs/network.h> 1.5 #include <hypervisor-ifs/block.h> 1.6 #include <hypervisor-ifs/hypervisor-if.h> 1.7 - 1.8 +#include "../../../tools/xend/lib/domain_controller.h" 1.9 1.10 /* 1.11 * a placeholder for the start of day information passed up from the hypervisor 1.12 @@ -155,25 +155,39 @@ static __inline__ int HYPERVISOR_block(v 1.13 return ret; 1.14 } 1.15 1.16 -static __inline__ int HYPERVISOR_exit(void) 1.17 +static inline int HYPERVISOR_shutdown(void) 1.18 { 1.19 int ret; 1.20 __asm__ __volatile__ ( 1.21 TRAP_INSTR 1.22 : "=a" (ret) : "0" (__HYPERVISOR_sched_op), 1.23 - "b" (SCHEDOP_exit) : "memory" ); 1.24 + "b" (SCHEDOP_stop | (STOPCODE_shutdown << SCHEDOP_reasonshift)) 1.25 + : "memory" ); 1.26 1.27 return ret; 1.28 } 1.29 1.30 -static __inline__ int HYPERVISOR_stop(unsigned long srec) 1.31 +static inline int HYPERVISOR_reboot(void) 1.32 +{ 1.33 + int ret; 1.34 + __asm__ __volatile__ ( 1.35 + TRAP_INSTR 1.36 + : "=a" (ret) : "0" (__HYPERVISOR_sched_op), 1.37 + "b" (SCHEDOP_stop | (STOPCODE_reboot << SCHEDOP_reasonshift)) 1.38 + : "memory" ); 1.39 + 1.40 + return ret; 1.41 +} 1.42 + 1.43 +static inline int HYPERVISOR_suspend(unsigned long srec) 1.44 { 1.45 int ret; 1.46 /* NB. On suspend, control software expects a suspend record in %esi. */ 1.47 __asm__ __volatile__ ( 1.48 TRAP_INSTR 1.49 : "=a" (ret) : "0" (__HYPERVISOR_sched_op), 1.50 - "b" (SCHEDOP_stop), "S" (srec) : "memory" ); 1.51 + "b" (SCHEDOP_stop | (STOPCODE_suspend << SCHEDOP_reasonshift)), 1.52 + "S" (srec) : "memory" ); 1.53 1.54 return ret; 1.55 }
2.1 --- a/extras/mini-os/kernel.c Wed Jun 09 16:36:08 2004 +0000 2.2 +++ b/extras/mini-os/kernel.c Thu Jun 10 11:33:45 2004 +0000 2.3 @@ -153,7 +153,7 @@ void start_kernel(start_info_t *si) 2.4 void do_exit(void) 2.5 { 2.6 printk("do_exit called!\n"); 2.7 - for ( ;; ) HYPERVISOR_exit(); 2.8 + for ( ;; ) HYPERVISOR_shutdown(); 2.9 } 2.10 static void exit_handler(int ev, struct pt_regs *regs) { 2.11 do_exit();
3.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/process.c Wed Jun 09 16:36:08 2004 +0000 3.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/process.c Thu Jun 10 11:33:45 2004 +0000 3.3 @@ -120,17 +120,23 @@ void machine_restart(char * __unused) 3.4 /* We really want to get pending console data out before we die. */ 3.5 extern void xencons_force_flush(void); 3.6 xencons_force_flush(); 3.7 - HYPERVISOR_exit(); 3.8 + HYPERVISOR_reboot(); 3.9 } 3.10 3.11 void machine_halt(void) 3.12 { 3.13 - machine_restart(NULL); 3.14 + /* We really want to get pending console data out before we die. */ 3.15 + extern void xencons_force_flush(void); 3.16 + xencons_force_flush(); 3.17 + HYPERVISOR_shutdown(); 3.18 } 3.19 3.20 void machine_power_off(void) 3.21 { 3.22 - machine_restart(NULL); 3.23 + /* We really want to get pending console data out before we die. */ 3.24 + extern void xencons_force_flush(void); 3.25 + xencons_force_flush(); 3.26 + HYPERVISOR_shutdown(); 3.27 } 3.28 3.29 extern void show_trace(unsigned long* esp);
4.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c Wed Jun 09 16:36:08 2004 +0000 4.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c Thu Jun 10 11:33:45 2004 +0000 4.3 @@ -1205,7 +1205,7 @@ static void stop_task(void *unused) 4.4 4.5 memcpy(&suspend_record->resume_info, &start_info, sizeof(start_info)); 4.6 4.7 - HYPERVISOR_stop(virt_to_machine(suspend_record) >> PAGE_SHIFT); 4.8 + HYPERVISOR_suspend(virt_to_machine(suspend_record) >> PAGE_SHIFT); 4.9 4.10 suspending = 0; 4.11
5.1 --- a/linux-2.4.26-xen-sparse/include/asm-xen/hypervisor.h Wed Jun 09 16:36:08 2004 +0000 5.2 +++ b/linux-2.4.26-xen-sparse/include/asm-xen/hypervisor.h Thu Jun 10 11:33:45 2004 +0000 5.3 @@ -253,25 +253,39 @@ static inline int HYPERVISOR_block(void) 5.4 return ret; 5.5 } 5.6 5.7 -static inline int HYPERVISOR_exit(void) 5.8 +static inline int HYPERVISOR_shutdown(void) 5.9 { 5.10 int ret; 5.11 __asm__ __volatile__ ( 5.12 TRAP_INSTR 5.13 : "=a" (ret) : "0" (__HYPERVISOR_sched_op), 5.14 - "b" (SCHEDOP_exit) : "memory" ); 5.15 + "b" (SCHEDOP_stop | (STOPCODE_shutdown << SCHEDOP_reasonshift)) 5.16 + : "memory" ); 5.17 5.18 return ret; 5.19 } 5.20 5.21 -static inline int HYPERVISOR_stop(unsigned long srec) 5.22 +static inline int HYPERVISOR_reboot(void) 5.23 +{ 5.24 + int ret; 5.25 + __asm__ __volatile__ ( 5.26 + TRAP_INSTR 5.27 + : "=a" (ret) : "0" (__HYPERVISOR_sched_op), 5.28 + "b" (SCHEDOP_stop | (STOPCODE_reboot << SCHEDOP_reasonshift)) 5.29 + : "memory" ); 5.30 + 5.31 + return ret; 5.32 +} 5.33 + 5.34 +static inline int HYPERVISOR_suspend(unsigned long srec) 5.35 { 5.36 int ret; 5.37 /* NB. On suspend, control software expects a suspend record in %esi. */ 5.38 __asm__ __volatile__ ( 5.39 TRAP_INSTR 5.40 : "=a" (ret) : "0" (__HYPERVISOR_sched_op), 5.41 - "b" (SCHEDOP_stop), "S" (srec) : "memory" ); 5.42 + "b" (SCHEDOP_stop | (STOPCODE_suspend << SCHEDOP_reasonshift)), 5.43 + "S" (srec) : "memory" ); 5.44 5.45 return ret; 5.46 }
6.1 --- a/tools/xc/lib/xc_domain.c Wed Jun 09 16:36:08 2004 +0000 6.2 +++ b/tools/xc/lib/xc_domain.c Thu Jun 10 11:33:45 2004 +0000 6.3 @@ -91,9 +91,14 @@ int xc_domain_getinfo(int xc_handle, 6.4 if ( do_dom0_op(xc_handle, &op) < 0 ) 6.5 break; 6.6 info->domid = (u32)op.u.getdomaininfo.domain; 6.7 - info->cpu = op.u.getdomaininfo.processor; 6.8 - info->has_cpu = op.u.getdomaininfo.has_cpu; 6.9 - info->stopped = (op.u.getdomaininfo.state == DOMSTATE_STOPPED); 6.10 + 6.11 + info->cpu = 6.12 + (op.u.getdomaininfo.flags>>DOMFLAGS_CPUSHIFT) & DOMFLAGS_CPUMASK; 6.13 + info->has_cpu = 6.14 + (op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) == DOMSTATE_RUNNING; 6.15 + info->stopped = 6.16 + (op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) == DOMSTATE_STOPPED; 6.17 + 6.18 info->nr_pages = op.u.getdomaininfo.tot_pages; 6.19 info->max_memkb = op.u.getdomaininfo.max_pages<<(PAGE_SHIFT-10); 6.20 info->shared_info_frame = op.u.getdomaininfo.shared_info_frame;
7.1 --- a/tools/xc/lib/xc_linux_build.c Wed Jun 09 16:36:08 2004 +0000 7.2 +++ b/tools/xc/lib/xc_linux_build.c Thu Jun 10 11:33:45 2004 +0000 7.3 @@ -436,7 +436,7 @@ int xc_linux_build(int xc_handle, 7.4 PERROR("Could not get info on domain"); 7.5 goto error_out; 7.6 } 7.7 - if ( (op.u.getdomaininfo.state != DOMSTATE_STOPPED) || 7.8 + if ( ((op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) != DOMSTATE_STOPPED) || 7.9 (ctxt->pt_base != 0) ) 7.10 { 7.11 ERROR("Domain is already constructed");
8.1 --- a/tools/xc/lib/xc_netbsd_build.c Wed Jun 09 16:36:08 2004 +0000 8.2 +++ b/tools/xc/lib/xc_netbsd_build.c Thu Jun 10 11:33:45 2004 +0000 8.3 @@ -258,7 +258,7 @@ int xc_netbsd_build(int xc_handle, 8.4 PERROR("Could not get info on domain"); 8.5 goto error_out; 8.6 } 8.7 - if ( (op.u.getdomaininfo.state != DOMSTATE_STOPPED) || 8.8 + if ( ((op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) != DOMSTATE_STOPPED) || 8.9 (op.u.getdomaininfo.ctxt->pt_base != 0) ) 8.10 { 8.11 ERROR("Domain is already constructed");
9.1 --- a/tools/xc/lib/xc_private.c Wed Jun 09 16:36:08 2004 +0000 9.2 +++ b/tools/xc/lib/xc_private.c Thu Jun 10 11:33:45 2004 +0000 9.3 @@ -229,7 +229,8 @@ int xc_domain_stop_sync( int xc_handle, 9.4 goto out; 9.5 } 9.6 9.7 - if ( op->u.getdomaininfo.state == DOMSTATE_STOPPED ) 9.8 + if ( (op->u.getdomaininfo.flags & DOMFLAGS_STATEMASK) == 9.9 + DOMSTATE_STOPPED ) 9.10 { 9.11 printf("Domain %u stopped\n",domid); 9.12 return 0;
10.1 --- a/tools/xend/lib/domain_controller.h Wed Jun 09 16:36:08 2004 +0000 10.2 +++ b/tools/xend/lib/domain_controller.h Thu Jun 10 11:33:45 2004 +0000 10.3 @@ -29,6 +29,16 @@ typedef struct { 10.4 10.5 10.6 /* 10.7 + * Stop codes for SCHEDOP_stop. These are opaque to Xen but interpreted by 10.8 + * control software to determine appropriate action. 10.9 + */ 10.10 + 10.11 +#define STOPCODE_shutdown 0 /* Domain exited normally. Clean up and kill. */ 10.12 +#define STOPCODE_reboot 1 /* Clean up, kill, and then restart. */ 10.13 +#define STOPCODE_suspend 2 /* Clean up, save suspend info, kill. */ 10.14 + 10.15 + 10.16 +/* 10.17 * CONTROLLER MESSAGING INTERFACE. 10.18 */ 10.19
11.1 --- a/xen/arch/i386/entry.S Wed Jun 09 16:36:08 2004 +0000 11.2 +++ b/xen/arch/i386/entry.S Thu Jun 10 11:33:45 2004 +0000 11.3 @@ -446,34 +446,34 @@ FAULT12:movl %eax,8(%esi) 11.4 11.5 .section __ex_table,"a" 11.6 .align 4 11.7 - .long FAULT1, kill_domain_fixup3 # Fault writing to ring-1 stack 11.8 - .long FAULT2, kill_domain_fixup3 # Fault writing to ring-1 stack 11.9 - .long FAULT3, kill_domain_fixup3 # Fault writing to ring-1 stack 11.10 - .long FAULT4, kill_domain_fixup3 # Fault writing to ring-1 stack 11.11 - .long FAULT5, kill_domain_fixup1 # Fault executing failsafe iret 11.12 - .long FAULT6, kill_domain_fixup2 # Fault loading ring-1 stack selector 11.13 - .long FAULT7, kill_domain_fixup2 # Fault writing to ring-1 stack 11.14 - .long FAULT8, kill_domain_fixup2 # Fault writing to ring-1 stack 11.15 - .long FAULT9, kill_domain_fixup2 # Fault loading ring-1 stack selector 11.16 - .long FAULT10,kill_domain_fixup2 # Fault writing to ring-1 stack 11.17 - .long FAULT11,kill_domain_fixup2 # Fault writing to ring-1 stack 11.18 - .long FAULT12,kill_domain_fixup2 # Fault writing to ring-1 stack 11.19 - .long FAULT13,kill_domain_fixup3 # Fault writing to ring-1 stack 11.20 - .long FAULT14,kill_domain_fixup3 # Fault writing to ring-1 stack 11.21 + .long FAULT1, crash_domain_fixup3 # Fault writing to ring-1 stack 11.22 + .long FAULT2, crash_domain_fixup3 # Fault writing to ring-1 stack 11.23 + .long FAULT3, crash_domain_fixup3 # Fault writing to ring-1 stack 11.24 + .long FAULT4, crash_domain_fixup3 # Fault writing to ring-1 stack 11.25 + .long FAULT5, crash_domain_fixup1 # Fault executing failsafe iret 11.26 + .long FAULT6, crash_domain_fixup2 # Fault loading ring-1 stack selector 11.27 + .long FAULT7, crash_domain_fixup2 # Fault writing to ring-1 stack 11.28 + .long FAULT8, crash_domain_fixup2 # Fault writing to ring-1 stack 11.29 + .long FAULT9, crash_domain_fixup2 # Fault loading ring-1 stack selector 11.30 + .long FAULT10,crash_domain_fixup2 # Fault writing to ring-1 stack 11.31 + .long FAULT11,crash_domain_fixup2 # Fault writing to ring-1 stack 11.32 + .long FAULT12,crash_domain_fixup2 # Fault writing to ring-1 stack 11.33 + .long FAULT13,crash_domain_fixup3 # Fault writing to ring-1 stack 11.34 + .long FAULT14,crash_domain_fixup3 # Fault writing to ring-1 stack 11.35 .previous 11.36 11.37 # This handler kills domains which experience unrecoverable faults. 11.38 .section .fixup,"ax" 11.39 -kill_domain_fixup1: 11.40 +crash_domain_fixup1: 11.41 subl $4,%esp 11.42 SAVE_ALL 11.43 - jmp kill_domain 11.44 -kill_domain_fixup2: 11.45 + jmp crash_domain 11.46 +crash_domain_fixup2: 11.47 addl $4,%esp 11.48 -kill_domain_fixup3: 11.49 +crash_domain_fixup3: 11.50 pushl %ss 11.51 popl %ds 11.52 - jmp kill_domain 11.53 + jmp crash_domain 11.54 .previous 11.55 11.56 ALIGN
12.1 --- a/xen/common/dom0_ops.c Wed Jun 09 16:36:08 2004 +0000 12.2 +++ b/xen/common/dom0_ops.c Thu Jun 10 11:33:45 2004 +0000 12.3 @@ -282,11 +282,12 @@ long do_dom0_op(dom0_op_t *u_dom0_op) 12.4 12.5 case DOM0_GETDOMAININFO: 12.6 { 12.7 - struct task_struct *p; 12.8 - u_long flags; 12.9 - int i; 12.10 + full_execution_context_t *c; 12.11 + struct task_struct *p; 12.12 + unsigned long flags; 12.13 + int i; 12.14 12.15 - read_lock_irqsave (&tasklist_lock, flags); 12.16 + read_lock_irqsave(&tasklist_lock, flags); 12.17 12.18 for_each_domain ( p ) 12.19 { 12.20 @@ -294,7 +295,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) 12.21 break; 12.22 } 12.23 12.24 - if ( p == NULL ) 12.25 + if ( (p == NULL) || (p->state == TASK_DYING) ) 12.26 { 12.27 ret = -ESRCH; 12.28 goto gdi_out; 12.29 @@ -302,12 +303,23 @@ long do_dom0_op(dom0_op_t *u_dom0_op) 12.30 else 12.31 { 12.32 op->u.getdomaininfo.domain = p->domain; 12.33 - strcpy (op->u.getdomaininfo.name, p->name); 12.34 - op->u.getdomaininfo.processor = p->processor; 12.35 - op->u.getdomaininfo.has_cpu = p->has_cpu; 12.36 - op->u.getdomaininfo.state = DOMSTATE_ACTIVE; 12.37 - if ( (p->state == TASK_STOPPED) || (p->state == TASK_DYING) ) 12.38 - op->u.getdomaininfo.state = DOMSTATE_STOPPED; 12.39 + strcpy(op->u.getdomaininfo.name, p->name); 12.40 + 12.41 + if ( p->state == TASK_RUNNING ) 12.42 + op->u.getdomaininfo.flags = 12.43 + p->has_cpu ? DOMSTATE_RUNNING : DOMSTATE_RUNNABLE; 12.44 + else if ( (p->state == TASK_INTERRUPTIBLE) || 12.45 + (p->state == TASK_UNINTERRUPTIBLE) ) 12.46 + op->u.getdomaininfo.flags = DOMSTATE_BLOCKED; 12.47 + else if ( p->state == TASK_PAUSED ) 12.48 + op->u.getdomaininfo.flags = DOMSTATE_PAUSED; 12.49 + else if ( p->state == TASK_CRASHED ) 12.50 + op->u.getdomaininfo.flags = DOMSTATE_CRASHED; 12.51 + else 12.52 + op->u.getdomaininfo.flags = DOMSTATE_STOPPED; 12.53 + op->u.getdomaininfo.flags |= p->processor << DOMFLAGS_CPUSHIFT; 12.54 + op->u.getdomaininfo.flags |= p->stop_code << DOMFLAGS_GUESTSHIFT; 12.55 + 12.56 op->u.getdomaininfo.hyp_events = p->hyp_events; 12.57 op->u.getdomaininfo.tot_pages = p->tot_pages; 12.58 op->u.getdomaininfo.max_pages = p->max_pages; 12.59 @@ -315,13 +327,12 @@ long do_dom0_op(dom0_op_t *u_dom0_op) 12.60 op->u.getdomaininfo.shared_info_frame = 12.61 __pa(p->shared_info) >> PAGE_SHIFT; 12.62 12.63 - if ( p->state == TASK_STOPPED && op->u.getdomaininfo.ctxt ) 12.64 + if ( (p->state == TASK_STOPPED) && 12.65 + (op->u.getdomaininfo.ctxt != NULL) ) 12.66 { 12.67 - full_execution_context_t *c=NULL; 12.68 - 12.69 if ( (c = kmalloc(sizeof(*c), GFP_KERNEL)) == NULL ) 12.70 { 12.71 - ret= -ENOMEM; 12.72 + ret = -ENOMEM; 12.73 goto gdi_out; 12.74 } 12.75 12.76 @@ -373,12 +384,11 @@ long do_dom0_op(dom0_op_t *u_dom0_op) 12.77 c->failsafe_callback_eip = 12.78 p->failsafe_address; 12.79 12.80 - if( copy_to_user(op->u.getdomaininfo.ctxt, c, sizeof(*c)) ) 12.81 - { 12.82 + if ( copy_to_user(op->u.getdomaininfo.ctxt, c, sizeof(*c)) ) 12.83 ret = -EINVAL; 12.84 - } 12.85 12.86 - if (c) kfree(c); 12.87 + if ( c != NULL ) 12.88 + kfree(c); 12.89 } 12.90 } 12.91 12.92 @@ -387,7 +397,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op) 12.93 12.94 gdi_out: 12.95 read_unlock_irqrestore(&tasklist_lock, flags); 12.96 - 12.97 } 12.98 break; 12.99
13.1 --- a/xen/common/domain.c Wed Jun 09 16:36:08 2004 +0000 13.2 +++ b/xen/common/domain.c Thu Jun 10 11:33:45 2004 +0000 13.3 @@ -170,13 +170,6 @@ struct task_struct *find_last_domain(voi 13.4 } 13.5 13.6 13.7 -void kill_domain_with_errmsg(const char *err) 13.8 -{ 13.9 - printk("DOM%u FATAL ERROR: %s\n", current->domain, err); 13.10 - kill_domain(); 13.11 -} 13.12 - 13.13 - 13.14 void __kill_domain(struct task_struct *p) 13.15 { 13.16 int i; 13.17 @@ -245,7 +238,7 @@ long kill_other_domain(domid_t dom, int 13.18 if ( (p = find_domain_by_id(dom)) == NULL ) 13.19 return -ESRCH; 13.20 13.21 - if ( p->state == TASK_STOPPED ) 13.22 + if ( (p->state == TASK_STOPPED) || (p->state == TASK_CRASHED) ) 13.23 __kill_domain(p); 13.24 else if ( force ) 13.25 send_hyp_event(p, _HYP_EVENT_DIE); 13.26 @@ -256,8 +249,27 @@ long kill_other_domain(domid_t dom, int 13.27 return 0; 13.28 } 13.29 13.30 -void stop_domain(void) 13.31 + 13.32 +void crash_domain(void) 13.33 { 13.34 + struct task_struct *p; 13.35 + 13.36 + set_current_state(TASK_CRASHED); 13.37 + 13.38 + p = find_domain_by_id(0); 13.39 + send_guest_virq(p, VIRQ_DOM_EXC); 13.40 + put_task_struct(p); 13.41 + 13.42 + __enter_scheduler(); 13.43 + BUG(); 13.44 +} 13.45 + 13.46 + 13.47 +void stop_domain(u8 reason) 13.48 +{ 13.49 + struct task_struct *p; 13.50 + 13.51 + current->stop_code = reason; 13.52 memcpy(¤t->shared_info->execution_context, 13.53 get_execution_context(), 13.54 sizeof(execution_context_t)); 13.55 @@ -265,13 +277,9 @@ void stop_domain(void) 13.56 wmb(); /* All CPUs must see saved info in state TASK_STOPPED. */ 13.57 set_current_state(TASK_STOPPED); 13.58 13.59 - /* OK, this is grim, but helps speed up live migrate. When a domain stops, 13.60 - kick Dom0 */ 13.61 - { 13.62 - struct task_struct *p; 13.63 - guest_schedule_to_run( p = find_domain_by_id(0ULL) ); 13.64 - put_task_struct(p); 13.65 - } 13.66 + p = find_domain_by_id(0); 13.67 + send_guest_virq(p, VIRQ_DOM_EXC); 13.68 + put_task_struct(p); 13.69 13.70 __enter_scheduler(); 13.71 }
14.1 --- a/xen/common/schedule.c Wed Jun 09 16:36:08 2004 +0000 14.2 +++ b/xen/common/schedule.c Thu Jun 10 11:33:45 2004 +0000 14.3 @@ -244,7 +244,7 @@ long do_sched_op(unsigned long op) 14.4 { 14.5 long ret = 0; 14.6 14.7 - switch( op ) 14.8 + switch ( op & SCHEDOP_cmdmask ) 14.9 { 14.10 14.11 case SCHEDOP_yield: 14.12 @@ -259,19 +259,9 @@ long do_sched_op(unsigned long op) 14.13 break; 14.14 } 14.15 14.16 - case SCHEDOP_exit: 14.17 - { 14.18 - DPRINTK("DOM%u killed itself!\n", current->domain); 14.19 - DPRINTK(" EIP == %08lx\n", get_execution_context()->eip); 14.20 - kill_domain(); 14.21 - break; 14.22 - } 14.23 - 14.24 case SCHEDOP_stop: 14.25 { 14.26 - DPRINTK("DOM%u stopped itself!\n", current->domain); 14.27 - DPRINTK(" EIP == %08lx\n", get_execution_context()->eip); 14.28 - stop_domain(); 14.29 + stop_domain((u8)(op >> SCHEDOP_reasonshift)); 14.30 break; 14.31 } 14.32 14.33 @@ -284,9 +274,9 @@ long do_sched_op(unsigned long op) 14.34 14.35 14.36 /* 14.37 - * sched_pause_sync - synchronously pause a domain's execution 14.38 - * XXXX This is horibly broken -- here just as a place holder at present, 14.39 - * do not use. 14.40 + * sched_pause_sync - synchronously pause a domain's execution. 14.41 + * XXXX This is horribly broken -- here just as a place holder at present, 14.42 + * do not use. 14.43 */ 14.44 void sched_pause_sync(struct task_struct *p) 14.45 {
15.1 --- a/xen/include/hypervisor-ifs/dom0_ops.h Wed Jun 09 16:36:08 2004 +0000 15.2 +++ b/xen/include/hypervisor-ifs/dom0_ops.h Thu Jun 10 11:33:45 2004 +0000 15.3 @@ -19,7 +19,7 @@ 15.4 * This makes sure that old versions of dom0 tools will stop working in a 15.5 * well-defined way (rather than crashing the machine, for instance). 15.6 */ 15.7 -#define DOM0_INTERFACE_VERSION 0xAAAA000E 15.8 +#define DOM0_INTERFACE_VERSION 0xAAAA000F 15.9 15.10 #define MAX_DOMAIN_NAME 16 15.11 15.12 @@ -84,24 +84,33 @@ typedef struct { 15.13 #define DOM0_GETDOMAININFO 12 15.14 typedef struct { 15.15 /* IN variables. */ 15.16 - domid_t domain; /* 0 */ 15.17 - u32 __pad; 15.18 - full_execution_context_t *ctxt; /* 8 */ 15.19 - MEMORY_PADDING; 15.20 + domid_t domain; /* 0 */ /* NB. IN/OUT variable. */ 15.21 /* OUT variables. */ 15.22 - u8 name[MAX_DOMAIN_NAME]; /* 16 */ 15.23 - u32 processor; /* 32 */ 15.24 - u32 has_cpu; /* 36 */ 15.25 -#define DOMSTATE_ACTIVE 0 15.26 -#define DOMSTATE_STOPPED 1 15.27 - u32 state; /* 40 */ 15.28 - u32 hyp_events; /* 44 */ 15.29 - u32 tot_pages; /* 48 */ 15.30 - u32 max_pages; /* 52 */ 15.31 - u64 cpu_time; /* 56 */ 15.32 - memory_t shared_info_frame; /* 64: MFN of shared_info struct */ 15.33 +#define DOMSTATE_CRASHED 0 /* Crashed domain; frozen for postmortem. */ 15.34 +#define DOMSTATE_STOPPED 1 /* Domain voluntarily halted it execution. */ 15.35 +#define DOMSTATE_PAUSED 2 /* Currently paused (forced non-schedulable). */ 15.36 +#define DOMSTATE_BLOCKED 3 /* Currently blocked pending a wake-up event. */ 15.37 +#define DOMSTATE_RUNNABLE 4 /* Currently runnable. */ 15.38 +#define DOMSTATE_RUNNING 5 /* Currently running. */ 15.39 +#define DOMFLAGS_STATEMASK 7 /* One of the DOMSTATE_??? values. */ 15.40 +#define DOMFLAGS_STATESHIFT 0 15.41 +#define DOMFLAGS_CPUMASK 255 /* CPU to which this domain is bound. */ 15.42 +#define DOMFLAGS_CPUSHIFT 3 15.43 +#define DOMFLAGS_GUESTMASK 255 /* DOMSTATE_STOPPED -> Guest-supplied code. */ 15.44 +#define DOMFLAGS_GUESTSHIFT 11 15.45 + u32 flags; /* 4 */ 15.46 + u8 name[MAX_DOMAIN_NAME]; /* 8 */ 15.47 + full_execution_context_t *ctxt; /* 24 */ /* NB. IN/OUT variable. */ 15.48 MEMORY_PADDING; 15.49 -} PACKED dom0_getdomaininfo_t; /* 72 bytes */ 15.50 + memory_t tot_pages; /* 32 */ 15.51 + MEMORY_PADDING; 15.52 + memory_t max_pages; /* 40 */ 15.53 + MEMORY_PADDING; 15.54 + memory_t shared_info_frame; /* 48: MFN of shared_info struct */ 15.55 + MEMORY_PADDING; 15.56 + u64 cpu_time; /* 56 */ 15.57 + u32 hyp_events; /* 64 */ 15.58 +} PACKED dom0_getdomaininfo_t; /* 68 bytes */ 15.59 15.60 #define DOM0_BUILDDOMAIN 13 15.61 typedef struct { 15.62 @@ -314,7 +323,7 @@ typedef struct { 15.63 u32 cmd; /* 0 */ 15.64 u32 interface_version; /* 4 */ /* DOM0_INTERFACE_VERSION */ 15.65 union { /* 8 */ 15.66 - u32 dummy[14]; /* 56 bytes */ 15.67 + u32 dummy[18]; /* 72 bytes */ 15.68 dom0_createdomain_t createdomain; 15.69 dom0_startdomain_t startdomain; 15.70 dom0_stopdomain_t stopdomain; 15.71 @@ -341,6 +350,6 @@ typedef struct { 15.72 dom0_setdomainmaxmem_t setdomainmaxmem; 15.73 dom0_getpageframeinfo2_t getpageframeinfo2; 15.74 } PACKED u; 15.75 -} PACKED dom0_op_t; /* 64 bytes */ 15.76 +} PACKED dom0_op_t; /* 80 bytes */ 15.77 15.78 #endif /* __DOM0_OPS_H__ */
16.1 --- a/xen/include/hypervisor-ifs/hypervisor-if.h Wed Jun 09 16:36:08 2004 +0000 16.2 +++ b/xen/include/hypervisor-ifs/hypervisor-if.h Thu Jun 10 11:33:45 2004 +0000 16.3 @@ -59,19 +59,20 @@ 16.4 * 16.5 * Virtual interrupts that a guest OS may receive from the hypervisor. 16.6 */ 16.7 -#define VIRQ_BLKDEV 0 /* A block device response has been queued. */ 16.8 +#define VIRQ_BLKDEV 0 /* (OBS) A block device response has been queued. */ 16.9 #define VIRQ_TIMER 1 /* A timeout has been updated. */ 16.10 -#define VIRQ_DIE 2 /* OS is about to be killed. Clean up please! */ 16.11 +#define VIRQ_DIE 2 /* (OBS) OS is about to be killed. Clean up! */ 16.12 #define VIRQ_DEBUG 3 /* Request guest to dump debug info (gross!) */ 16.13 -#define VIRQ_NET 4 /* There are packets for transmission. */ 16.14 -#define VIRQ_PS2 5 /* PS/2 keyboard or mouse event(s) */ 16.15 -#define VIRQ_STOP 6 /* Prepare for stopping and possible pickling */ 16.16 +#define VIRQ_NET 4 /* (OBS) There are packets for transmission. */ 16.17 +#define VIRQ_PS2 5 /* (OBS) PS/2 keyboard or mouse event(s) */ 16.18 +#define VIRQ_STOP 6 /* (OBS) Prepare for stopping and pickling */ 16.19 #define VIRQ_EVTCHN 7 /* Event pending on an event channel */ 16.20 -#define VIRQ_VBD_UPD 8 /* Event to signal VBDs should be reprobed */ 16.21 -#define VIRQ_CONSOLE 9 /* This is only for domain-0 initial console. */ 16.22 -#define VIRQ_PHYSIRQ 10 /* Event to signal pending physical IRQs. */ 16.23 +#define VIRQ_VBD_UPD 8 /* (OBS) Event to signal VBDs should be reprobed */ 16.24 +#define VIRQ_CONSOLE 9 /* (DOM0) bytes received on master console. */ 16.25 +#define VIRQ_PHYSIRQ 10 /* Pending physical IRQs. */ 16.26 #define VIRQ_MISDIRECT 11 /* Catch-all virtual interrupt. */ 16.27 -#define NR_VIRQS 12 16.28 +#define VIRQ_DOM_EXC 12 /* (DOM0) Exceptional event for some domain. */ 16.29 +#define NR_VIRQS 13 16.30 16.31 /* 16.32 * MMU-UPDATE REQUESTS 16.33 @@ -169,8 +170,9 @@ 16.34 */ 16.35 #define SCHEDOP_yield 0 /* Give up the CPU voluntarily. */ 16.36 #define SCHEDOP_block 1 /* Block until an event is received. */ 16.37 -#define SCHEDOP_exit 3 /* Exit and kill this domain. */ 16.38 #define SCHEDOP_stop 4 /* Stop executing this domain. */ 16.39 +#define SCHEDOP_cmdmask 255 /* 8-bit command. */ 16.40 +#define SCHEDOP_reasonshift 8 /* 8-bit stop code. (SCHEDOP_stop only) */ 16.41 16.42 /* 16.43 * Commands to HYPERVISOR_console_io().
17.1 --- a/xen/include/xen/sched.h Wed Jun 09 16:36:08 2004 +0000 17.2 +++ b/xen/include/xen/sched.h Thu Jun 10 11:33:45 2004 +0000 17.3 @@ -123,6 +123,7 @@ struct task_struct 17.4 struct list_head run_list; 17.5 int has_cpu; 17.6 int state; /* current run state */ 17.7 + int stop_code; /* stop code from OS (if TASK_STOPPED). */ 17.8 int cpupinned; /* true if pinned to curent CPU */ 17.9 s_time_t lastschd; /* time this domain was last scheduled */ 17.10 s_time_t lastdeschd; /* time this domain was last descheduled */ 17.11 @@ -207,6 +208,7 @@ struct task_struct 17.12 #define TASK_STOPPED 4 17.13 #define TASK_DYING 8 17.14 #define TASK_PAUSED 16 17.15 +#define TASK_CRASHED 32 17.16 17.17 #include <asm/uaccess.h> /* for KERNEL_DS */ 17.18 17.19 @@ -255,9 +257,8 @@ struct task_struct *find_last_domain(voi 17.20 extern void release_task(struct task_struct *); 17.21 extern void __kill_domain(struct task_struct *p); 17.22 extern void kill_domain(void); 17.23 -extern void kill_domain_with_errmsg(const char *err); 17.24 extern long kill_other_domain(domid_t dom, int force); 17.25 -extern void stop_domain(void); 17.26 +extern void stop_domain(u8 reason); 17.27 extern long stop_other_domain(domid_t dom); 17.28 17.29 /* arch/process.c */