All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86/efi: Skip FPU save/restore for idle vCPU in EFI runtime path
@ 2026-06-12 16:54 Bernhard Kaindl
  2026-06-12 17:29 ` Anthony PERARD
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Bernhard Kaindl @ 2026-06-12 16:54 UTC (permalink / raw)
  To: xen-devel, Anthony PERARD
  Cc: Bernhard Kaindl, Daniel P. Smith, Marek Marczykowski-Górecki,
	Jan Beulich

Anthony reported a boot-time assertion in init_xen_time() via efi_get_time()
-> efi_rs_enter() in vcpu_save_fpu() on a Broadwell-D system:

  Assertion '!is_idle_vcpu(v)' failed at arch/x86/i387.c:195

This became fragile after the lazy-FPU removal cleanup series:

In 1792bb9a99d2 ("x86: Cleanup cr0.TS flag handling"),
efi_rs_enter() was changed from save_fpu_enable() to vcpu_save_fpu(curr),
which unconditionally asserts !is_idle_vcpu(v)
so an EFI runtime call in idle context now asserts.

Likewise, in dba44e051209 ("x86: Remove fully_eager_fpu"),
efi_rs_leave() was changed to call vcpu_restore_fpu(curr),
which has the same assertion and can fail for the same reason.

Guard both EFI runtime FPU calls with !is_idle_vcpu() to skip save/restore
for idle vCPUs, which don't have an FPU context to save/restore,
much like the calls are guarded in __context_switch(),
where save/restore is done only for non-idle vCPUs.

Fixes: 1792bb9a99d2 ("x86: Cleanup cr0.TS flag handling")
Fixes: dba44e051209 ("x86: Remove fully_eager_fpu")
Reported-by: Anthony PERARD <anthony.perard@vates.tech>
Suggested-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Bernhard Kaindl <bernhard.kaindl@citrix.com>
---
 xen/common/efi/runtime.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Jan Beulich's suggestion to guard the calls to vcpu_save_fpu() and
vcpu_restore_fpu() in the EFI runtime path with is_idle_vcpu() checks
seems to be the right approach to fix the assertion failure for idle vCPUs:

> The thinko looks to be in 4b9851c64522 ("x86: Remove fpu_initialised/fpu_dirty"):
> While vcpu_restore_fpu() indeed unconditionally set the two boolean fields to
> true at that point, idle vCPU-s may never make it through that function, and
> hence ->fpu_dirtied would have remained false, triggering the (original) early
> exit from _vcpu_save_fpu(). Perhaps all we can do now is guard the call to
> vcpu_save_fpu() (and also the one to vcpu_restore_fpu() out of efi_rs_leave())
> by explicit is_idle_vcpu() checks. Much like the calls are guarded in
> __context_switch().

Anthony, could you test this with the 'cmos-rtc-probe' workaround you just
added removed to check if guarding the assertions as Jan suggested is enough
to fix the issues triggered on your machine?

diff --git a/xen/common/efi/runtime.c b/xen/common/efi/runtime.c
index a23fa75e3740..596f2710fb21 100644
--- a/xen/common/efi/runtime.c
+++ b/xen/common/efi/runtime.c
@@ -98,7 +98,8 @@ struct efi_rs_state efi_rs_enter(void)
      */
     sync_local_execstate();
     state.cr3 = read_cr3();
-    vcpu_save_fpu(current);
+    if ( !is_idle_vcpu(current) )
+        vcpu_save_fpu(current);
     asm volatile ( "fnclex; fldcw %0" :: "m" (fcw) );
     asm volatile ( "ldmxcsr %0" :: "m" (mxcsr) );
 
@@ -159,7 +160,8 @@ void efi_rs_leave(struct efi_rs_state *state)
     }
     irq_exit();
     spin_unlock(&efi_rs_lock);
-    vcpu_restore_fpu(curr);
+    if ( !is_idle_vcpu(curr) )
+        vcpu_restore_fpu(curr);
 }
 
 unsigned long efi_get_time(void)
-- 
2.39.5



^ permalink raw reply related	[flat|nested] 8+ messages in thread
* Assertion '!is_idle_vcpu(v)' failed after 'Remove fully_eager_fpu' commit on EFI
@ 2026-06-12 13:53 Anthony PERARD
  2026-06-12 14:17 ` Jan Beulich
  0 siblings, 1 reply; 8+ messages in thread
From: Anthony PERARD @ 2026-06-12 13:53 UTC (permalink / raw)
  To: xen-devel
  Cc: Ross Lagerwall, Jan Beulich, Andrew Cooper, Roger Pau Monné,
	Daniel P. Smith, Marek Marczykowski-Górecki

[-- Attachment #1: Type: text/plain, Size: 1221 bytes --]

Hi,

Since commit dba44e051209 ("x86: Remove fully_eager_fpu"), I can't boot
a machine and get assertion '!is_idle_vcpu(v)' failed instead. It's
netbooted and EFI.

Xen call trace:
   [<ffff82d04033da2c>] R vcpu_save_fpu+0x65/0xdc
   [<ffff82d04029c5c4>] S efi_rs_enter+0x37/0x16a
   [<ffff82d04029c7e3>] F efi_get_time+0x19/0xb2
   [<ffff82d04047cbf0>] F init_xen_time+0x1e3/0x2b4
   [<ffff82d040477a49>] F __start_xen+0x1d71/0x24b8
   [<ffff82d0402043e7>] F __high_start+0xb7/0xc0

Assertion '!is_idle_vcpu(v)' failed at arch/x86/i387.c:195

A few more lines from Xen:
    CPU Vendor: Intel, Family 6 (0x6), Model 86 (0x56), Stepping 3 (raw 00050663)
    Bootloader: GRUB 2.06
    [...]
    Enabling APIC mode.  Using 2 I/O APICs
    ENABLING IO-APIC IRQs
     -> Using old ACK method
     ..TIMER: vector=0xF0 apic1=0 pin1=2 apic2=-1 pin2=-1
    TSC deadline timer enabled
    Assertion '!is_idle_vcpu(v)' failed at arch/x86/i387.c:195

Commit this Xen is built from: 50936ea05660.

full logs at:
    https://paste.vates.tech/?bd8a9a0955798a97#A1DU2efwUt7bbHQUxdo9UXGcsJ2XPNJNZHPz87LqLtcF

Thanks,


--
 | Vates

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-06-16 11:23 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-12 16:54 [PATCH] x86/efi: Skip FPU save/restore for idle vCPU in EFI runtime path Bernhard Kaindl
2026-06-12 17:29 ` Anthony PERARD
2026-06-15  7:04 ` Jan Beulich
2026-06-16 11:23 ` Marek Marczykowski-Górecki
  -- strict thread matches above, loose matches on Subject: below --
2026-06-12 13:53 Assertion '!is_idle_vcpu(v)' failed after 'Remove fully_eager_fpu' commit on EFI Anthony PERARD
2026-06-12 14:17 ` Jan Beulich
2026-06-12 15:41   ` [PATCH] x86/efi: Skip FPU save/restore for idle vCPU in EFI, runtime path Bernhard Kaindl
2026-06-12 16:00     ` Anthony PERARD
2026-06-15  6:52     ` Jan Beulich
2026-06-16  7:33     ` Oleksii Kurochko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.