atomic_set(&d->refcnt, 1);
spin_lock_init_prof(d, domain_lock);
spin_lock_init_prof(d, page_alloc_lock);
- spin_lock_init(&d->shutdown_lock);
spin_lock_init(&d->hypercall_deadlock_mutex);
INIT_PAGE_LIST_HEAD(&d->page_list);
INIT_PAGE_LIST_HEAD(&d->xenpage_list);
+ spin_lock_init(&d->shutdown_lock);
+ d->shutdown_code = -1;
+
if ( domcr_flags & DOMCRF_hvm )
d->is_hvm = 1;
{
struct vcpu *v;
+ spin_lock(&d->shutdown_lock);
+
+ if ( d->shutdown_code == -1 )
+ d->shutdown_code = reason;
+ reason = d->shutdown_code;
+
if ( d->domain_id == 0 )
dom0_shutdown(reason);
- spin_lock(&d->shutdown_lock);
-
if ( d->is_shutting_down )
{
spin_unlock(&d->shutdown_lock);
}
d->is_shutting_down = 1;
- d->shutdown_code = reason;
smp_mb(); /* set shutdown status /then/ check for per-cpu deferrals */
spin_lock(&d->shutdown_lock);
d->is_shutting_down = d->is_shut_down = 0;
+ d->shutdown_code = -1;
for_each_vcpu ( d, v )
{
break;
}
+ case SCHEDOP_shutdown_code:
+ {
+ struct sched_shutdown sched_shutdown;
+ struct domain *d = current->domain;
+
+ ret = -EFAULT;
+ if ( copy_from_guest(&sched_shutdown, arg, 1) )
+ break;
+
+ TRACE_3D(TRC_SCHED_SHUTDOWN_CODE,
+ d->domain_id, current->vcpu_id, sched_shutdown.reason);
+
+ spin_lock(&d->shutdown_lock);
+ if ( d->shutdown_code == -1 )
+ d->shutdown_code = (u8)sched_shutdown.reason;
+ spin_unlock(&d->shutdown_lock);
+
+ ret = 0;
+ break;
+ }
+
case SCHEDOP_poll:
{
struct sched_poll sched_poll;
typedef struct sched_remote_shutdown sched_remote_shutdown_t;
DEFINE_XEN_GUEST_HANDLE(sched_remote_shutdown_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
#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)