All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH for-4.22] x86/kexec: Check for a good per-cpu area before accessing IDTs
@ 2026-06-22 17:20 Andrew Cooper
  2026-06-23  7:38 ` Jan Beulich
  2026-06-23 13:15 ` Oleksii Kurochko
  0 siblings, 2 replies; 3+ messages in thread
From: Andrew Cooper @ 2026-06-22 17:20 UTC (permalink / raw)
  To: Xen-devel
  Cc: Andrew Cooper, Lin Liu, Jan Beulich, Roger Pau Monné,
	Teddy Astie, Oleksii Kurochko

Prior to commit 9c20d3c5915d ("x86/IDT: Make idt_tables[] be per_cpu(idt)"),
the global idt_tables[] was always safe to use for CPUs in any state.

However, not-yet-onlined CPUs (e.g. MADT with more entries than exist in
practice) or offlined CPUs (e.g. xen-hptool) have their per-cpu pointer
poisoned to detect incorrect uses.  machine_kexec() trips over the posion when
clobbering #MC entry paths.

This fixes a fatal #GP (non-canonical memory reference) when trying to enter
the crash kernel.

Fixes: 9c20d3c5915d ("x86/IDT: Make idt_tables[] be per_cpu(idt)")
Reported-by: Lin Liu <Lin.Liu01@citrix.com>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <jbeulich@suse.com>
CC: Roger Pau Monné <roger.pau@citrix.com>
CC: Teddy Astie <teddy.astie@vates.tech>
CC: Oleksii Kurochko <oleksii.kurochko@gmail.com>
CC: Lin Liu <Lin.Liu01@citrix.com>

The fix here is a bit ugly.  nmi_shootdown_cpus() uses the cpu_online_map but
this is wrong too; it misses parked CPUs, which do want to be captured.

For 4.22.  This is the minimal fix to stop systems crashing, but more work is
needed to make this path fully robust.
---
 xen/arch/x86/machine_kexec.c | 8 +++++++-
 xen/common/percpu.c          | 1 -
 xen/include/xen/percpu.h     | 1 +
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/machine_kexec.c b/xen/arch/x86/machine_kexec.c
index f921eec5aae6..0f5437cb65cc 100644
--- a/xen/arch/x86/machine_kexec.c
+++ b/xen/arch/x86/machine_kexec.c
@@ -18,6 +18,7 @@
 #include <xen/domain_page.h>
 #include <xen/elfstructs.h>
 #include <xen/kexec.h>
+#include <xen/percpu.h>
 #include <xen/types.h>
 
 #include <asm/fixmap.h>
@@ -171,7 +172,12 @@ void machine_kexec(struct kexec_image *image)
      */
     for ( i = 0; i < nr_cpu_ids; i++ )
     {
-        idt_entry_t *idt = per_cpu(idt, i);
+        idt_entry_t *idt;
+
+        if ( __per_cpu_offset[i] == INVALID_PERCPU_AREA )
+            continue;
+
+        idt = per_cpu(idt, i);
 
         if ( !idt )
             continue;
diff --git a/xen/common/percpu.c b/xen/common/percpu.c
index cdd70acbeaf3..f180f37253ed 100644
--- a/xen/common/percpu.c
+++ b/xen/common/percpu.c
@@ -13,7 +13,6 @@
 
 #define PERCPU_ORDER get_order_from_bytes(__per_cpu_data_end - __per_cpu_start)
 
-extern char __per_cpu_start[];
 extern const char __per_cpu_data_end[];
 
 unsigned long __read_mostly __per_cpu_offset[NR_CPUS];
diff --git a/xen/include/xen/percpu.h b/xen/include/xen/percpu.h
index fcf2095bd543..30609f49f0b3 100644
--- a/xen/include/xen/percpu.h
+++ b/xen/include/xen/percpu.h
@@ -43,6 +43,7 @@
 #endif
 
 extern unsigned long __per_cpu_offset[];
+extern char __per_cpu_start[];
 
 #define per_cpu(var, cpu)  \
     (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]))

base-commit: 6a21252a742ec021a814e124b88d273da37065db
-- 
2.39.5



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

* Re: [PATCH for-4.22] x86/kexec: Check for a good per-cpu area before accessing IDTs
  2026-06-22 17:20 [PATCH for-4.22] x86/kexec: Check for a good per-cpu area before accessing IDTs Andrew Cooper
