aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/platform_hypercall.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/arch/x86/platform_hypercall.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/arch/x86/platform_hypercall.c')
-rw-r--r--xen/arch/x86/platform_hypercall.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c
index f9a836a8bd..d5f978ac31 100644
--- a/xen/arch/x86/platform_hypercall.c
+++ b/xen/arch/x86/platform_hypercall.c
@@ -166,7 +166,23 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op)
break;
guest_from_compat_handle(data, op->u.microcode.data);
+
+ /*
+ * alloc_vcpu() will access data which is modified during
+ * microcode update
+ */
+ while ( !spin_trylock(&vcpu_alloc_lock) )
+ {
+ if ( hypercall_preempt_check() )
+ {
+ ret = hypercall_create_continuation(
+ __HYPERVISOR_platform_op, "h", u_xenpf_op);
+ goto out;
+ }
+ }
+
ret = microcode_update(data, op->u.microcode.length);
+ spin_unlock(&vcpu_alloc_lock);
}
break;