x86/xen: don't unbind uninitialized lock_kicker_irq
authorBrian Masney <bmasney@redhat.com>
Sat, 7 Nov 2020 01:11:19 +0000 (20:11 -0500)
committerBoris Ostrovsky <boris.ostrovsky@oracle.com>
Mon, 9 Nov 2020 13:43:45 +0000 (07:43 -0600)
When booting a hyperthreaded system with the kernel parameter
'mitigations=auto,nosmt', the following warning occurs:

    WARNING: CPU: 0 PID: 1 at drivers/xen/events/events_base.c:1112 unbind_from_irqhandler+0x4e/0x60
    ...
    Hardware name: Xen HVM domU, BIOS 4.2.amazon 08/24/2006
    ...
    Call Trace:
     xen_uninit_lock_cpu+0x28/0x62
     xen_hvm_cpu_die+0x21/0x30
     takedown_cpu+0x9c/0xe0
     ? trace_suspend_resume+0x60/0x60
     cpuhp_invoke_callback+0x9a/0x530
     _cpu_up+0x11a/0x130
     cpu_up+0x7e/0xc0
     bringup_nonboot_cpus+0x48/0x50
     smp_init+0x26/0x79
     kernel_init_freeable+0xea/0x229
     ? rest_init+0xaa/0xaa
     kernel_init+0xa/0x106
     ret_from_fork+0x35/0x40

The secondary CPUs are not activated with the nosmt mitigations and only
the primary thread on each CPU core is used. In this situation,
xen_hvm_smp_prepare_cpus(), and more importantly xen_init_lock_cpu(), is
not called, so the lock_kicker_irq is not initialized for the secondary
CPUs. Let's fix this by exiting early in xen_uninit_lock_cpu() if the
irq is not set to avoid the warning from above for each secondary CPU.

Signed-off-by: Brian Masney <bmasney@redhat.com>
Link: https://lore.kernel.org/r/20201107011119.631442-1-bmasney@redhat.com
Reviewed-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
arch/x86/xen/spinlock.c

index 799f4eb..043c73d 100644 (file)
@@ -93,10 +93,20 @@ void xen_init_lock_cpu(int cpu)
 
 void xen_uninit_lock_cpu(int cpu)
 {
+       int irq;
+
        if (!xen_pvspin)
                return;
 
-       unbind_from_irqhandler(per_cpu(lock_kicker_irq, cpu), NULL);
+       /*
+        * When booting the kernel with 'mitigations=auto,nosmt', the secondary
+        * CPUs are not activated, and lock_kicker_irq is not initialized.
+        */
+       irq = per_cpu(lock_kicker_irq, cpu);
+       if (irq == -1)
+               return;
+
+       unbind_from_irqhandler(irq, NULL);
        per_cpu(lock_kicker_irq, cpu) = -1;
        kfree(per_cpu(irq_name, cpu));
        per_cpu(irq_name, cpu) = NULL;