aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Stabellini <stefano.stabellini@eu.citrix.com>2011-08-31 15:32:24 +0100
committerStefano Stabellini <stefano.stabellini@eu.citrix.com>2011-08-31 15:32:24 +0100
commit0596edb27f162c8bcdeb60b8b35dea812ba655ac (patch)
treef915bbb2f4a745342ad7a26a396cceb2e8fd1339
parent0a0a2267d398bfefe32b04189cba432a098931da (diff)
downloadxen-0596edb27f162c8bcdeb60b8b35dea812ba655ac.tar.gz
xen-0596edb27f162c8bcdeb60b8b35dea812ba655ac.tar.bz2
xen-0596edb27f162c8bcdeb60b8b35dea812ba655ac.zip
xen: fix hvm_domain_use_pirq's behavior
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
-rw-r--r--xen/arch/x86/irq.c2
-rw-r--r--xen/arch/x86/physdev.c7
-rw-r--r--xen/common/event_channel.c5
3 files changed, 8 insertions, 6 deletions
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index de2a56f956..410b9e8cd6 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -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;
diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c
index 2701a7f9e6..fff3544b68 100644
--- a/xen/arch/x86/physdev.c
+++ b/xen/arch/x86/physdev.c
@@ -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;
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index c4308ed8f7..fee9a7a484 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -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: