]> git.ipfire.org Git - people/arne_f/kernel.git/commitdiff
xen/qspinlock: Don't kick CPU if IRQ is not initialized
authorRoss Lagerwall <ross.lagerwall@citrix.com>
Fri, 22 Apr 2016 12:05:31 +0000 (13:05 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 26 Mar 2017 10:13:18 +0000 (12:13 +0200)
commit 707e59ba494372a90d245f18b0c78982caa88e48 upstream.

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

Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: David Vrabel <david.vrabel@citrix.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Cc: xen-devel@lists.xenproject.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/xen/spinlock.c

index 9e2ba5c6e1dd7be4a0b10a70b315cf5f0f20c081..f42e78de1e107d662e3d806d1dc88ceeaf77ca02 100644 (file)
@@ -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);
 }