Skip to content

Commit 6ad0ad2

Browse files
Peter Zijlstrasuryasaimadhu
authored andcommitted
x86/bugs: Report Intel retbleed vulnerability
Skylake suffers from RSB underflow speculation issues; report this vulnerability and it's mitigation (spectre_v2=ibrs). [jpoimboe: cleanups, eibrs] Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Borislav Petkov <bp@suse.de> Reviewed-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Borislav Petkov <bp@suse.de>
1 parent 166115c commit 6ad0ad2

3 files changed

Lines changed: 46 additions & 18 deletions

File tree

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
#define MSR_IA32_ARCH_CAPABILITIES 0x0000010a
9494
#define ARCH_CAP_RDCL_NO BIT(0) /* Not susceptible to Meltdown */
9595
#define ARCH_CAP_IBRS_ALL BIT(1) /* Enhanced IBRS support */
96+
#define ARCH_CAP_RSBA BIT(2) /* RET may use alternative branch predictors */
9697
#define ARCH_CAP_SKIP_VMENTRY_L1DFLUSH BIT(3) /* Skip L1D flush on vmentry */
9798
#define ARCH_CAP_SSB_NO BIT(4) /*
9899
* Not susceptible to Speculative Store Bypass

arch/x86/kernel/cpu/bugs.c

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -790,12 +790,17 @@ static int __init nospectre_v1_cmdline(char *str)
790790
}
791791
early_param("nospectre_v1", nospectre_v1_cmdline);
792792

793+
static enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init =
794+
SPECTRE_V2_NONE;
795+
793796
#undef pr_fmt
794797
#define pr_fmt(fmt) "RETBleed: " fmt
795798

796799
enum retbleed_mitigation {
797800
RETBLEED_MITIGATION_NONE,
798801
RETBLEED_MITIGATION_UNRET,
802+
RETBLEED_MITIGATION_IBRS,
803+
RETBLEED_MITIGATION_EIBRS,
799804
};
800805

801806
enum retbleed_mitigation_cmd {
@@ -807,6 +812,8 @@ enum retbleed_mitigation_cmd {
807812
const char * const retbleed_strings[] = {
808813
[RETBLEED_MITIGATION_NONE] = "Vulnerable",
809814
[RETBLEED_MITIGATION_UNRET] = "Mitigation: untrained return thunk",
815+
[RETBLEED_MITIGATION_IBRS] = "Mitigation: IBRS",
816+
[RETBLEED_MITIGATION_EIBRS] = "Mitigation: Enhanced IBRS",
810817
};
811818

812819
static enum retbleed_mitigation retbleed_mitigation __ro_after_init =
@@ -849,6 +856,7 @@ early_param("retbleed", retbleed_parse_cmdline);
849856

850857
#define RETBLEED_UNTRAIN_MSG "WARNING: BTB untrained return thunk mitigation is only effective on AMD/Hygon!\n"
851858
#define RETBLEED_COMPILER_MSG "WARNING: kernel not compiled with RETPOLINE or -mfunction-return capable compiler!\n"
859+
#define RETBLEED_INTEL_MSG "WARNING: Spectre v2 mitigation leaves CPU vulnerable to RETBleed attacks, data leaks possible!\n"
852860

853861
static void __init retbleed_select_mitigation(void)
854862
{
@@ -865,12 +873,15 @@ static void __init retbleed_select_mitigation(void)
865873

866874
case RETBLEED_CMD_AUTO:
867875
default:
868-
if (!boot_cpu_has_bug(X86_BUG_RETBLEED))
869-
break;
870-
871876
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
872877
boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
873878
retbleed_mitigation = RETBLEED_MITIGATION_UNRET;
879+
880+
/*
881+
* The Intel mitigation (IBRS) was already selected in
882+
* spectre_v2_select_mitigation().
883+
*/
884+
874885
break;
875886
}
876887

@@ -900,15 +911,31 @@ static void __init retbleed_select_mitigation(void)
900911
break;
901912
}
902913

914+
/*
915+
* Let IBRS trump all on Intel without affecting the effects of the
916+
* retbleed= cmdline option.
917+
*/
918+
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
919+
switch (spectre_v2_enabled) {
920+
case SPECTRE_V2_IBRS:
921+
retbleed_mitigation = RETBLEED_MITIGATION_IBRS;
922+
break;
923+
case SPECTRE_V2_EIBRS:
924+
case SPECTRE_V2_EIBRS_RETPOLINE:
925+
case SPECTRE_V2_EIBRS_LFENCE:
926+
retbleed_mitigation = RETBLEED_MITIGATION_EIBRS;
927+
break;
928+
default:
929+
pr_err(RETBLEED_INTEL_MSG);
930+
}
931+
}
932+
903933
pr_info("%s\n", retbleed_strings[retbleed_mitigation]);
904934
}
905935

906936
#undef pr_fmt
907937
#define pr_fmt(fmt) "Spectre V2 : " fmt
908938

