diff options
| author | Arnd Bergmann <arnd@arndb.de> | 2013-04-09 15:29:20 +0200 |
|---|---|---|
| committer | Arnd Bergmann <arnd@arndb.de> | 2013-04-09 15:29:43 +0200 |
| commit | 44c0d2377539fafd1023ec7e16765b71c7f4fbce (patch) | |
| tree | 49065c2af83c723f150bf636939790ad3108a897 /drivers/xen/events.c | |
| parent | 8024206dbf4e0701f0cdf259a122ea23db3a7a16 (diff) | |
| parent | 07961ac7c0ee8b546658717034fe692fd12eefa9 (diff) | |
| download | olio-linux-3.10-44c0d2377539fafd1023ec7e16765b71c7f4fbce.tar.xz olio-linux-3.10-44c0d2377539fafd1023ec7e16765b71c7f4fbce.zip | |
Merge tag 'v3.9-rc5' into next/cleanup
This is a dependency for the mxs/cleanup branch.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/xen/events.c')
| -rw-r--r-- | drivers/xen/events.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index d17aa41a904..aa85881d17b 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -403,11 +403,23 @@ static void unmask_evtchn(int port) if (unlikely((cpu != cpu_from_evtchn(port)))) do_hypercall = 1; - else + else { + /* + * Need to clear the mask before checking pending to + * avoid a race with an event becoming pending. + * + * EVTCHNOP_unmask will only trigger an upcall if the + * mask bit was set, so if a hypercall is needed + * remask the event. + */ + sync_clear_bit(port, BM(&s->evtchn_mask[0])); evtchn_pending = sync_test_bit(port, BM(&s->evtchn_pending[0])); - if (unlikely(evtchn_pending && xen_hvm_domain())) - do_hypercall = 1; + if (unlikely(evtchn_pending && xen_hvm_domain())) { + sync_set_bit(port, BM(&s->evtchn_mask[0])); + do_hypercall = 1; + } + } /* Slow path (hypercall) if this is a non-local port or if this is * an hvm domain and an event is pending (hvm domains don't have @@ -418,8 +430,6 @@ static void unmask_evtchn(int port) } else { struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); - sync_clear_bit(port, BM(&s->evtchn_mask[0])); - /* * The following is basically the equivalent of * 'hw_resend_irq'. Just like a real IO-APIC we 'lose |