diff options
Diffstat (limited to 'arch/x86/kvm/x86.c')
| -rw-r--r-- | arch/x86/kvm/x86.c | 93 |
1 files changed, 67 insertions, 26 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 21338bdb28ff..63a77caa59f1 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -492,8 +492,8 @@ static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data) | |||
| 492 | static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) | 492 | static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) |
| 493 | { | 493 | { |
| 494 | static int version; | 494 | static int version; |
| 495 | struct kvm_wall_clock wc; | 495 | struct pvclock_wall_clock wc; |
| 496 | struct timespec wc_ts; | 496 | struct timespec now, sys, boot; |
| 497 | 497 | ||
| 498 | if (!wall_clock) | 498 | if (!wall_clock) |
| 499 | return; | 499 | return; |
| @@ -502,10 +502,19 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) | |||
| 502 | 502 | ||
| 503 | kvm_write_guest(kvm, wall_clock, &version, sizeof(version)); | 503 | kvm_write_guest(kvm, wall_clock, &version, sizeof(version)); |
| 504 | 504 | ||
| 505 | wc_ts = current_kernel_time(); | 505 | /* |
| 506 | wc.wc_sec = wc_ts.tv_sec; | 506 | * The guest calculates current wall clock time by adding |
| 507 | wc.wc_nsec = wc_ts.tv_nsec; | 507 | * system time (updated by kvm_write_guest_time below) to the |
| 508 | wc.wc_version = version; | 508 | * wall clock specified here. guest system time equals host |
| 509 | * system time for us, thus we must fill in host boot time here. | ||
| 510 | */ | ||
| 511 | now = current_kernel_time(); | ||
| 512 | ktime_get_ts(&sys); | ||
| 513 | boot = ns_to_timespec(timespec_to_ns(&now) - timespec_to_ns(&sys)); | ||
| 514 | |||
| 515 | wc.sec = boot.tv_sec; | ||
| 516 | wc.nsec = boot.tv_nsec; | ||
| 517 | wc.version = version; | ||
| 509 | 518 | ||
| 510 | kvm_write_guest(kvm, wall_clock, &wc, sizeof(wc)); | 519 | kvm_write_guest(kvm, wall_clock, &wc, sizeof(wc)); |
| 511 | 520 | ||
| @@ -513,6 +522,45 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) | |||
| 513 | kvm_write_guest(kvm, wall_clock, &version, sizeof(version)); | 522 | kvm_write_guest(kvm, wall_clock, &version, sizeof(version)); |
| 514 | } | 523 | } |
| 515 | 524 | ||
| 525 | static uint32_t div_frac(uint32_t dividend, uint32_t divisor) | ||
| 526 | { | ||
| 527 | uint32_t quotient, remainder; | ||
| 528 | |||
| 529 | /* Don't try to replace with do_div(), this one calculates | ||
| 530 | * "(dividend << 32) / divisor" */ | ||
| 531 | __asm__ ( "divl %4" | ||
| 532 | : "=a" (quotient), "=d" (remainder) | ||
| 533 | : "0" (0), "1" (dividend), "r" (divisor) ); | ||
| 534 | return quotient; | ||
| 535 | } | ||
| 536 | |||
| 537 | static void kvm_set_time_scale(uint32_t tsc_khz, struct pvclock_vcpu_time_info *hv_clock) | ||
| 538 | { | ||
| 539 | uint64_t nsecs = 1000000000LL; | ||
| 540 | int32_t shift = 0; | ||
| 541 | uint64_t tps64; | ||
| 542 | uint32_t tps32; | ||
| 543 | |||
| 544 | tps64 = tsc_khz * 1000LL; | ||
| 545 | while (tps64 > nsecs*2) { | ||
| 546 | tps64 >>= 1; | ||
| 547 | shift--; | ||
| 548 | } | ||
| 549 | |||
| 550 | tps32 = (uint32_t)tps64; | ||
| 551 | while (tps32 <= (uint32_t)nsecs) { | ||
| 552 | tps32 <<= 1; | ||
| 553 | shift++; | ||
| 554 | } | ||
| 555 | |||
| 556 | hv_clock->tsc_shift = shift; | ||
| 557 | hv_clock->tsc_to_system_mul = div_frac(nsecs, tps32); | ||
| 558 | |||
| 559 | pr_debug("%s: tsc_khz %u, tsc_shift %d, tsc_mul %u\n", | ||
| 560 | __FUNCTION__, tsc_khz, hv_clock->tsc_shift, | ||
| 561 | hv_clock->tsc_to_system_mul); | ||
| 562 | } | ||
| 563 | |||
| 516 | static void kvm_write_guest_time(struct kvm_vcpu *v) | 564 | static void kvm_write_guest_time(struct kvm_vcpu *v) |
| 517 | { | 565 | { |
| 518 | struct timespec ts; | 566 | struct timespec ts; |
| @@ -523,6 +571,11 @@ static void kvm_write_guest_time(struct kvm_vcpu *v) | |||
| 523 | if ((!vcpu->time_page)) | 571 | if ((!vcpu->time_page)) |
| 524 | return; | 572 | return; |
| 525 | 573 | ||
| 574 | if (unlikely(vcpu->hv_clock_tsc_khz != tsc_khz)) { | ||
| 575 | kvm_set_time_scale(tsc_khz, &vcpu->hv_clock); | ||
| 576 | vcpu->hv_clock_tsc_khz = tsc_khz; | ||
| 577 | } | ||
| 578 | |||
| 526 | /* Keep irq disabled to prevent changes to the clock */ | 579 | /* Keep irq disabled to prevent changes to the clock */ |
| 527 | local_irq_save(flags); | 580 | local_irq_save(flags); |
| 528 | kvm_get_msr(v, MSR_IA32_TIME_STAMP_COUNTER, | 581 | kvm_get_msr(v, MSR_IA32_TIME_STAMP_COUNTER, |
| @@ -537,14 +590,14 @@ static void kvm_write_guest_time(struct kvm_vcpu *v) | |||
| 537 | /* | 590 | /* |
| 538 | * The interface expects us to write an even number signaling that the | 591 | * The interface expects us to write an even number signaling that the |
| 539 | * update is finished. Since the guest won't see the intermediate | 592 | * update is finished. Since the guest won't see the intermediate |
| 540 | * state, we just write "2" at the end | 593 | * state, we just increase by 2 at the end. |
| 541 | */ | 594 | */ |
| 542 | vcpu->hv_clock.version = 2; | 595 | vcpu->hv_clock.version += 2; |
| 543 | 596 | ||
| 544 | shared_kaddr = kmap_atomic(vcpu->time_page, KM_USER0); | 597 | shared_kaddr = kmap_atomic(vcpu->time_page, KM_USER0); |
| 545 | 598 | ||
| 546 | memcpy(shared_kaddr + vcpu->time_offset, &vcpu->hv_clock, | 599 | memcpy(shared_kaddr + vcpu->time_offset, &vcpu->hv_clock, |
| 547 | sizeof(vcpu->hv_clock)); | 600 | sizeof(vcpu->hv_clock)); |
| 548 | 601 | ||
| 549 | kunmap_atomic(shared_kaddr, KM_USER0); | 602 | kunmap_atomic(shared_kaddr, KM_USER0); |
| 550 | 603 | ||
| @@ -599,10 +652,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) | |||
| 599 | /* ...but clean it before doing the actual write */ | 652 | /* ...but clean it before doing the actual write */ |
| 600 | vcpu->arch.time_offset = data & ~(PAGE_MASK | 1); | 653 | vcpu->arch.time_offset = data & ~(PAGE_MASK | 1); |
| 601 | 654 | ||
| 602 | vcpu->arch.hv_clock.tsc_to_system_mul = | ||
| 603 | clocksource_khz2mult(tsc_khz, 22); | ||
| 604 | vcpu->arch.hv_clock.tsc_shift = 22; | ||
| 605 | |||
| 606 | down_read(¤t->mm->mmap_sem); | 655 | down_read(¤t->mm->mmap_sem); |
| 607 | vcpu->arch.time_page = | 656 | vcpu->arch.time_page = |
| 608 | gfn_to_page(vcpu->kvm, data >> PAGE_SHIFT); | 657 | gfn_to_page(vcpu->kvm, data >> PAGE_SHIFT); |
| @@ -2758,7 +2807,9 @@ again: | |||
| 2758 | 2807 | ||
| 2759 | if (vcpu->requests) { | 2808 | if (vcpu->requests) { |
| 2760 | if (test_and_clear_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests)) | 2809 | if (test_and_clear_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests)) |
| 2761 | __kvm_migrate_apic_timer(vcpu); | 2810 | __kvm_migrate_timers(vcpu); |
| 2811 | if (test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests)) | ||
| 2812 | kvm_x86_ops->tlb_flush(vcpu); | ||
| 2762 | if (test_and_clear_bit(KVM_REQ_REPORT_TPR_ACCESS, | 2813 | if (test_and_clear_bit(KVM_REQ_REPORT_TPR_ACCESS, |
| 2763 | &vcpu->requests)) { | 2814 | &vcpu->requests)) { |
| 2764 | kvm_run->exit_reason = KVM_EXIT_TPR_ACCESS; | 2815 | kvm_run->exit_reason = KVM_EXIT_TPR_ACCESS; |
| @@ -2772,6 +2823,7 @@ again: | |||
| 2772 | } | 2823 | } |
| 2773 | } | 2824 | } |
| 2774 | 2825 | ||
| 2826 | clear_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests); | ||
| 2775 | kvm_inject_pending_timer_irqs(vcpu); | 2827 | kvm_inject_pending_timer_irqs(vcpu); |
| 2776 | 2828 | ||
| 2777 | preempt_disable(); | 2829 | preempt_disable(); |
| @@ -2781,21 +2833,13 @@ again: | |||
| 2781 | 2833 | ||
| 2782 | local_irq_disable(); | 2834 | local_irq_disable(); |
| 2783 | 2835 | ||
| 2784 | if (need_resched()) { | 2836 | if (vcpu->requests || need_resched()) { |
| 2785 | local_irq_enable(); | 2837 | local_irq_enable(); |
| 2786 | preempt_enable(); | 2838 | preempt_enable(); |
| 2787 | r = 1; | 2839 | r = 1; |
| 2788 | goto out; | 2840 | goto out; |
| 2789 | } | 2841 | } |
| 2790 | 2842 | ||
| 2791 | if (vcpu->requests) | ||
| 2792 | if (test_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests)) { | ||
| 2793 | local_irq_enable(); | ||
| 2794 | preempt_enable(); | ||
| 2795 | r = 1; | ||
| 2796 | goto out; | ||
| 2797 | } | ||
| 2798 | |||
| 2799 | if (signal_pending(current)) { | 2843 | if (signal_pending(current)) { |
| 2800 | local_irq_enable(); | 2844 | local_irq_enable(); |
| 2801 | preempt_enable(); | 2845 | preempt_enable(); |
| @@ -2825,9 +2869,6 @@ again: | |||
| 2825 | 2869 | ||
| 2826 | kvm_guest_enter(); | 2870 | kvm_guest_enter(); |
| 2827 | 2871 | ||
| 2828 | if (vcpu->requests) | ||
| 2829 | if (test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests)) | ||
| 2830 | kvm_x86_ops->tlb_flush(vcpu); | ||
| 2831 | 2872 | ||
| 2832 | KVMTRACE_0D(VMENTRY, vcpu, entryexit); | 2873 | KVMTRACE_0D(VMENTRY, vcpu, entryexit); |
| 2833 | kvm_x86_ops->run(vcpu, kvm_run); | 2874 | kvm_x86_ops->run(vcpu, kvm_run); |
