diff options
-rw-r--r-- | Documentation/ABI/testing/sysfs-devices-system-cpu | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/cpufeatures.h | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/msr-index.h | 7 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/bugs.c | 13 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 65 | ||||
-rw-r--r-- | drivers/base/cpu.c | 8 | ||||
-rw-r--r-- | include/linux/cpu.h | 2 |
7 files changed, 67 insertions, 30 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index 0e77569bd5e0..fc20cde63d1e 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu | |||
@@ -487,6 +487,7 @@ What: /sys/devices/system/cpu/vulnerabilities | |||
487 | /sys/devices/system/cpu/vulnerabilities/l1tf | 487 | /sys/devices/system/cpu/vulnerabilities/l1tf |
488 | /sys/devices/system/cpu/vulnerabilities/mds | 488 | /sys/devices/system/cpu/vulnerabilities/mds |
489 | /sys/devices/system/cpu/vulnerabilities/tsx_async_abort | 489 | /sys/devices/system/cpu/vulnerabilities/tsx_async_abort |
490 | /sys/devices/system/cpu/vulnerabilities/itlb_multihit | ||
490 | Date: January 2018 | 491 | Date: January 2018 |
491 | Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> | 492 | Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> |
492 | Description: Information about CPU vulnerabilities | 493 | Description: Information about CPU vulnerabilities |
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index 989e03544f18..c4fbe379cc0b 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h | |||
@@ -400,5 +400,6 @@ | |||
400 | #define X86_BUG_MSBDS_ONLY X86_BUG(20) /* CPU is only affected by the MSDBS variant of BUG_MDS */ | 400 | #define X86_BUG_MSBDS_ONLY X86_BUG(20) /* CPU is only affected by the MSDBS variant of BUG_MDS */ |
401 | #define X86_BUG_SWAPGS X86_BUG(21) /* CPU is affected by speculation through SWAPGS */ | 401 | #define X86_BUG_SWAPGS X86_BUG(21) /* CPU is affected by speculation through SWAPGS */ |
402 | #define X86_BUG_TAA X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */ | 402 | #define X86_BUG_TAA X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */ |
403 | #define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */ | ||
403 | 404 | ||
404 | #endif /* _ASM_X86_CPUFEATURES_H */ | 405 | #endif /* _ASM_X86_CPUFEATURES_H */ |
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index b3a8bb2af0b6..6a3124664289 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h | |||
@@ -93,6 +93,13 @@ | |||
93 | * Microarchitectural Data | 93 | * Microarchitectural Data |
94 | * Sampling (MDS) vulnerabilities. | 94 | * Sampling (MDS) vulnerabilities. |
95 | */ | 95 | */ |
96 | #define ARCH_CAP_PSCHANGE_MC_NO BIT(6) /* | ||
97 | * The processor is not susceptible to a | ||
98 | * machine check error due to modifying the | ||
99 | * code page size along with either the | ||
100 | * physical address or cache type | ||
101 | * without TLB invalidation. | ||
102 | */ | ||
96 | #define ARCH_CAP_TSX_CTRL_MSR BIT(7) /* MSR for TSX control is available. */ | 103 | #define ARCH_CAP_TSX_CTRL_MSR BIT(7) /* MSR for TSX control is available. */ |
97 | #define ARCH_CAP_TAA_NO BIT(8) /* | 104 | #define ARCH_CAP_TAA_NO BIT(8) /* |
98 | * Not susceptible to | 105 | * Not susceptible to |
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 43c647e19439..5364beda8c61 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c | |||
@@ -1419,6 +1419,11 @@ static ssize_t l1tf_show_state(char *buf) | |||
1419 | } | 1419 | } |
1420 | #endif | 1420 | #endif |
1421 | 1421 | ||
1422 | static ssize_t itlb_multihit_show_state(char *buf) | ||
1423 | { | ||
1424 | return sprintf(buf, "Processor vulnerable\n"); | ||
1425 | } | ||
1426 | |||
1422 | static ssize_t mds_show_state(char *buf) | 1427 | static ssize_t mds_show_state(char *buf) |
1423 | { | 1428 | { |
1424 | if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) { | 1429 | if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) { |
@@ -1524,6 +1529,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr | |||
1524 | case X86_BUG_TAA: | 1529 | case X86_BUG_TAA: |
1525 | return tsx_async_abort_show_state(buf); | 1530 | return tsx_async_abort_show_state(buf); |
1526 | 1531 | ||
1532 | case X86_BUG_ITLB_MULTIHIT: | ||
1533 | return itlb_multihit_show_state(buf); | ||
1534 | |||
1527 | default: | 1535 | default: |
1528 | break; | 1536 | break; |
1529 | } | 1537 | } |
@@ -1565,4 +1573,9 @@ ssize_t cpu_show_tsx_async_abort(struct device *dev, struct device_attribute *at | |||
1565 | { | 1573 | { |
1566 | return cpu_show_common(dev, attr, buf, X86_BUG_TAA); | 1574 | return cpu_show_common(dev, attr, buf, X86_BUG_TAA); |
1567 | } | 1575 | } |
1576 | |||
1577 | ssize_t cpu_show_itlb_multihit(struct device *dev, struct device_attribute *attr, char *buf) | ||
1578 | { | ||
1579 | return cpu_show_common(dev, attr, buf, X86_BUG_ITLB_MULTIHIT); | ||
1580 | } | ||
1568 | #endif | 1581 | #endif |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index f8b8afc8f5b5..d29b71ca3ca7 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -1016,13 +1016,14 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c) | |||
1016 | #endif | 1016 | #endif |
1017 | } | 1017 | } |
1018 | 1018 | ||
1019 | #define NO_SPECULATION BIT(0) | 1019 | #define NO_SPECULATION BIT(0) |
1020 | #define NO_MELTDOWN BIT(1) | 1020 | #define NO_MELTDOWN BIT(1) |
1021 | #define NO_SSB BIT(2) | 1021 | #define NO_SSB BIT(2) |
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 | #define NO_SWAPGS BIT(6) |
1026 | #define NO_ITLB_MULTIHIT BIT(7) | ||
1026 | 1027 | ||
1027 | #define VULNWL(_vendor, _family, _model, _whitelist) \ | 1028 | #define VULNWL(_vendor, _family, _model, _whitelist) \ |
1028 | { X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist } | 1029 | { X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist } |
@@ -1043,27 +1044,27 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { | |||
1043 | VULNWL(NSC, 5, X86_MODEL_ANY, NO_SPECULATION), | 1044 | VULNWL(NSC, 5, X86_MODEL_ANY, NO_SPECULATION), |
1044 | 1045 | ||
1045 | /* Intel Family 6 */ | 1046 | /* Intel Family 6 */ |
1046 | VULNWL_INTEL(ATOM_SALTWELL, NO_SPECULATION), | 1047 | VULNWL_INTEL(ATOM_SALTWELL, NO_SPECULATION | NO_ITLB_MULTIHIT), |
1047 | VULNWL_INTEL(ATOM_SALTWELL_TABLET, NO_SPECULATION), | 1048 | VULNWL_INTEL(ATOM_SALTWELL_TABLET, NO_SPECULATION | NO_ITLB_MULTIHIT), |
1048 | VULNWL_INTEL(ATOM_SALTWELL_MID, NO_SPECULATION), | 1049 | VULNWL_INTEL(ATOM_SALTWELL_MID, NO_SPECULATION | NO_ITLB_MULTIHIT), |
1049 | VULNWL_INTEL(ATOM_BONNELL, NO_SPECULATION), | 1050 | VULNWL_INTEL(ATOM_BONNELL, NO_SPECULATION | NO_ITLB_MULTIHIT), |
1050 | VULNWL_INTEL(ATOM_BONNELL_MID, NO_SPECULATION), | 1051 | VULNWL_INTEL(ATOM_BONNELL_MID, NO_SPECULATION | NO_ITLB_MULTIHIT), |
1051 | 1052 | ||
1052 | VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), | 1053 | VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT), |
1053 | VULNWL_INTEL(ATOM_SILVERMONT_D, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), | 1054 | VULNWL_INTEL(ATOM_SILVERMONT_D, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT), |
1054 | VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), | 1055 | VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT), |
1055 | VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), | 1056 | VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT), |
1056 | VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), | 1057 | VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT), |
1057 | VULNWL_INTEL(XEON_PHI_KNM, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), | 1058 | VULNWL_INTEL(XEON_PHI_KNM, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT), |
1058 | 1059 | ||
1059 | VULNWL_INTEL(CORE_YONAH, NO_SSB), | 1060 | VULNWL_INTEL(CORE_YONAH, NO_SSB), |
1060 | 1061 | ||
1061 | VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY | NO_SWAPGS), | 1062 | VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT), |
1062 | VULNWL_INTEL(ATOM_AIRMONT_NP, NO_L1TF | NO_SWAPGS), | 1063 | VULNWL_INTEL(ATOM_AIRMONT_NP, NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), |
1063 | 1064 | ||
1064 | VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS), | 1065 | VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), |
1065 | VULNWL_INTEL(ATOM_GOLDMONT_D, NO_MDS | NO_L1TF | NO_SWAPGS), | 1066 | VULNWL_INTEL(ATOM_GOLDMONT_D, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), |
1066 | VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS), | 1067 | VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), |
1067 | 1068 | ||
1068 | /* | 1069 | /* |
1069 | * Technically, swapgs isn't serializing on AMD (despite it previously | 1070 | * Technically, swapgs isn't serializing on AMD (despite it previously |
@@ -1074,14 +1075,14 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { | |||
1074 | */ | 1075 | */ |
1075 | 1076 | ||
1076 | /* AMD Family 0xf - 0x12 */ | 1077 | /* AMD Family 0xf - 0x12 */ |
1077 | VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS), | 1078 | VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), |
1078 | VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS), | 1079 | VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), |
1079 | VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS), | 1080 | VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), |
1080 | VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS), | 1081 | VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), |
1081 | 1082 | ||
1082 | /* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */ | 1083 | /* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */ |
1083 | VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS), | 1084 | VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), |
1084 | VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS), | 1085 | VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), |
1085 | {} | 1086 | {} |
1086 | }; | 1087 | }; |
1087 | 1088 | ||
@@ -1106,6 +1107,10 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) | |||
1106 | { | 1107 | { |
1107 | u64 ia32_cap = x86_read_arch_cap_msr(); | 1108 | u64 ia32_cap = x86_read_arch_cap_msr(); |
1108 | 1109 | ||
1110 | /* Set ITLB_MULTIHIT bug if cpu is not in the whitelist and not mitigated */ | ||
1111 | if (!cpu_matches(NO_ITLB_MULTIHIT) && !(ia32_cap & ARCH_CAP_PSCHANGE_MC_NO)) | ||
1112 | setup_force_cpu_bug(X86_BUG_ITLB_MULTIHIT); | ||
1113 | |||
1109 | if (cpu_matches(NO_SPECULATION)) | 1114 | if (cpu_matches(NO_SPECULATION)) |
1110 | return; | 1115 | return; |
1111 | 1116 | ||
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 0fccd8c0312e..6265871a4af2 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -561,6 +561,12 @@ ssize_t __weak cpu_show_tsx_async_abort(struct device *dev, | |||
561 | return sprintf(buf, "Not affected\n"); | 561 | return sprintf(buf, "Not affected\n"); |
562 | } | 562 | } |
563 | 563 | ||
564 | ssize_t __weak cpu_show_itlb_multihit(struct device *dev, | ||
565 | struct device_attribute *attr, char *buf) | ||
566 | { | ||
567 | return sprintf(buf, "Not affected\n"); | ||
568 | } | ||
569 | |||
564 | static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); | 570 | static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); |
565 | static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); | 571 | static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); |
566 | static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL); | 572 | static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL); |
@@ -568,6 +574,7 @@ static DEVICE_ATTR(spec_store_bypass, 0444, cpu_show_spec_store_bypass, NULL); | |||
568 | static DEVICE_ATTR(l1tf, 0444, cpu_show_l1tf, NULL); | 574 | static DEVICE_ATTR(l1tf, 0444, cpu_show_l1tf, NULL); |
569 | static DEVICE_ATTR(mds, 0444, cpu_show_mds, NULL); | 575 | static DEVICE_ATTR(mds, 0444, cpu_show_mds, NULL); |
570 | static DEVICE_ATTR(tsx_async_abort, 0444, cpu_show_tsx_async_abort, NULL); | 576 | static DEVICE_ATTR(tsx_async_abort, 0444, cpu_show_tsx_async_abort, NULL); |
577 | static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL); | ||
571 | 578 | ||
572 | static struct attribute *cpu_root_vulnerabilities_attrs[] = { | 579 | static struct attribute *cpu_root_vulnerabilities_attrs[] = { |
573 | &dev_attr_meltdown.attr, | 580 | &dev_attr_meltdown.attr, |
@@ -577,6 +584,7 @@ static struct attribute *cpu_root_vulnerabilities_attrs[] = { | |||
577 | &dev_attr_l1tf.attr, | 584 | &dev_attr_l1tf.attr, |
578 | &dev_attr_mds.attr, | 585 | &dev_attr_mds.attr, |
579 | &dev_attr_tsx_async_abort.attr, | 586 | &dev_attr_tsx_async_abort.attr, |
587 | &dev_attr_itlb_multihit.attr, | ||
580 | NULL | 588 | NULL |
581 | }; | 589 | }; |
582 | 590 | ||
diff --git a/include/linux/cpu.h b/include/linux/cpu.h index f35369f79771..2a093434e975 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h | |||
@@ -62,6 +62,8 @@ extern ssize_t cpu_show_mds(struct device *dev, | |||
62 | extern ssize_t cpu_show_tsx_async_abort(struct device *dev, | 62 | extern ssize_t cpu_show_tsx_async_abort(struct device *dev, |
63 | struct device_attribute *attr, | 63 | struct device_attribute *attr, |
64 | char *buf); | 64 | char *buf); |
65 | extern ssize_t cpu_show_itlb_multihit(struct device *dev, | ||
66 | struct device_attribute *attr, char *buf); | ||
65 | 67 | ||
66 | extern __printf(4, 5) | 68 | extern __printf(4, 5) |
67 | struct device *cpu_device_create(struct device *parent, void *drvdata, | 69 | struct device *cpu_device_create(struct device *parent, void *drvdata, |