diff options
Diffstat (limited to 'arch/x86/kernel/cpu/common.c')
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 121 |
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 | ||
943 | static 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 | |||
962 | static 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 | ||
956 | static const __initconst struct x86_cpu_id cpu_no_meltdown[] = { | 1002 | static 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 */ | ||
963 | static 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 | ||
978 | static 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 | ||
993 | static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) | 1009 | static 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); |