Re: [PATCH v2 0/2] x86/cpu: fix invalid MTRR mask values for SEV or TME

From: Dave Hansen
Date: Thu Feb 01 2024 - 16:42:37 EST


On 2/1/24 10:29, Dave Hansen wrote:
> Could we instead do something more like the (completely untested)
> attached patch?

.. actually attaching it herediff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 26620d7642a9..415ae443ef79 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -119,6 +119,7 @@ struct cpuinfo_x86 {
#endif
__u8 x86_virt_bits;
__u8 x86_phys_bits;
+ __u8 enc_phys_bits;
/* CPUID returned core id bits: */
__u8 x86_coreid_bits;
/* Max extended CPUID function supported: */
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index f3abca334199..40fc44dfa7a4 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -618,11 +618,13 @@ static void early_detect_mem_encrypt(struct cpuinfo_x86 *c)
goto clear_all;

/*
- * Always adjust physical address bits. Even though this
- * will be a value above 32-bits this is still done for
- * CONFIG_X86_32 so that accurate values are reported.
+ * Record the number of physical address bits that
+ * have been repurposed for memory encryption. Do
+ * this even on CONFIG_X86_32 configs that do can
+ * not support memory encryption so it is still
+ * reported accurately.
*/
- c->x86_phys_bits -= (cpuid_ebx(0x8000001f) >> 6) & 0x3f;
+ c->enc_phys_bits = (cpuid_ebx(0x8000001f) >> 6) & 0x3f;

if (IS_ENABLED(CONFIG_X86_32))
goto clear_all;
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 0b97bcde70c6..b998ae7fbbfb 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1098,6 +1098,10 @@ void get_cpu_address_sizes(struct cpuinfo_x86 *c)
u32 eax, ebx, ecx, edx;
bool vp_bits_from_cpuid = true;

+ WARN_ON(c->x86_clflush_size ||
+ c->x86_phys_bits ||
+ c->x86_virt_bits);
+
if (!cpu_has(c, X86_FEATURE_CPUID) ||
(c->extended_cpuid_level < 0x80000008))
vp_bits_from_cpuid = false;
@@ -1122,6 +1126,8 @@ void get_cpu_address_sizes(struct cpuinfo_x86 *c)
c->x86_phys_bits = 36;
}
}
+ c->x86_phys_bits -= c->enc_phys_bits;
+
c->x86_cache_bits = c->x86_phys_bits;
c->x86_cache_alignment = c->x86_clflush_size;
}