diff options
author | Avi Kivity <avi@redhat.com> | 2009-05-31 15:58:47 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-09-10 01:32:46 -0400 |
commit | 6de4f3ada40b336522250a7832a0cc4de8856589 (patch) | |
tree | 90920846774aa0fb0fb47ac245fcf5f8b73afcee /arch/x86/kvm/svm.c | |
parent | 8f5d549f028056d6ad6044f2d9e27ecf361d955e (diff) |
KVM: Cache pdptrs
Instead of reloading the pdptrs on every entry and exit (vmcs writes on vmx,
guest memory access on svm) extract them on demand.
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r-- | arch/x86/kvm/svm.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 522e69597a16..7749b0692cb2 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -777,6 +777,18 @@ static void svm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) | |||
777 | to_svm(vcpu)->vmcb->save.rflags = rflags; | 777 | to_svm(vcpu)->vmcb->save.rflags = rflags; |
778 | } | 778 | } |
779 | 779 | ||
780 | static void svm_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg) | ||
781 | { | ||
782 | switch (reg) { | ||
783 | case VCPU_EXREG_PDPTR: | ||
784 | BUG_ON(!npt_enabled); | ||
785 | load_pdptrs(vcpu, vcpu->arch.cr3); | ||
786 | break; | ||
787 | default: | ||
788 | BUG(); | ||
789 | } | ||
790 | } | ||
791 | |||
780 | static void svm_set_vintr(struct vcpu_svm *svm) | 792 | static void svm_set_vintr(struct vcpu_svm *svm) |
781 | { | 793 | { |
782 | svm->vmcb->control.intercept |= 1ULL << INTERCEPT_VINTR; | 794 | svm->vmcb->control.intercept |= 1ULL << INTERCEPT_VINTR; |
@@ -2285,12 +2297,6 @@ static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
2285 | } | 2297 | } |
2286 | vcpu->arch.cr0 = svm->vmcb->save.cr0; | 2298 | vcpu->arch.cr0 = svm->vmcb->save.cr0; |
2287 | vcpu->arch.cr3 = svm->vmcb->save.cr3; | 2299 | vcpu->arch.cr3 = svm->vmcb->save.cr3; |
2288 | if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { | ||
2289 | if (!load_pdptrs(vcpu, vcpu->arch.cr3)) { | ||
2290 | kvm_inject_gp(vcpu, 0); | ||
2291 | return 1; | ||
2292 | } | ||
2293 | } | ||
2294 | if (mmu_reload) { | 2300 | if (mmu_reload) { |
2295 | kvm_mmu_reset_context(vcpu); | 2301 | kvm_mmu_reset_context(vcpu); |
2296 | kvm_mmu_load(vcpu); | 2302 | kvm_mmu_load(vcpu); |
@@ -2641,6 +2647,11 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
2641 | 2647 | ||
2642 | svm->next_rip = 0; | 2648 | svm->next_rip = 0; |
2643 | 2649 | ||
2650 | if (npt_enabled) { | ||
2651 | vcpu->arch.regs_avail &= ~(1 << VCPU_EXREG_PDPTR); | ||
2652 | vcpu->arch.regs_dirty &= ~(1 << VCPU_EXREG_PDPTR); | ||
2653 | } | ||
2654 | |||
2644 | svm_complete_interrupts(svm); | 2655 | svm_complete_interrupts(svm); |
2645 | } | 2656 | } |
2646 | 2657 | ||
@@ -2749,6 +2760,7 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
2749 | .set_gdt = svm_set_gdt, | 2760 | .set_gdt = svm_set_gdt, |
2750 | .get_dr = svm_get_dr, | 2761 | .get_dr = svm_get_dr, |
2751 | .set_dr = svm_set_dr, | 2762 | .set_dr = svm_set_dr, |
2763 | .cache_reg = svm_cache_reg, | ||
2752 | .get_rflags = svm_get_rflags, | 2764 | .get_rflags = svm_get_rflags, |
2753 | .set_rflags = svm_set_rflags, | 2765 | .set_rflags = svm_set_rflags, |
2754 | 2766 | ||