909-
static enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init =
910-
SPECTRE_V2_NONE;
911-
912939
static enum spectre_v2_user_mitigation spectre_v2_user_stibp __ro_after_init =
913940
SPECTRE_V2_USER_NONE;
914941
static enum spectre_v2_user_mitigation spectre_v2_user_ibpb __ro_after_init =

arch/x86/kernel/cpu/common.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,24 +1237,24 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
12371237
VULNBL_INTEL_STEPPINGS(BROADWELL_G, X86_STEPPING_ANY, SRBDS),
12381238
VULNBL_INTEL_STEPPINGS(BROADWELL_X, X86_STEPPING_ANY, MMIO),
12391239
VULNBL_INTEL_STEPPINGS(BROADWELL, X86_STEPPING_ANY, SRBDS),
1240-
VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPINGS(0x3, 0x3), SRBDS | MMIO),
1240+
VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPINGS(0x3, 0x3), SRBDS | MMIO | RETBLEED),
12411241
VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPING_ANY, SRBDS),
12421242
VULNBL_INTEL_STEPPINGS(SKYLAKE_X, BIT(3) | BIT(4) | BIT(6) |
1243-
BIT(7) | BIT(0xB), MMIO),
1244-
VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPINGS(0x3, 0x3), SRBDS | MMIO),
1243+
BIT(7) | BIT(0xB), MMIO | RETBLEED),
1244+
VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPINGS(0x3, 0x3), SRBDS | MMIO | RETBLEED),
12451245
VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPING_ANY, SRBDS),
1246-
VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPINGS(0x9, 0xC), SRBDS | MMIO),
1246+
VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPINGS(0x9, 0xC), SRBDS | MMIO | RETBLEED),
12471247
VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPINGS(0x0, 0x8), SRBDS),
1248-
VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPINGS(0x9, 0xD), SRBDS | MMIO),
1248+
VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPINGS(0x9, 0xD), SRBDS | MMIO | RETBLEED),
12491249
VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPINGS(0x0, 0x8), SRBDS),
1250-
VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPINGS(0x5, 0x5), MMIO | MMIO_SBDS),
1250+
VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPINGS(0x5, 0x5), MMIO | MMIO_SBDS | RETBLEED),
12511251
VULNBL_INTEL_STEPPINGS(ICELAKE_D, X86_STEPPINGS(0x1, 0x1), MMIO),
12521252
VULNBL_INTEL_STEPPINGS(ICELAKE_X, X86_STEPPINGS(0x4, 0x6), MMIO),
1253-
VULNBL_INTEL_STEPPINGS(COMETLAKE, BIT(2) | BIT(3) | BIT(5), MMIO | MMIO_SBDS),
1254-
VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPINGS(0x1, 0x1), MMIO | MMIO_SBDS),
1255-
VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPINGS(0x0, 0x0), MMIO),
1256-
VULNBL_INTEL_STEPPINGS(LAKEFIELD, X86_STEPPINGS(0x1, 0x1), MMIO | MMIO_SBDS),
1257-
VULNBL_INTEL_STEPPINGS(ROCKETLAKE, X86_STEPPINGS(0x1, 0x1), MMIO),
1253+
VULNBL_INTEL_STEPPINGS(COMETLAKE, BIT(2) | BIT(3) | BIT(5), MMIO | MMIO_SBDS | RETBLEED),
1254+
VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPINGS(0x1, 0x1), MMIO | MMIO_SBDS | RETBLEED),
1255+
VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPINGS(0x0, 0x0), MMIO | RETBLEED),
1256+
VULNBL_INTEL_STEPPINGS(LAKEFIELD, X86_STEPPINGS(0x1, 0x1), MMIO | MMIO_SBDS | RETBLEED),
1257+
VULNBL_INTEL_STEPPINGS(ROCKETLAKE, X86_STEPPINGS(0x1, 0x1), MMIO | RETBLEED),
12581258
VULNBL_INTEL_STEPPINGS(ATOM_TREMONT, X86_STEPPINGS(0x1, 0x1), MMIO | MMIO_SBDS),
12591259
VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_D, X86_STEPPING_ANY, MMIO),
12601260
VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L, X86_STEPPINGS(0x0, 0x0), MMIO | MMIO_SBDS),
@@ -1364,7 +1364,7 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
13641364
!arch_cap_mmio_immune(ia32_cap))
13651365
setup_force_cpu_bug(X86_BUG_MMIO_STALE_DATA);
13661366

1367-
if (cpu_matches(cpu_vuln_blacklist, RETBLEED))
1367+
if ((cpu_matches(cpu_vuln_blacklist, RETBLEED) || (ia32_cap & ARCH_CAP_RSBA)))
13681368
setup_force_cpu_bug(X86_BUG_RETBLEED);
13691369

13701370
if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))

0 commit comments

Comments
 (0)