39 lines
1.4 KiB
Diff
39 lines
1.4 KiB
Diff
# HG changeset patch
|
|
# User Yongan Liu<Liuyongan@huawei.com>
|
|
# Date 1325752199 -3600
|
|
# Node ID 02b92d035f6484ea33f03c4a59630d82e0469eeb
|
|
# Parent efaa28639a71524a693ba500624f8512e5795e18
|
|
x86/vIRQ: IRR and TMR race condition bug fix
|
|
|
|
In vlapic_set_irq, we set the IRR register before the TMR. And the IRR
|
|
might be serviced before setting TMR, and even worse EOI might occur
|
|
before TMR setting, in which case the vioapic_update_EOI won't be
|
|
called, and further prevent all the subsequent interrupt injecting.
|
|
Reorder setting the TMR and IRR will solve the problem.
|
|
|
|
Besides, KVM has fixed a similar bug in:
|
|
http://markmail.org/search/?q=APIC_TMR#query:APIC_TMR+page:1+mid:rphs4f7lkxjlldne+state:results
|
|
|
|
Signed-off-by: Yongan Liu<Liuyongan@huawei.com>
|
|
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
|
Committed-by: Jan Beulich <jbeulich@suse.com>
|
|
|
|
--- a/xen/arch/x86/hvm/vlapic.c
|
|
+++ b/xen/arch/x86/hvm/vlapic.c
|
|
@@ -142,14 +142,11 @@ static int vlapic_find_highest_irr(struc
|
|
|
|
int vlapic_set_irq(struct vlapic *vlapic, uint8_t vec, uint8_t trig)
|
|
{
|
|
- int ret;
|
|
-
|
|
- ret = !vlapic_test_and_set_irr(vec, vlapic);
|
|
if ( trig )
|
|
vlapic_set_vector(vec, &vlapic->regs->data[APIC_TMR]);
|
|
|
|
/* We may need to wake up target vcpu, besides set pending bit here */
|
|
- return ret;
|
|
+ return !vlapic_test_and_set_irr(vec, vlapic);
|
|
}
|
|
|
|
static int vlapic_find_highest_isr(struct vlapic *vlapic)
|