|
|
fbce2fe |
|
|
|
fbce2fe |
# HG changeset patch
|
|
|
fbce2fe |
# User Stefano Stabellini <stefano.stabellini@eu.citrix.com>
|
|
|
fbce2fe |
# Date 1321623485 0
|
|
|
fbce2fe |
# Node ID 5a00ccfc63915650b8e1a262c2cad8e8d8670612
|
|
|
fbce2fe |
# Parent e73ada19a69daf821aa7d80323f1bd76239b9bae
|
|
|
fbce2fe |
x86: re-inject emulated level pirqs in PV on HVM guests if still asserted
|
|
|
fbce2fe |
|
|
|
fbce2fe |
PV on HVM guests can loose level interrupts coming from emulated
|
|
|
fbce2fe |
devices if they have been remapped onto event channels. The reason is
|
|
|
fbce2fe |
that we are missing the code to inject a pirq again in the guest when
|
|
|
fbce2fe |
the guest EOIs it, if it corresponds to an emulated level interrupt
|
|
|
fbce2fe |
and the interrupt is still asserted.
|
|
|
fbce2fe |
|
|
|
fbce2fe |
Fix this issue and also return error when the guest tries to get the
|
|
|
fbce2fe |
irq_status of a non-existing pirq.
|
|
|
fbce2fe |
|
|
|
fbce2fe |
|
|
|
fbce2fe |
Changes in this backport:
|
|
|
fbce2fe |
- move the spinlock afterward to cover the new code only.
|
|
|
fbce2fe |
|
|
|
fbce2fe |
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
|
|
|
fbce2fe |
Committed-by: Keir Fraser <keir@xen.org>
|
|
|
fbce2fe |
xen-unstable changeset: 24007:0526644ad2a6
|
|
|
fbce2fe |
xen-unstable date: Thu Oct 27 16:07:18 2011 +0100
|
|
|
fbce2fe |
|
|
|
fbce2fe |
diff -r e73ada19a69d -r 5a00ccfc6391 xen/arch/x86/physdev.c
|
|
|
fbce2fe |
--- a/xen/arch/x86/physdev.c Thu Nov 17 09:13:25 2011 +0000
|
|
|
fbce2fe |
+++ b/xen/arch/x86/physdev.c Fri Nov 18 13:38:05 2011 +0000
|
|
|
fbce2fe |
@@ -268,6 +268,20 @@
|
|
|
fbce2fe |
ret = pirq_guest_eoi(v->domain, eoi.irq);
|
|
|
fbce2fe |
else
|
|
|
fbce2fe |
ret = 0;
|
|
|
fbce2fe |
+ spin_lock(&v->domain->event_lock);
|
|
|
fbce2fe |
+ if ( is_hvm_domain(v->domain) &&
|
|
|
fbce2fe |
+ domain_pirq_to_emuirq(v->domain, eoi.irq) > 0 )
|
|
|
fbce2fe |
+ {
|
|
|
fbce2fe |
+ struct hvm_irq *hvm_irq = &v->domain->arch.hvm_domain.irq;
|
|
|
fbce2fe |
+ int gsi = domain_pirq_to_emuirq(v->domain, eoi.irq);
|
|
|
fbce2fe |
+
|
|
|
fbce2fe |
+ /* if this is a level irq and count > 0, send another
|
|
|
fbce2fe |
+ * notification */
|
|
|
fbce2fe |
+ if ( gsi >= NR_ISAIRQS /* ISA irqs are edge triggered */
|
|
|
fbce2fe |
+ && hvm_irq->gsi_assert_count[gsi] )
|
|
|
fbce2fe |
+ send_guest_pirq(v->domain, eoi.irq);
|
|
|
fbce2fe |
+ }
|
|
|
fbce2fe |
+ spin_unlock(&v->domain->event_lock);
|
|
|
fbce2fe |
break;
|
|
|
fbce2fe |
}
|
|
|
fbce2fe |
|
|
|
fbce2fe |
@@ -323,9 +337,10 @@
|
|
|
fbce2fe |
break;
|
|
|
fbce2fe |
irq_status_query.flags = 0;
|
|
|
fbce2fe |
if ( is_hvm_domain(v->domain) &&
|
|
|
fbce2fe |
- domain_pirq_to_irq(v->domain, irq) <= 0 )
|
|
|
fbce2fe |
+ domain_pirq_to_irq(v->domain, irq) <= 0 &&
|
|
|
fbce2fe |
+ domain_pirq_to_emuirq(v->domain, irq) == IRQ_UNBOUND )
|
|
|
fbce2fe |
{
|
|
|
fbce2fe |
- ret = copy_to_guest(arg, &irq_status_query, 1) ? -EFAULT : 0;
|
|
|
fbce2fe |
+ ret = -EINVAL;
|
|
|
fbce2fe |
break;
|
|
|
fbce2fe |
}
|
|
|
fbce2fe |
|
|
|
fbce2fe |
|