[PATCH Xenial SRU] xen/qspinlock: Don't kick CPU if IRQ is not initialized

Tim Gardner tim.gardner at canonical.com
Wed Dec 14 15:07:01 UTC 2016

From: Ross Lagerwall <ross.lagerwall at citrix.com>

BugLink: http://bugs.launchpad.net/bugs/1649821

The following commit:

  1fb3a8b2cfb2 ("xen/spinlock: Fix locking path engaging too soon under PVHVM.")

... moved the initalization of the kicker interrupt until after
native_cpu_up() is called.

However, when using qspinlocks, a CPU may try to kick another CPU that is
spinning (because it has not yet initialized its kicker interrupt), resulting
in the following crash during boot:

  kernel BUG at /build/linux-Ay7j_C/linux-4.4.0/drivers/xen/events/events_base.c:1210!
  invalid opcode: 0000 [#1] SMP
  RIP: 0010:[<ffffffff814c97c9>]  [<ffffffff814c97c9>] xen_send_IPI_one+0x59/0x60
  Call Trace:
   [<ffffffff8102be9e>] xen_qlock_kick+0xe/0x10
   [<ffffffff810cabc2>] __pv_queued_spin_unlock+0xb2/0xf0
   [<ffffffff810ca6d1>] ? __raw_callee_save___pv_queued_spin_unlock+0x11/0x20
   [<ffffffff81052936>] ? check_tsc_warp+0x76/0x150
   [<ffffffff81052aa6>] check_tsc_sync_source+0x96/0x160
   [<ffffffff81051e28>] native_cpu_up+0x3d8/0x9f0
   [<ffffffff8102b315>] xen_hvm_cpu_up+0x35/0x80
   [<ffffffff8108198c>] _cpu_up+0x13c/0x180
   [<ffffffff81081a4a>] cpu_up+0x7a/0xa0
   [<ffffffff81f80dfc>] smp_init+0x7f/0x81
   [<ffffffff81f5a121>] kernel_init_freeable+0xef/0x212
   [<ffffffff81817f30>] ? rest_init+0x80/0x80
   [<ffffffff81817f3e>] kernel_init+0xe/0xe0
   [<ffffffff8182488f>] ret_from_fork+0x3f/0x70
   [<ffffffff81817f30>] ? rest_init+0x80/0x80

To fix this, only send the kick if the target CPU's interrupt has been
initialized. This check isn't racy, because the target is waiting for
the spinlock, so it won't have initialized the interrupt in the

Signed-off-by: Ross Lagerwall <ross.lagerwall at citrix.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: David Vrabel <david.vrabel at citrix.com>
Cc: Juergen Gross <jgross at suse.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Linus Torvalds <torvalds at linux-foundation.org>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: linux-kernel at vger.kernel.org
Cc: xen-devel at lists.xenproject.org
Signed-off-by: Ingo Molnar <mingo at kernel.org>
(cherry picked from commit 707e59ba494372a90d245f18b0c78982caa88e48)
Signed-off-by: Tim Gardner <tim.gardner at canonical.com>
 arch/x86/xen/spinlock.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index 9e2ba5c..f42e78d 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -27,6 +27,12 @@ static bool xen_pvspin = true;
 static void xen_qlock_kick(int cpu)
+	int irq = per_cpu(lock_kicker_irq, cpu);
+	/* Don't kick if the target's kicker interrupt is not initialized. */
+	if (irq == -1)
+		return;
 	xen_send_IPI_one(cpu, XEN_SPIN_UNLOCK_VECTOR);

More information about the kernel-team mailing list