Re: [PATCH v2 1/2] x86/cpu: Disable CR pinning during CPU bringup

From: Nikunj A. Dadhania

Date: Thu Mar 12 2026 - 03:23:20 EST




On 3/11/2026 10:58 PM, Dave Hansen wrote:
> On 3/11/26 08:42, Nikunj A. Dadhania wrote:
>> -void cr4_init(void)
>> +void cr4_init(bool boot_cpu)
>
> I think the "pass a bool to a function" pattern is really not great.

The reason I introduced it was to avoid double-enabling PCIDE on the boot
CPU. The boot CPU already enables PCIDE via setup_pcid().

> The problem isn't actually setting CR4 twice. The problem is having two
> different code paths to set it. Doing the 'bool' doesn't eliminate the
> code path, it just makes the whole thing more complicated to reason
> about and further bifurcates the boot and secondary CPU bringup paths.
>
> We want to unify those, not bifurcate them.
>
> Why don't we just universally set X86_CR4_FSGSBASE in cr4_init()?

Right, this approach becomes much simpler with the boot_cpu:

diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 1c3261cae40c..6c0493eaf813 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -502,6 +502,17 @@ void cr4_init(void)

if (boot_cpu_has(X86_FEATURE_PCID))
cr4 |= X86_CR4_PCIDE;
+
+ /*
+ * CPUs that support FSGSBASE may use RDGSBASE/WRGSBASE in
+ * paranoid_entry(). Enable the feature before any exceptions
+ * occur.
+ */
+ if (boot_cpu_has(X86_FEATURE_FSGSBASE)) {
+ cr4 |= X86_CR4_FSGSBASE;
+ elf_hwcap2 |= HWCAP2_FSGSBASE;
+ }
+
if (static_branch_likely(&cr_pinning))
cr4 = (cr4 & ~cr4_pinned_mask) | cr4_pinned_bits;

@@ -2047,12 +2058,6 @@ static void identify_cpu(struct cpuinfo_x86 *c)
setup_umip(c);
setup_lass(c);

- /* Enable FSGSBASE instructions if available. */
- if (cpu_has(c, X86_FEATURE_FSGSBASE)) {
- cr4_set_bits(X86_CR4_FSGSBASE);
- elf_hwcap2 |= HWCAP2_FSGSBASE;
- }
-
/*
* The vendor-specific functions might have changed features.
* Now we do "generic changes."
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 4dbff8ef9b1c..0a2b129bda03 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -1685,6 +1685,13 @@ void __init trap_init(void)
/* Init GHCB memory pages when running as an SEV-ES guest */
sev_es_init_vc_handling();

+ /*
+ * Initialize CR4 early, before cpu_init(). This ensures features like
+ * FSGSBASE are enabled before exception handlers run, avoiding double
+ * initialization later.
+ */
+ cr4_init();
+
/* Initialize TSS before setting up traps so ISTs work */
cpu_init_exception_handling(true);