#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 */
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:
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) */
case 0x00000007:
if ( input[1] == 0 )
+ {
regs[1] &= (bitmaskof(X86_FEATURE_BMI1) |
bitmaskof(X86_FEATURE_HLE) |
bitmaskof(X86_FEATURE_AVX2) |
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:
{"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},
{"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},
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,
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;
}
}
/* 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;
}
}
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");
#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 */
#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 */
#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
#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