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

[Xen-changelog] [xen stable-4.6] x86/feature: Definitions for Indirect Branch Controls



commit ff4800cac63756f7755e6c251571cd29fd5171eb
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Wed Feb 14 12:43:37 2018 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Wed Feb 14 12:43:37 2018 +0100

    x86/feature: Definitions for Indirect Branch Controls
    
    Contemporary processors are gaining Indirect Branch Controls via microcode
    updates.  Intel are introducing one bit to indicate IBRS and IBPB support, 
and
    a second bit for STIBP.  AMD are introducing IBPB only, so enumerate it 
with a
    separate bit.
    
    Furthermore, depending on compiler and microcode availability, we may want 
to
    run Xen with IBRS set, or clear.
    
    To use these facilities, we synthesise separate IBRS and IBPB bits for
    internal use.  A lot of infrastructure is required before these features are
    safe to offer to guests.
    
    This is part of XSA-254.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Wei Liu <wei.liu2@xxxxxxxxxx>
    master commit: 0d703a701cc4bc47773986b2796eebd28b1439b5
    master date: 2018-01-16 17:45:50 +0000
---
 tools/libxc/xc_cpufeature.h      |  6 ++++++
 tools/libxc/xc_cpuid_x86.c       | 17 ++++++++++++-----
 tools/libxl/libxl_cpuid.c        |  3 +++
 xen/arch/x86/cpu/common.c        |  9 +++++----
 xen/arch/x86/spec_ctrl.c         | 17 +++++++++++++++++
 xen/include/asm-x86/cpufeature.h | 12 +++++++++++-
 xen/include/asm-x86/msr-index.h  |  8 ++++++++
 7 files changed, 62 insertions(+), 10 deletions(-)

diff --git a/tools/libxc/xc_cpufeature.h b/tools/libxc/xc_cpufeature.h
index c3ddc80..8a3fac0 100644
--- a/tools/libxc/xc_cpufeature.h
+++ b/tools/libxc/xc_cpufeature.h
@@ -141,5 +141,11 @@
 #define X86_FEATURE_ADX         19 /* ADCX, ADOX instructions */
 #define X86_FEATURE_SMAP        20 /* Supervisor Mode Access Protection */
 
+/* AMD-defined CPU features, CPUID level 0x80000008, ebx */
+#define X86_FEATURE_IBPB        12 /* IBPB support only (no IBRS, used by AMD) 
*/
+
+/* Intel-defined CPU features, CPUID level 0x00000007:0 (edx) */
+#define X86_FEATURE_IBRSB       26 /* IBRS and IBPB support (used by Intel) */
+#define X86_FEATURE_STIBP       27 /* STIBP */
 
 #endif /* __LIBXC_CPUFEATURE_H */
diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
index 11fecd5..454be0b 100644
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -368,9 +368,11 @@ static void xc_cpuid_hvm_policy(
                         bitmaskof(X86_FEATURE_ADX)  |
                         bitmaskof(X86_FEATURE_SMAP) |
                         bitmaskof(X86_FEATURE_FSGSBASE));
+            regs[3] &= (bitmaskof(X86_FEATURE_IBRSB) |
+                        bitmaskof(X86_FEATURE_STIBP));
         } else
-            regs[1] = 0;
-        regs[0] = regs[2] = regs[3] = 0;
+            regs[1] = regs[3] = 0;
+        regs[0] = regs[2] = 0;
         break;
 
     case 0x0000000d:
