aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2015-07-29 09:03:06 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2015-10-01 09:06:22 -0400
commitbdaffe1d93e7eddbcc71d074a5d49eba7fe1c765 (patch)
tree65a17f3827ebfdf66caa55a70386368cd13a002e
parent58219c1ab32be51e23f672ec52d2c6a86b0489d8 (diff)
KVM: x86: set TMR when the interrupt is accepted
Do not compute TMR in advance. Instead, set the TMR just before the interrupt is accepted into the IRR. This limits the coupling between IOAPIC and LAPIC. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/kvm/ioapic.c9
-rw-r--r--arch/x86/kvm/ioapic.h3
-rw-r--r--arch/x86/kvm/lapic.c19
-rw-r--r--arch/x86/kvm/lapic.h1
-rw-r--r--arch/x86/kvm/x86.c5
5 files changed, 14 insertions, 23 deletions
diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c
index 856f79105bb5..eaf4ec38d980 100644
--- a/arch/x86/kvm/ioapic.c
+++ b/arch/x86/kvm/ioapic.c
@@ -246,8 +246,7 @@ static void update_handled_vectors(struct kvm_ioapic *ioapic)
246 smp_wmb(); 246 smp_wmb();
247} 247}
248 248
249void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap, 249void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
250 u32 *tmr)
251{ 250{
252 struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic; 251 struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic;
253 union kvm_ioapic_redirect_entry *e; 252 union kvm_ioapic_redirect_entry *e;
@@ -260,13 +259,9 @@ void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap,
260 kvm_irq_has_notifier(ioapic->kvm, KVM_IRQCHIP_IOAPIC, index) || 259 kvm_irq_has_notifier(ioapic->kvm, KVM_IRQCHIP_IOAPIC, index) ||
261 index == RTC_GSI) { 260 index == RTC_GSI) {
262 if (kvm_apic_match_dest(vcpu, NULL, 0, 261 if (kvm_apic_match_dest(vcpu, NULL, 0,
263 e->fields.dest_id, e->fields.dest_mode)) { 262 e->fields.dest_id, e->fields.dest_mode))
264 __set_bit(e->fields.vector, 263 __set_bit(e->fields.vector,
265 (unsigned long *)eoi_exit_bitmap); 264 (unsigned long *)eoi_exit_bitmap);
266 if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG)
267 __set_bit(e->fields.vector,
268 (unsigned long *)tmr);
269 }
270 } 265 }
271 } 266 }
272 spin_unlock(&ioapic->lock); 267 spin_unlock(&ioapic->lock);
diff --git a/arch/x86/kvm/ioapic.h b/arch/x86/kvm/ioapic.h
index ca0b0b4e6256..3dbd0e2aac4e 100644
--- a/arch/x86/kvm/ioapic.h
+++ b/arch/x86/kvm/ioapic.h
@@ -120,7 +120,6 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
120 struct kvm_lapic_irq *irq, unsigned long *dest_map); 120 struct kvm_lapic_irq *irq, unsigned long *dest_map);
121int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); 121int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state);
122int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); 122int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state);
123void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap, 123void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
124 u32 *tmr);
125 124
126#endif 125#endif
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 8d9013c5e1ee..5693dd9fc163 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -551,15 +551,6 @@ static void pv_eoi_clr_pending(struct kvm_vcpu *vcpu)
551 __clear_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention); 551 __clear_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention);
552} 552}
553 553
554void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr)
555{
556 struct kvm_lapic *apic = vcpu->arch.apic;
557 int i;
558
559 for (i = 0; i < 8; i++)
560 apic_set_reg(apic, APIC_TMR + 0x10 * i, tmr[i]);
561}
562
563static void apic_update_ppr(struct kvm_lapic *apic) 554static void apic_update_ppr(struct kvm_lapic *apic)
564{ 555{
565 u32 tpr, isrv, ppr, old_ppr; 556 u32 tpr, isrv, ppr, old_ppr;
@@ -781,6 +772,9 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
781 case APIC_DM_LOWEST: 772 case APIC_DM_LOWEST:
782 vcpu->arch.apic_arb_prio++; 773 vcpu->arch.apic_arb_prio++;
783 case APIC_DM_FIXED: 774 case APIC_DM_FIXED:
775 if (unlikely(trig_mode && !level))
776 break;
777
784 /* FIXME add logic for vcpu on reset */ 778 /* FIXME add logic for vcpu on reset */
785 if (unlikely(!apic_enabled(apic))) 779 if (unlikely(!apic_enabled(apic)))
786 break; 780 break;
@@ -790,6 +784,13 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
790 if (dest_map) 784 if (dest_map)
791 __set_bit(vcpu->vcpu_id, dest_map); 785 __set_bit(vcpu->vcpu_id, dest_map);
792 786
787 if (apic_test_vector(vector, apic->regs + APIC_TMR) != !!trig_mode) {
788 if (trig_mode)
789 apic_set_vector(vector, apic->regs + APIC_TMR);
790 else
791 apic_clear_vector(vector, apic->regs + APIC_TMR);
792 }
793
793 if (kvm_x86_ops->deliver_posted_interrupt) 794 if (kvm_x86_ops->deliver_posted_interrupt)
794 kvm_x86_ops->deliver_posted_interrupt(vcpu, vector); 795 kvm_x86_ops->deliver_posted_interrupt(vcpu, vector);
795 else { 796 else {
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index 764037991d26..eb46d6bcaa75 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -57,7 +57,6 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value);
57u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu); 57u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu);
58void kvm_apic_set_version(struct kvm_vcpu *vcpu); 58void kvm_apic_set_version(struct kvm_vcpu *vcpu);
59 59
60void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr);
61void __kvm_apic_update_irr(u32 *pir, void *regs); 60void __kvm_apic_update_irr(u32 *pir, void *regs);
62void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir); 61void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir);
63int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq, 62int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 92511d4b7236..c1ed74ebc502 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6144,17 +6144,14 @@ static void process_smi(struct kvm_vcpu *vcpu)
6144static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu) 6144static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
6145{ 6145{
6146 u64 eoi_exit_bitmap[4]; 6146 u64 eoi_exit_bitmap[4];
6147 u32 tmr[8];
6148 6147
6149 if (!kvm_apic_hw_enabled(vcpu->arch.apic)) 6148 if (!kvm_apic_hw_enabled(vcpu->arch.apic))
6150 return; 6149 return;
6151 6150
6152 memset(eoi_exit_bitmap, 0, 32); 6151 memset(eoi_exit_bitmap, 0, 32);
6153 memset(tmr, 0, 32);
6154 6152
6155 kvm_ioapic_scan_entry(vcpu, eoi_exit_bitmap, tmr); 6153 kvm_ioapic_scan_entry(vcpu, eoi_exit_bitmap);
6156 kvm_x86_ops->load_eoi_exitmap(vcpu, eoi_exit_bitmap); 6154 kvm_x86_ops->load_eoi_exitmap(vcpu, eoi_exit_bitmap);
6157 kvm_apic_update_tmr(vcpu, tmr);
6158} 6155}
6159 6156
6160static void kvm_vcpu_flush_tlb(struct kvm_vcpu *vcpu) 6157static void kvm_vcpu_flush_tlb(struct kvm_vcpu *vcpu)