From: Keir Fraser Date: Thu, 15 Apr 2010 12:06:48 +0000 (+0100) Subject: acpi sleep: Must acquire hypercall_deadlock_mutex when a domain X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~12357 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=37cd685b750d34833bfca8b220f1bf34c66ea88c;p=xen.git acpi sleep: Must acquire hypercall_deadlock_mutex when a domain freezes its own vcpus. Signed-off-by: Keir Fraser --- diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c index 7978e01de2..4fbfd5da9a 100644 --- a/xen/arch/x86/acpi/power.c +++ b/xen/arch/x86/acpi/power.c @@ -74,11 +74,14 @@ static void device_power_up(void) console_resume(); } -static void freeze_domains(void) +static int freeze_domains(void) { struct domain *d; struct vcpu *v; + if ( !spin_trylock(¤t->domain->hypercall_deadlock_mutex) ) + return -EBUSY; + rcu_read_lock(&domlist_read_lock); for_each_domain ( d ) { @@ -91,6 +94,10 @@ static void freeze_domains(void) } } rcu_read_unlock(&domlist_read_lock); + + spin_unlock(¤t->domain->hypercall_deadlock_mutex); + + return 0; } static void thaw_domains(void) @@ -254,16 +261,22 @@ int acpi_enter_sleep(struct xenpf_enter_acpi_sleep *sleep) printk(XENLOG_INFO "Preparing system for ACPI S%d state.", state); - freeze_domains(); + rc = freeze_domains(); + if ( rc ) + goto unlock_and_fail; rc = continue_hypercall_on_cpu(0, enter_state_helper, &acpi_sinfo); if ( rc ) { /* Continuation will not execute: undo our own work so far. */ thaw_domains(); - spin_unlock(&pm_lock); + goto unlock_and_fail; } + return 0; + + unlock_and_fail: + spin_unlock(&pm_lock); return rc; }