Skip to contentSkip to conversation

x86/speculation/l1tf: Increase l1tf memory limit for Nehalem+

PATCH New Andi Kleen 2 participants 4 messages Aug 24, 2018 – Aug 27, 2018

Subsystems (2)
lore
Share & tools
lore

Andi Kleen

author
#0 lore raw

PATCH 1/2 x86/speculation/l1tf: Increase l1tf memory limit for Nehalem+

From: Andi Kleen <[email protected]>

On Nehalem and newer core CPUs the CPU cache internally uses 44 bits physical address space. The L1TF workaround is limited by this internal cache address width, and needs to have one bit free there for the mitigation to work.

Older client systems report only 36bit physical address space so we warn that L1TF is not mitigated for a 36bit phys/32GB system with some memory holes.

But since these actually have the larger internal cache width this warning is bogus because it would only really be needed if the system had more than 43bits of memory

This patch adds a new internal x86_cache_bits field. Normally it is the same as the phys bits field reported by CPUID, but for Nehalem and newer we force it to be at least 44bits.

Then change the L1TF memory size warning to use the new cache_bits field to avoid bogus warnings.

I also removed a now known to be bogus comment about the memory size.

---
 arch/x86/include/asm/processor.h |  4 +++-
 arch/x86/kernel/cpu/bugs.c       | 41 ++++++++++++++++++++++++++++----
 arch/x86/kernel/cpu/common.c     |  1 +
 3 files changed, 40 insertions(+), 6 deletions(-)
arch/x86/include/asm/processor.h +3 -1
index c24297268ebc..d53c54b842da 100644
@@ -132,6 +132,8 @@ struct cpuinfo_x86 {
 	/* Index into per_cpu list: */
 	u16			cpu_index;
 	u32			microcode;
+	/* Address space bits used by the cache internally */
+	u8			x86_cache_bits;
 	unsigned		initialized : 1;
 } __randomize_layout;
 
@@ -183,7 +185,7 @@ extern void cpu_detect(struct cpuinfo_x86 *c);
 
 static inline unsigned long long l1tf_pfn_limit(void)
 {
-	return BIT_ULL(boot_cpu_data.x86_phys_bits - 1 - PAGE_SHIFT);
+	return BIT_ULL(boot_cpu_data.x86_cache_bits - 1 - PAGE_SHIFT);
 }
 
 extern void early_cpu_init(void);
arch/x86/kernel/cpu/bugs.c +36 -5

59 lines not on this page · raw message

arch/x86/kernel/cpu/common.c +1 -0
index 84dee5ab745a..44c4ef3d989b 100644
@@ -919,6 +919,7 @@ void get_cpu_address_sizes(struct cpuinfo_x86 *c)
 	else if (cpu_has(c, X86_FEATURE_PAE) || cpu_has(c, X86_FEATURE_PSE36))
 		c->x86_phys_bits = 36;
 #endif
+	c->x86_cache_bits = c->x86_phys_bits;
 }
 
 static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
Signature · 1 line
2.17.1
author
#1 lore raw

PATCH 2/2 x86/spectre: Add missing family 6 check to microcode check

From: Andi Kleen <[email protected]>

The check for Spectre microcodes did not check for family 6, only the model numbers. Add a family 6 check too just to avoid ambiguity with other families.

---
 arch/x86/kernel/cpu/intel.c | 3 +++
 1 file changed, 3 insertions(+)
arch/x86/kernel/cpu/intel.c +3 -0
index 401e8c133108..fc3c07fe7df5 100644
@@ -150,6 +150,9 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c)
 	if (cpu_has(c, X86_FEATURE_HYPERVISOR))
 		return false;
 
