mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-03 20:36:39 +07:00
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 0bc830b05c
("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>
This commit is contained in:
parent
ae548c5c80
commit
5bda6eed2e
@ -206,6 +206,8 @@ static int ioapic_set_irq(struct kvm_ioapic *ioapic, unsigned int irq,
|
||||
|
||||
old_irr = ioapic->irr;
|
||||
ioapic->irr |= mask;
|
||||
if (edge)
|
||||
ioapic->irr_delivered &= ~mask;
|
||||
if ((edge && old_irr == ioapic->irr) ||
|
||||
(!edge && entry.fields.remote_irr)) {
|
||||
ret = 0;
|
||||
@ -349,7 +351,7 @@ static int ioapic_service(struct kvm_ioapic *ioapic, int irq, bool line_status)
|
||||
irqe.shorthand = 0;
|
||||
|
||||
if (irqe.trig_mode == IOAPIC_EDGE_TRIG)
|
||||
ioapic->irr &= ~(1 << irq);
|
||||
ioapic->irr_delivered |= 1 << irq;
|
||||
|
||||
if (irq == RTC_GSI && line_status) {
|
||||
/*
|
||||
@ -597,6 +599,7 @@ static void kvm_ioapic_reset(struct kvm_ioapic *ioapic)
|
||||
ioapic->base_address = IOAPIC_DEFAULT_BASE_ADDRESS;
|
||||
ioapic->ioregsel = 0;
|
||||
ioapic->irr = 0;
|
||||
ioapic->irr_delivered = 0;
|
||||
ioapic->id = 0;
|
||||
memset(ioapic->irq_eoi, 0x00, IOAPIC_NUM_PINS);
|
||||
rtc_irq_eoi_tracking_reset(ioapic);
|
||||
@ -654,6 +657,7 @@ int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
|
||||
|
||||
spin_lock(&ioapic->lock);
|
||||
memcpy(state, ioapic, sizeof(struct kvm_ioapic_state));
|
||||
state->irr &= ~ioapic->irr_delivered;
|
||||
spin_unlock(&ioapic->lock);
|
||||
return 0;
|
||||
}
|
||||
@ -667,6 +671,7 @@ int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
|
||||
spin_lock(&ioapic->lock);
|
||||
memcpy(ioapic, state, sizeof(struct kvm_ioapic_state));
|
||||
ioapic->irr = 0;
|
||||
ioapic->irr_delivered = 0;
|
||||
update_handled_vectors(ioapic);
|
||||
kvm_vcpu_request_scan_ioapic(kvm);
|
||||
kvm_ioapic_inject_all(ioapic, state->irr);
|
||||
|
@ -77,6 +77,7 @@ struct kvm_ioapic {
|
||||
struct rtc_status rtc_status;
|
||||
struct delayed_work eoi_inject;
|
||||
u32 irq_eoi[IOAPIC_NUM_PINS];
|
||||
u32 irr_delivered;
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
|
Loading…
Reference in New Issue
Block a user