]> xenbits.xensource.com Git - people/iwj/xen.git/commitdiff
x86/CPUID: block speculative out-of-bound accesses
authorNorbert Manthey <nmanthey@amazon.de>
Mon, 28 Jan 2019 16:38:29 +0000 (17:38 +0100)
committerJan Beulich <jbeulich@suse.com>
Mon, 28 Jan 2019 16:38:29 +0000 (17:38 +0100)
During instruction emulation, the cpuid instruction is emulated with
data that is controlled by the guest. As speculation might pass bound
checks, we have to ensure that no out-of-bound loads are possible.

To not rely on the compiler to perform value propagation, instead of
using the array_index_nospec macro, we replace the variable with the
constant to be propagated instead.

This commit is part of the SpectreV1+L1TF mitigation patch series.

Signed-off-by: Norbert Manthey <nmanthey@amazon.de>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Release-acked-by: Juergen Gross <jgross@suse.com>
xen/arch/x86/cpuid.c

index 0591a7dc602714a08c6bffede7b792c122861a1c..ab0aab678c74f183a8e7e1ef3b3d5bcbc5fe8d95 100644 (file)
@@ -1,6 +1,7 @@
 #include <xen/init.h>
 #include <xen/lib.h>
 #include <xen/sched.h>
+#include <xen/nospec.h>
 #include <asm/cpuid.h>
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/nestedhvm.h>
@@ -629,7 +630,7 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf,
             if ( subleaf >= ARRAY_SIZE(p->cache.raw) )
                 return;
 
-            *res = p->cache.raw[subleaf];
+            *res = array_access_nospec(p->cache.raw, subleaf);
             break;
 
         case 0x7:
@@ -638,25 +639,25 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf,
                                  ARRAY_SIZE(p->feat.raw) - 1) )
                 return;
 
-            *res = p->feat.raw[subleaf];
+            *res = array_access_nospec(p->feat.raw, subleaf);
             break;
 
         case 0xb:
             if ( subleaf >= ARRAY_SIZE(p->topo.raw) )
                 return;
 
-            *res = p->topo.raw[subleaf];
+            *res = array_access_nospec(p->topo.raw, subleaf);
             break;
 
         case XSTATE_CPUID:
             if ( !p->basic.xsave || subleaf >= ARRAY_SIZE(p->xstate.raw) )
                 return;
 
-            *res = p->xstate.raw[subleaf];
+            *res = array_access_nospec(p->xstate.raw, subleaf);
             break;
 
         default:
-            *res = p->basic.raw[leaf];
+            *res = array_access_nospec(p->basic.raw, leaf);
             break;
         }
         break;
@@ -680,7 +681,7 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf,
                                      ARRAY_SIZE(p->extd.raw) - 1) )
             return;
 
-        *res = p->extd.raw[leaf & 0xffff];
+        *res = array_access_nospec(p->extd.raw, leaf & 0xffff);
         break;
 
     default:
@@ -847,7 +848,7 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf,
         if ( is_pv_domain(d) && is_hardware_domain(d) &&
              guest_kernel_mode(v, regs) && cpu_has_monitor &&
              regs->entry_vector == TRAP_gp_fault )
-            *res = raw_cpuid_policy.basic.raw[leaf];
+            *res = raw_cpuid_policy.basic.raw[5];
         break;
 
     case 0x7: