]> xenbits.xensource.com Git - xen.git/commitdiff
x86: Initial support for WRMSRNS
authorAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 9 Jan 2023 15:25:11 +0000 (15:25 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 20 Jan 2023 19:39:33 +0000 (19:39 +0000)
WRMSR Non-Serialising is an optimisation intended for cases where an MSR needs
updating, but architectural serialising properties are not needed.

In is anticipated that this will apply to most if not all MSRs modified on
context switch paths.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
tools/libs/light/libxl_cpuid.c
tools/misc/xen-cpuid.c
xen/arch/x86/include/asm/msr.h
xen/include/public/arch-x86/cpufeatureset.h

index cbd4e511e8ab21c5cb9562f7c94c232c91975885..8da78773a88618c52afaa9c29255cdaf428418f0 100644 (file)
@@ -235,6 +235,7 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list *cpuid, const char* str)
         {"fzrm",         0x00000007,  1, CPUID_REG_EAX, 10,  1},
         {"fsrs",         0x00000007,  1, CPUID_REG_EAX, 11,  1},
         {"fsrcs",        0x00000007,  1, CPUID_REG_EAX, 12,  1},
+        {"wrmsrns",      0x00000007,  1, CPUID_REG_EAX, 19,  1},
 
         {"intel-psfd",   0x00000007,  2, CPUID_REG_EDX,  0,  1},
         {"mcdt-no",      0x00000007,  2, CPUID_REG_EDX,  5,  1},
index ea7ff320e0e4ebd6f7404a3e6de38ea06a85e47f..08831af46c3f1c6114603d95e52d82bd9b28506e 100644 (file)
@@ -189,6 +189,8 @@ static const char *const str_7a1[32] =
 
     [10] = "fzrm",          [11] = "fsrs",
     [12] = "fsrcs",
+
+    /* 18 */                [19] = "wrmsrns",
 };
 
 static const char *const str_e21a[32] =
index dd1eee04a637eb5eac1899abbeb5f0b476564eef..191e54068856e6ef0fb3a3592ef5bd2b0699c164 100644 (file)
@@ -38,6 +38,18 @@ static inline void wrmsrl(unsigned int msr, __u64 val)
         wrmsr(msr, lo, hi);
 }
 
+/* Non-serialising WRMSR, when available.  Falls back to a serialising WRMSR. */
+static inline void wrmsr_ns(uint32_t msr, uint32_t lo, uint32_t hi)
+{
+    /*
+     * WRMSR is 2 bytes.  WRMSRNS is 3 bytes.  Pad WRMSR with a redundant CS
+     * prefix to avoid a trailing NOP.
+     */
+    alternative_input(".byte 0x2e; wrmsr",
+                      ".byte 0x0f,0x01,0xc6", X86_FEATURE_WRMSRNS,
+                      "c" (msr), "a" (lo), "d" (hi));
+}
+
 /* rdmsr with exception handling */
 #define rdmsr_safe(msr,val) ({\
     int rc_; \
index ad7e89dd4c407660d82c2a6bb3d09ad870ea0546..5444bc5d83746902ba7ac903f43d9745dc8bbd84 100644 (file)
@@ -281,6 +281,7 @@ XEN_CPUFEATURE(AVX512_BF16,  10*32+ 5) /*A  AVX512 BFloat16 Instructions */
 XEN_CPUFEATURE(FZRM,         10*32+10) /*A  Fast Zero-length REP MOVSB */
 XEN_CPUFEATURE(FSRS,         10*32+11) /*A  Fast Short REP STOSB */
 XEN_CPUFEATURE(FSRCS,        10*32+12) /*A  Fast Short REP CMPSB/SCASB */
+XEN_CPUFEATURE(WRMSRNS,      10*32+19) /*   WRMSR Non-Serialising */
 
 /* AMD-defined CPU features, CPUID level 0x80000021.eax, word 11 */
 XEN_CPUFEATURE(LFENCE_DISPATCH,    11*32+ 2) /*A  LFENCE always serializing */