diff options
Diffstat (limited to 'drivers/kvm/mmu.c')
-rw-r--r-- | drivers/kvm/mmu.c | 43 |
1 files changed, 22 insertions, 21 deletions
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 | ||
975 | static void inject_page_fault(struct kvm_vcpu *vcpu, | 968 | static 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 | ||
1065 | int kvm_mmu_reset_context(struct kvm_vcpu *vcpu) | 1051 | int kvm_mmu_reset_context(struct kvm_vcpu *vcpu) |
1066 | { | 1052 | { |
1053 | destroy_kvm_mmu(vcpu); | ||
1054 | return init_kvm_mmu(vcpu); | ||
1055 | } | ||
1056 | |||
1057 | int 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); | ||
1074 | out: | 1068 | out: |
1069 | spin_unlock(&vcpu->kvm->lock); | ||
1075 | return r; | 1070 | return r; |
1076 | } | 1071 | } |
1072 | EXPORT_SYMBOL_GPL(kvm_mmu_load); | ||
1073 | |||
1074 | void kvm_mmu_unload(struct kvm_vcpu *vcpu) | ||
1075 | { | ||
1076 | mmu_free_roots(vcpu); | ||
1077 | } | ||
1077 | 1078 | ||
1078 | static void mmu_pte_write_zap_pte(struct kvm_vcpu *vcpu, | 1079 | static void mmu_pte_write_zap_pte(struct kvm_vcpu *vcpu, |
1079 | struct kvm_mmu_page *page, | 1080 | struct kvm_mmu_page *page, |