]> xenbits.xensource.com Git - people/dariof/xen.git/commitdiff
x86/msr: Emulation of MSR_{SPEC_CTRL,PRED_CMD} for guests
authorAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 9 Nov 2017 19:28:04 +0000 (19:28 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 26 Jan 2018 14:10:21 +0000 (14:10 +0000)
As per the spec currently available here:

https://software.intel.com/sites/default/files/managed/c5/63/336996-Speculative-Execution-Side-Channel-Mitigations.pdf

MSR_ARCH_CAPABILITIES will only come into existence on new hardware, but is
implemented as a straight #GP for now to avoid being leaky when new hardware
arrives.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/msr.c
xen/include/asm-x86/msr-index.h
xen/include/asm-x86/msr.h

index 187f8623a5f191289ae5fdc8ad610565b1694fd8..7875d9c1e0cd71a301e0a65363b728977b563d44 100644 (file)
@@ -120,11 +120,22 @@ int init_vcpu_msr_policy(struct vcpu *v)
 
 int guest_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val)
 {
+    const struct cpuid_policy *cp = v->domain->arch.cpuid;
     const struct msr_domain_policy *dp = v->domain->arch.msr;
     const struct msr_vcpu_policy *vp = v->arch.msr;
 
     switch ( msr )
     {
+    case MSR_PRED_CMD:
+        /* Write-only */
+        goto gp_fault;
+
+    case MSR_SPEC_CTRL:
+        if ( !cp->feat.ibrsb )
+            goto gp_fault;
+        *val = vp->spec_ctrl.raw;
+        break;
+
     case MSR_INTEL_PLATFORM_INFO:
         if ( !dp->plaform_info.available )
             goto gp_fault;
@@ -132,6 +143,10 @@ int guest_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val)
                _MSR_PLATFORM_INFO_CPUID_FAULTING;
         break;
 
+    case MSR_ARCH_CAPABILITIES:
+        /* Not implemented yet. */
+        goto gp_fault;
+
     case MSR_INTEL_MISC_FEATURES_ENABLES:
         if ( !vp->misc_features_enables.available )
             goto gp_fault;
@@ -153,14 +168,44 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
 {
     const struct vcpu *curr = current;
     struct domain *d = v->domain;
+    const struct cpuid_policy *cp = d->arch.cpuid;
     struct msr_domain_policy *dp = d->arch.msr;
     struct msr_vcpu_policy *vp = v->arch.msr;
 
     switch ( msr )
     {
     case MSR_INTEL_PLATFORM_INFO:
+    case MSR_ARCH_CAPABILITIES:
+        /* Read-only */
         goto gp_fault;
 
+    case MSR_SPEC_CTRL:
+        if ( !cp->feat.ibrsb )
+            goto gp_fault; /* MSR available? */
+
+        /*
+         * Note: SPEC_CTRL_STIBP is specified as safe to use (i.e. ignored)
+         * when STIBP isn't enumerated in hardware.
+         */
+
+        if ( val & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP) )
+            goto gp_fault; /* Rsvd bit set? */
+
+        vp->spec_ctrl.raw = val;
+        break;
+
+    case MSR_PRED_CMD:
+        if ( !cp->feat.ibrsb && !cp->extd.ibpb )
+            goto gp_fault; /* MSR available? */
+
+        /*
+         * The only defined behaviour is when writing PRED_CMD_IBPB.  In
+         * practice, real hardware accepts any value without faulting.
+         */
+        if ( v == curr && (val & PRED_CMD_IBPB) )
+            wrmsrl(MSR_PRED_CMD, PRED_CMD_IBPB);
+        break;
+
     case MSR_INTEL_MISC_FEATURES_ENABLES:
     {
         uint64_t rsvd = ~0ull;
index a0aacfaee51f434551f3f2d23b9098570c42beee..23ad74399ce97337386f698e4a77a96539c24f8d 100644 (file)
@@ -39,6 +39,8 @@
 #define MSR_PRED_CMD                   0x00000049
 #define PRED_CMD_IBPB                  (_AC(1, ULL) << 0)
 
+#define MSR_ARCH_CAPABILITIES          0x0000010a
+
 /* Intel MSRs. Some also available on other CPUs */
 #define MSR_IA32_PERFCTR0              0x000000c1
 #define MSR_IA32_A_PERFCTR0            0x000004c1
index 2fbed0251ed94da337c2bb1db1ff3580beea979b..928f1cc454c02ede3889efcb8f82ec1bf0596946 100644 (file)
@@ -223,6 +223,16 @@ struct msr_domain_policy
 /* MSR policy object for per-vCPU MSRs */
 struct msr_vcpu_policy
 {
+    /* 0x00000048 - MSR_SPEC_CTRL */
+    struct {
+        /*
+         * Only the bottom two bits are defined, so no need to waste space
+         * with uint64_t at the moment, but use uint32_t for the convenience
+         * of the assembly code.
+         */
+        uint32_t raw;
+    } spec_ctrl;
+
     /* 0x00000140  MSR_INTEL_MISC_FEATURES_ENABLES */
     struct {
         bool available; /* This MSR is non-architectural */