diff options
Diffstat (limited to 'drivers/xen/events.c')
-rw-r--r-- | drivers/xen/events.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index d659480125f0..7c64473c9f3f 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -665,7 +665,7 @@ static void __xen_evtchn_do_upcall(void) | |||
665 | 665 | ||
666 | count = __get_cpu_var(xed_nesting_count); | 666 | count = __get_cpu_var(xed_nesting_count); |
667 | __get_cpu_var(xed_nesting_count) = 0; | 667 | __get_cpu_var(xed_nesting_count) = 0; |
668 | } while(count != 1); | 668 | } while (count != 1 || vcpu_info->evtchn_upcall_pending); |
669 | 669 | ||
670 | out: | 670 | out: |
671 | 671 | ||
@@ -689,6 +689,7 @@ void xen_hvm_evtchn_do_upcall(void) | |||
689 | { | 689 | { |
690 | __xen_evtchn_do_upcall(); | 690 | __xen_evtchn_do_upcall(); |
691 | } | 691 | } |
692 | EXPORT_SYMBOL_GPL(xen_hvm_evtchn_do_upcall); | ||
692 | 693 | ||
693 | /* Rebind a new event channel to an existing irq. */ | 694 | /* Rebind a new event channel to an existing irq. */ |
694 | void rebind_evtchn_irq(int evtchn, int irq) | 695 | void rebind_evtchn_irq(int evtchn, int irq) |
@@ -725,7 +726,10 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) | |||
725 | struct evtchn_bind_vcpu bind_vcpu; | 726 | struct evtchn_bind_vcpu bind_vcpu; |
726 | int evtchn = evtchn_from_irq(irq); | 727 | int evtchn = evtchn_from_irq(irq); |
727 | 728 | ||
728 | if (!VALID_EVTCHN(evtchn)) | 729 | /* events delivered via platform PCI interrupts are always |
730 | * routed to vcpu 0 */ | ||
731 | if (!VALID_EVTCHN(evtchn) || | ||
732 | (xen_hvm_domain() && !xen_have_vector_callback)) | ||
729 | return -1; | 733 | return -1; |
730 | 734 | ||
731 | /* Send future instances of this interrupt to other vcpu. */ | 735 | /* Send future instances of this interrupt to other vcpu. */ |