aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWincy Van <fanwenyi0529@gmail.com>2014-12-23 22:14:29 -0500
committerMarcelo Tosatti <mtosatti@redhat.com>2015-03-10 09:37:43 -0400
commit5bda6eed2e3626f40f2602a8fed72007f1fafaf8 (patch)
treeddea5207022bd6dbf8e974dcbb6673374bc05106
parentae548c5c806497b3495019f550f93dee03f6c15a (diff)
KVM: ioapic: Record edge-triggered interrupts delivery status
This patch fixes the bug discussed in https://www.mail-archive.com/kvm@vger.kernel.org/msg109813.html This patch uses a new field named irr_delivered to record the delivery status of edge-triggered interrupts, and clears the delivered interrupts in kvm_get_ioapic. So it has the same effect of commit 0bc830b05c667218d703f2026ec866c49df974fc ("KVM: ioapic: clear IRR for edge-triggered interrupts at delivery") while avoids the bug of Windows guests. Signed-off-by: Wincy Van <fanwenyi0529@gmail.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-rw-r--r--arch/x86/kvm/ioapic.c7
-rw-r--r--arch/x86/kvm/ioapic.h1
2 files changed, 7 insertions, 1 deletions
diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c
index b1947e0f3e10..a2e9d961c7fe 100644
--- a/arch/x86/kvm/ioapic.c
+++ b/arch/x86/kvm/ioapic.c
@@ -206,6 +206,8 @@ static int ioapic_set_irq(struct kvm_ioapic *ioapic, unsigned int irq,
206 206
207 old_irr = ioapic->irr; 207 old_irr = ioapic->irr;
208 ioapic->irr |= mask; 208 ioapic->irr |= mask;
209 if (edge)
210 ioapic->irr_delivered &= ~mask;
209 if ((edge && old_irr == ioapic->irr) || 211 if ((edge && old_irr == ioapic->irr) ||
210 (!edge && entry.fields.remote_irr)) { 212 (!edge && entry.fields.remote_irr)) {
211 ret = 0; 213 ret = 0;
@@ -349,7 +351,7 @@ static int ioapic_service(struct kvm_ioapic *ioapic, int irq, bool line_status)
349 irqe.shorthand = 0; 351 irqe.shorthand = 0;
350 352
351 if (irqe.trig_mode == IOAPIC_EDGE_TRIG) 353 if (irqe.trig_mode == IOAPIC_EDGE_TRIG)
352 ioapic->irr &= ~(1 << irq); 354 ioapic->irr_delivered |= 1 << irq;
353 355
354 if (irq == RTC_GSI && line_status) { 356 if (irq == RTC_GSI && line_status) {
355 /* 357 /*
@@ -597,6 +599,7 @@ static void kvm_ioapic_reset(struct kvm_ioapic *ioapic)
597 ioapic->base_address = IOAPIC_DEFAULT_BASE_ADDRESS; 599 ioapic->base_address = IOAPIC_DEFAULT_BASE_ADDRESS;
598 ioapic->ioregsel = 0; 600 ioapic->ioregsel = 0;
599 ioapic->irr = 0; 601 ioapic->irr = 0;
602 ioapic->irr_delivered = 0;
600 ioapic->id = 0; 603 ioapic->id = 0;
601 memset(ioapic->irq_eoi, 0x00, IOAPIC_NUM_PINS); 604 memset(ioapic->irq_eoi, 0x00, IOAPIC_NUM_PINS);
602 rtc_irq_eoi_tracking_reset(ioapic); 605 rtc_irq_eoi_tracking_reset(ioapic);
@@ -654,6 +657,7 @@ int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
654 657
655 spin_lock(&ioapic->lock); 658 spin_lock(&ioapic->lock);
656 memcpy(state, ioapic, sizeof(struct kvm_ioapic_state)); 659 memcpy(state, ioapic, sizeof(struct kvm_ioapic_state));
660 state->irr &= ~ioapic->irr_delivered;
657 spin_unlock(&ioapic->lock); 661 spin_unlock(&ioapic->lock);
658 return 0; 662 return 0;
659} 663}
@@ -667,6 +671,7 @@ int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
667 spin_lock(&ioapic->lock); 671 spin_lock(&ioapic->lock);
668 memcpy(ioapic, state, sizeof(struct kvm_ioapic_state)); 672 memcpy(ioapic, state, sizeof(struct kvm_ioapic_state));
669 ioapic->irr = 0; 673 ioapic->irr = 0;
674 ioapic->irr_delivered = 0;
670 update_handled_vectors(ioapic); 675 update_handled_vectors(ioapic);
671 kvm_vcpu_request_scan_ioapic(kvm); 676 kvm_vcpu_request_scan_ioapic(kvm);
672 kvm_ioapic_inject_all(ioapic, state->irr); 677 kvm_ioapic_inject_all(ioapic, state->irr);
diff --git a/arch/x86/kvm/ioapic.h b/arch/x86/kvm/ioapic.h
index c2e36d934af4..38d8402ea65c 100644
--- a/arch/x86/kvm/ioapic.h
+++ b/arch/x86/kvm/ioapic.h
@@ -77,6 +77,7 @@ struct kvm_ioapic {
77 struct rtc_status rtc_status; 77 struct rtc_status rtc_status;
78 struct delayed_work eoi_inject; 78 struct delayed_work eoi_inject;
79 u32 irq_eoi[IOAPIC_NUM_PINS]; 79 u32 irq_eoi[IOAPIC_NUM_PINS];
80 u32 irr_delivered;
80}; 81};
81 82
82#ifdef DEBUG 83#ifdef DEBUG