aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/kvm/kvm.h10
-rw-r--r--drivers/kvm/mmu.c43
-rw-r--r--drivers/kvm/svm.c4
-rw-r--r--drivers/kvm/vmx.c4
4 files changed, 40 insertions, 21 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 199e1e9bae25..3ec4e26b9bd7 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -544,6 +544,8 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
544 const u8 *old, const u8 *new, int bytes); 544 const u8 *old, const u8 *new, int bytes);
545int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva); 545int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva);
546void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu); 546void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu);
547int kvm_mmu_load(struct kvm_vcpu *vcpu);
548void kvm_mmu_unload(struct kvm_vcpu *vcpu);
547 549
548int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run); 550int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run);
549 551
@@ -555,6 +557,14 @@ static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
555 return vcpu->mmu.page_fault(vcpu, gva, error_code); 557 return vcpu->mmu.page_fault(vcpu, gva, error_code);
556} 558}
557 559
560static inline int kvm_mmu_reload(struct kvm_vcpu *vcpu)
561{
562 if (likely(vcpu->mmu.root_hpa != INVALID_PAGE))
563 return 0;
564
565 return kvm_mmu_load(vcpu);
566}
567
558static inline int is_long_mode(struct kvm_vcpu *vcpu) 568static inline int is_long_mode(struct kvm_vcpu *vcpu)
559{ 569{
560#ifdef CONFIG_X86_64 570#ifdef CONFIG_X86_64
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
index 283df031b03d..5915d7a1c4f7 100644
--- a/drivers/kvm/mmu.c
+++ b/drivers/kvm/mmu.c
@@ -949,9 +949,7 @@ static int nonpaging_init_context(struct kvm_vcpu *vcpu)
949 context->free = nonpaging_free; 949 context->free = nonpaging_free;
950 context->root_level = 0; 950 context->root_level = 0;
951 context->shadow_root_level = PT32E_ROOT_LEVEL; 951 context->shadow_root_level = PT32E_ROOT_LEVEL;
952 mmu_alloc_roots(vcpu); 952 context->root_hpa = INVALID_PAGE;
953 ASSERT(VALID_PAGE(context->root_hpa));
954 kvm_arch_ops->set_cr3(vcpu, context->root_hpa);
955 return 0; 953 return 0;
956} 954}
957 955
@@ -965,11 +963,6 @@ static void paging_new_cr3(struct kvm_vcpu *vcpu)
965{ 963{
966 pgprintk("%s: cr3 %lx\n", __FUNCTION__, vcpu->cr3); 964 pgprintk("%s: cr3 %lx\n", __FUNCTION__, vcpu->cr3);
967 mmu_free_roots(vcpu); 965 mmu_free_roots(vcpu);
968 if (unlikely(vcpu->kvm->n_free_mmu_pages < KVM_MIN_FREE_MMU_PAGES))
969 kvm_mmu_free_some_pages(vcpu);
970 mmu_alloc_roots(vcpu);
971 kvm_mmu_flush_tlb(vcpu);
972 kvm_arch_ops->set_cr3(vcpu, vcpu->mmu.root_hpa);
973} 966}
974 967
975static void inject_page_fault(struct kvm_vcpu *vcpu, 968static void inject_page_fault(struct kvm_vcpu *vcpu,
@@ -1003,10 +996,7 @@ static int paging64_init_context_common(struct kvm_vcpu *vcpu, int level)
1003 context->free = paging_free; 996 context->free = paging_free;
1004 context->root_level = level; 997 context->root_level = level;
1005 context->shadow_root_level = level; 998 context->shadow_root_level = level;
1006 mmu_alloc_roots(vcpu); 999 context->root_hpa = INVALID_PAGE;
1007 ASSERT(VALID_PAGE(context->root_hpa));
1008 kvm_arch_ops->set_cr3(vcpu, context->root_hpa |
1009 (vcpu->cr3 & (CR3_PCD_MASK | CR3_WPT_MASK)));
1010 return 0; 1000 return 0;
1011} 1001}
1012 1002
@@ -1025,10 +1015,7 @@ static int paging32_init_context(struct kvm_vcpu *vcpu)
1025 context->free = paging_free; 1015 context->free = paging_free;
1026 context->root_level = PT32_ROOT_LEVEL; 1016 context->root_level = PT32_ROOT_LEVEL;
1027 context->shadow_root_level = PT32E_ROOT_LEVEL; 1017 context->shadow_root_level = PT32E_ROOT_LEVEL;
1028 mmu_alloc_roots(vcpu); 1018 context->root_hpa = INVALID_PAGE;
1029 ASSERT(VALID_PAGE(context->root_hpa));
1030 kvm_arch_ops->set_cr3(vcpu, context->root_hpa |
1031 (vcpu->cr3 & (CR3_PCD_MASK | CR3_WPT_MASK)));
1032 return 0; 1019 return 0;
1033} 1020}
1034 1021
@@ -1042,7 +1029,6 @@ static int init_kvm_mmu(struct kvm_vcpu *vcpu)
1042 ASSERT(vcpu); 1029 ASSERT(vcpu);
1043 ASSERT(!VALID_PAGE(vcpu->mmu.root_hpa)); 1030 ASSERT(!VALID_PAGE(vcpu->mmu.root_hpa));
1044 1031
1045 mmu_topup_memory_caches(vcpu);
1046 if (!is_paging(vcpu)) 1032 if (!is_paging(vcpu))
1047 return nonpaging_init_context(vcpu); 1033 return nonpaging_init_context(vcpu);
1048 else if (is_long_mode(vcpu)) 1034 else if (is_long_mode(vcpu))
@@ -1064,16 +1050,31 @@ static void destroy_kvm_mmu(struct kvm_vcpu *vcpu)
1064 1050
1065int kvm_mmu_reset_context(struct kvm_vcpu *vcpu) 1051int kvm_mmu_reset_context(struct kvm_vcpu *vcpu)
1066{ 1052{
1053 destroy_kvm_mmu(vcpu);
1054 return init_kvm_mmu(vcpu);
1055}
1056
1057int kvm_mmu_load(struct kvm_vcpu *vcpu)
1058{
1067 int r; 1059 int r;
1068 1060
1069 destroy_kvm_mmu(vcpu); 1061 spin_lock(&vcpu->kvm->lock);
1070 r = init_kvm_mmu(vcpu);
1071 if (r < 0)
1072 goto out;
1073 r = mmu_topup_memory_caches(vcpu); 1062 r = mmu_topup_memory_caches(vcpu);
1063 if (r)
1064 goto out;
1065 mmu_alloc_roots(vcpu);
1066 kvm_arch_ops->set_cr3(vcpu, vcpu->mmu.root_hpa);
1067 kvm_mmu_flush_tlb(vcpu);
1074out: 1068out:
1069 spin_unlock(&vcpu->kvm->lock);
1075 return r; 1070 return r;
1076} 1071}
1072EXPORT_SYMBOL_GPL(kvm_mmu_load);
1073
1074void kvm_mmu_unload(struct kvm_vcpu *vcpu)
1075{
1076 mmu_free_roots(vcpu);
1077}
1077 1078
1078static void mmu_pte_write_zap_pte(struct kvm_vcpu *vcpu, 1079static void mmu_pte_write_zap_pte(struct kvm_vcpu *vcpu,
1079 struct kvm_mmu_page *page, 1080 struct kvm_mmu_page *page,
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 6cd6a50a0340..ec040e2f8c58 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -1483,6 +1483,10 @@ static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1483 int r; 1483 int r;
1484 1484
1485again: 1485again:
1486 r = kvm_mmu_reload(vcpu);
1487 if (unlikely(r))
1488 return r;
1489
1486 if (!vcpu->mmio_read_completed) 1490 if (!vcpu->mmio_read_completed)
1487 do_interrupt_requests(vcpu, kvm_run); 1491 do_interrupt_requests(vcpu, kvm_run);
1488 1492
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 93e5bb2c40e3..4d255493a57e 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1988,6 +1988,10 @@ again:
1988 vmx_save_host_state(vcpu); 1988 vmx_save_host_state(vcpu);
1989 kvm_load_guest_fpu(vcpu); 1989 kvm_load_guest_fpu(vcpu);
1990 1990
1991 r = kvm_mmu_reload(vcpu);
1992 if (unlikely(r))
1993 goto out;
1994
1991 /* 1995 /*
1992 * Loading guest fpu may have cleared host cr0.ts 1996 * Loading guest fpu may have cleared host cr0.ts
1993 */ 1997 */