History

x86/bugs: Add ITLB_MULTIHIT bug infrastructure

Some processors may incur a machine check error possibly resulting in an unrecoverable CPU lockup when an instruction fetch encounters a TLB multi-hit in the instruction TLB. This can occur when the page size is changed along with either the physical address or cache type. The relevant erratum can be found here: https://bugzilla.kernel.org/show_bug.cgi?id=205195 There are other processors affected for which the erratum does not fully disclose the impact. This issue affects both bare-metal x86 page tables and EPT. It can be mitigated by either eliminating the use of large pages or by using careful TLB invalidations when changing the page size in the page tables. Just like Spectre, Meltdown, L1TF and MDS, a new bit has been allocated in MSR_IA32_ARCH_CAPABILITIES (PSCHANGE_MC_NO) and will be set on CPUs which are mitigated against this issue.

Vineela Tummalapalli committed 7 years ago

Commit db4d30f1 parent ca8888d7 files · +67 −30Browse files

Unified · Split

7 files
  1. Documentation/ABI/testing/sysfs-devices-system-cpu +1 −0
  2. arch/x86/include/asm/cpufeatures.h +1 −0
  3. arch/x86/include/asm/msr-index.h +7 −0
  4. arch/x86/kernel/cpu/bugs.c +13 −0
  5. arch/x86/kernel/cpu/common.c +35 −30
  6. drivers/base/cpu.c +8 −0
  7. include/linux/cpu.h +2 −0
Documentation/ABI/testing/sysfs-devices-system-cpu+1−0
@@ -487,6 +487,7 @@ What: /sys/devices/system/cpu/vulnerabilities · 486 unmodified lines
487 /sys/devices/system/cpu/vulnerabilities/l1tf487 /sys/devices/system/cpu/vulnerabilities/l1tf
488 /sys/devices/system/cpu/vulnerabilities/mds488 /sys/devices/system/cpu/vulnerabilities/mds
489 /sys/devices/system/cpu/vulnerabilities/tsx_async_abort489 /sys/devices/system/cpu/vulnerabilities/tsx_async_abort
490 /sys/devices/system/cpu/vulnerabilities/itlb_multihit
490Date: January 2018491Date: January 2018
491Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>492Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
492Description: Information about CPU vulnerabilities493Description: Information about CPU vulnerabilities
arch/x86/include/asm/cpufeatures.h+1−0
@@ -400,5 +400,6 @@ · 399 unmodified lines
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 */
arch/x86/include/asm/msr-index.h+7−0
@@ -93,6 +93,13 @@ · 92 unmodified lines
93 * Microarchitectural Data93 * 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 to105 * Not susceptible to
arch/x86/kernel/cpu/bugs.c+13−0
@@ -1419,6 +1419,11 @@ static ssize_t l1tf_show_state(char *buf) · 1418 unmodified lines
1419}1419}
1420#endif1420#endif
1421 1421
1422static ssize_t itlb_multihit_show_state(char *buf)
1423{
1424 return sprintf(buf, "Processor vulnerable\n");
1425}
1426
1422static ssize_t mds_show_state(char *buf)1427static 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 · 99 unmodified lines
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 · 35 unmodified lines
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
1577ssize_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#endif1581#endif
arch/x86/kernel/cpu/common.c+35−30
@@ -1016,13 +1016,14 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c) · 1015 unmodified lines
1016#endif1016#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[] = { · 14 unmodified lines
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 previously1070 * Technically, swapgs isn't serializing on AMD (despite it previously
@@ -1074,14 +1075,14 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { · 4 unmodified lines
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) · 18 unmodified lines
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
drivers/base/cpu.c+8−0
@@ -561,6 +561,12 @@ ssize_t __weak cpu_show_tsx_async_abort(struct device *dev, · 560 unmodified lines
561 return sprintf(buf, "Not affected\n");561 return sprintf(buf, "Not affected\n");
562}562}
563 563
564ssize_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
564static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL);570static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL);
565static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL);571static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL);
566static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL);572static 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); · 1 unmodified line
568static DEVICE_ATTR(l1tf, 0444, cpu_show_l1tf, NULL);574static DEVICE_ATTR(l1tf, 0444, cpu_show_l1tf, NULL);
569static DEVICE_ATTR(mds, 0444, cpu_show_mds, NULL);575static DEVICE_ATTR(mds, 0444, cpu_show_mds, NULL);
570static DEVICE_ATTR(tsx_async_abort, 0444, cpu_show_tsx_async_abort, NULL);576static DEVICE_ATTR(tsx_async_abort, 0444, cpu_show_tsx_async_abort, NULL);
577static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL);
571 578
572static struct attribute *cpu_root_vulnerabilities_attrs[] = {579static 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[] = { · 3 unmodified lines
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 NULL588 NULL
581};589};
582 590
include/linux/cpu.h+2−0
@@ -62,6 +62,8 @@ extern ssize_t cpu_show_mds(struct device *dev, · 61 unmodified lines
62extern ssize_t cpu_show_tsx_async_abort(struct device *dev,62extern 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);
65extern ssize_t cpu_show_itlb_multihit(struct device *dev,
66 struct device_attribute *attr, char *buf);
65 67
66extern __printf(4, 5)68extern __printf(4, 5)
67struct device *cpu_device_create(struct device *parent, void *drvdata,69struct device *cpu_device_create(struct device *parent, void *drvdata,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t