aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/cpu/common.c')
-rw-r--r--arch/x86/kernel/cpu/common.c121
1 files changed, 71 insertions, 50 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 8739bdfe9bdf..d7f55ad2dfb1 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -940,61 +940,77 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
940#endif 940#endif
941} 941}
942 942
943static const __initconst struct x86_cpu_id cpu_no_speculation[] = { 943#define NO_SPECULATION BIT(0)
944 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SALTWELL, X86_FEATURE_ANY }, 944#define NO_MELTDOWN BIT(1)
945 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SALTWELL_TABLET, X86_FEATURE_ANY }, 945#define NO_SSB BIT(2)
946 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_BONNELL_MID, X86_FEATURE_ANY }, 946#define NO_L1TF BIT(3)
947 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SALTWELL_MID, X86_FEATURE_ANY }, 947#define NO_MDS BIT(4)
948 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_BONNELL, X86_FEATURE_ANY }, 948#define MSBDS_ONLY BIT(5)
949 { X86_VENDOR_CENTAUR, 5 }, 949
950 { X86_VENDOR_INTEL, 5 }, 950#define VULNWL(_vendor, _family, _model, _whitelist) \
951 { X86_VENDOR_NSC, 5 }, 951 { X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist }
952 { X86_VENDOR_ANY, 4 }, 952
953#define VULNWL_INTEL(model, whitelist) \
954 VULNWL(INTEL, 6, INTEL_FAM6_##model, whitelist)
955
956#define VULNWL_AMD(family, whitelist) \
957 VULNWL(AMD, family, X86_MODEL_ANY, whitelist)
958
959#define VULNWL_HYGON(family, whitelist) \
960 VULNWL(HYGON, family, X86_MODEL_ANY, whitelist)
961
962static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
963 VULNWL(ANY, 4, X86_MODEL_ANY, NO_SPECULATION),
964 VULNWL(CENTAUR, 5, X86_MODEL_ANY, NO_SPECULATION),
965 VULNWL(INTEL, 5, X86_MODEL_ANY, NO_SPECULATION),
966 VULNWL(NSC, 5, X86_MODEL_ANY, NO_SPECULATION),
967
968 /* Intel Family 6 */
969 VULNWL_INTEL(ATOM_SALTWELL, NO_SPECULATION),
970 VULNWL_INTEL(ATOM_SALTWELL_TABLET, NO_SPECULATION),
971 VULNWL_INTEL(ATOM_SALTWELL_MID, NO_SPECULATION),
972 VULNWL_INTEL(ATOM_BONNELL, NO_SPECULATION),
973 VULNWL_INTEL(ATOM_BONNELL_MID, NO_SPECULATION),
974
975 VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY),
976 VULNWL_INTEL(ATOM_SILVERMONT_X, NO_SSB | NO_L1TF | MSBDS_ONLY),
977 VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY),
978 VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY),
979 VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY),
980 VULNWL_INTEL(XEON_PHI_KNM, NO_SSB | NO_L1TF | MSBDS_ONLY),
981
982 VULNWL_INTEL(CORE_YONAH, NO_SSB),
983
984 VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY),
985
986 VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF),
987 VULNWL_INTEL(ATOM_GOLDMONT_X, NO_MDS | NO_L1TF),
988 VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF),
989
990 /* AMD Family 0xf - 0x12 */
991 VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
992 VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
993 VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
994 VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
995
996 /* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */
997 VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS),
998 VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS),
953 {} 999 {}
954}; 1000};
955 1001
956static const __initconst struct x86_cpu_id cpu_no_meltdown[] = { 1002static bool __init cpu_matches(unsigned long which)
957 { X86_VENDOR_AMD }, 1003{
958 { X86_VENDOR_HYGON }, 1004 const struct x86_cpu_id *m = x86_match_cpu(cpu_vuln_whitelist);
959 {}
960};
961
962/* Only list CPUs which speculate but are non susceptible to SSB */
963static const __initconst struct x86_cpu_id cpu_no_spec_store_bypass[] = {
964 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT },
965 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_AIRMONT },
966 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT_X },
967 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT_MID },
968 { X86_VENDOR_INTEL, 6, INTEL_FAM6_CORE_YONAH },
969 { X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNL },
970 { X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNM },
971 { X86_VENDOR_AMD, 0x12, },
972 { X86_VENDOR_AMD, 0x11, },
973 { X86_VENDOR_AMD, 0x10, },
974 { X86_VENDOR_AMD, 0xf, },
975 {}
976};
977 1005
978static const __initconst struct x86_cpu_id cpu_no_l1tf[] = { 1006 return m && !!(m->driver_data & which);
979 /* in addition to cpu_no_speculation */ 1007}
980 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT },
981 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT_X },
982 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_AIRMONT },
983 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT_MID },
984 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_AIRMONT_MID },
985 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_GOLDMONT },
986 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_GOLDMONT_X },
987 { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_GOLDMONT_PLUS },
988 { X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNL },
989 { X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNM },
990 {}
991};
992 1008
993static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) 1009static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
994{ 1010{
995 u64 ia32_cap = 0; 1011 u64 ia32_cap = 0;
996 1012
997 if (x86_match_cpu(cpu_no_speculation)) 1013 if (cpu_matches(NO_SPECULATION))
998 return; 1014 return;
999 1015
1000 setup_force_cpu_bug(X86_BUG_SPECTRE_V1); 1016 setup_force_cpu_bug(X86_BUG_SPECTRE_V1);
@@ -1003,15 +1019,20 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
1003 if (cpu_has(c, X86_FEATURE_ARCH_CAPABILITIES)) 1019 if (cpu_has(c, X86_FEATURE_ARCH_CAPABILITIES))
1004 rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap); 1020 rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap);
1005 1021
1006 if (!x86_match_cpu(cpu_no_spec_store_bypass) && 1022 if (!cpu_matches(NO_SSB) && !(ia32_cap & ARCH_CAP_SSB_NO) &&
1007 !(ia32_cap & ARCH_CAP_SSB_NO) &&
1008 !cpu_has(c, X86_FEATURE_AMD_SSB_NO)) 1023 !cpu_has(c, X86_FEATURE_AMD_SSB_NO))
1009 setup_force_cpu_bug(X86_BUG_SPEC_STORE_BYPASS); 1024 setup_force_cpu_bug(X86_BUG_SPEC_STORE_BYPASS);
1010 1025
1011 if (ia32_cap & ARCH_CAP_IBRS_ALL) 1026 if (ia32_cap & ARCH_CAP_IBRS_ALL)
1012 setup_force_cpu_cap(X86_FEATURE_IBRS_ENHANCED); 1027 setup_force_cpu_cap(X86_FEATURE_IBRS_ENHANCED);
1013 1028
1014 if (x86_match_cpu(cpu_no_meltdown)) 1029 if (!cpu_matches(NO_MDS) && !(ia32_cap & ARCH_CAP_MDS_NO)) {
1030 setup_force_cpu_bug(X86_BUG_MDS);
1031 if (cpu_matches(MSBDS_ONLY))
1032 setup_force_cpu_bug(X86_BUG_MSBDS_ONLY);
1033 }
1034
1035 if (cpu_matches(NO_MELTDOWN))
1015 return; 1036 return;
1016 1037
1017 /* Rogue Data Cache Load? No! */ 1038 /* Rogue Data Cache Load? No! */
@@ -1020,7 +1041,7 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
1020 1041
1021 setup_force_cpu_bug(X86_BUG_CPU_MELTDOWN); 1042 setup_force_cpu_bug(X86_BUG_CPU_MELTDOWN);
1022 1043
1023 if (x86_match_cpu(cpu_no_l1tf)) 1044 if (cpu_matches(NO_L1TF))
1024 return; 1045 return;
1025 1046
1026 setup_force_cpu_bug(X86_BUG_L1TF); 1047 setup_force_cpu_bug(X86_BUG_L1TF);