Commit 73270c1f authored by Xin Li (Intel)'s avatar Xin Li (Intel) Committed by Thomas Gleixner
Browse files

x86/fred: Move FRED RSP initialization into a separate function



To enable FRED earlier, move the RSP initialization out of
cpu_init_fred_exceptions() into cpu_init_fred_rsps().

This is required as the FRED RSP initialization depends on the availability
of the CPU entry areas which are set up late in trap_init(),

No functional change intended. Marked with Fixes as it's a depedency for
the real fix.

Fixes: 14619d91 ("x86/fred: FRED entry/exit and dispatch code")
Signed-off-by: default avatarXin Li (Intel) <xin@zytor.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20240709154048.3543361-3-xin@zytor.com
parent 989b5cfa
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -84,11 +84,13 @@ static __always_inline void fred_entry_from_kvm(unsigned int type, unsigned int
}

void cpu_init_fred_exceptions(void);
void cpu_init_fred_rsps(void);
void fred_complete_exception_setup(void);

#else /* CONFIG_X86_FRED */
static __always_inline unsigned long fred_event_data(struct pt_regs *regs) { return 0; }
static inline void cpu_init_fred_exceptions(void) { }
static inline void cpu_init_fred_rsps(void) { }
static inline void fred_complete_exception_setup(void) { }
static __always_inline void fred_entry_from_kvm(unsigned int type, unsigned int vector) { }
#endif /* CONFIG_X86_FRED */
+4 −2
Original line number Diff line number Diff line
@@ -2195,11 +2195,13 @@ void cpu_init_exception_handling(void)
	/* GHCB needs to be setup to handle #VC. */
	setup_ghcb();

	if (cpu_feature_enabled(X86_FEATURE_FRED))
	if (cpu_feature_enabled(X86_FEATURE_FRED)) {
		cpu_init_fred_exceptions();
	else
		cpu_init_fred_rsps();
	} else {
		load_current_idt();
	}
}

/*
 * cpu_init() initializes state that is per-CPU. Some data is already
+19 −9
Original line number Diff line number Diff line
@@ -32,6 +32,25 @@ void cpu_init_fred_exceptions(void)
	       FRED_CONFIG_INT_STKLVL(0) |
	       FRED_CONFIG_ENTRYPOINT(asm_fred_entrypoint_user));

	wrmsrl(MSR_IA32_FRED_STKLVLS, 0);
	wrmsrl(MSR_IA32_FRED_RSP0, 0);
	wrmsrl(MSR_IA32_FRED_RSP1, 0);
	wrmsrl(MSR_IA32_FRED_RSP2, 0);
	wrmsrl(MSR_IA32_FRED_RSP3, 0);

	/* Enable FRED */
	cr4_set_bits(X86_CR4_FRED);
	/* Any further IDT use is a bug */
	idt_invalidate();

	/* Use int $0x80 for 32-bit system calls in FRED mode */
	setup_clear_cpu_cap(X86_FEATURE_SYSENTER32);
	setup_clear_cpu_cap(X86_FEATURE_SYSCALL32);
}

/* Must be called after setup_cpu_entry_areas() */
void cpu_init_fred_rsps(void)
{
	/*
	 * The purpose of separate stacks for NMI, #DB and #MC *in the kernel*
	 * (remember that user space faults are always taken on stack level 0)
@@ -47,13 +66,4 @@ void cpu_init_fred_exceptions(void)
	wrmsrl(MSR_IA32_FRED_RSP1, __this_cpu_ist_top_va(DB));
	wrmsrl(MSR_IA32_FRED_RSP2, __this_cpu_ist_top_va(NMI));
	wrmsrl(MSR_IA32_FRED_RSP3, __this_cpu_ist_top_va(DF));

	/* Enable FRED */
	cr4_set_bits(X86_CR4_FRED);
	/* Any further IDT use is a bug */
	idt_invalidate();

	/* Use int $0x80 for 32-bit system calls in FRED mode */
	setup_clear_cpu_cap(X86_FEATURE_SYSENTER32);
	setup_clear_cpu_cap(X86_FEATURE_SYSCALL32);
}