diff options
Diffstat (limited to 'arch/x86/kvm/lapic.c')
-rw-r--r-- | arch/x86/kvm/lapic.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 08e8a899e005..b8345dd41b25 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -112,17 +112,6 @@ static inline int __apic_test_and_clear_vector(int vec, void *bitmap) | |||
112 | struct static_key_deferred apic_hw_disabled __read_mostly; | 112 | struct static_key_deferred apic_hw_disabled __read_mostly; |
113 | struct static_key_deferred apic_sw_disabled __read_mostly; | 113 | struct static_key_deferred apic_sw_disabled __read_mostly; |
114 | 114 | ||
115 | static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val) | ||
116 | { | ||
117 | if ((kvm_apic_get_reg(apic, APIC_SPIV) ^ val) & APIC_SPIV_APIC_ENABLED) { | ||
118 | if (val & APIC_SPIV_APIC_ENABLED) | ||
119 | static_key_slow_dec_deferred(&apic_sw_disabled); | ||
120 | else | ||
121 | static_key_slow_inc(&apic_sw_disabled.key); | ||
122 | } | ||
123 | apic_set_reg(apic, APIC_SPIV, val); | ||
124 | } | ||
125 | |||
126 | static inline int apic_enabled(struct kvm_lapic *apic) | 115 | static inline int apic_enabled(struct kvm_lapic *apic) |
127 | { | 116 | { |
128 | return kvm_apic_sw_enabled(apic) && kvm_apic_hw_enabled(apic); | 117 | return kvm_apic_sw_enabled(apic) && kvm_apic_hw_enabled(apic); |
@@ -210,6 +199,20 @@ out: | |||
210 | kvm_vcpu_request_scan_ioapic(kvm); | 199 | kvm_vcpu_request_scan_ioapic(kvm); |
211 | } | 200 | } |
212 | 201 | ||
202 | static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val) | ||
203 | { | ||
204 | u32 prev = kvm_apic_get_reg(apic, APIC_SPIV); | ||
205 | |||
206 | apic_set_reg(apic, APIC_SPIV, val); | ||
207 | if ((prev ^ val) & APIC_SPIV_APIC_ENABLED) { | ||
208 | if (val & APIC_SPIV_APIC_ENABLED) { | ||
209 | static_key_slow_dec_deferred(&apic_sw_disabled); | ||
210 | recalculate_apic_map(apic->vcpu->kvm); | ||
211 | } else | ||
212 | static_key_slow_inc(&apic_sw_disabled.key); | ||
213 | } | ||
214 | } | ||
215 | |||
213 | static inline void kvm_apic_set_id(struct kvm_lapic *apic, u8 id) | 216 | static inline void kvm_apic_set_id(struct kvm_lapic *apic, u8 id) |
214 | { | 217 | { |
215 | apic_set_reg(apic, APIC_ID, id << 24); | 218 | apic_set_reg(apic, APIC_ID, id << 24); |
@@ -706,6 +709,8 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, | |||
706 | int result = 0; | 709 | int result = 0; |
707 | struct kvm_vcpu *vcpu = apic->vcpu; | 710 | struct kvm_vcpu *vcpu = apic->vcpu; |
708 | 711 | ||
712 | trace_kvm_apic_accept_irq(vcpu->vcpu_id, delivery_mode, | ||
713 | trig_mode, vector); | ||
709 | switch (delivery_mode) { | 714 | switch (delivery_mode) { |
710 | case APIC_DM_LOWEST: | 715 | case APIC_DM_LOWEST: |
711 | vcpu->arch.apic_arb_prio++; | 716 | vcpu->arch.apic_arb_prio++; |
@@ -727,8 +732,6 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, | |||
727 | kvm_make_request(KVM_REQ_EVENT, vcpu); | 732 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
728 | kvm_vcpu_kick(vcpu); | 733 | kvm_vcpu_kick(vcpu); |
729 | } | 734 | } |
730 | trace_kvm_apic_accept_irq(vcpu->vcpu_id, delivery_mode, | ||
731 | trig_mode, vector, false); | ||
732 | break; | 735 | break; |
733 | 736 | ||
734 | case APIC_DM_REMRD: | 737 | case APIC_DM_REMRD: |
@@ -1352,6 +1355,9 @@ void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data) | |||
1352 | return; | 1355 | return; |
1353 | 1356 | ||
1354 | hrtimer_cancel(&apic->lapic_timer.timer); | 1357 | hrtimer_cancel(&apic->lapic_timer.timer); |
1358 | /* Inject here so clearing tscdeadline won't override new value */ | ||
1359 | if (apic_has_pending_timer(vcpu)) | ||
1360 | kvm_inject_apic_timer_irqs(vcpu); | ||
1355 | apic->lapic_timer.tscdeadline = data; | 1361 | apic->lapic_timer.tscdeadline = data; |
1356 | start_apic_timer(apic); | 1362 | start_apic_timer(apic); |
1357 | } | 1363 | } |
@@ -1639,6 +1645,8 @@ void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu) | |||
1639 | 1645 | ||
1640 | if (atomic_read(&apic->lapic_timer.pending) > 0) { | 1646 | if (atomic_read(&apic->lapic_timer.pending) > 0) { |
1641 | kvm_apic_local_deliver(apic, APIC_LVTT); | 1647 | kvm_apic_local_deliver(apic, APIC_LVTT); |
1648 | if (apic_lvtt_tscdeadline(apic)) | ||
1649 | apic->lapic_timer.tscdeadline = 0; | ||
1642 | atomic_set(&apic->lapic_timer.pending, 0); | 1650 | atomic_set(&apic->lapic_timer.pending, 0); |
1643 | } | 1651 | } |
1644 | } | 1652 | } |