Skip to content

Commit e7862ed

Browse files
kimphillamdbp3tk0v
authored andcommitted
x86/cpu: Support AMD Automatic IBRS
The AMD Zen4 core supports a new feature called Automatic IBRS. It is a "set-and-forget" feature that means that, like Intel's Enhanced IBRS, h/w manages its IBRS mitigation resources automatically across CPL transitions. The feature is advertised by CPUID_Fn80000021_EAX bit 8 and is enabled by setting MSR C000_0080 (EFER) bit 21. Enable Automatic IBRS by default if the CPU feature is present. It typically provides greater performance over the incumbent generic retpolines mitigation. Reuse the SPECTRE_V2_EIBRS spectre_v2_mitigation enum. AMD Automatic IBRS and Intel Enhanced IBRS have similar enablement. Add NO_EIBRS_PBRSB to cpu_vuln_whitelist, since AMD Automatic IBRS isn't affected by PBRSB-eIBRS. The kernel command line option spectre_v2=eibrs is used to select AMD Automatic IBRS, if available. Signed-off-by: Kim Phillips <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Acked-by: Sean Christopherson <[email protected]> Acked-by: Dave Hansen <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent faabfcb commit e7862ed

File tree

6 files changed

+32
-22
lines changed

6 files changed

+32
-22
lines changed

Documentation/admin-guide/hw-vuln/spectre.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -610,9 +610,9 @@ kernel command line.
610610
retpoline,generic Retpolines
611611
retpoline,lfence LFENCE; indirect branch
612612
retpoline,amd alias for retpoline,lfence
613-
eibrs enhanced IBRS
614-
eibrs,retpoline enhanced IBRS + Retpolines
615-
eibrs,lfence enhanced IBRS + LFENCE
613+
eibrs Enhanced/Auto IBRS
614+
eibrs,retpoline Enhanced/Auto IBRS + Retpolines
615+
eibrs,lfence Enhanced/Auto IBRS + LFENCE
616616
ibrs use IBRS to protect kernel
617617

618618
Not specifying this option is equivalent to

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5729,9 +5729,9 @@
57295729
retpoline,generic - Retpolines
57305730
retpoline,lfence - LFENCE; indirect branch
57315731
retpoline,amd - alias for retpoline,lfence
5732-
eibrs - enhanced IBRS
5733-
eibrs,retpoline - enhanced IBRS + Retpolines
5734-
eibrs,lfence - enhanced IBRS + LFENCE
5732+
eibrs - Enhanced/Auto IBRS
5733+
eibrs,retpoline - Enhanced/Auto IBRS + Retpolines
5734+
eibrs,lfence - Enhanced/Auto IBRS + LFENCE
57355735
ibrs - use IBRS to protect kernel
57365736

57375737
Not specifying this option is equivalent to

arch/x86/include/asm/cpufeatures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@
431431
#define X86_FEATURE_NO_NESTED_DATA_BP (20*32+ 0) /* "" No Nested Data Breakpoints */
432432
#define X86_FEATURE_LFENCE_RDTSC (20*32+ 2) /* "" LFENCE always serializing / synchronizes RDTSC */
433433
#define X86_FEATURE_NULL_SEL_CLR_BASE (20*32+ 6) /* "" Null Selector Clears Base */
434+
#define X86_FEATURE_AUTOIBRS (20*32+ 8) /* "" Automatic IBRS */
434435
#define X86_FEATURE_NO_SMM_CTL_MSR (20*32+ 9) /* "" SMM_CTL MSR is not present */
435436

436437
/*

arch/x86/include/asm/msr-index.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#define _EFER_SVME 12 /* Enable virtualization */
2626
#define _EFER_LMSLE 13 /* Long Mode Segment Limit Enable */
2727
#define _EFER_FFXSR 14 /* Enable Fast FXSAVE/FXRSTOR */
28+
#define _EFER_AUTOIBRS 21 /* Enable Automatic IBRS */
2829

2930
#define EFER_SCE (1<<_EFER_SCE)
3031
#define EFER_LME (1<<_EFER_LME)
@@ -33,6 +34,7 @@
3334
#define EFER_SVME (1<<_EFER_SVME)
3435
#define EFER_LMSLE (1<<_EFER_LMSLE)
3536
#define EFER_FFXSR (1<<_EFER_FFXSR)
37+
#define EFER_AUTOIBRS (1<<_EFER_AUTOIBRS)
3638

3739
/* Intel MSRs. Some also available on other CPUs */
3840

arch/x86/kernel/cpu/bugs.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,9 +1238,9 @@ static const char * const spectre_v2_strings[] = {
12381238
[SPECTRE_V2_NONE] = "Vulnerable",
12391239
[SPECTRE_V2_RETPOLINE] = "Mitigation: Retpolines",
12401240
[SPECTRE_V2_LFENCE] = "Mitigation: LFENCE",
1241-
[SPECTRE_V2_EIBRS] = "Mitigation: Enhanced IBRS",
1242-
[SPECTRE_V2_EIBRS_LFENCE] = "Mitigation: Enhanced IBRS + LFENCE",
1243-
[SPECTRE_V2_EIBRS_RETPOLINE] = "Mitigation: Enhanced IBRS + Retpolines",
1241+
[SPECTRE_V2_EIBRS] = "Mitigation: Enhanced / Automatic IBRS",
1242+
[SPECTRE_V2_EIBRS_LFENCE] = "Mitigation: Enhanced / Automatic IBRS + LFENCE",
1243+
[SPECTRE_V2_EIBRS_RETPOLINE] = "Mitigation: Enhanced / Automatic IBRS + Retpolines",
12441244
[SPECTRE_V2_IBRS] = "Mitigation: IBRS",
12451245
};
12461246

@@ -1309,7 +1309,7 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
13091309
cmd == SPECTRE_V2_CMD_EIBRS_LFENCE ||
13101310
cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) &&
13111311
!boot_cpu_has(X86_FEATURE_IBRS_ENHANCED)) {
1312-
pr_err("%s selected but CPU doesn't have eIBRS. Switching to AUTO select\n",
1312+
pr_err("%s selected but CPU doesn't have Enhanced or Automatic IBRS. Switching to AUTO select\n",
13131313
mitigation_options[i].option);
13141314
return SPECTRE_V2_CMD_AUTO;
13151315
}
@@ -1495,8 +1495,12 @@ static void __init spectre_v2_select_mitigation(void)
14951495
pr_err(SPECTRE_V2_EIBRS_EBPF_MSG);
14961496

14971497
if (spectre_v2_in_ibrs_mode(mode)) {
1498-
x86_spec_ctrl_base |= SPEC_CTRL_IBRS;
1499-
update_spec_ctrl(x86_spec_ctrl_base);
1498+
if (boot_cpu_has(X86_FEATURE_AUTOIBRS)) {
1499+
msr_set_bit(MSR_EFER, _EFER_AUTOIBRS);
1500+
} else {
1501+
x86_spec_ctrl_base |= SPEC_CTRL_IBRS;
1502+
update_spec_ctrl(x86_spec_ctrl_base);
1503+
}
15001504
}
15011505

15021506
switch (mode) {
@@ -1580,8 +1584,8 @@ static void __init spectre_v2_select_mitigation(void)
15801584
/*
15811585
* Retpoline protects the kernel, but doesn't protect firmware. IBRS
15821586
* and Enhanced IBRS protect firmware too, so enable IBRS around
1583-
* firmware calls only when IBRS / Enhanced IBRS aren't otherwise
1584-
* enabled.
1587+
* firmware calls only when IBRS / Enhanced / Automatic IBRS aren't
1588+
* otherwise enabled.
15851589
*
15861590
* Use "mode" to check Enhanced IBRS instead of boot_cpu_has(), because
15871591
* the user might select retpoline on the kernel command line and if

arch/x86/kernel/cpu/common.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,8 +1229,8 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
12291229
VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
12301230

12311231
/* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */
1232-
VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
1233-
VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
1232+
VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB),
1233+
VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB),
12341234

12351235
/* Zhaoxin Family 7 */
12361236
VULNWL(CENTAUR, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO),
@@ -1341,8 +1341,16 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
13411341
!cpu_has(c, X86_FEATURE_AMD_SSB_NO))
13421342
setup_force_cpu_bug(X86_BUG_SPEC_STORE_BYPASS);
13431343

1344-
if (ia32_cap & ARCH_CAP_IBRS_ALL)
1344+
/*
1345+
* AMD's AutoIBRS is equivalent to Intel's eIBRS - use the Intel feature
1346+
* flag and protect from vendor-specific bugs via the whitelist.
1347+
*/
1348+
if ((ia32_cap & ARCH_CAP_IBRS_ALL) || cpu_has(c, X86_FEATURE_AUTOIBRS)) {
13451349
setup_force_cpu_cap(X86_FEATURE_IBRS_ENHANCED);
1350+
if (!cpu_matches(cpu_vuln_whitelist, NO_EIBRS_PBRSB) &&
1351+
!(ia32_cap & ARCH_CAP_PBRSB_NO))
1352+
setup_force_cpu_bug(X86_BUG_EIBRS_PBRSB);
1353+
}
13461354

13471355
if (!cpu_matches(cpu_vuln_whitelist, NO_MDS) &&
13481356
!(ia32_cap & ARCH_CAP_MDS_NO)) {
@@ -1404,11 +1412,6 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
14041412
setup_force_cpu_bug(X86_BUG_RETBLEED);
14051413
}
14061414

1407-
if (cpu_has(c, X86_FEATURE_IBRS_ENHANCED) &&
1408-
!cpu_matches(cpu_vuln_whitelist, NO_EIBRS_PBRSB) &&
1409-
!(ia32_cap & ARCH_CAP_PBRSB_NO))
1410-
setup_force_cpu_bug(X86_BUG_EIBRS_PBRSB);
1411-
14121415
if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
14131416
return;
14141417

0 commit comments

Comments
 (0)