@ 2026-06-23  7:38 ` Jan Beulich
  2026-06-23 13:15 ` Oleksii Kurochko
  1 sibling, 0 replies; 3+ messages in thread
From: Jan Beulich @ 2026-06-23  7:38 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: Lin Liu, Roger Pau Monné, Teddy Astie, Oleksii Kurochko,
	Xen-devel

On 22.06.2026 19:20, Andrew Cooper wrote:
> Prior to commit 9c20d3c5915d ("x86/IDT: Make idt_tables[] be per_cpu(idt)"),
> the global idt_tables[] was always safe to use for CPUs in any state.
> 
> However, not-yet-onlined CPUs (e.g. MADT with more entries than exist in
> practice) or offlined CPUs (e.g. xen-hptool) have their per-cpu pointer
> poisoned to detect incorrect uses.  machine_kexec() trips over the posion when
> clobbering #MC entry paths.
> 
> This fixes a fatal #GP (non-canonical memory reference) when trying to enter
> the crash kernel.
> 
> Fixes: 9c20d3c5915d ("x86/IDT: Make idt_tables[] be per_cpu(idt)")
> Reported-by: Lin Liu <Lin.Liu01@citrix.com>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>
albeit preferably, because of ...

> The fix here is a bit ugly.  nmi_shootdown_cpus() uses the cpu_online_map but
> this is wrong too; it misses parked CPUs, which do want to be captured.

... this, ...

> @@ -171,7 +172,12 @@ void machine_kexec(struct kexec_image *image)
>       */
>      for ( i = 0; i < nr_cpu_ids; i++ )
>      {
> -        idt_entry_t *idt = per_cpu(idt, i);
> +        idt_entry_t *idt;
> +
> +        if ( __per_cpu_offset[i] == INVALID_PERCPU_AREA )
> +            continue;
> +
> +        idt = per_cpu(idt, i);
>  
>          if ( !idt )
>              continue;

... with the comment ahead of the for() also adjusted to at least briefly
mention why cpu_online() cannot be used, and why hence this (seemingly)
awkward check is needed instead.

Jan


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

* Re: [PATCH for-4.22] x86/kexec: Check for a good per-cpu area before accessing IDTs
  2026-06-22 17:20 [PATCH for-4.22] x86/kexec: Check for a good per-cpu area before accessing IDTs Andrew Cooper
  2026-06-23  7:38 ` Jan Beulich
@ 2026-06-23 13:15 ` Oleksii Kurochko
  1 sibling, 0 replies; 3+ messages in thread
From: Oleksii Kurochko @ 2026-06-23 13:15 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel
  Cc: Lin Liu, Jan Beulich, Roger Pau Monné, Teddy Astie



On 6/22/26 7:20 PM, Andrew Cooper wrote:
> Prior to commit 9c20d3c5915d ("x86/IDT: Make idt_tables[] be per_cpu(idt)"),
> the global idt_tables[] was always safe to use for CPUs in any state.
> 
> However, not-yet-onlined CPUs (e.g. MADT with more entries than exist in
> practice) or offlined CPUs (e.g. xen-hptool) have their per-cpu pointer
> poisoned to detect incorrect uses.  machine_kexec() trips over the posion when
> clobbering #MC entry paths.
> 
> This fixes a fatal #GP (non-canonical memory reference) when trying to enter
> the crash kernel.
> 
> Fixes: 9c20d3c5915d ("x86/IDT: Make idt_tables[] be per_cpu(idt)")
> Reported-by: Lin Liu <Lin.Liu01@citrix.com>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> CC: Jan Beulich <jbeulich@suse.com>
> CC: Roger Pau Monné <roger.pau@citrix.com>
> CC: Teddy Astie <teddy.astie@vates.tech>
> CC: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> CC: Lin Liu <Lin.Liu01@citrix.com>
> 
> The fix here is a bit ugly.  nmi_shootdown_cpus() uses the cpu_online_map but
> this is wrong too; it misses parked CPUs, which do want to be captured.
> 
> For 4.22.  This is the minimal fix to stop systems crashing, but more work is
> needed to make this path fully robust.
> ---

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

Thanks.

~ Oleksii


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

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

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-22 17:20 [PATCH for-4.22] x86/kexec: Check for a good per-cpu area before accessing IDTs Andrew Cooper
2026-06-23  7:38 ` Jan Beulich
2026-06-23 13:15 ` 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.