@@ -403,7 +405,8 @@ static void xc_cpuid_hvm_policy(
 
     case 0x80000008:
         regs[0] &= 0x0000ffffu;
-        regs[1] = regs[3] = 0;
+        regs[3] &= bitmaskof(X86_FEATURE_IBPB);
+        regs[1] = 0;
         break;
 
     case 0x00000002: /* Intel cache info (dumped by AMD policy) */
@@ -498,6 +501,7 @@ static void xc_cpuid_pv_policy(
 
     case 0x00000007:
         if ( input[1] == 0 )
+        {
             regs[1] &= (bitmaskof(X86_FEATURE_BMI1) |
                         bitmaskof(X86_FEATURE_HLE)  |
                         bitmaskof(X86_FEATURE_AVX2) |
@@ -507,9 +511,12 @@ static void xc_cpuid_pv_policy(
                         bitmaskof(X86_FEATURE_RDSEED)  |
                         bitmaskof(X86_FEATURE_ADX)  |
                         bitmaskof(X86_FEATURE_FSGSBASE));
+            regs[3] &= (bitmaskof(X86_FEATURE_IBRSB) |
+                        bitmaskof(X86_FEATURE_STIBP));
+        }
         else
-            regs[1] = 0;
-        regs[0] = regs[2] = regs[3] = 0;
+            regs[1] = regs[3] = 0;
+        regs[0] = regs[2] = 0;
         break;
 
     case 0x0000000d:
diff --git a/tools/libxl/libxl_cpuid.c b/tools/libxl/libxl_cpuid.c
index c66e912..17e9f0f 100644
--- a/tools/libxl/libxl_cpuid.c
+++ b/tools/libxl/libxl_cpuid.c
@@ -158,6 +158,8 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list 
*cpuid, const char* str)
         {"de",           0x00000001, NA, CPUID_REG_EDX,  2,  1},
         {"vme",          0x00000001, NA, CPUID_REG_EDX,  1,  1},
         {"fpu",          0x00000001, NA, CPUID_REG_EDX,  0,  1},
+        {"ibrsb",        0x00000007,  0, CPUID_REG_EDX, 26,  1},
+        {"stibp",        0x00000007,  0, CPUID_REG_EDX, 27,  1},
         {"topoext",      0x80000001, NA, CPUID_REG_ECX, 22,  1},
         {"tbm",          0x80000001, NA, CPUID_REG_ECX, 21,  1},
         {"nodeid",       0x80000001, NA, CPUID_REG_ECX, 19,  1},
@@ -187,6 +189,7 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list 
*cpuid, const char* str)
         {"nx",           0x80000001, NA, CPUID_REG_EDX, 20,  1},
         {"syscall",      0x80000001, NA, CPUID_REG_EDX, 11,  1},
         {"procpkg",      0x00000004,  0, CPUID_REG_EAX, 26,  6},
+        {"ibpb",         0x80000008, NA, CPUID_REG_EBX, 12,  1},
         {"apicidsize",   0x80000008, NA, CPUID_REG_ECX, 12,  4},
         {"nc",           0x80000008, NA, CPUID_REG_ECX,  0,  8},
         {"svm_npt",      0x8000000a, NA, CPUID_REG_EDX,  0,  1},
diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index 0c1eb5f..dc0bc76 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -212,7 +212,7 @@ static void __init early_cpu_detect(void)
 
 static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
 {
-       u32 tfms, capability, excap, ebx, eax;
+       u32 tfms, capability, excap, ebx, eax, edx, dummy;
 
        /* Get vendor name */
        cpuid(0x00000000, &c->cpuid_level,
@@ -250,9 +250,10 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 
*c)
                if ( c->extended_cpuid_level >= 0x80000004 )
                        get_model_name(c); /* Default name */
                if ( c->extended_cpuid_level >= 0x80000008 ) {
-                       eax = cpuid_eax(0x80000008);
+                       cpuid(0x80000008, &eax, &ebx, &dummy, &dummy);
                        paddr_bits = eax & 0xff;
                        hap_paddr_bits = ((eax >> 16) & 0xff) ?: paddr_bits;
+                       c->x86_capability[X86_FEATURE_IBPB / 32] = ebx;
                }
        }
 
@@ -261,9 +262,9 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 
*c)
 
        /* Intel-defined flags: level 0x00000007 */
        if ( c->cpuid_level >= 0x00000007 ) {
-               u32 dummy;
-               cpuid_count(0x00000007, 0, &dummy, &ebx, &dummy, &dummy);
+               cpuid_count(0x00000007, 0, &dummy, &ebx, &dummy, &edx);
                c->x86_capability[X86_FEATURE_FSGSBASE / 32] = ebx;
+               c->x86_capability[X86_FEATURE_IBRSB / 32] = edx;
        }
 }
 
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
index 621f4e8..f66a286 100644
--- a/xen/arch/x86/spec_ctrl.c
+++ b/xen/arch/x86/spec_ctrl.c
@@ -67,8 +67,25 @@ custom_param("bti", parse_bti);
 
 static void __init print_details(enum ind_thunk thunk)
 {
+    unsigned int _7d0 = 0, e8b = 0, tmp;
+
+    /* Collect diagnostics about available mitigations. */
+    if ( boot_cpu_data.cpuid_level >= 7 )
+        cpuid_count(7, 0, &tmp, &tmp, &tmp, &_7d0);
+    if ( boot_cpu_data.extended_cpuid_level >= 0x80000008 )
+        cpuid(0x80000008, &tmp, &e8b, &tmp, &tmp);
+
     printk(XENLOG_DEBUG "Speculative mitigation facilities:\n");
 
+    /* Hardware features which pertain to speculative mitigations. */
+    if ( (_7d0 & (cpufeat_mask(X86_FEATURE_IBRSB) |
+                  cpufeat_mask(X86_FEATURE_STIBP))) ||
+         (e8b & cpufeat_mask(X86_FEATURE_IBPB)) )
+        printk(XENLOG_DEBUG "  Hardware features:%s%s%s\n",
+               (_7d0 & cpufeat_mask(X86_FEATURE_IBRSB)) ? " IBRS/IBPB" : "",
+               (_7d0 & cpufeat_mask(X86_FEATURE_STIBP)) ? " STIBP"     : "",
+               (e8b  & cpufeat_mask(X86_FEATURE_IBPB))  ? " IBPB"      : "");
+
     /* Compiled-in support which pertains to BTI mitigations. */
 #ifdef CONFIG_INDIRECT_THUNK
     printk(XENLOG_DEBUG "  Compiled-in support: INDIRECT_THUNK\n");
diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h
index ec99337..633c4c5 100644
--- a/xen/include/asm-x86/cpufeature.h
+++ b/xen/include/asm-x86/cpufeature.h
@@ -9,7 +9,7 @@
 #define __ASM_I386_CPUFEATURE_H
 #endif
 
-#define NCAPINTS       8       /* N 32-bit words worth of info */
+#define NCAPINTS       10      /* N 32-bit words worth of info */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
 #define X86_FEATURE_FPU                (0*32+ 0) /* Onboard FPU */
@@ -64,6 +64,9 @@
 #define X86_FEATURE_LFENCE_DISPATCH (3*32+ 0) /* lfence set as Dispatch 
Serialising */
 #define X86_FEATURE_IND_THUNK_LFENCE (3*32+ 1) /* Use IND_THUNK_LFENCE */
 #define X86_FEATURE_IND_THUNK_JMP   (3*32+ 2) /* Use IND_THUNK_JMP */
+#define X86_FEATURE_XEN_IBPB        (3*32+ 3) /* IBRSB || IBPB */
+#define X86_FEATURE_XEN_IBRS_SET    (3*32+ 4) /* IBRSB && IRBS set in Xen */
+#define X86_FEATURE_XEN_IBRS_CLEAR  (3*32+ 5) /* IBRSB && IBRS clear in Xen */
 #define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */
 #define X86_FEATURE_NONSTOP_TSC        (3*32+ 9) /* TSC does not stop in C 
states */
 #define X86_FEATURE_ARAT       (3*32+ 10) /* Always running APIC timer */
@@ -158,6 +161,13 @@
 #define X86_FEATURE_ADX                (7*32+19) /* ADCX, ADOX instructions */
 #define X86_FEATURE_SMAP       (7*32+20) /* Supervisor Mode Access Prevention 
*/
 
+/* AMD-defined CPU features, CPUID level 0x80000008.ebx, word 8 */
+#define X86_FEATURE_IBPB       (8*32+12) /* IBPB support only (no IBRS, used 
by AMD) */
+
+/* Intel-defined CPU features, CPUID level 0x00000007:0.edx, word 9 */
+#define X86_FEATURE_IBRSB      (9*32+26) /* IBRS and IBPB support (used by 
Intel) */
+#define X86_FEATURE_STIBP      (9*32+27) /* STIBP */
+
 /* An alias of a feature we know is always going to be present. */
 #define X86_FEATURE_ALWAYS      X86_FEATURE_LM
 
diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
index 6fae144..ec2be6a 100644
--- a/xen/include/asm-x86/msr-index.h
+++ b/xen/include/asm-x86/msr-index.h
@@ -31,6 +31,14 @@
 #define EFER_LMSLE             (1<<_EFER_LMSLE)
 #define EFER_FFXSE             (1<<_EFER_FFXSE)
 
+/* Speculation Controls. */
+#define MSR_SPEC_CTRL                  0x00000048
+#define SPEC_CTRL_IBRS                 (_AC(1, ULL) << 0)
+#define SPEC_CTRL_STIBP                        (_AC(1, ULL) << 1)
+
+#define MSR_PRED_CMD                   0x00000049
+#define PRED_CMD_IBPB                  (_AC(1, ULL) << 0)
+
 /* Intel MSRs. Some also available on other CPUs */
 #define MSR_IA32_PERFCTR0              0x000000c1
 #define MSR_IA32_A_PERFCTR0            0x000004c1
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.6

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

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