[PATCH v7 113/120] x86/asm/32: Cache CPUID(0x1).EDX in cpuid_table

"Ahmed S. Darwish" <[email protected]> Thu, 28 May 2026 17:39:15 +0200
Newsgroups dev.linux.lists.x86-cpuid,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
The x86-32 early boot code initializes new_cpu_data from the boot CPU and
stores CPUID(0x1).EDX in cpuinfo_x86::x86_capability[].

Introduce the CPUINFO_CPUID_0x1_EDX asm-offset, and store %edx in the
cached CPUID table entry for new_cpu_data.  This prepares for the removal
of cpuinfo_x86::x86_capability[].

Note that the definition of CPUINFO_CPUID_0x1_EDX is much more complex than
X86_CAPABILITY, even though both are used as:

    movl $1,%eax
    cpuid
    ...
    movl %edx,X86_CAPABILITY
    movl %edx,CPUINFO_CPUID_0x1_EDX

This is because CPUID(0x1).EDX is conveniently the first word of
cpuinfo_x86::x86_capability[], but not of cpuinfo_x86::cpuid_table.

Signed-off-by: Ahmed S. Darwish <[email protected]>
---
 arch/x86/kernel/asm-offsets.c | 5 +++++
 arch/x86/kernel/head_32.S     | 2 ++
 2 files changed, 7 insertions(+)

diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
index 081816888f7a..0bc36d617801 100644
--- a/arch/x86/kernel/asm-offsets.c
+++ b/arch/x86/kernel/asm-offsets.c
@@ -40,6 +40,11 @@ static void __used common(void)
 	OFFSET(CPUINFO_cpuid_level, cpuinfo_x86, cpuid_level);
 	OFFSET(CPUINFO_x86_capability, cpuinfo_x86, x86_capability);
 	OFFSET(CPUINFO_x86_vendor_id, cpuinfo_x86, x86_vendor_id);
+	DEFINE(CPUINFO_CPUID_0x1_EDX,
+	       offsetof(struct cpuinfo_x86, cpuid)		+
+	       offsetof(struct cpuid_table, leaves)		+
+	       offsetof(struct cpuid_leaves, leaf_0x1_0)	+
+	       offsetof(struct cpuid_regs, edx));
 
 	BLANK();
 	OFFSET(TASK_threadsp, task_struct, thread.sp);
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 5171cb746444..9c96fdf66aa9 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -43,6 +43,7 @@
 #define X86_CPUID	new_cpu_data+CPUINFO_cpuid_level
 #define X86_CAPABILITY	new_cpu_data+CPUINFO_x86_capability
 #define X86_VENDOR_ID	new_cpu_data+CPUINFO_x86_vendor_id
+#define X86_FEATUREFLAG	new_cpu_data+CPUINFO_CPUID_0x1_EDX
 
 /*
  * Worst-case size of the kernel mapping we need to make:
@@ -263,6 +264,7 @@ SYM_FUNC_START(startup_32_smp)
 	andb $0x0f,%cl		# mask mask revision
 	movb %cl,X86_STEPPING
 	movl %edx,X86_CAPABILITY
+	movl %edx,X86_FEATUREFLAG
 
 .Lis486:
 	movl $0x50022,%ecx	# set AM, WP, NE and MP
-- 
2.54.0