Re: Reserved bits and commit x86/sev-es: Set x86_virt_bits to the correct value straight away, instead of a two-phase approach

From: Tom Lendacky
Date: Wed Jan 31 2024 - 16:34:26 EST


On 1/30/24 15:33, Jacob Xu wrote:
Adding some AMD folk to the thread here.

For AMD CPUs, initialization of c->x86_phys_bits occurs in
get_cpu_address_sizes() which is called from early_identify_cpu().

However, early_identify_cpu() will first call early_init_amd() which adjusts
x86_phys_bits based on the PhysAddrReduction CPUID field.

c->x86_phys_bits -= (cpuid_ebx(0x8000001f) >> 6) & 0x3f;

Thus, this adjustment is ignored.

Adding a new cpu_dev callback to calculate num reserved_cpu_bits makes sense to
me, hopefully the AMD folk can chime in here though.

Later identify_cpu() calls init_amd() which then makes the adjustment. So there is a window between when the value is at 48 and when it gets reduced to 43 (on my Milan system).

The actual flow has setup_arch() set the value to MAX_PHYSMEM_BITS, which is 46. Then early_detect_mem_encrypt() reduces that to 41. Then get_cpu_address_sizes() resets it to 48. Then a bit later, identify_cpu() calls init_amd() which calls early_init_amd() which calls early_detect_mem_encrypt() which reduces x86_phys_bits to 43.

Looking closer, if mem_encrypt=off is specified, then X86_FEATURE_SME is cleared and it is X86_FEATURE_SEV that causes the adjustment. If X86_FEATURE_SEV also gets cleared, we won't make the adjustment even though when we should.

So I like the idea of a callback to calculate the number of reserved physical address bits.

Thanks,
Tom


Jacob