[PATCH Xenial SRU] xen/qspinlock: Don't kick CPU if IRQ is not initialized
Colin Ian King
colin.king at canonical.com
Wed Dec 14 15:13:16 UTC 2016
On 14/12/16 15:07, Tim Gardner wrote:
> 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
> meantime.
>
> 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);
> }
>
>
Seems OK to me, however has this been tested for this specific bug?
Colin
More information about the kernel-team
mailing list