diff options
author | Joerg Roedel <jroedel@suse.de> | 2016-02-29 10:04:45 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2016-03-03 08:36:18 -0500 |
commit | 4d99ba898dd0c521ca6cdfdde55c9b58aea3cb3d (patch) | |
tree | 3019e11a4187a786fd4b51f5fc8305acffa89e3f | |
parent | 9daa50076f585854f0040aa8403eac020d6f5d64 (diff) |
kvm: x86: Check dest_map->vector to match eoi signals for rtc
Using the vector stored at interrupt delivery makes the eoi
matching safe agains irq migration in the ioapic.
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | arch/x86/kvm/ioapic.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c index f2c9906c5849..9db47090ead0 100644 --- a/arch/x86/kvm/ioapic.c +++ b/arch/x86/kvm/ioapic.c | |||
@@ -237,10 +237,17 @@ static void kvm_ioapic_inject_all(struct kvm_ioapic *ioapic, unsigned long irr) | |||
237 | void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, ulong *ioapic_handled_vectors) | 237 | void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, ulong *ioapic_handled_vectors) |
238 | { | 238 | { |
239 | struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic; | 239 | struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic; |
240 | struct dest_map *dest_map = &ioapic->rtc_status.dest_map; | ||
240 | union kvm_ioapic_redirect_entry *e; | 241 | union kvm_ioapic_redirect_entry *e; |
241 | int index; | 242 | int index; |
242 | 243 | ||
243 | spin_lock(&ioapic->lock); | 244 | spin_lock(&ioapic->lock); |
245 | |||
246 | /* Make sure we see any missing RTC EOI */ | ||
247 | if (test_bit(vcpu->vcpu_id, dest_map->map)) | ||
248 | __set_bit(dest_map->vectors[vcpu->vcpu_id], | ||
249 | ioapic_handled_vectors); | ||
250 | |||
244 | for (index = 0; index < IOAPIC_NUM_PINS; index++) { | 251 | for (index = 0; index < IOAPIC_NUM_PINS; index++) { |
245 | e = &ioapic->redirtbl[index]; | 252 | e = &ioapic->redirtbl[index]; |
246 | if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG || | 253 | if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG || |
@@ -408,8 +415,14 @@ static void kvm_ioapic_eoi_inject_work(struct work_struct *work) | |||
408 | static void __kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, | 415 | static void __kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, |
409 | struct kvm_ioapic *ioapic, int vector, int trigger_mode) | 416 | struct kvm_ioapic *ioapic, int vector, int trigger_mode) |
410 | { | 417 | { |
411 | int i; | 418 | struct dest_map *dest_map = &ioapic->rtc_status.dest_map; |
412 | struct kvm_lapic *apic = vcpu->arch.apic; | 419 | struct kvm_lapic *apic = vcpu->arch.apic; |
420 | int i; | ||
421 | |||
422 | /* RTC special handling */ | ||
423 | if (test_bit(vcpu->vcpu_id, dest_map->map) && | ||
424 | vector == dest_map->vectors[vcpu->vcpu_id]) | ||
425 | rtc_irq_eoi(ioapic, vcpu); | ||
413 | 426 | ||
414 | for (i = 0; i < IOAPIC_NUM_PINS; i++) { | 427 | for (i = 0; i < IOAPIC_NUM_PINS; i++) { |
415 | union kvm_ioapic_redirect_entry *ent = &ioapic->redirtbl[i]; | 428 | union kvm_ioapic_redirect_entry *ent = &ioapic->redirtbl[i]; |
@@ -417,8 +430,6 @@ static void __kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, | |||
417 | if (ent->fields.vector != vector) | 430 | if (ent->fields.vector != vector) |
418 | continue; | 431 | continue; |
419 | 432 | ||
420 | if (i == RTC_GSI) | ||
421 | rtc_irq_eoi(ioapic, vcpu); | ||
422 | /* | 433 | /* |
423 | * We are dropping lock while calling ack notifiers because ack | 434 | * We are dropping lock while calling ack notifiers because ack |
424 | * notifier callbacks for assigned devices call into IOAPIC | 435 | * notifier callbacks for assigned devices call into IOAPIC |