diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/kvm/kvm.h | 1 | ||||
-rw-r--r-- | drivers/kvm/svm.c | 21 |
2 files changed, 18 insertions, 4 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index f5e343cb06b0..6d0bd7aab92e 100644 --- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h | |||
@@ -244,6 +244,7 @@ struct kvm_vcpu { | |||
244 | struct mutex mutex; | 244 | struct mutex mutex; |
245 | int cpu; | 245 | int cpu; |
246 | int launched; | 246 | int launched; |
247 | u64 host_tsc; | ||
247 | struct kvm_run *run; | 248 | struct kvm_run *run; |
248 | int interrupt_window_open; | 249 | int interrupt_window_open; |
249 | unsigned long irq_summary; /* bit vector: 1 per word in irq_pending */ | 250 | unsigned long irq_summary; /* bit vector: 1 per word in irq_pending */ |
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c index 0542d3357ce1..ca2642fc091f 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c | |||
@@ -459,7 +459,6 @@ static void init_vmcb(struct vmcb *vmcb) | |||
459 | { | 459 | { |
460 | struct vmcb_control_area *control = &vmcb->control; | 460 | struct vmcb_control_area *control = &vmcb->control; |
461 | struct vmcb_save_area *save = &vmcb->save; | 461 | struct vmcb_save_area *save = &vmcb->save; |
462 | u64 tsc; | ||
463 | 462 | ||
464 | control->intercept_cr_read = INTERCEPT_CR0_MASK | | 463 | control->intercept_cr_read = INTERCEPT_CR0_MASK | |
465 | INTERCEPT_CR3_MASK | | 464 | INTERCEPT_CR3_MASK | |
@@ -517,8 +516,7 @@ static void init_vmcb(struct vmcb *vmcb) | |||
517 | 516 | ||
518 | control->iopm_base_pa = iopm_base; | 517 | control->iopm_base_pa = iopm_base; |
519 | control->msrpm_base_pa = msrpm_base; | 518 | control->msrpm_base_pa = msrpm_base; |
520 | rdtscll(tsc); | 519 | control->tsc_offset = 0; |
521 | control->tsc_offset = -tsc; | ||
522 | control->int_ctl = V_INTR_MASKING_MASK; | 520 | control->int_ctl = V_INTR_MASKING_MASK; |
523 | 521 | ||
524 | init_seg(&save->es); | 522 | init_seg(&save->es); |
@@ -606,11 +604,26 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu) | |||
606 | 604 | ||
607 | static void svm_vcpu_load(struct kvm_vcpu *vcpu) | 605 | static void svm_vcpu_load(struct kvm_vcpu *vcpu) |
608 | { | 606 | { |
609 | get_cpu(); | 607 | int cpu; |
608 | |||
609 | cpu = get_cpu(); | ||
610 | if (unlikely(cpu != vcpu->cpu)) { | ||
611 | u64 tsc_this, delta; | ||
612 | |||
613 | /* | ||
614 | * Make sure that the guest sees a monotonically | ||
615 | * increasing TSC. | ||
616 | */ | ||
617 | rdtscll(tsc_this); | ||
618 | delta = vcpu->host_tsc - tsc_this; | ||
619 | vcpu->svm->vmcb->control.tsc_offset += delta; | ||
620 | vcpu->cpu = cpu; | ||
621 | } | ||
610 | } | 622 | } |
611 | 623 | ||
612 | static void svm_vcpu_put(struct kvm_vcpu *vcpu) | 624 | static void svm_vcpu_put(struct kvm_vcpu *vcpu) |
613 | { | 625 | { |
626 | rdtscll(vcpu->host_tsc); | ||
614 | put_cpu(); | 627 | put_cpu(); |
615 | } | 628 | } |
616 | 629 | ||