x86: re-inject emulated level pirqs in PV on HVM guests if still asserted

PV on HVM guests can loose level interrupts coming from emulated
devices if they have been remapped onto event channels.  The reason is
that we are missing the code to inject a pirq again in the guest when
the guest EOIs it, if it corresponds to an emulated level interrupt
and the interrupt is still asserted.

Fix this issue and also return error when the guest tries to get the
irq_status of a non-existing pirq.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Committed-by: Keir Fraser <keir@xen.org>
xen-unstable changeset:   24007:0526644ad2a6
xen-unstable date:        Thu Oct 27 16:07:18 2011 +0100
This commit is contained in:
Stefano Stabellini committed 2011-11-16 16:33:58 +00:00
1 parent 5966ce084e
commit 29907d89a8
1 file changed
+17 -2
+17 -2
View File
@@ -261,6 +261,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
ret = -EINVAL;
if ( eoi.irq >= v->domain->nr_pirqs )
break;
spin_lock(&v->domain->event_lock);
if ( v->domain->arch.pirq_eoi_map )
evtchn_unmask(v->domain->pirq_to_evtchn[eoi.irq]);
if ( !is_hvm_domain(v->domain) ||
@@ -268,6 +269,19 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
ret = pirq_guest_eoi(v->domain, eoi.irq);
else
ret = 0;
if ( is_hvm_domain(v->domain) &&
domain_pirq_to_emuirq(v->domain, eoi.irq) > 0 )
{
struct hvm_irq *hvm_irq = &v->domain->arch.hvm_domain.irq;
int gsi = domain_pirq_to_emuirq(v->domain, eoi.irq);
/* if this is a level irq and count > 0, send another
* notification */
if ( gsi >= NR_ISAIRQS /* ISA irqs are edge triggered */
&& hvm_irq->gsi_assert_count[gsi] )
send_guest_pirq(v->domain, eoi.irq);
}
spin_unlock(&v->domain->event_lock);
break;
}
@@ -323,9 +337,10 @@ 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_irq(v->domain, irq) <= 0 )
domain_pirq_to_irq(v->domain, irq) <= 0 &&
domain_pirq_to_emuirq(v->domain, irq) == IRQ_UNBOUND )
{
ret = copy_to_guest(arg, &irq_status_query, 1) ? -EFAULT : 0;
ret = -EINVAL;
break;
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.