aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/domctl.c
diff options
context:
space:
mode:
authorBoris Ostrovsky <boris.ostrovsky@amd.com>2012-02-07 15:05:19 +0100
committerBoris Ostrovsky <boris.ostrovsky@amd.com>2012-02-07 15:05:19 +0100
commit8cbb5278e034e5d7878f7a6a7d6987e5a7acf986 (patch)
treeca2b3b44237ca4631b489603e45ad6c148a3164b /xen/common/domctl.c
parent62698cdaf331db0ba7f621040b5c63eaacf6c4a9 (diff)
downloadxen-8cbb5278e034e5d7878f7a6a7d6987e5a7acf986.tar.gz
xen-8cbb5278e034e5d7878f7a6a7d6987e5a7acf986.tar.bz2
xen-8cbb5278e034e5d7878f7a6a7d6987e5a7acf986.zip
x86/AMD: Add support for AMD's OSVW feature in guests.
In some cases guests should not provide workarounds for errata even when the physical processor is affected. For example, because of erratum 400 on family 10h processors a Linux guest will read an MSR (resulting in VMEXIT) before going to idle in order to avoid getting stuck in a non-C0 state. This is not necessary: HLT and IO instructions are intercepted and therefore there is no reason for erratum 400 workaround in the guest. This patch allows us to present a guest with certain errata as fixed, regardless of the state of actual hardware. Signed-off-by: Boris Ostrovsky <boris.ostrovsky@amd.com> Acked-by: Christoph Egger <Christoph.Egger@amd.com> Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org> Committed-by: Jan Beulich <jbeulich@suse.com>
Diffstat (limited to 'xen/common/domctl.c')
-rw-r--r--xen/common/domctl.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index 904fb45e8f..9f1a9ada8c 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -29,6 +29,7 @@
#include <xsm/xsm.h>
static DEFINE_SPINLOCK(domctl_lock);
+DEFINE_SPINLOCK(vcpu_alloc_lock);
int cpumask_to_xenctl_cpumap(
struct xenctl_cpumap *xenctl_cpumap, const cpumask_t *cpumask)
@@ -506,6 +507,20 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
/* Needed, for example, to ensure writable p.t. state is synced. */
domain_pause(d);
+ /*
+ * Certain operations (e.g. CPU microcode updates) modify data which is
+ * used during VCPU allocation/initialization
+ */
+ while ( !spin_trylock(&vcpu_alloc_lock) )
+ {
+ if ( hypercall_preempt_check() )
+ {
+ ret = hypercall_create_continuation(
+ __HYPERVISOR_domctl, "h", u_domctl);
+ goto maxvcpu_out_novcpulock;
+ }
+ }
+
/* We cannot reduce maximum VCPUs. */
ret = -EINVAL;
if ( (max < d->max_vcpus) && (d->vcpu[max] != NULL) )
@@ -555,6 +570,9 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
ret = 0;
maxvcpu_out:
+ spin_unlock(&vcpu_alloc_lock);
+
+ maxvcpu_out_novcpulock:
domain_unpause(d);
rcu_unlock_domain(d);
}