aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kvm/lapic.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 629af0f1c5c4..4c7deb4f78a1 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -1090,6 +1090,17 @@ static void update_divide_count(struct kvm_lapic *apic)
1090 apic->divide_count); 1090 apic->divide_count);
1091} 1091}
1092 1092
1093static void apic_update_lvtt(struct kvm_lapic *apic)
1094{
1095 u32 timer_mode = kvm_apic_get_reg(apic, APIC_LVTT) &
1096 apic->lapic_timer.timer_mode_mask;
1097
1098 if (apic->lapic_timer.timer_mode != timer_mode) {
1099 apic->lapic_timer.timer_mode = timer_mode;
1100 hrtimer_cancel(&apic->lapic_timer.timer);
1101 }
1102}
1103
1093static void apic_timer_expired(struct kvm_lapic *apic) 1104static void apic_timer_expired(struct kvm_lapic *apic)
1094{ 1105{
1095 struct kvm_vcpu *vcpu = apic->vcpu; 1106 struct kvm_vcpu *vcpu = apic->vcpu;
@@ -1298,6 +1309,7 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
1298 apic_set_reg(apic, APIC_LVTT + 0x10 * i, 1309 apic_set_reg(apic, APIC_LVTT + 0x10 * i,
1299 lvt_val | APIC_LVT_MASKED); 1310 lvt_val | APIC_LVT_MASKED);
1300 } 1311 }
1312 apic_update_lvtt(apic);
1301 atomic_set(&apic->lapic_timer.pending, 0); 1313 atomic_set(&apic->lapic_timer.pending, 0);
1302 1314
1303 } 1315 }
@@ -1330,20 +1342,13 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
1330 1342
1331 break; 1343 break;
1332 1344
1333 case APIC_LVTT: { 1345 case APIC_LVTT:
1334 u32 timer_mode = val & apic->lapic_timer.timer_mode_mask;
1335
1336 if (apic->lapic_timer.timer_mode != timer_mode) {
1337 apic->lapic_timer.timer_mode = timer_mode;
1338 hrtimer_cancel(&apic->lapic_timer.timer);
1339 }
1340
1341 if (!kvm_apic_sw_enabled(apic)) 1346 if (!kvm_apic_sw_enabled(apic))
1342 val |= APIC_LVT_MASKED; 1347 val |= APIC_LVT_MASKED;
1343 val &= (apic_lvt_mask[0] | apic->lapic_timer.timer_mode_mask); 1348 val &= (apic_lvt_mask[0] | apic->lapic_timer.timer_mode_mask);
1344 apic_set_reg(apic, APIC_LVTT, val); 1349 apic_set_reg(apic, APIC_LVTT, val);
1350 apic_update_lvtt(apic);
1345 break; 1351 break;
1346 }
1347 1352
1348 case APIC_TMICT: 1353 case APIC_TMICT:
1349 if (apic_lvtt_tscdeadline(apic)) 1354 if (apic_lvtt_tscdeadline(apic))
@@ -1576,7 +1581,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
1576 1581
1577 for (i = 0; i < APIC_LVT_NUM; i++) 1582 for (i = 0; i < APIC_LVT_NUM; i++)
1578 apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED); 1583 apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED);
1579 apic->lapic_timer.timer_mode = 0; 1584 apic_update_lvtt(apic);
1580 apic_set_reg(apic, APIC_LVT0, 1585 apic_set_reg(apic, APIC_LVT0,
1581 SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT)); 1586 SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT));
1582 1587
@@ -1802,6 +1807,7 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu,
1802 1807
1803 apic_update_ppr(apic); 1808 apic_update_ppr(apic);
1804 hrtimer_cancel(&apic->lapic_timer.timer); 1809 hrtimer_cancel(&apic->lapic_timer.timer);
1810 apic_update_lvtt(apic);
1805 update_divide_count(apic); 1811 update_divide_count(apic);
1806 start_apic_timer(apic); 1812 start_apic_timer(apic);
1807 apic->irr_pending = true; 1813 apic->irr_pending = true;