diff options
Diffstat (limited to 'arch/x86/kernel/cpu/common.c')
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 11472178e17f..f125bf7ecb6f 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -1022,6 +1022,7 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c) | |||
1022 | #define NO_L1TF BIT(3) | 1022 | #define NO_L1TF BIT(3) |
1023 | #define NO_MDS BIT(4) | 1023 | #define NO_MDS BIT(4) |
1024 | #define MSBDS_ONLY BIT(5) | 1024 | #define MSBDS_ONLY BIT(5) |
1025 | #define NO_SWAPGS BIT(6) | ||
1025 | 1026 | ||
1026 | #define VULNWL(_vendor, _family, _model, _whitelist) \ | 1027 | #define VULNWL(_vendor, _family, _model, _whitelist) \ |
1027 | { X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist } | 1028 | { X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist } |
@@ -1048,30 +1049,38 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { | |||
1048 | VULNWL_INTEL(ATOM_BONNELL, NO_SPECULATION), | 1049 | VULNWL_INTEL(ATOM_BONNELL, NO_SPECULATION), |
1049 | VULNWL_INTEL(ATOM_BONNELL_MID, NO_SPECULATION), | 1050 | VULNWL_INTEL(ATOM_BONNELL_MID, NO_SPECULATION), |
1050 | 1051 | ||
1051 | VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY), | 1052 | VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), |
1052 | VULNWL_INTEL(ATOM_SILVERMONT_X, NO_SSB | NO_L1TF | MSBDS_ONLY), | 1053 | VULNWL_INTEL(ATOM_SILVERMONT_X, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), |
1053 | VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY), | 1054 | VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), |
1054 | VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY), | 1055 | VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), |
1055 | VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY), | 1056 | VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), |
1056 | VULNWL_INTEL(XEON_PHI_KNM, NO_SSB | NO_L1TF | MSBDS_ONLY), | 1057 | VULNWL_INTEL(XEON_PHI_KNM, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), |
1057 | 1058 | ||
1058 | VULNWL_INTEL(CORE_YONAH, NO_SSB), | 1059 | VULNWL_INTEL(CORE_YONAH, NO_SSB), |
1059 | 1060 | ||
1060 | VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY), | 1061 | VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY | NO_SWAPGS), |
1061 | 1062 | ||
1062 | VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF), | 1063 | VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS), |
1063 | VULNWL_INTEL(ATOM_GOLDMONT_X, NO_MDS | NO_L1TF), | 1064 | VULNWL_INTEL(ATOM_GOLDMONT_X, NO_MDS | NO_L1TF | NO_SWAPGS), |
1064 | VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF), | 1065 | VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS), |
1066 | |||
1067 | /* | ||
1068 | * Technically, swapgs isn't serializing on AMD (despite it previously | ||
1069 | * being documented as such in the APM). But according to AMD, %gs is | ||
1070 | * updated non-speculatively, and the issuing of %gs-relative memory | ||
1071 | * operands will be blocked until the %gs update completes, which is | ||
1072 | * good enough for our purposes. | ||
1073 | */ | ||
1065 | 1074 | ||
1066 | /* AMD Family 0xf - 0x12 */ | 1075 | /* AMD Family 0xf - 0x12 */ |
1067 | VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS), | 1076 | VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS), |
1068 | VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS), | 1077 | VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS), |
1069 | VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS), | 1078 | VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS), |
1070 | VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS), | 1079 | VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS), |
1071 | 1080 | ||
1072 | /* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */ | 1081 | /* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */ |
1073 | VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS), | 1082 | VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS), |
1074 | VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS), | 1083 | VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS), |
1075 | {} | 1084 | {} |
1076 | }; | 1085 | }; |
1077 | 1086 | ||
@@ -1108,6 +1117,9 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) | |||
1108 | setup_force_cpu_bug(X86_BUG_MSBDS_ONLY); | 1117 | setup_force_cpu_bug(X86_BUG_MSBDS_ONLY); |
1109 | } | 1118 | } |
1110 | 1119 | ||
1120 | if (!cpu_matches(NO_SWAPGS)) | ||
1121 | setup_force_cpu_bug(X86_BUG_SWAPGS); | ||
1122 | |||
1111 | if (cpu_matches(NO_MELTDOWN)) | 1123 | if (cpu_matches(NO_MELTDOWN)) |
1112 | return; | 1124 | return; |
1113 | 1125 | ||