[RFC][PATCH 16/34] x86/cpu: Move physical address limit out of cpuinfo_x86

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

There are no longer any direct references to cpuinfo_x86->x86_phys_bits.
The only remaining references are to 'boot_cpu_data' via the
x86_phys_bits() helper.

This means the farce that x86_phys_bits is per-cpu data can end. Remove
it from cpuinfo_x86 and add it to a new global data structure:
'x86_config'. (Better names welcome)

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

b/arch/x86/include/asm/processor.h | 16 ++++++++++++++--
b/arch/x86/kernel/cpu/common.c | 12 ++++++------
b/arch/x86/kernel/setup.c | 1 +
3 files changed, 21 insertions(+), 8 deletions(-)

diff -puN arch/x86/include/asm/processor.h~no-cpu-data-phys_bits arch/x86/include/asm/processor.h
--- a/arch/x86/include/asm/processor.h~no-cpu-data-phys_bits 2024-02-22 10:08:56.220757996 -0800
+++ b/arch/x86/include/asm/processor.h 2024-02-22 10:08:56.228758310 -0800
@@ -118,7 +118,6 @@ struct cpuinfo_x86 {
__u32 vmx_capability[NVMXINTS];
#endif
__u8 x86_virt_bits;
- __u8 x86_phys_bits;
/* CPUID returned core id bits: */
__u8 x86_coreid_bits;
/* Max extended CPUID function supported: */
@@ -176,6 +175,19 @@ struct x86_addr_config {
u8 phys_addr_reduction_bits;
};

+/*
+ * System-wide configuration that is shared by all processors.
+ *
+ * Built in early_cpu_init() on the boot CPU and and never
+ * modified after that.
+ */
+struct x86_sys_config {
+ /* Physical address bits supported by all processors */
+ u8 phys_bits;
+};
+
+extern struct x86_sys_config x86_config;
+
#define X86_VENDOR_INTEL 0
#define X86_VENDOR_CYRIX 1
#define X86_VENDOR_AMD 2
@@ -783,7 +795,7 @@ static inline void weak_wrmsr_fence(void

static inline u8 x86_phys_bits(void)
{
- return boot_cpu_data.x86_phys_bits;
+ return x86_config.phys_bits;
}

static inline u8 x86_virt_bits(void)
diff -puN arch/x86/kernel/cpu/common.c~no-cpu-data-phys_bits arch/x86/kernel/cpu/common.c
--- a/arch/x86/kernel/cpu/common.c~no-cpu-data-phys_bits 2024-02-22 10:08:56.224758153 -0800
+++ b/arch/x86/kernel/cpu/common.c 2024-02-22 10:08:56.228758310 -0800
@@ -1107,27 +1107,27 @@ void get_cpu_address_sizes(struct cpuinf
cpuid(0x80000008, &eax, &ebx, &ecx, &edx);

c->x86_virt_bits = (eax >> 8) & 0xff;
- c->x86_phys_bits = eax & 0xff;
+ x86_config.phys_bits = eax & 0xff;
} else {
if (IS_ENABLED(CONFIG_X86_64)) {
+ x86_config.phys_bits = 36;
c->x86_clflush_size = 64;
- c->x86_phys_bits = 36;
c->x86_virt_bits = 48;
} else {
+ x86_config.phys_bits = 32;
c->x86_clflush_size = 32;
c->x86_virt_bits = 32;
- c->x86_phys_bits = 32;

if (cpu_has(c, X86_FEATURE_PAE) ||
cpu_has(c, X86_FEATURE_PSE36))
- c->x86_phys_bits = 36;
+ x86_config.phys_bits = 36;
}
}
- c->x86_cache_bits = c->x86_phys_bits;
+ c->x86_cache_bits = x86_config.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;
+ x86_config.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~no-cpu-data-phys_bits arch/x86/kernel/setup.c
--- a/arch/x86/kernel/setup.c~no-cpu-data-phys_bits 2024-02-22 10:08:56.224758153 -0800
+++ b/arch/x86/kernel/setup.c 2024-02-22 10:08:56.228758310 -0800
@@ -132,6 +132,7 @@ struct cpuinfo_x86 boot_cpu_data __read_
EXPORT_SYMBOL(boot_cpu_data);

struct x86_addr_config bsp_addr_config;
+struct x86_sys_config x86_config __read_mostly;

#if !defined(CONFIG_X86_PAE) || defined(CONFIG_X86_64)
__visible unsigned long mmu_cr4_features __ro_after_init;
_