]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
xen/events: fix binding user event channels to cpus
authorJuergen Gross <jgross@suse.com>
Fri, 21 Jun 2019 18:47:03 +0000 (20:47 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 26 Jul 2019 07:13:02 +0000 (09:13 +0200)
commit bce5963bcb4f9934faa52be323994511d59fd13c upstream.

When binding an interdomain event channel to a vcpu via
IOCTL_EVTCHN_BIND_INTERDOMAIN not only the event channel needs to be
bound, but the affinity of the associated IRQi must be changed, too.
Otherwise the IRQ and the event channel won't be moved to another vcpu
in case the original vcpu they were bound to is going offline.

Cc: <stable@vger.kernel.org> # 4.13
Fixes: c48f64ab472389df ("xen-evtchn: Bind dyn evtchn:qemu-dm interrupt to next online VCPU")
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/xen/events/events_base.c
drivers/xen/evtchn.c
include/xen/events.h

index 117e76b2f9391a1983a0c46b3276e7606412977e..cf4ec27407db60b650a54d22f2c454a9eae73ff9 100644 (file)
@@ -1293,7 +1293,7 @@ void rebind_evtchn_irq(int evtchn, int irq)
 }
 
 /* Rebind an evtchn so that it gets delivered to a specific cpu */
-int xen_rebind_evtchn_to_cpu(int evtchn, unsigned tcpu)
+static int xen_rebind_evtchn_to_cpu(int evtchn, unsigned int tcpu)
 {
        struct evtchn_bind_vcpu bind_vcpu;
        int masked;
@@ -1327,7 +1327,6 @@ int xen_rebind_evtchn_to_cpu(int evtchn, unsigned tcpu)
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(xen_rebind_evtchn_to_cpu);
 
 static int set_affinity_irq(struct irq_data *data, const struct cpumask *dest,
                            bool force)
@@ -1341,6 +1340,15 @@ static int set_affinity_irq(struct irq_data *data, const struct cpumask *dest,
        return ret;
 }
 
+/* To be called with desc->lock held. */
+int xen_set_affinity_evtchn(struct irq_desc *desc, unsigned int tcpu)
+{
+       struct irq_data *d = irq_desc_get_irq_data(desc);
+
+       return set_affinity_irq(d, cpumask_of(tcpu), false);
+}
+EXPORT_SYMBOL_GPL(xen_set_affinity_evtchn);
+
 static void enable_dynirq(struct irq_data *data)
 {
        int evtchn = evtchn_from_irq(data->irq);
index 6d1a5e58968ffdfb42a71e5f984a52475ea0ca9c..47c70b826a6abf227960030cb09dd3a45fec4746 100644 (file)
@@ -447,7 +447,7 @@ static void evtchn_bind_interdom_next_vcpu(int evtchn)
        this_cpu_write(bind_last_selected_cpu, selected_cpu);
 
        /* unmask expects irqs to be disabled */
-       xen_rebind_evtchn_to_cpu(evtchn, selected_cpu);
+       xen_set_affinity_evtchn(desc, selected_cpu);
        raw_spin_unlock_irqrestore(&desc->lock, flags);
 }
 
index a488971999754562f2c78c811ddddc2b5ae00d0e..c0e6a059839766e5b8725d650d402ab759ee0436 100644 (file)
@@ -3,6 +3,7 @@
 #define _XEN_EVENTS_H
 
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #ifdef CONFIG_PCI_MSI
 #include <linux/msi.h>
 #endif
@@ -59,7 +60,7 @@ void evtchn_put(unsigned int evtchn);
 
 void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector);
 void rebind_evtchn_irq(int evtchn, int irq);
-int xen_rebind_evtchn_to_cpu(int evtchn, unsigned tcpu);
+int xen_set_affinity_evtchn(struct irq_desc *desc, unsigned int tcpu);
 
 static inline void notify_remote_via_evtchn(int port)
 {