[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen stable-4.15] x86/AMD: expose SYSCFG, TOM, TOM2, and IORRs to Dom0



commit 9ab1714708ed23f7709a10ba839ebcb203ef1657
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Wed Aug 25 14:49:02 2021 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Wed Aug 25 14:49:02 2021 +0200

    x86/AMD: expose SYSCFG, TOM, TOM2, and IORRs to Dom0
    
    Sufficiently old Linux (3.12-ish) accesses these MSRs (with the
    exception of IORRs) in an unguarded manner. Furthermore these same MSRs,
    at least on Fam11 and older CPUs, are also consulted by modern Linux,
    and their (bogus) built-in zapping of #GP faults from MSR accesses leads
    to it effectively reading zero instead of the intended values, which are
    relevant for PCI BAR placement (which ought to all live in MMIO-type
    space, not in DRAM-type one).
    
    For SYSCFG, only certain bits get exposed. Since MtrrVarDramEn also
    covers the IORRs, expose them as well. Introduce (consistently named)
    constants for the bits we're interested in and use them in pre-existing
    code as well. While there also drop the unused and somewhat questionable
    K8_MTRR_RDMEM_WRMEM_MASK. To complete the set of memory type and DRAM vs
    MMIO controlling MSRs, also expose TSEG_{BASE,MASK} (the former also
    gets read by Linux, dealing with which was already the subject of
    6eef0a99262c ["x86/PV: conditionally avoid raising #GP for early guest
    MSR reads"]).
    
    As a welcome side effect, verbosity on/of debug builds gets (perhaps
    significantly) reduced.
    
    Note that at least as far as those MSR accesses by Linux are concerned,
    there's no similar issue for DomU-s, as the accesses sit behind PCI
    device matching logic. The checked for devices would never be exposed to
    DomU-s in the first place. Nevertheless I think that at least for HVM we
    should return sensible values, not 0 (as svm_msr_read_intercept() does
    right now). The intended values may, however, need to be determined by
    hvmloader, and then get made known to Xen.
    
    Fixes: 322ec7c89f66 ("x86/pv: disallow access to unknown MSRs")
    Reported-by: Olaf Hering <olaf@xxxxxxxxx>
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    
    x86/AMD: adjust SYSCFG, TOM, etc exposure to deal with running nested
    
    In the original change I neglected to consider the case of us running as
    L1 under another Xen. In this case we're not Dom0, so the underlying Xen
    wouldn't permit us access to these MSRs. As an immediate workaround use
    rdmsr_safe(); I don't view this as the final solution though, as the
    original problem the earlier change tried to address also applies when
    running nested. Yet it is then unclear to me how to properly address the
    issue: We shouldn't generally expose the MSR values, but handing back
    zero (or effectively any other static value) doesn't look appropriate
    either.
    
    Fixes: bfcdaae9c210 ("x86/AMD: expose SYSCFG, TOM, TOM2, and IORRs to Dom0")
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Julien Grall <jgrall@xxxxxxxxxx>
    master commit: bfcdaae9c210bd7984d7691285aaf43deb1b0604
    master date: 2021-07-09 08:28:14 +0200
    master commit: 471383ddd1843700fdd7d74242ba0e5f314dc678
    master date: 2021-07-19 12:28:50 +0200
---
 xen/arch/x86/cpu/amd.c              |  4 ++--
 xen/arch/x86/cpu/mtrr/generic.c     |  2 +-
 xen/arch/x86/msr.c                  | 20 ++++++++++++++++++++
 xen/arch/x86/x86_64/mmconf-fam10h.c |  2 +-
 xen/include/asm-x86/msr-index.h     | 20 +++++++++++++++-----
 5 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
index 8bc51bec10..db6916c1fd 100644
--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -468,14 +468,14 @@ static void check_syscfg_dram_mod_en(void)
                return;
 
        rdmsrl(MSR_K8_SYSCFG, syscfg);
-       if (!(syscfg & K8_MTRRFIXRANGE_DRAM_MODIFY))
+       if (!(syscfg & SYSCFG_MTRR_FIX_DRAM_MOD_EN))
                return;
 
        if (!test_and_set_bool(printed))
                printk(KERN_ERR "MTRR: SYSCFG[MtrrFixDramModEn] not "
                        "cleared by BIOS, clearing this bit\n");
 
-       syscfg &= ~K8_MTRRFIXRANGE_DRAM_MODIFY;
+       syscfg &= ~SYSCFG_MTRR_FIX_DRAM_MOD_EN;
        wrmsrl(MSR_K8_SYSCFG, syscfg);
 }
 
diff --git a/xen/arch/x86/cpu/mtrr/generic.c b/xen/arch/x86/cpu/mtrr/generic.c
index 06fa0c0420..883e3398ff 100644
--- a/xen/arch/x86/cpu/mtrr/generic.c
+++ b/xen/arch/x86/cpu/mtrr/generic.c
@@ -224,7 +224,7 @@ static void __init print_mtrr_state(const char *level)
                uint64_t syscfg, tom2;
 
                rdmsrl(MSR_K8_SYSCFG, syscfg);
-               if (syscfg & (1 << 21)) {
+               if (syscfg & SYSCFG_MTRR_TOM2_EN) {
                        rdmsrl(MSR_K8_TOP_MEM2, tom2);
                        printk("%sTOM2: %012"PRIx64"%s\n", level, tom2,
                               syscfg & (1 << 22) ? " (WB)" : "");
diff --git a/xen/arch/x86/msr.c b/xen/arch/x86/msr.c
index 374f92b2c5..75b89777a2 100644
--- a/xen/arch/x86/msr.c
+++ b/xen/arch/x86/msr.c
@@ -339,6 +339,26 @@ int guest_rdmsr(struct vcpu *v, uint32_t msr, uint64_t 
*val)
         *val = msrs->tsc_aux;
         break;
 
+    case MSR_K8_SYSCFG:
+    case MSR_K8_TOP_MEM1:
+    case MSR_K8_TOP_MEM2:
+    case MSR_K8_IORR_BASE0:
+    case MSR_K8_IORR_MASK0:
+    case MSR_K8_IORR_BASE1:
+    case MSR_K8_IORR_MASK1:
+    case MSR_K8_TSEG_BASE:
+    case MSR_K8_TSEG_MASK:
+        if ( !(cp->x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON)) )
+            goto gp_fault;
+        if ( !is_hardware_domain(d) )
+            return X86EMUL_UNHANDLEABLE;
+        if ( rdmsr_safe(msr, *val) )
+            goto gp_fault;
+        if ( msr == MSR_K8_SYSCFG )
+            *val &= (SYSCFG_TOM2_FORCE_WB | SYSCFG_MTRR_TOM2_EN |
+                     SYSCFG_MTRR_VAR_DRAM_EN | SYSCFG_MTRR_FIX_DRAM_EN);
+        break;
+
     case MSR_K8_HWCR:
         if ( !(cp->x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON)) )
             goto gp_fault;
diff --git a/xen/arch/x86/x86_64/mmconf-fam10h.c 
b/xen/arch/x86/x86_64/mmconf-fam10h.c
index 3b57d2b5ca..a834ab3149 100644
--- a/xen/arch/x86/x86_64/mmconf-fam10h.c
+++ b/xen/arch/x86/x86_64/mmconf-fam10h.c
@@ -69,7 +69,7 @@ static void __init get_fam10h_pci_mmconf_base(void)
        rdmsrl(address, val);
 
        /* TOP_MEM2 is not enabled? */
-       if (!(val & (1<<21))) {
+       if (!(val & SYSCFG_MTRR_TOM2_EN)) {
                tom2 = 1ULL << 32;
        } else {
                /* TOP_MEM2 */
diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
index 9a772c12b8..7e38c257d8 100644
--- a/xen/include/asm-x86/msr-index.h
+++ b/xen/include/asm-x86/msr-index.h
@@ -118,6 +118,21 @@
 #define  PASID_PASID_MASK                   0x000fffff
 #define  PASID_VALID                        (_AC(1, ULL) << 31)
 
+#define MSR_K8_SYSCFG                       0xc0010010
+#define  SYSCFG_MTRR_FIX_DRAM_EN            (_AC(1, ULL) << 18)
+#define  SYSCFG_MTRR_FIX_DRAM_MOD_EN        (_AC(1, ULL) << 19)
+#define  SYSCFG_MTRR_VAR_DRAM_EN            (_AC(1, ULL) << 20)
+#define  SYSCFG_MTRR_TOM2_EN                (_AC(1, ULL) << 21)
+#define  SYSCFG_TOM2_FORCE_WB               (_AC(1, ULL) << 22)
+
+#define MSR_K8_IORR_BASE0                   0xc0010016
+#define MSR_K8_IORR_MASK0                   0xc0010017
+#define MSR_K8_IORR_BASE1                   0xc0010018
+#define MSR_K8_IORR_MASK1                   0xc0010019
+
+#define MSR_K8_TSEG_BASE                    0xc0010112 /* AMD doc: SMMAddr */
+#define MSR_K8_TSEG_MASK                    0xc0010113 /* AMD doc: SMMMask */
+
 #define MSR_K8_VM_CR                        0xc0010114
 #define  VM_CR_INIT_REDIRECTION             (_AC(1, ULL) <<  1)
 #define  VM_CR_SVM_DISABLE                  (_AC(1, ULL) <<  4)
@@ -281,11 +296,6 @@
 #define MSR_K8_TOP_MEM1                        0xc001001a
 #define MSR_K7_CLK_CTL                 0xc001001b
 #define MSR_K8_TOP_MEM2                        0xc001001d
-#define MSR_K8_SYSCFG                  0xc0010010
-
-#define K8_MTRRFIXRANGE_DRAM_ENABLE    0x00040000 /* MtrrFixDramEn bit    */
-#define K8_MTRRFIXRANGE_DRAM_MODIFY    0x00080000 /* MtrrFixDramModEn bit */
-#define K8_MTRR_RDMEM_WRMEM_MASK       0x18181818 /* Mask: RdMem|WrMem    */
 
 #define MSR_K7_HWCR                    0xc0010015
 #define MSR_K8_HWCR                    0xc0010015
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.15



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.