Merge tag 'v3.11-rc7' into stable/for-linus-3.12
[cascardo/linux.git] / drivers / xen / events.c
index a58ac43..4035e83 100644 (file)
@@ -56,6 +56,7 @@
 #include <xen/interface/hvm/params.h>
 #include <xen/interface/physdev.h>
 #include <xen/interface/sched.h>
+#include <xen/interface/vcpu.h>
 #include <asm/hw_irq.h>
 
 /*
@@ -348,7 +349,7 @@ static void init_evtchn_cpu_bindings(void)
 
        for_each_possible_cpu(i)
                memset(per_cpu(cpu_evtchn_mask, i),
-                      (i == 0) ? ~0 : 0, sizeof(*per_cpu(cpu_evtchn_mask, i)));
+                      (i == 0) ? ~0 : 0, NR_EVENT_CHANNELS/8);
 }
 
 static inline void clear_evtchn(int port)
@@ -1212,7 +1213,17 @@ EXPORT_SYMBOL_GPL(evtchn_put);
 
 void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector)
 {
-       int irq = per_cpu(ipi_to_irq, cpu)[vector];
+       int irq;
+
+#ifdef CONFIG_X86
+       if (unlikely(vector == XEN_NMI_VECTOR)) {
+               int rc =  HYPERVISOR_vcpu_op(VCPUOP_send_nmi, cpu, NULL);
+               if (rc < 0)
+                       printk(KERN_WARNING "Sending nmi to CPU%d failed (rc:%d)\n", cpu, rc);
+               return;
+       }
+#endif
+       irq = per_cpu(ipi_to_irq, cpu)[vector];
        BUG_ON(irq < 0);
        notify_remote_via_irq(irq);
 }
@@ -1379,14 +1390,21 @@ static void __xen_evtchn_do_upcall(void)
 
                        pending_bits = active_evtchns(cpu, s, word_idx);
                        bit_idx = 0; /* usually scan entire word from start */
+                       /*
+                        * We scan the starting word in two parts.
+                        *
+                        * 1st time: start in the middle, scanning the
+                        * upper bits.
+                        *
+                        * 2nd time: scan the whole word (not just the
+                        * parts skipped in the first pass) -- if an
+                        * event in the previously scanned bits is
+                        * pending again it would just be scanned on
+                        * the next loop anyway.
+                        */
                        if (word_idx == start_word_idx) {
-                               /* We scan the starting word in two parts */
                                if (i == 0)
-                                       /* 1st time: start in the middle */
                                        bit_idx = start_bit_idx;
-                               else
-                                       /* 2nd time: mask bits done already */
-                                       bit_idx &= (1UL << start_bit_idx) - 1;
                        }
 
                        do {
@@ -1493,8 +1511,10 @@ void rebind_evtchn_irq(int evtchn, int irq)
 /* Rebind an evtchn so that it gets delivered to a specific cpu */
 static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
 {
+       struct shared_info *s = HYPERVISOR_shared_info;
        struct evtchn_bind_vcpu bind_vcpu;
        int evtchn = evtchn_from_irq(irq);
+       int masked;
 
        if (!VALID_EVTCHN(evtchn))
                return -1;
@@ -1510,6 +1530,12 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
        bind_vcpu.port = evtchn;
        bind_vcpu.vcpu = tcpu;
 
+       /*
+        * Mask the event while changing the VCPU binding to prevent
+        * it being delivered on an unexpected VCPU.
+        */
+       masked = sync_test_and_set_bit(evtchn, BM(s->evtchn_mask));
+
        /*
         * If this fails, it usually just indicates that we're dealing with a
         * virq or IPI channel, which don't actually need to be rebound. Ignore
@@ -1518,6 +1544,9 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
        if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0)
                bind_evtchn_to_cpu(evtchn, tcpu);
 
+       if (!masked)
+               unmask_evtchn(evtchn);
+
        return 0;
 }