aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorYunhong Jiang <yunhong.jiang@gmail.com>2016-06-13 17:20:00 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2016-06-16 04:07:46 -0400
commit53f9eedff713bab262b64682ad1abb1e8116d041 (patch)
tree8c30b9ff56470304f867af0615aec25afe2f99fa /arch/x86
parenta03825bbd0c39feeba605912cdbc28e79e4e01e1 (diff)
kvm: lapic: separate start_sw_tscdeadline from start_apic_timer
The function to start the tsc deadline timer virtualization will be used also by the pre_block hook when we use the preemption timer; change it to a separate function. No logic changes. Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kvm/lapic.c57
1 files changed, 31 insertions, 26 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index bbb5b283ff63..f1cf8a5ede11 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -1313,6 +1313,36 @@ void wait_lapic_expire(struct kvm_vcpu *vcpu)
1313 __delay(tsc_deadline - guest_tsc); 1313 __delay(tsc_deadline - guest_tsc);
1314} 1314}
1315 1315
1316static void start_sw_tscdeadline(struct kvm_lapic *apic)
1317{
1318 u64 guest_tsc, tscdeadline = apic->lapic_timer.tscdeadline;
1319 u64 ns = 0;
1320 ktime_t expire;
1321 struct kvm_vcpu *vcpu = apic->vcpu;
1322 unsigned long this_tsc_khz = vcpu->arch.virtual_tsc_khz;
1323 unsigned long flags;
1324 ktime_t now;
1325
1326 if (unlikely(!tscdeadline || !this_tsc_khz))
1327 return;
1328
1329 local_irq_save(flags);
1330
1331 now = apic->lapic_timer.timer.base->get_time();
1332 guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc());
1333 if (likely(tscdeadline > guest_tsc)) {
1334 ns = (tscdeadline - guest_tsc) * 1000000ULL;
1335 do_div(ns, this_tsc_khz);
1336 expire = ktime_add_ns(now, ns);
1337 expire = ktime_sub_ns(expire, lapic_timer_advance_ns);
1338 hrtimer_start(&apic->lapic_timer.timer,
1339 expire, HRTIMER_MODE_ABS_PINNED);
1340 } else
1341 apic_timer_expired(apic);
1342
1343 local_irq_restore(flags);
1344}
1345
1316static void start_apic_timer(struct kvm_lapic *apic) 1346static void start_apic_timer(struct kvm_lapic *apic)
1317{ 1347{
1318 ktime_t now; 1348 ktime_t now;
@@ -1359,32 +1389,7 @@ static void start_apic_timer(struct kvm_lapic *apic)
1359 ktime_to_ns(ktime_add_ns(now, 1389 ktime_to_ns(ktime_add_ns(now,
1360 apic->lapic_timer.period))); 1390 apic->lapic_timer.period)));
1361 } else if (apic_lvtt_tscdeadline(apic)) { 1391 } else if (apic_lvtt_tscdeadline(apic)) {
1362 /* lapic timer in tsc deadline mode */ 1392 start_sw_tscdeadline(apic);
1363 u64 guest_tsc, tscdeadline = apic->lapic_timer.tscdeadline;
1364 u64 ns = 0;
1365 ktime_t expire;
1366 struct kvm_vcpu *vcpu = apic->vcpu;
1367 unsigned long this_tsc_khz = vcpu->arch.virtual_tsc_khz;
1368 unsigned long flags;
1369
1370 if (unlikely(!tscdeadline || !this_tsc_khz))
1371 return;
1372
1373 local_irq_save(flags);
1374
1375 now = apic->lapic_timer.timer.base->get_time();
1376 guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc());
1377 if (likely(tscdeadline > guest_tsc)) {
1378 ns = (tscdeadline - guest_tsc) * 1000000ULL;
1379 do_div(ns, this_tsc_khz);
1380 expire = ktime_add_ns(now, ns);
1381 expire = ktime_sub_ns(expire, lapic_timer_advance_ns);
1382 hrtimer_start(&apic->lapic_timer.timer,
1383 expire, HRTIMER_MODE_ABS_PINNED);
1384 } else
1385 apic_timer_expired(apic);
1386
1387 local_irq_restore(flags);
1388 } 1393 }
1389} 1394}
1390 1395