]> xenbits.xensource.com Git - people/vhanquez/xen.git/commitdiff
xen: fix hvm_domain_use_pirq's behavior
authorStefano Stabellini <stefano.stabellini@eu.citrix.com>
Wed, 31 Aug 2011 14:32:24 +0000 (15:32 +0100)
committerStefano Stabellini <stefano.stabellini@eu.citrix.com>
Wed, 31 Aug 2011 14:32:24 +0000 (15:32 +0100)
hvm_domain_use_pirq should return true when the guest is using a
certain pirq, no matter if the corresponding event channel is
currently enabled or disabled.  As an additional complication, qemu is
going to request pirqs for passthrough devices even for Xen unaware
HVM guests, so we need to wait for an event channel to be connected
before considering the pirq of a passthrough device as "in use".

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
xen-unstable changeset:   23806:4226ea1785b5
xen-unstable date:        Wed Aug 31 15:23:12 2011 +0100

xen/arch/x86/irq.c
xen/arch/x86/physdev.c
xen/common/event_channel.c

index de2a56f9562bedca42dbae16672cfbb9542a3d0b..410b9e8cd62356ae32e3d2e230789df16e2a5b57 100644 (file)
@@ -1879,7 +1879,7 @@ int hvm_domain_use_pirq(struct domain *d, int pirq)
         return 0;
 
     emuirq = domain_pirq_to_emuirq(d, pirq);
-    if ( emuirq != IRQ_UNBOUND && d->pirq_to_evtchn[pirq] != 0 )
+    if ( emuirq != IRQ_UNBOUND )
         return 1;
     else
         return 0;
index 2701a7f9e6c4a74a763c3907566285483b603389..fff3544b688710c6263a6907aaf365bed134bc57 100644 (file)
@@ -202,9 +202,6 @@ static int physdev_map_pirq(struct physdev_map_pirq *map)
     if ( ret == 0 )
         map->pirq = pirq;
 
-    if ( !ret && is_hvm_domain(d) )
-        map_domain_emuirq_pirq(d, pirq, IRQ_PT);
-
  done:
     spin_unlock(&d->event_lock);
     spin_unlock(&pcidevs_lock);
@@ -267,7 +264,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
         if ( v->domain->arch.pirq_eoi_map )
             evtchn_unmask(v->domain->pirq_to_evtchn[eoi.irq]);
         if ( !is_hvm_domain(v->domain) ||
-             domain_pirq_to_emuirq(v->domain, eoi.irq) == IRQ_PT )
+             domain_pirq_to_irq(v->domain, eoi.irq) > 0 )
             ret = pirq_guest_eoi(v->domain, eoi.irq);
         else
             ret = 0;
@@ -326,7 +323,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
             break;
         irq_status_query.flags = 0;
         if ( is_hvm_domain(v->domain) &&
-             domain_pirq_to_emuirq(v->domain, irq) != IRQ_PT )
+             domain_pirq_to_irq(v->domain, irq) <= 0 )
         {
             ret = copy_to_guest(arg, &irq_status_query, 1) ? -EFAULT : 0;
             break;
index c4308ed8f7b5bcaf0980afff4ae153fe7a4a7370..fee9a7a4845522e7900aee3fbdbfbbd232dc8aff 100644 (file)
@@ -361,6 +361,9 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
 
     bind->port = port;
 
+    if ( is_hvm_domain(d) && domain_pirq_to_irq(d, pirq) > 0 )
+        map_domain_emuirq_pirq(d, pirq, IRQ_PT);
+
  out:
     spin_unlock(&d->event_lock);
 
@@ -409,6 +412,8 @@ static long __evtchn_close(struct domain *d1, int port1)
             pirq_guest_unbind(d1, chn1->u.pirq.irq);
         d1->pirq_to_evtchn[chn1->u.pirq.irq] = 0;
         unlink_pirq_port(chn1, d1->vcpu[chn1->notify_vcpu_id]);
+        if ( is_hvm_domain(d1) && domain_pirq_to_irq(d1, chn1->u.pirq.irq) > 0 )
+            unmap_domain_pirq_emuirq(d1, chn1->u.pirq.irq);
         break;
 
     case ECS_VIRQ: