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 14:17 ` Jan Beulich
@ 2026-06-12 15:41   ` Bernhard Kaindl
  2026-06-12 16:00     ` Anthony PERARD
                       ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Bernhard Kaindl @ 2026-06-12 15:41 UTC (permalink / raw)
  To: xen-devel, Anthony PERARD, Jan Beulich

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

Hi Anthony, could you test this patch which exactly applies the changes 
Jan suggested? Summary:
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.
As these simple guards should preferably go into Xen 4.22: Please test 
if there are any further regressions 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. 
Thanks, Bernhard The patch to test follows: [PATCH] x86/efi: Skip FPU 
save/restore for idle vCPU in EFI, runtime path
Anthony reported a boot-time crash in init_xen_time() via efi_get_time()
on a Broadwell-D system:
   Assertion '!is_idle_vcpu(v)' failed at arch/x86/i387.c:195
The failing path is an EFI runtime call reached early during boot,
where current may still be the idle vCPU.
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(-)
diff --git a/xen/common/efi/runtime.c b/xen/common/efi/runtime.c
index a23fa75e37..596f2710fb 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.43.0
--- PS: The suggestion by Jan to fix this issue: On 12/06/2026 16:17, 
Jan Beulich wrote:
> 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().
>
> Jan

[-- Attachment #2: Type: text/html, Size: 7191 bytes --]

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

* Re: [PATCH] x86/efi: Skip FPU save/restore for idle vCPU in EFI, runtime path
  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
  2 siblings, 0 replies; 8+ messages in thread
From: Anthony PERARD @ 2026-06-12 16:00 UTC (permalink / raw)
  To: Bernhard Kaindl; +Cc: xen-devel, Jan Beulich

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

On Fri, Jun 12, 2026 at 05:41:07PM +0200, Bernhard Kaindl wrote:
> Hi Anthony, could you test this patch which exactly applies the changes Jan
> suggested? Summary:

Sure but could you use `git send-email` to send patch please? Trying to
apply this email is not fun. The patch part is just corrupted. I might
try to edit the source by hand...

If you have a good setup, sending a patch is really just `git send-email
-1`, if you want to send it as a reply to an email, there's
`--in-reply-to` for that, but that's not really necessary, and sometime
counter productive. And no need to for `--cc` to CC me, has `git` can
also pick that up from the "reported-by". ;-)

If you want to add comments to a patch, and not have it committed, do not
use "PS:" after a signature. Add it between the "---" line and the first
line starting by "diff ", like git do with the diffstat.

Cheers,


--
Anthony Perard | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech

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

* [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

* Re: [PATCH] x86/efi: Skip FPU save/restore for idle vCPU in EFI runtime path
  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
  2 siblings, 0 replies; 8+ messages in thread
From: Anthony PERARD @ 2026-06-12 17:29 UTC (permalink / raw)
  To: Bernhard Kaindl
  Cc: xen-devel, Daniel P. Smith, Marek Marczykowski-Górecki,
	Jan Beulich

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

On Fri, Jun 12, 2026 at 05:54:36PM +0100, Bernhard Kaindl wrote:
> 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?

Yes, that patch works. I've also checked that I have
"Wallclock source: EFI" in the boot logs.

Tested-by: Anthony PERARD <anthony.perard@vates.tech>

Thanks,


--
Anthony Perard | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech

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

* Re: [PATCH] x86/efi: Skip FPU save/restore for idle vCPU in EFI, runtime path
  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
  2 siblings, 0 replies; 8+ messages in thread
From: Jan Beulich @ 2026-06-15  6:52 UTC (permalink / raw)
  To: Bernhard Kaindl; +Cc: xen-devel, Anthony PERARD

On 12.06.2026 17:41, Bernhard Kaindl wrote:
> Hi Anthony, could you test this patch which exactly applies the changes 
> Jan suggested? Summary:

So I'm a little irritated by this: The subject suggests this is a proper
patch submission, yet about everything else here suggests it is not. For
the eventual real patch, may I minimally suggest ...

> 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.
> As these simple guards should preferably go into Xen 4.22: Please test 
> if there are any further regressions 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. 
> Thanks, Bernhard The patch to test follows: [PATCH] x86/efi: Skip FPU 
> save/restore for idle vCPU in EFI, runtime path
> Anthony reported a boot-time crash in init_xen_time() via efi_get_time()
> on a Broadwell-D system:
>    Assertion '!is_idle_vcpu(v)' failed at arch/x86/i387.c:195

... to resolve this line number to a function name, to provide sufficient
context.

> The failing path is an EFI runtime call reached early during boot,
> where current may still be the idle vCPU.
> 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.

I further would help if it was explicitly stated that no other uses of
the two functions are affected (provided the necessary auditing was done,
but ftoad I did go through that already on Friday and didn't find other
problematic call sites).

Jan

> 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(-)
> diff --git a/xen/common/efi/runtime.c b/xen/common/efi/runtime.c
> index a23fa75e37..596f2710fb 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)



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

* Re: [PATCH] x86/efi: Skip FPU save/restore for idle vCPU in EFI runtime path
  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
  2 siblings, 0 replies; 8+ messages in thread
From: Jan Beulich @ 2026-06-15  7:04 UTC (permalink / raw)
  To: Bernhard Kaindl
  Cc: Daniel P. Smith, Marek Marczykowski-Górecki, xen-devel,
	Anthony PERARD, Oleksii Kurochko

On 12.06.2026 18:54, Bernhard Kaindl wrote:
> 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>

Also Cc Oleksii for an eventual release-ack.

Jan

> ---
>  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)



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

* Re: [PATCH] x86/efi: Skip FPU save/restore for idle vCPU in EFI, runtime path
  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
  2 siblings, 0 replies; 8+ messages in thread
From: Oleksii Kurochko @ 2026-06-16  7:33 UTC (permalink / raw)
  To: Bernhard Kaindl, xen-devel, Anthony PERARD, Jan Beulich



On 6/12/26 5:41 PM, Bernhard Kaindl wrote:
> Hi Anthony, could you test this patch which exactly applies the changes 
> Jan suggested? Summary:
> 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.
> As these simple guards should preferably go into Xen 4.22: Please test 
> if there are any further regressions 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. 
> Thanks, Bernhard The patch to test follows: [PATCH] x86/efi: Skip FPU 
> save/restore for idle vCPU in EFI, runtime path
> Anthony reported a boot-time crash in init_xen_time() via efi_get_time()
> on a Broadwell-D system:
>    Assertion '!is_idle_vcpu(v)' failed at arch/x86/i387.c:195
> The failing path is an EFI runtime call reached early during boot,
> where current may still be the idle vCPU.
> 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>
> ---


Release-Acked-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

Thanks.

~ Oleksii


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

* Re: [PATCH] x86/efi: Skip FPU save/restore for idle vCPU in EFI runtime path
  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
  2 siblings, 0 replies; 8+ messages in thread
From: Marek Marczykowski-Górecki @ 2026-06-16 11:23 UTC (permalink / raw)
  To: Bernhard Kaindl; +Cc: xen-devel, Anthony PERARD, Daniel P. Smith, Jan Beulich

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

On Fri, Jun 12, 2026 at 05:54:36PM +0100, Bernhard Kaindl wrote:
> 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>

Acked-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.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
> 

-- 
Best Regards,
Marek Marczykowski-Górecki
Invisible Things Lab

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ 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.