diff options
author | Boris Ostrovsky <boris.ostrovsky@amd.com> | 2012-02-07 15:05:19 +0100 |
---|---|---|
committer | Boris Ostrovsky <boris.ostrovsky@amd.com> | 2012-02-07 15:05:19 +0100 |
commit | 8cbb5278e034e5d7878f7a6a7d6987e5a7acf986 (patch) | |
tree | ca2b3b44237ca4631b489603e45ad6c148a3164b /xen/arch/x86/platform_hypercall.c | |
parent | 62698cdaf331db0ba7f621040b5c63eaacf6c4a9 (diff) | |
download | xen-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.c | 16 |
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; |