+	if (c->x86 != 6)
+		return false;
+
 	for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) {
 		if (c->x86_model == spectre_bad_microcodes[i].model &&
 		    c->x86_stepping == spectre_bad_microcodes[i].stepping)
Signature · 1 line
2.17.1
#2 lore raw

[tip:x86/urgent] x86/spectre: Add missing family 6 check to microcode check

x86/spectre: Add missing family 6 check to microcode check
Commit-ID:  1ab534e85c93945f7862378d8c8adcf408205b19
Gitweb:     https://git.kernel.org/tip/1ab534e85c93945f7862378d8c8adcf408205b19
Author:     Andi Kleen <[email protected]>
AuthorDate: Fri, 24 Aug 2018 10:03:51 -0700
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 27 Aug 2018 10:29:14 +0200

x86/spectre: Add missing family 6 check to microcode check

The check for Spectre microcodes does not check for family 6, only the model numbers.

Add a family 6 check to avoid ambiguity with other families.

Fixes a5b296636453 ("x86/cpufeature: Blacklist SPEC_CTRL/PRED_CMD on early Spectre v2 microcodes")
---
 arch/x86/kernel/cpu/intel.c | 3 +++
 1 file changed, 3 insertions(+)
arch/x86/kernel/cpu/intel.c +3 -0
index 401e8c133108..fc3c07fe7df5 100644
@@ -150,6 +150,9 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c)
 	if (cpu_has(c, X86_FEATURE_HYPERVISOR))
 		return false;
 
+	if (c->x86 != 6)
+		return false;
+
 	for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) {
 		if (c->x86_model == spectre_bad_microcodes[i].model &&
 		    c->x86_stepping == spectre_bad_microcodes[i].stepping)
#3 lore raw
In reply to Andi Kleen
x86/speculation/l1tf: Increase l1tf memory limit for Nehalem+
Commit-ID:  cc51e5428ea54f575d49cfcede1d4cb3a72b4ec4
Gitweb:     https://git.kernel.org/tip/cc51e5428ea54f575d49cfcede1d4cb3a72b4ec4
Author:     Andi Kleen <[email protected]>
AuthorDate: Fri, 24 Aug 2018 10:03:50 -0700
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Mon, 27 Aug 2018 10:29:14 +0200

x86/speculation/l1tf: Increase l1tf memory limit for Nehalem+

On Nehalem and newer core CPUs the CPU cache internally uses 44 bits physical address space. The L1TF workaround is limited by this internal cache address width, and needs to have one bit free there for the mitigation to work.

Older client systems report only 36bit physical address space so the range check decides that L1TF is not mitigated for a 36bit phys/32GB system with some memory holes.

But since these actually have the larger internal cache width this warning is bogus because it would only really be needed if the system had more than 43bits of memory.

Add a new internal x86_cache_bits field. Normally it is the same as the physical bits field reported by CPUID, but for Nehalem and newerforce it to be at least 44bits.

Change the L1TF memory size warning to use the new cache_bits field to avoid bogus warnings and remove the bogus comment about memory size.

---
 arch/x86/include/asm/processor.h |  4 +++-
 arch/x86/kernel/cpu/bugs.c       | 46 +++++++++++++++++++++++++++++++++++-----
 arch/x86/kernel/cpu/common.c     |  1 +
 3 files changed, 45 insertions(+), 6 deletions(-)
arch/x86/include/asm/processor.h +3 -1
index c24297268ebc..d53c54b842da 100644
@@ -132,6 +132,8 @@ struct cpuinfo_x86 {
 	/* Index into per_cpu list: */
 	u16			cpu_index;
 	u32			microcode;
+	/* Address space bits used by the cache internally */
+	u8			x86_cache_bits;
 	unsigned		initialized : 1;
 } __randomize_layout;
 
@@ -183,7 +185,7 @@ extern void cpu_detect(struct cpuinfo_x86 *c);
 
 static inline unsigned long long l1tf_pfn_limit(void)
 {
-	return BIT_ULL(boot_cpu_data.x86_phys_bits - 1 - PAGE_SHIFT);
+	return BIT_ULL(boot_cpu_data.x86_cache_bits - 1 - PAGE_SHIFT);
 }
 
 extern void early_cpu_init(void);
arch/x86/kernel/cpu/bugs.c +41 -5

64 lines not on this page · raw message

arch/x86/kernel/cpu/common.c +1 -0
index 84dee5ab745a..44c4ef3d989b 100644
@@ -919,6 +919,7 @@ void get_cpu_address_sizes(struct cpuinfo_x86 *c)
 	else if (cpu_has(c, X86_FEATURE_PAE) || cpu_has(c, X86_FEATURE_PSE36))
 		c->x86_phys_bits = 36;
 #endif
+	c->x86_cache_bits = c->x86_phys_bits;
 }
 
 static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)