diff mbox series

[2/3] x86/pm: Use fpu_save_state() in __save_processor_state()

Message ID 20250516231858.27899-3-ebiggers@kernel.org
State New
Headers show
Series [1/3] x86/fpu: Add fpu_save_state() for __save_processor_state() | expand

Commit Message

Eric Biggers May 16, 2025, 11:18 p.m. UTC
From: Eric Biggers <ebiggers@google.com>

Make __save_processor_state() use fpu_save_state() instead of a
kernel_fpu_begin() and kernel_fpu_end() pair.  This matches more
directly what it needs.  This eliminates the need for kernel_fpu_begin()
and kernel_fpu_end() to support the irqs_disabled() case.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 arch/x86/power/cpu.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)
diff mbox series

Patch

diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 916441f5e85ce..dde4ccbc77f4b 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -81,11 +81,17 @@  static void msr_restore_context(struct saved_context *ctxt)
 static void __save_processor_state(struct saved_context *ctxt)
 {
 #ifdef CONFIG_X86_32
 	mtrr_save_fixed_ranges(NULL);
 #endif
-	kernel_fpu_begin();
+
+	/*
+	 * The FPU registers may be live for the current task, so save them to
+	 * current's memory register state.  The corresponding restore happens
+	 * lazily when returning to userspace, not in restore_processor_state().
+	 */
+	fpu_save_state();
 
 	/*
 	 * descriptor tables
 	 */
 	store_idt(&ctxt->idt);
@@ -99,11 +105,10 @@  static void __save_processor_state(struct saved_context *ctxt)
 	ctxt->gdt_desc.size = GDT_SIZE - 1;
 	ctxt->gdt_desc.address = (unsigned long)get_cpu_gdt_rw(smp_processor_id());
 
 	store_tr(ctxt->tr);
 
-	/* XMM0..XMM15 should be handled by kernel_fpu_begin(). */
 	/*
 	 * segment registers
 	 */
 	savesegment(gs, ctxt->gs);
 #ifdef CONFIG_X86_64
@@ -139,18 +144,10 @@  void save_processor_state(void)
 }
 #ifdef CONFIG_X86_32
 EXPORT_SYMBOL(save_processor_state);
 #endif
 
-static void do_fpu_end(void)
-{
-	/*
-	 * Restore FPU regs if necessary.
-	 */
-	kernel_fpu_end();
-}
-
 static void fix_processor_context(void)
 {
 	int cpu = smp_processor_id();
 #ifdef CONFIG_X86_64
 	struct desc_struct *desc = get_cpu_gdt_rw(cpu);
@@ -272,11 +269,10 @@  static void notrace __restore_processor_state(struct saved_context *ctxt)
 	wrmsrq(MSR_KERNEL_GS_BASE, ctxt->usermode_gs_base);
 #else
 	loadsegment(gs, ctxt->gs);
 #endif
 
-	do_fpu_end();
 	tsc_verify_tsc_adjust(true);
 	x86_platform.restore_sched_clock_state();
 	cache_bp_restore();
 	perf_restore_debug_store();