aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTang Chen <tangchen@cn.fujitsu.com>2014-09-16 06:41:58 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-09-17 07:10:11 -0400
commita255d4795f83cf3e6a1c7d5ab998392d9413298c (patch)
tree79c39a27f4b9e3eb0707e6726d11b80397b6d996
parent80ce1639727e9d38729c34f162378508c307ca25 (diff)
kvm: Remove ept_identity_pagetable from struct kvm_arch.
kvm_arch->ept_identity_pagetable holds the ept identity pagetable page. But it is never used to refer to the page at all. In vcpu initialization, it indicates two things: 1. indicates if ept page is allocated 2. indicates if a memory slot for identity page is initialized Actually, kvm_arch->ept_identity_pagetable_done is enough to tell if the ept identity pagetable is initialized. So we can remove ept_identity_pagetable. NOTE: In the original code, ept identity pagetable page is pinned in memroy. As a result, it cannot be migrated/hot-removed. After this patch, since kvm_arch->ept_identity_pagetable is removed, ept identity pagetable page is no longer pinned in memory. And it can be migrated/hot-removed. Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com> Reviewed-by: Gleb Natapov <gleb@kernel.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/include/asm/kvm_host.h1
-rw-r--r--arch/x86/kvm/vmx.c47
-rw-r--r--arch/x86/kvm/x86.c2
3 files changed, 22 insertions, 28 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 2dbde3b7446c..028df8dc538e 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -578,7 +578,6 @@ struct kvm_arch {
578 578
579 gpa_t wall_clock; 579 gpa_t wall_clock;
580 580
581 struct page *ept_identity_pagetable;
582 bool ept_identity_pagetable_done; 581 bool ept_identity_pagetable_done;
583 gpa_t ept_identity_map_addr; 582 gpa_t ept_identity_map_addr;
584 583
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 5db47db6574b..5de0d7b1d8a9 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -767,6 +767,7 @@ static u32 vmx_segment_access_rights(struct kvm_segment *var);
767static void vmx_sync_pir_to_irr_dummy(struct kvm_vcpu *vcpu); 767static void vmx_sync_pir_to_irr_dummy(struct kvm_vcpu *vcpu);
768static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx); 768static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx);
769static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx); 769static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx);
770static int alloc_identity_pagetable(struct kvm *kvm);
770 771
771static DEFINE_PER_CPU(struct vmcs *, vmxarea); 772static DEFINE_PER_CPU(struct vmcs *, vmxarea);
772static DEFINE_PER_CPU(struct vmcs *, current_vmcs); 773static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
@@ -3962,21 +3963,27 @@ out:
3962 3963
3963static int init_rmode_identity_map(struct kvm *kvm) 3964static int init_rmode_identity_map(struct kvm *kvm)
3964{ 3965{
3965 int i, idx, r, ret; 3966 int i, idx, r, ret = 0;
3966 pfn_t identity_map_pfn; 3967 pfn_t identity_map_pfn;
3967 u32 tmp; 3968 u32 tmp;
3968 3969
3969 if (!enable_ept) 3970 if (!enable_ept)
3970 return 1; 3971 return 1;
3971 if (unlikely(!kvm->arch.ept_identity_pagetable)) { 3972
3972 printk(KERN_ERR "EPT: identity-mapping pagetable " 3973 /* Protect kvm->arch.ept_identity_pagetable_done. */
3973 "haven't been allocated!\n"); 3974 mutex_lock(&kvm->slots_lock);
3974 return 0; 3975
3976 if (likely(kvm->arch.ept_identity_pagetable_done)) {
3977 ret = 1;
3978 goto out2;
3975 } 3979 }
3976 if (likely(kvm->arch.ept_identity_pagetable_done)) 3980
3977 return 1;
3978 ret = 0;
3979 identity_map_pfn = kvm->arch.ept_identity_map_addr >> PAGE_SHIFT; 3981 identity_map_pfn = kvm->arch.ept_identity_map_addr >> PAGE_SHIFT;
3982
3983 r = alloc_identity_pagetable(kvm);
3984 if (r)
3985 goto out2;
3986
3980 idx = srcu_read_lock(&kvm->srcu); 3987 idx = srcu_read_lock(&kvm->srcu);
3981 r = kvm_clear_guest_page(kvm, identity_map_pfn, 0, PAGE_SIZE); 3988 r = kvm_clear_guest_page(kvm, identity_map_pfn, 0, PAGE_SIZE);
3982 if (r < 0) 3989 if (r < 0)
@@ -3994,6 +4001,9 @@ static int init_rmode_identity_map(struct kvm *kvm)
3994 ret = 1; 4001 ret = 1;
3995out: 4002out:
3996 srcu_read_unlock(&kvm->srcu, idx); 4003 srcu_read_unlock(&kvm->srcu, idx);
4004
4005out2:
4006 mutex_unlock(&kvm->slots_lock);
3997 return ret; 4007 return ret;
3998} 4008}
3999 4009
@@ -4043,31 +4053,20 @@ out:
4043 4053
4044static int alloc_identity_pagetable(struct kvm *kvm) 4054static int alloc_identity_pagetable(struct kvm *kvm)
4045{ 4055{
4046 struct page *page; 4056 /* Called with kvm->slots_lock held. */
4057
4047 struct kvm_userspace_memory_region kvm_userspace_mem; 4058 struct kvm_userspace_memory_region kvm_userspace_mem;
4048 int r = 0; 4059 int r = 0;
4049 4060
4050 mutex_lock(&kvm->slots_lock); 4061 BUG_ON(kvm->arch.ept_identity_pagetable_done);
4051 if (kvm->arch.ept_identity_pagetable) 4062
4052 goto out;
4053 kvm_userspace_mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT; 4063 kvm_userspace_mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT;
4054 kvm_userspace_mem.flags = 0; 4064 kvm_userspace_mem.flags = 0;
4055 kvm_userspace_mem.guest_phys_addr = 4065 kvm_userspace_mem.guest_phys_addr =
4056 kvm->arch.ept_identity_map_addr; 4066 kvm->arch.ept_identity_map_addr;
4057 kvm_userspace_mem.memory_size = PAGE_SIZE; 4067 kvm_userspace_mem.memory_size = PAGE_SIZE;
4058 r = __kvm_set_memory_region(kvm, &kvm_userspace_mem); 4068 r = __kvm_set_memory_region(kvm, &kvm_userspace_mem);
4059 if (r)
4060 goto out;
4061
4062 page = gfn_to_page(kvm, kvm->arch.ept_identity_map_addr >> PAGE_SHIFT);
4063 if (is_error_page(page)) {
4064 r = -EFAULT;
4065 goto out;
4066 }
4067 4069
4068 kvm->arch.ept_identity_pagetable = page;
4069out:
4070 mutex_unlock(&kvm->slots_lock);
4071 return r; 4070 return r;
4072} 4071}
4073 4072
@@ -7758,8 +7757,6 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
7758 kvm->arch.ept_identity_map_addr = 7757 kvm->arch.ept_identity_map_addr =
7759 VMX_EPT_IDENTITY_PAGETABLE_ADDR; 7758 VMX_EPT_IDENTITY_PAGETABLE_ADDR;
7760 err = -ENOMEM; 7759 err = -ENOMEM;
7761 if (alloc_identity_pagetable(kvm) != 0)
7762 goto free_vmcs;
7763 if (!init_rmode_identity_map(kvm)) 7760 if (!init_rmode_identity_map(kvm))
7764 goto free_vmcs; 7761 goto free_vmcs;
7765 } 7762 }
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 68660b31457e..2d7f65daa8d0 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -7273,8 +7273,6 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
7273 kvm_free_vcpus(kvm); 7273 kvm_free_vcpus(kvm);
7274 if (kvm->arch.apic_access_page) 7274 if (kvm->arch.apic_access_page)
7275 put_page(kvm->arch.apic_access_page); 7275 put_page(kvm->arch.apic_access_page);
7276 if (kvm->arch.ept_identity_pagetable)
7277 put_page(kvm->arch.ept_identity_pagetable);
7278 kfree(rcu_dereference_check(kvm->arch.apic_map, 1)); 7276 kfree(rcu_dereference_check(kvm->arch.apic_map, 1));
7279} 7277}
7280 7278