]> xenbits.xensource.com Git - people/iwj/xen.git/commitdiff
x86/pv: Hide more EFER bits from PV guests
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 20 Mar 2018 19:36:40 +0000 (19:36 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 7 May 2018 10:52:57 +0000 (11:52 +0100)
We don't advertise SVM in CPUID so a PV guest shouldn't be under the
impression that it can use SVM functionality, but despite this, it really
shouldn't see SVME set when reading EFER.

On Intel processors, 32bit PV guests don't see, and can't use SYSCALL.

Introduce EFER_KNOWN_MASK to whitelist the features Xen knows about, and use
this to clamp the guests view.

Take the opportunity to reuse the mask to simplify svm_vmcb_isvalid(), and
change "undefined" to "unknown" in the print message, as there is at least
EFER.TCE (Translation Cache Extension) defined but unknown to Xen.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Release-acked-by: Juergen Gross <jgross@suse.com>
xen/arch/x86/hvm/svm/svmdebug.c
xen/arch/x86/pv/emul-priv-op.c
xen/include/asm-x86/msr-index.h

index 6c215d19fe019733a501f064c18d78085f64e5ad..d35e40596b58666f033a6f0548e0947e24dc1238 100644 (file)
@@ -133,9 +133,8 @@ bool svm_vmcb_isvalid(const char *from, const struct vmcb_struct *vmcb,
         PRINTF("DR7: bits [63:32] are not zero (%#"PRIx64")\n",
                vmcb_get_dr7(vmcb));
 
-    if ( efer & ~(EFER_SCE | EFER_LME | EFER_LMA | EFER_NX | EFER_SVME |
-                  EFER_LMSLE | EFER_FFXSE) )
-        PRINTF("EFER: undefined bits are not zero (%#"PRIx64")\n", efer);
+    if ( efer & ~EFER_KNOWN_MASK )
+        PRINTF("EFER: unknown bits are not zero (%#"PRIx64")\n", efer);
 
     if ( hvm_efer_valid(v, efer, -1) )
         PRINTF("EFER: %s (%"PRIx64")\n", hvm_efer_valid(v, efer, -1), efer);
index 15f42b34ce66bf17f9f3716ead3654d20eae989d..ce2ec76cdeb25cf5a536141787b4c85581b1b2a6 100644 (file)
@@ -867,9 +867,16 @@ static int read_msr(unsigned int reg, uint64_t *val,
         return X86EMUL_OKAY;
 
     case MSR_EFER:
-        *val = read_efer();
+        /* Hide unknown bits, and unconditionally hide SVME from guests. */
+        *val = read_efer() & EFER_KNOWN_MASK & ~EFER_SVME;
+        /*
+         * Hide the 64-bit features from 32-bit guests.  SCE has
+         * vendor-dependent behaviour.
+         */
         if ( is_pv_32bit_domain(currd) )
-            *val &= ~(EFER_LME | EFER_LMA | EFER_LMSLE);
+            *val &= ~(EFER_LME | EFER_LMA | EFER_LMSLE |
+                      (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL
+                       ? EFER_SCE : 0));
         return X86EMUL_OKAY;
 
     case MSR_K7_FID_VID_CTL:
index c9f44ebdb33708b6b67f6df66867cd7bbd7c759e..6d94d655750308ca49e9bc3c54ecf167d9b257bb 100644 (file)
@@ -31,6 +31,9 @@
 #define EFER_LMSLE             (1<<_EFER_LMSLE)
 #define EFER_FFXSE             (1<<_EFER_FFXSE)
 
+#define EFER_KNOWN_MASK                (EFER_SCE | EFER_LME | EFER_LMA | EFER_NX | \
+                                EFER_SVME | EFER_LMSLE | EFER_FFXSE)
+
 /* Speculation Controls. */
 #define MSR_SPEC_CTRL                  0x00000048
 #define SPEC_CTRL_IBRS                 (_AC(1, ULL) << 0)