aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-08-21 19:38:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-08-21 19:38:33 -0400
commitd936d2d452ca1848cc4b397bdfb96d4278b9f934 (patch)
tree205a6d386d363d94208a3340f911009d74d2aa29 /drivers/xen
parent0903391acbc1b509a60a6cb682344c748a69821a (diff)
parentfc78d343fa74514f6fd117b5ef4cd27e4ac30236 (diff)
Merge tag 'stable/for-linus-3.11-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull Xen bug-fixes from Konrad Rzeszutek Wilk: - On ARM did not have balanced calls to get/put_cpu. - Fix to make tboot + Xen + Linux correctly. - Fix events VCPU binding issues. - Fix a vCPU online race where IPIs are sent to not-yet-online vCPU. * tag 'stable/for-linus-3.11-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen/smp: initialize IPI vectors before marking CPU online xen/events: mask events when changing their VCPU binding xen/events: initialize local per-cpu mask for all possible events x86/xen: do not identity map UNUSABLE regions in the machine E820 xen/arm: missing put_cpu in xen_percpu_init
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/events.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index a58ac435a9a4..5e8be462aed5 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -348,7 +348,7 @@ static void init_evtchn_cpu_bindings(void)
348 348
349 for_each_possible_cpu(i) 349 for_each_possible_cpu(i)
350 memset(per_cpu(cpu_evtchn_mask, i), 350 memset(per_cpu(cpu_evtchn_mask, i),
351 (i == 0) ? ~0 : 0, sizeof(*per_cpu(cpu_evtchn_mask, i))); 351 (i == 0) ? ~0 : 0, NR_EVENT_CHANNELS/8);
352} 352}
353 353
354static inline void clear_evtchn(int port) 354static inline void clear_evtchn(int port)
@@ -1493,8 +1493,10 @@ void rebind_evtchn_irq(int evtchn, int irq)
1493/* Rebind an evtchn so that it gets delivered to a specific cpu */ 1493/* Rebind an evtchn so that it gets delivered to a specific cpu */
1494static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) 1494static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
1495{ 1495{
1496 struct shared_info *s = HYPERVISOR_shared_info;
1496 struct evtchn_bind_vcpu bind_vcpu; 1497 struct evtchn_bind_vcpu bind_vcpu;
1497 int evtchn = evtchn_from_irq(irq); 1498 int evtchn = evtchn_from_irq(irq);
1499 int masked;
1498 1500
1499 if (!VALID_EVTCHN(evtchn)) 1501 if (!VALID_EVTCHN(evtchn))
1500 return -1; 1502 return -1;
@@ -1511,6 +1513,12 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
1511 bind_vcpu.vcpu = tcpu; 1513 bind_vcpu.vcpu = tcpu;
1512 1514
1513 /* 1515 /*
1516 * Mask the event while changing the VCPU binding to prevent
1517 * it being delivered on an unexpected VCPU.
1518 */
1519 masked = sync_test_and_set_bit(evtchn, BM(s->evtchn_mask));
1520
1521 /*
1514 * If this fails, it usually just indicates that we're dealing with a 1522 * If this fails, it usually just indicates that we're dealing with a
1515 * virq or IPI channel, which don't actually need to be rebound. Ignore 1523 * virq or IPI channel, which don't actually need to be rebound. Ignore
1516 * it, but don't do the xenlinux-level rebind in that case. 1524 * it, but don't do the xenlinux-level rebind in that case.
@@ -1518,6 +1526,9 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
1518 if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0) 1526 if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0)
1519 bind_evtchn_to_cpu(evtchn, tcpu); 1527 bind_evtchn_to_cpu(evtchn, tcpu);
1520 1528
1529 if (!masked)
1530 unmask_evtchn(evtchn);
1531
1521 return 0; 1532 return 0;
1522} 1533}
1523 1534