diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-04-01 13:50:58 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-04-01 13:50:58 -0400 |
commit | 974857266aae29c371ac2313ab520616335caec9 (patch) | |
tree | 9c2c67433a2783f29fe1f99cf44380b4fbb725af /drivers/xen/events.c | |
parent | 5ed0505c713805f89473cdc0bbfb5110dfd840cb (diff) | |
parent | 07961ac7c0ee8b546658717034fe692fd12eefa9 (diff) |
Merge v3.9-rc5 into char-misc-next
This picks up the fixes in 3.9-rc5 that we need here.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
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 d17aa41a9041..aa85881d17b2 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -403,11 +403,23 @@ static void unmask_evtchn(int port) | |||
403 | 403 | ||
404 | if (unlikely((cpu != cpu_from_evtchn(port)))) | 404 | if (unlikely((cpu != cpu_from_evtchn(port)))) |
405 | do_hypercall = 1; | 405 | do_hypercall = 1; |
406 | else | 406 | else { |
407 | /* | ||
408 | * Need to clear the mask before checking pending to | ||
409 | * avoid a race with an event becoming pending. | ||
410 | * | ||
411 | * EVTCHNOP_unmask will only trigger an upcall if the | ||
412 | * mask bit was set, so if a hypercall is needed | ||
413 | * remask the event. | ||
414 | */ | ||
415 | sync_clear_bit(port, BM(&s->evtchn_mask[0])); | ||
407 | evtchn_pending = sync_test_bit(port, BM(&s->evtchn_pending[0])); | 416 | evtchn_pending = sync_test_bit(port, BM(&s->evtchn_pending[0])); |
408 | 417 | ||
409 | if (unlikely(evtchn_pending && xen_hvm_domain())) | 418 | if (unlikely(evtchn_pending && xen_hvm_domain())) { |
410 | do_hypercall = 1; | 419 | sync_set_bit(port, BM(&s->evtchn_mask[0])); |
420 | do_hypercall = 1; | ||
421 | } | ||
422 | } | ||
411 | 423 | ||
412 | /* Slow path (hypercall) if this is a non-local port or if this is | 424 | /* Slow path (hypercall) if this is a non-local port or if this is |
413 | * an hvm domain and an event is pending (hvm domains don't have | 425 | * an hvm domain and an event is pending (hvm domains don't have |
@@ -418,8 +430,6 @@ static void unmask_evtchn(int port) | |||
418 | } else { | 430 | } else { |
419 | struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); | 431 | struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); |
420 | 432 | ||
421 | sync_clear_bit(port, BM(&s->evtchn_mask[0])); | ||
422 | |||
423 | /* | 433 | /* |
424 | * The following is basically the equivalent of | 434 | * The following is basically the equivalent of |
425 | * 'hw_resend_irq'. Just like a real IO-APIC we 'lose | 435 | * 'hw_resend_irq'. Just like a real IO-APIC we 'lose |