mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
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>
This commit is contained in:
1 parent
12b6ea528f
commit
79858fee30
3 files changed
+8
-7
No files matched your search
+1
-2
@@ -2027,6 +2027,5 @@ int unmap_domain_pirq_emuirq(struct domain *d, int pirq)
|
||||
bool_t hvm_domain_use_pirq(const struct domain *d, const struct pirq *pirq)
|
||||
{
|
||||
return is_hvm_domain(d) && pirq &&
|
||||
pirq->arch.hvm.emuirq != IRQ_UNBOUND &&
|
||||
pirq->evtchn != 0;
|
||||
pirq->arch.hvm.emuirq != IRQ_UNBOUND;
|
||||
}
|
||||
@@ -196,9 +196,6 @@ int physdev_map_pirq(domid_t domid, int type, int *index, int *pirq_p,
|
||||
if ( ret == 0 )
|
||||
*pirq_p = 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);
|
||||
@@ -271,7 +268,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
|
||||
v->domain->arch.pv_domain.pirq_eoi_map )
|
||||
evtchn_unmask(pirq->evtchn);
|
||||
if ( !is_hvm_domain(v->domain) ||
|
||||
pirq->arch.hvm.emuirq == IRQ_PT )
|
||||
domain_pirq_to_irq(v->domain, eoi.irq) > 0 )
|
||||
pirq_guest_eoi(pirq);
|
||||
spin_unlock(&v->domain->event_lock);
|
||||
ret = 0;
|
||||
@@ -331,7 +328,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;
|
||||
|
||||
@@ -366,6 +366,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);
|
||||
|
||||
@@ -419,6 +422,8 @@ static long __evtchn_close(struct domain *d1, int port1)
|
||||
pirq->evtchn = 0;
|
||||
pirq_cleanup_check(pirq, d1);
|
||||
unlink_pirq_port(chn1, d1->vcpu[chn1->notify_vcpu_id]);
|
||||
if ( is_hvm_domain(d1) && domain_pirq_to_irq(d1, pirq->pirq) > 0 )
|
||||
unmap_domain_pirq_emuirq(d1, pirq->pirq);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||