diff options
author | Yunhong Jiang <yunhong.jiang@gmail.com> | 2016-06-13 17:20:00 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2016-06-16 04:07:46 -0400 |
commit | 53f9eedff713bab262b64682ad1abb1e8116d041 (patch) | |
tree | 8c30b9ff56470304f867af0615aec25afe2f99fa /arch/x86 | |
parent | a03825bbd0c39feeba605912cdbc28e79e4e01e1 (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.c | 57 |
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 | ||
1316 | static 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 | |||
1316 | static void start_apic_timer(struct kvm_lapic *apic) | 1346 | static 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 | ||