diff --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; }