summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomáš Mózes <tomas.mozes@gmail.com>2024-08-01 15:02:58 +0200
committerTomáš Mózes <tomas.mozes@gmail.com>2024-08-01 15:02:58 +0200
commit212febf72900c12405591dcc5902d4cfa11173bf (patch)
tree7a093fae6f723d02b6c4a573669615024fe65e4d /0024-x86-smp-do-not-use-shorthand-IPI-destinations-in-CPU.patch
parentXen 4.17.4-pre-patchset-1 (diff)
downloadxen-upstream-patches-212febf72900c12405591dcc5902d4cfa11173bf.tar.gz
xen-upstream-patches-212febf72900c12405591dcc5902d4cfa11173bf.tar.bz2
xen-upstream-patches-212febf72900c12405591dcc5902d4cfa11173bf.zip
Xen 4.18.3-pre-patchset-04.18.3-pre-patchset-0
Signed-off-by: Tomáš Mózes <tomas.mozes@gmail.com>
Diffstat (limited to '0024-x86-smp-do-not-use-shorthand-IPI-destinations-in-CPU.patch')
-rw-r--r--0024-x86-smp-do-not-use-shorthand-IPI-destinations-in-CPU.patch98
1 files changed, 98 insertions, 0 deletions
diff --git a/0024-x86-smp-do-not-use-shorthand-IPI-destinations-in-CPU.patch b/0024-x86-smp-do-not-use-shorthand-IPI-destinations-in-CPU.patch
new file mode 100644
index 0000000..b69c88c
--- /dev/null
+++ b/0024-x86-smp-do-not-use-shorthand-IPI-destinations-in-CPU.patch
@@ -0,0 +1,98 @@
+From 98238d49ecb149a5ac07cb8032817904c404ac2b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= <roger.pau@citrix.com>
+Date: Wed, 26 Jun 2024 13:38:36 +0200
+Subject: [PATCH 24/56] x86/smp: do not use shorthand IPI destinations in CPU
+ hot{,un}plug contexts
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Due to the current rwlock logic, if the CPU calling get_cpu_maps() does
+so from a cpu_hotplug_{begin,done}() region the function will still
+return success, because a CPU taking the rwlock in read mode after
+having taken it in write mode is allowed. Such corner case makes using
+get_cpu_maps() alone not enough to prevent using the shorthand in CPU
+hotplug regions.
+
+Introduce a new helper to detect whether the current caller is between a
+cpu_hotplug_{begin,done}() region and use it in send_IPI_mask() to restrict
+shorthand usage.
+
+Fixes: 5500d265a2a8 ('x86/smp: use APIC ALLBUT destination shorthand when possible')
+Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+master commit: 171c52fba5d94e050d704770480dcb983490d0ad
+master date: 2024-06-12 14:29:31 +0200
+---
+ xen/arch/x86/smp.c | 2 +-
+ xen/common/cpu.c | 5 +++++
+ xen/include/xen/cpu.h | 10 ++++++++++
+ xen/include/xen/rwlock.h | 2 ++
+ 4 files changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/xen/arch/x86/smp.c b/xen/arch/x86/smp.c
+index 3a331cbdbc..340fcafb46 100644
+--- a/xen/arch/x86/smp.c
++++ b/xen/arch/x86/smp.c
+@@ -88,7 +88,7 @@ void send_IPI_mask(const cpumask_t *mask, int vector)
+ * the system have been accounted for.
+ */
+ if ( system_state > SYS_STATE_smp_boot &&
+- !unaccounted_cpus && !disabled_cpus &&
++ !unaccounted_cpus && !disabled_cpus && !cpu_in_hotplug_context() &&
+ /* NB: get_cpu_maps lock requires enabled interrupts. */
+ local_irq_is_enabled() && (cpus_locked = get_cpu_maps()) &&
+ (park_offline_cpus ||
+diff --git a/xen/common/cpu.c b/xen/common/cpu.c
+index 8709db4d29..6e35b114c0 100644
+--- a/xen/common/cpu.c
++++ b/xen/common/cpu.c
+@@ -68,6 +68,11 @@ void cpu_hotplug_done(void)
+ write_unlock(&cpu_add_remove_lock);
+ }
+
++bool cpu_in_hotplug_context(void)
++{
++ return rw_is_write_locked_by_me(&cpu_add_remove_lock);
++}
++
+ static NOTIFIER_HEAD(cpu_chain);
+
+ void __init register_cpu_notifier(struct notifier_block *nb)
+diff --git a/xen/include/xen/cpu.h b/xen/include/xen/cpu.h
+index e1d4eb5967..6bf5786750 100644
+--- a/xen/include/xen/cpu.h
++++ b/xen/include/xen/cpu.h
+@@ -13,6 +13,16 @@ void put_cpu_maps(void);
+ void cpu_hotplug_begin(void);
+ void cpu_hotplug_done(void);
+
++/*
++ * Returns true when the caller CPU is between a cpu_hotplug_{begin,done}()
++ * region.
++ *
++ * This is required to safely identify hotplug contexts, as get_cpu_maps()
++ * would otherwise succeed because a caller holding the lock in write mode is
++ * allowed to acquire the same lock in read mode.
++ */
++bool cpu_in_hotplug_context(void);
++
+ /* Receive notification of CPU hotplug events. */
+ void register_cpu_notifier(struct notifier_block *nb);
+
+diff --git a/xen/include/xen/rwlock.h b/xen/include/xen/rwlock.h
+index 9e35ee2edf..dc74d1c057 100644
+--- a/xen/include/xen/rwlock.h
++++ b/xen/include/xen/rwlock.h
+@@ -309,6 +309,8 @@ static always_inline void write_lock_irq(rwlock_t *l)
+
+ #define rw_is_locked(l) _rw_is_locked(l)
+ #define rw_is_write_locked(l) _rw_is_write_locked(l)
++#define rw_is_write_locked_by_me(l) \
++ lock_evaluate_nospec(_is_write_locked_by_me(atomic_read(&(l)->cnts)))
+
+
+ typedef struct percpu_rwlock percpu_rwlock_t;
+--
+2.45.2
+