Allow domains to set a shutdown code without actually shutting down. Useful for Windows guests, since the PV drivers are notified that the domain is about to crash just before the crash dump gets written. diff -r 582c46d3a995 xen/common/domain.c --- a/xen/common/domain.c Thu Oct 30 15:14:07 2008 +0000 +++ b/xen/common/domain.c Fri Oct 31 09:59:32 2008 +0000 @@ -440,10 +440,21 @@ void domain_shutdown(struct domain *d, u { struct vcpu *v; + spin_lock(&d->shutdown_lock); + if ( !d->has_shutdown_code ) + { + d->shutdown_code = reason; + d->has_shutdown_code = 1; + } + else + reason = d->shutdown_code; + if ( d->domain_id == 0 ) + { + spin_unlock(&d->shutdown_lock); dom0_shutdown(reason); - - spin_lock(&d->shutdown_lock); + spin_lock(&d->shutdown_lock); + } if ( d->is_shutting_down ) { @@ -452,7 +463,6 @@ void domain_shutdown(struct domain *d, u } d->is_shutting_down = 1; - d->shutdown_code = reason; smp_mb(); /* set shutdown status /then/ check for per-cpu deferrals */ @@ -482,6 +492,7 @@ void domain_resume(struct domain *d) spin_lock(&d->shutdown_lock); d->is_shutting_down = d->is_shut_down = 0; + d->shutdown_code = d->has_shutdown_code = 0; for_each_vcpu ( d, v ) { diff -r 582c46d3a995 xen/common/schedule.c --- a/xen/common/schedule.c Thu Oct 30 15:14:07 2008 +0000 +++ b/xen/common/schedule.c Fri Oct 31 09:58:40 2008 +0000 @@ -536,6 +536,29 @@ ret_t do_sched_op(int cmd, XEN_GUEST_HAN break; } + case SCHEDOP_shutdown_code: + { + struct sched_shutdown sched_shutdown; + + ret = -EFAULT; + if ( copy_from_guest(&sched_shutdown, arg, 1) ) + break; + + ret = 0; + TRACE_3D(TRC_SCHED_SHUTDOWN_CODE, + current->domain->domain_id, current->vcpu_id, + sched_shutdown.reason); + spin_lock(¤t->domain->shutdown_lock); + if ( !current->domain->has_shutdown_code ) + { + current->domain->shutdown_code = (u8)sched_shutdown.reason; + current->domain->has_shutdown_code = 1; + } + spin_unlock(¤t->domain->shutdown_lock); + + break; + } + case SCHEDOP_poll: { struct sched_poll sched_poll; diff -r 582c46d3a995 xen/include/public/sched.h --- a/xen/include/public/sched.h Thu Oct 30 15:14:07 2008 +0000 +++ b/xen/include/public/sched.h Fri Oct 31 09:58:40 2008 +0000 @@ -115,6 +115,13 @@ DEFINE_XEN_GUEST_HANDLE(sched_watchdog_t DEFINE_XEN_GUEST_HANDLE(sched_watchdog_t); /* + * Latch a shutdown code, so that when the domain later shuts down it + * reports this code to the control tools. + * @arg == as for SCHEDOP_shutdown. + */ +#define SCHEDOP_shutdown_code 5 + +/* * 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. diff -r 582c46d3a995 xen/include/public/trace.h --- a/xen/include/public/trace.h Thu Oct 30 15:14:07 2008 +0000 +++ b/xen/include/public/trace.h Fri Oct 31 09:58:40 2008 +0000 @@ -75,6 +75,7 @@ #define TRC_SCHED_DOM_TIMER_FN (TRC_SCHED_VERBOSE + 13) #define TRC_SCHED_SWITCH_INFPREV (TRC_SCHED_VERBOSE + 14) #define TRC_SCHED_SWITCH_INFNEXT (TRC_SCHED_VERBOSE + 15) +#define TRC_SCHED_SHUTDOWN_CODE (TRC_SCHED_VERBOSE + 16) #define TRC_MEM_PAGE_GRANT_MAP (TRC_MEM + 1) #define TRC_MEM_PAGE_GRANT_UNMAP (TRC_MEM + 2) diff -r 582c46d3a995 xen/include/xen/sched.h --- a/xen/include/xen/sched.h Thu Oct 30 15:14:07 2008 +0000 +++ b/xen/include/xen/sched.h Fri Oct 31 09:58:40 2008 +0000 @@ -226,6 +226,7 @@ struct domain spinlock_t shutdown_lock; bool_t is_shutting_down; /* in process of shutting down? */ bool_t is_shut_down; /* fully shut down? */ + bool_t has_shutdown_code; /* shutdown_code has been set? */ int shutdown_code; /* If this is not 0, send suspend notification here instead of