[RFC][PATCH 09/34] x86/cpu: Introduce address configuration structure

Dave Hansen
2024-02-22T18:39:39Z

Right now, 'boot_cpu_data' is established in a very ad hoc way. Random
bits of the initialization code write random things to it, either
blowing away state or tweaking it as they see fit. It's madness.

Add some more structure to the process.

Introduce an "address configuration" structure just for the boot CPU.
This will be used to establish system-wide address space configuration.
It is written while bringing up the boot CPU and then read *ONCE* to
establish the configuration.

Also introduce the first field: phys_addr_reduction_bits. This field
will be used by memory encryption hardware that reduces the actual
usable address bits beneath what the hardware enumerates.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
---

b/arch/x86/include/asm/processor.h | 14 ++++++++++++++
b/arch/x86/kernel/cpu/common.c | 3 +++
b/arch/x86/kernel/setup.c | 2 ++
3 files changed, 19 insertions(+)

diff -puN arch/x86/include/asm/processor.h~bsp-addr-info arch/x86/include/asm/processor.h
--- a/arch/x86/include/asm/processor.h~bsp-addr-info 2024-02-22 10:08:52.824624673 -0800
+++ b/arch/x86/include/asm/processor.h 2024-02-22 10:08:52.828624830 -0800
@@ -163,6 +163,19 @@ struct cpuinfo_x86 {
unsigned initialized : 1;
} __randomize_layout;

+/*
+ * Must be written by the time ->c_bsp_init() completes.
+ * Consumed in get_cpu_address_sizes().
+ */
+struct x86_addr_config {
+ /*
+ * How many bits of the expected or enumerated physical
+ * address space are unavailable? Typically set on
+ * platforms that use memory encryption.
+ */
+ u8 phys_addr_reduction_bits;
+};
+
#define X86_VENDOR_INTEL 0
#define X86_VENDOR_CYRIX 1
#define X86_VENDOR_AMD 2
@@ -182,6 +195,7 @@ struct cpuinfo_x86 {
*/
extern struct cpuinfo_x86 boot_cpu_data;
extern struct cpuinfo_x86 new_cpu_data;
+extern struct x86_addr_config bsp_addr_config;

extern __u32 cpu_caps_cleared[NCAPINTS + NBUGINTS];
extern __u32 cpu_caps_set[NCAPINTS + NBUGINTS];
diff -puN arch/x86/kernel/cpu/common.c~bsp-addr-info arch/x86/kernel/cpu/common.c
--- a/arch/x86/kernel/cpu/common.c~bsp-addr-info 2024-02-22 10:08:52.824624673 -0800
+++ b/arch/x86/kernel/cpu/common.c 2024-02-22 10:08:52.828624830 -0800
@@ -1125,6 +1125,9 @@ void get_cpu_address_sizes(struct cpuinf
}
c->x86_cache_bits = c->x86_phys_bits;
c->x86_cache_alignment = x86_clflush_size();
+
+ /* Do this last to avoid affecting ->x86_cache_bits. */
+ c->x86_phys_bits -= bsp_addr_config.phys_addr_reduction_bits;
}

static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
diff -puN arch/x86/kernel/setup.c~bsp-addr-info arch/x86/kernel/setup.c
--- a/arch/x86/kernel/setup.c~bsp-addr-info 2024-02-22 10:08:52.824624673 -0800
+++ b/arch/x86/kernel/setup.c 2024-02-22 10:08:52.828624830 -0800
@@ -131,6 +131,8 @@ struct ist_info ist_info;
struct cpuinfo_x86 boot_cpu_data __read_mostly;
EXPORT_SYMBOL(boot_cpu_data);

+struct x86_addr_config bsp_addr_config;
+
#if !defined(CONFIG_X86_PAE) || defined(CONFIG_X86_64)
__visible unsigned long mmu_cr4_features __ro_after_init;
#else
_