aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/microcode.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/microcode.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/microcode.c')
-rw-r--r--xen/arch/x86/microcode.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c
index c3a8472e3b..bdda3f5f4d 100644
--- a/xen/arch/x86/microcode.c
+++ b/xen/arch/x86/microcode.c
@@ -218,6 +218,16 @@ int microcode_update(XEN_GUEST_HANDLE(const_void) buf, unsigned long len)
info->error = 0;
info->cpu = cpumask_first(&cpu_online_map);
+ if ( microcode_ops->start_update )
+ {
+ ret = microcode_ops->start_update();
+ if ( ret != 0 )
+ {
+ xfree(info);
+ return ret;
+ }
+ }
+
return continue_hypercall_on_cpu(info->cpu, do_microcode_update, info);
}
@@ -240,6 +250,12 @@ static int __init microcode_init(void)
if ( !data )
return -ENOMEM;
+ if ( microcode_ops->start_update && microcode_ops->start_update() != 0 )
+ {
+ ucode_mod_map(NULL);
+ return 0;
+ }
+
softirq_tasklet_init(&tasklet, _do_microcode_update, (unsigned long)data);
for_each_online_cpu ( cpu )