|
@@ -92,6 +92,11 @@ static inline int apic_test_and_clear_vector(int vec, void *bitmap)
|
|
|
return test_and_clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
|
|
|
}
|
|
|
|
|
|
+static inline int apic_test_vector(int vec, void *bitmap)
|
|
|
+{
|
|
|
+ return test_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
|
|
|
+}
|
|
|
+
|
|
|
static inline void apic_set_vector(int vec, void *bitmap)
|
|
|
{
|
|
|
set_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
|
|
@@ -480,7 +485,6 @@ int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2)
|
|
|
static void apic_set_eoi(struct kvm_lapic *apic)
|
|
|
{
|
|
|
int vector = apic_find_highest_isr(apic);
|
|
|
- int trigger_mode;
|
|
|
/*
|
|
|
* Not every write EOI will has corresponding ISR,
|
|
|
* one example is when Kernel check timer on setup_IO_APIC
|
|
@@ -491,12 +495,15 @@ static void apic_set_eoi(struct kvm_lapic *apic)
|
|
|
apic_clear_vector(vector, apic->regs + APIC_ISR);
|
|
|
apic_update_ppr(apic);
|
|
|
|
|
|
- if (apic_test_and_clear_vector(vector, apic->regs + APIC_TMR))
|
|
|
- trigger_mode = IOAPIC_LEVEL_TRIG;
|
|
|
- else
|
|
|
- trigger_mode = IOAPIC_EDGE_TRIG;
|
|
|
- if (!(apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI))
|
|
|
+ if (!(apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI) &&
|
|
|
+ kvm_ioapic_handles_vector(apic->vcpu->kvm, vector)) {
|
|
|
+ int trigger_mode;
|
|
|
+ if (apic_test_vector(vector, apic->regs + APIC_TMR))
|
|
|
+ trigger_mode = IOAPIC_LEVEL_TRIG;
|
|
|
+ else
|
|
|
+ trigger_mode = IOAPIC_EDGE_TRIG;
|
|
|
kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode);
|
|
|
+ }
|
|
|
kvm_make_request(KVM_REQ_EVENT, apic->vcpu);
|
|
|
}
|
|
|
|