]>
Commit | Line | Data |
---|---|---|
0f3ed05c JR |
1 | |
2 | # HG changeset patch | |
3 | # User Stefano Stabellini <stefano.stabellini@eu.citrix.com> | |
4 | # Date 1321623485 0 | |
5 | # Node ID 5a00ccfc63915650b8e1a262c2cad8e8d8670612 | |
6 | # Parent e73ada19a69daf821aa7d80323f1bd76239b9bae | |
7 | x86: re-inject emulated level pirqs in PV on HVM guests if still asserted | |
8 | ||
9 | PV on HVM guests can loose level interrupts coming from emulated | |
10 | devices if they have been remapped onto event channels. The reason is | |
11 | that we are missing the code to inject a pirq again in the guest when | |
12 | the guest EOIs it, if it corresponds to an emulated level interrupt | |
13 | and the interrupt is still asserted. | |
14 | ||
15 | Fix this issue and also return error when the guest tries to get the | |
16 | irq_status of a non-existing pirq. | |
17 | ||
18 | ||
19 | Changes in this backport: | |
20 | - move the spinlock afterward to cover the new code only. | |
21 | ||
22 | Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> | |
23 | Committed-by: Keir Fraser <keir@xen.org> | |
24 | xen-unstable changeset: 24007:0526644ad2a6 | |
25 | xen-unstable date: Thu Oct 27 16:07:18 2011 +0100 | |
26 | ||
27 | diff -r e73ada19a69d -r 5a00ccfc6391 xen/arch/x86/physdev.c | |
28 | --- a/xen/arch/x86/physdev.c Thu Nov 17 09:13:25 2011 +0000 | |
29 | +++ b/xen/arch/x86/physdev.c Fri Nov 18 13:38:05 2011 +0000 | |
30 | @@ -268,6 +268,20 @@ | |
31 | ret = pirq_guest_eoi(v->domain, eoi.irq); | |
32 | else | |
33 | ret = 0; | |
34 | + spin_lock(&v->domain->event_lock); | |
35 | + if ( is_hvm_domain(v->domain) && | |
36 | + domain_pirq_to_emuirq(v->domain, eoi.irq) > 0 ) | |
37 | + { | |
38 | + struct hvm_irq *hvm_irq = &v->domain->arch.hvm_domain.irq; | |
39 | + int gsi = domain_pirq_to_emuirq(v->domain, eoi.irq); | |
40 | + | |
41 | + /* if this is a level irq and count > 0, send another | |
42 | + * notification */ | |
43 | + if ( gsi >= NR_ISAIRQS /* ISA irqs are edge triggered */ | |
44 | + && hvm_irq->gsi_assert_count[gsi] ) | |
45 | + send_guest_pirq(v->domain, eoi.irq); | |
46 | + } | |
47 | + spin_unlock(&v->domain->event_lock); | |
48 | break; | |
49 | } | |
50 | ||
51 | @@ -323,9 +337,10 @@ | |
52 | break; | |
53 | irq_status_query.flags = 0; | |
54 | if ( is_hvm_domain(v->domain) && | |
55 | - domain_pirq_to_irq(v->domain, irq) <= 0 ) | |
56 | + domain_pirq_to_irq(v->domain, irq) <= 0 && | |
57 | + domain_pirq_to_emuirq(v->domain, irq) == IRQ_UNBOUND ) | |
58 | { | |
59 | - ret = copy_to_guest(arg, &irq_status_query, 1) ? -EFAULT : 0; | |
60 | + ret = -EINVAL; | |
61 | break; | |
62 | } | |
63 | ||
64 |