linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/9] KVM: cleanups for memslots data structures
@ 2015-05-19 17:25 Paolo Bonzini
  2015-05-19 17:25 ` [PATCH 1/9] KVM: introduce kvm_alloc/free_memslots Paolo Bonzini
                   ` (9 more replies)
  0 siblings, 10 replies; 16+ messages in thread
From: Paolo Bonzini @ 2015-05-19 17:25 UTC (permalink / raw)
  To: linux-kernel, kvm; +Cc: Takuya Yoshikawa, Xiao Guangrong, rkrcmar

These are extracted out of the SMM series, and they make
some sense on their own.

Paolo

Paolo Bonzini (9):
  KVM: introduce kvm_alloc/free_memslots
  KVM: use kvm_memslots whenever possible
  KVM: const-ify uses of struct kvm_userspace_memory_region
  KVM: add memslots argument to kvm_arch_memslots_updated
  KVM: add "new" argument to kvm_arch_commit_memory_region
  KVM: pass kvm_memory_slot to gfn_to_page_many_atomic
  KVM: remove __gfn_to_pfn
  KVM: x86: pass kvm_mmu_page to gfn_to_rmap
  KVM: x86: pass struct kvm_mmu_page to account/unaccount_shadowed

 arch/arm/kvm/mmu.c                  |  10 +-
 arch/mips/include/asm/kvm_host.h    |   2 +-
 arch/mips/kvm/mips.c                |   9 +-
 arch/powerpc/include/asm/kvm_host.h |   2 +-
 arch/powerpc/include/asm/kvm_ppc.h  |  14 +--
 arch/powerpc/kvm/book3s.c           |   9 +-
 arch/powerpc/kvm/book3s_64_mmu_hv.c |   2 +-
 arch/powerpc/kvm/book3s_hv.c        |  15 ++-
 arch/powerpc/kvm/book3s_pr.c        |  11 ++-
 arch/powerpc/kvm/booke.c            |   7 +-
 arch/powerpc/kvm/powerpc.c          |   7 +-
 arch/s390/include/asm/kvm_host.h    |   2 +-
 arch/s390/kvm/kvm-s390.c            |   9 +-
 arch/x86/include/asm/kvm_host.h     |   2 +-
 arch/x86/kvm/mmu.c                  |  34 ++++---
 arch/x86/kvm/mmu_audit.c            |   7 +-
 arch/x86/kvm/x86.c                  |  17 ++--
 include/linux/kvm_host.h            |  15 +--
 include/linux/kvm_types.h           |   1 +
 virt/kvm/kvm_main.c                 | 191 ++++++++++++++++++------------------
 20 files changed, 199 insertions(+), 167 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/9] KVM: introduce kvm_alloc/free_memslots
  2015-05-19 17:25 [PATCH 0/9] KVM: cleanups for memslots data structures Paolo Bonzini
@ 2015-05-19 17:25 ` Paolo Bonzini
  2015-05-20  7:38   ` Takuya Yoshikawa
  2015-05-19 17:25 ` [PATCH 2/9] KVM: use kvm_memslots whenever possible Paolo Bonzini
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 16+ messages in thread
From: Paolo Bonzini @ 2015-05-19 17:25 UTC (permalink / raw)
  To: linux-kernel, kvm; +Cc: Takuya Yoshikawa, Xiao Guangrong, rkrcmar

kvm_alloc_memslots is extracted out of previously scattered code
that was in kvm_init_memslots_id and kvm_create_vm.

kvm_free_memslot and kvm_free_memslots are new names of
kvm_free_physmem and kvm_free_physmem_slot, but they also take
an explicit pointer to struct kvm_memslots.

This will simplify the transition to multiple address spaces,
each represented by one pointer to struct kvm_memslots.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 virt/kvm/kvm_main.c | 104 +++++++++++++++++++++++++++-------------------------
 1 file changed, 55 insertions(+), 49 deletions(-)

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index bd3c08a7c6c2..e299763ef744 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -440,13 +440,60 @@ static int kvm_init_mmu_notifier(struct kvm *kvm)
 
 #endif /* CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER */
 
-static void kvm_init_memslots_id(struct kvm *kvm)
+static struct kvm_memslots *kvm_alloc_memslots(void)
 {
 	int i;
-	struct kvm_memslots *slots = kvm->memslots;
+	struct kvm_memslots *slots;
 
+	slots = kvm_kvzalloc(sizeof(struct kvm_memslots));
+	if (!slots)
+		return NULL;
+
+	/*
+	 * Init kvm generation close to the maximum to easily test the
+	 * code of handling generation number wrap-around.
+	 */
+	slots->generation = -150;
 	for (i = 0; i < KVM_MEM_SLOTS_NUM; i++)
 		slots->id_to_index[i] = slots->memslots[i].id = i;
+
+	return slots;
+}
+
+static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot)
+{
+	if (!memslot->dirty_bitmap)
+		return;
+
+	kvfree(memslot->dirty_bitmap);
+	memslot->dirty_bitmap = NULL;
+}
+
+/*
+ * Free any memory in @free but not in @dont.
+ */
+static void kvm_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free,
+			      struct kvm_memory_slot *dont)
+{
+	if (!dont || free->dirty_bitmap != dont->dirty_bitmap)
+		kvm_destroy_dirty_bitmap(free);
+
+	kvm_arch_free_memslot(kvm, free, dont);
+
+	free->npages = 0;
+}
+
+static void kvm_free_memslots(struct kvm *kvm, struct kvm_memslots *slots)
+{
+	struct kvm_memory_slot *memslot;
+
+	if (!slots)
+		return;
+
+	kvm_for_each_memslot(memslot, slots)
+		kvm_free_memslot(kvm, memslot, NULL);
+
+	kvfree(slots);
 }
 
 static struct kvm *kvm_create_vm(unsigned long type)
@@ -472,17 +519,10 @@ static struct kvm *kvm_create_vm(unsigned long type)
 	BUILD_BUG_ON(KVM_MEM_SLOTS_NUM > SHRT_MAX);
 
 	r = -ENOMEM;
-	kvm->memslots = kvm_kvzalloc(sizeof(struct kvm_memslots));
+	kvm->memslots = kvm_alloc_memslots();
 	if (!kvm->memslots)
 		goto out_err_no_srcu;
 
-	/*
-	 * Init kvm generation close to the maximum to easily test the
-	 * code of handling generation number wrap-around.
-	 */
-	kvm->memslots->generation = -150;
-
-	kvm_init_memslots_id(kvm);
 	if (init_srcu_struct(&kvm->srcu))
 		goto out_err_no_srcu;
 	if (init_srcu_struct(&kvm->irq_srcu))
@@ -523,7 +563,7 @@ out_err_no_srcu:
 out_err_no_disable:
 	for (i = 0; i < KVM_NR_BUSES; i++)
 		kfree(kvm->buses[i]);
-	kvfree(kvm->memslots);
+	kvm_free_memslots(kvm, kvm->memslots);
 	kvm_arch_free_vm(kvm);
 	return ERR_PTR(r);
 }
@@ -540,40 +580,6 @@ void *kvm_kvzalloc(unsigned long size)
 		return kzalloc(size, GFP_KERNEL);
 }
 
-static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot)
-{
-	if (!memslot->dirty_bitmap)
-		return;
-
-	kvfree(memslot->dirty_bitmap);
-	memslot->dirty_bitmap = NULL;
-}
-
-/*
- * Free any memory in @free but not in @dont.
- */
-static void kvm_free_physmem_slot(struct kvm *kvm, struct kvm_memory_slot *free,
-				  struct kvm_memory_slot *dont)
-{
-	if (!dont || free->dirty_bitmap != dont->dirty_bitmap)
-		kvm_destroy_dirty_bitmap(free);
-
-	kvm_arch_free_memslot(kvm, free, dont);
-
-	free->npages = 0;
-}
-
-static void kvm_free_physmem(struct kvm *kvm)
-{
-	struct kvm_memslots *slots = kvm->memslots;
-	struct kvm_memory_slot *memslot;
-
-	kvm_for_each_memslot(memslot, slots)
-		kvm_free_physmem_slot(kvm, memslot, NULL);
-
-	kvfree(kvm->memslots);
-}
-
 static void kvm_destroy_devices(struct kvm *kvm)
 {
 	struct list_head *node, *tmp;
@@ -607,7 +613,7 @@ static void kvm_destroy_vm(struct kvm *kvm)
 #endif
 	kvm_arch_destroy_vm(kvm);
 	kvm_destroy_devices(kvm);
-	kvm_free_physmem(kvm);
+	kvm_free_memslots(kvm, kvm->memslots);
 	cleanup_srcu_struct(&kvm->irq_srcu);
 	cleanup_srcu_struct(&kvm->srcu);
 	kvm_arch_free_vm(kvm);
@@ -898,7 +904,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
 	if (r)
 		goto out_slots;
 
-	/* actual memory is freed via old in kvm_free_physmem_slot below */
+	/* actual memory is freed via old in kvm_free_memslot below */
 	if (change == KVM_MR_DELETE) {
 		new.dirty_bitmap = NULL;
 		memset(&new.arch, 0, sizeof(new.arch));
@@ -909,7 +915,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
 
 	kvm_arch_commit_memory_region(kvm, mem, &old, change);
 
-	kvm_free_physmem_slot(kvm, &old, &new);
+	kvm_free_memslot(kvm, &old, &new);
 	kvfree(old_memslots);
 
 	/*
@@ -931,7 +937,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
 out_slots:
 	kvfree(slots);
 out_free:
-	kvm_free_physmem_slot(kvm, &new, &old);
+	kvm_free_memslot(kvm, &new, &old);
 out:
 	return r;
 }
-- 
1.8.3.1



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/9] KVM: use kvm_memslots whenever possible
  2015-05-19 17:25 [PATCH 0/9] KVM: cleanups for memslots data structures Paolo Bonzini
  2015-05-19 17:25 ` [PATCH 1/9] KVM: introduce kvm_alloc/free_memslots Paolo Bonzini
@ 2015-05-19 17:25 ` Paolo Bonzini
  2015-05-19 17:25 ` [PATCH 3/9] KVM: const-ify uses of struct kvm_userspace_memory_region Paolo Bonzini
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Paolo Bonzini @ 2015-05-19 17:25 UTC (permalink / raw)
  To: linux-kernel, kvm; +Cc: Takuya Yoshikawa, Xiao Guangrong, rkrcmar

kvm_memslots provides lockdep checking.  Use it consistently instead of
explicit dereferencing of kvm->memslots.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 arch/arm/kvm/mmu.c                  |  3 ++-
 arch/mips/kvm/mips.c                |  4 +++-
 arch/powerpc/kvm/book3s_64_mmu_hv.c |  2 +-
 arch/powerpc/kvm/book3s_hv.c        |  8 ++++++--
 arch/powerpc/kvm/book3s_pr.c        |  4 +++-
 arch/s390/kvm/kvm-s390.c            |  4 +++-
 arch/x86/kvm/x86.c                  |  4 +++-
 virt/kvm/kvm_main.c                 | 16 ++++++++++------
 8 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 1d5accbd3dcf..6f0f8f3ac7df 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -1155,7 +1155,8 @@ static void stage2_wp_range(struct kvm *kvm, phys_addr_t addr, phys_addr_t end)
  */
 void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot)
 {
-	struct kvm_memory_slot *memslot = id_to_memslot(kvm->memslots, slot);
+	struct kvm_memslots *slots = kvm_memslots(kvm);
+	struct kvm_memory_slot *memslot = id_to_memslot(slots, slot);
 	phys_addr_t start = memslot->base_gfn << PAGE_SHIFT;
 	phys_addr_t end = (memslot->base_gfn + memslot->npages) << PAGE_SHIFT;
 
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index a8e660a44474..bc5ddd973b44 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -968,6 +968,7 @@ out:
 /* Get (and clear) the dirty memory log for a memory slot. */
 int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
 {
+	struct kvm_memslots *slots;
 	struct kvm_memory_slot *memslot;
 	unsigned long ga, ga_end;
 	int is_dirty = 0;
@@ -982,7 +983,8 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
 
 	/* If nothing is dirty, don't bother messing with page tables. */
 	if (is_dirty) {
-		memslot = id_to_memslot(kvm->memslots, log->slot);
+		slots = kvm_memslots(kvm);
+		memslot = id_to_memslot(slots, log->slot);
 
 		ga = memslot->base_gfn << PAGE_SHIFT;
 		ga_end = ga + (memslot->npages << PAGE_SHIFT);
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index 1a4acf8bf4f4..dab68b7af3f2 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -650,7 +650,7 @@ static void kvmppc_rmap_reset(struct kvm *kvm)
 	int srcu_idx;
 
 	srcu_idx = srcu_read_lock(&kvm->srcu);
-	slots = kvm->memslots;
+	slots = kvm_memslots(kvm);
 	kvm_for_each_memslot(memslot, slots) {
 		/*
 		 * This assumes it is acceptable to lose reference and
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 48d3c5d2ecc9..7bc6137ece74 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -2320,6 +2320,7 @@ static int kvm_vm_ioctl_get_smmu_info_hv(struct kvm *kvm,
 static int kvm_vm_ioctl_get_dirty_log_hv(struct kvm *kvm,
 					 struct kvm_dirty_log *log)
 {
+	struct kvm_memslots *slots;
 	struct kvm_memory_slot *memslot;
 	int r;
 	unsigned long n;
@@ -2330,7 +2331,8 @@ static int kvm_vm_ioctl_get_dirty_log_hv(struct kvm *kvm,
 	if (log->slot >= KVM_USER_MEM_SLOTS)
 		goto out;
 
-	memslot = id_to_memslot(kvm->memslots, log->slot);
+	slots = kvm_memslots(kvm);
+	memslot = id_to_memslot(slots, log->slot);
 	r = -ENOENT;
 	if (!memslot->dirty_bitmap)
 		goto out;
@@ -2383,6 +2385,7 @@ static void kvmppc_core_commit_memory_region_hv(struct kvm *kvm,
 				const struct kvm_memory_slot *old)
 {
 	unsigned long npages = mem->memory_size >> PAGE_SHIFT;
+	struct kvm_memslots *slots;
 	struct kvm_memory_slot *memslot;
 
 	if (npages && old->npages) {
@@ -2392,7 +2395,8 @@ static void kvmppc_core_commit_memory_region_hv(struct kvm *kvm,
 		 * since the rmap array starts out as all zeroes,
 		 * i.e. no pages are dirty.
 		 */
-		memslot = id_to_memslot(kvm->memslots, mem->slot);
+		slots = kvm_memslots(kvm);
+		memslot = id_to_memslot(slots, mem->slot);
 		kvmppc_hv_get_dirty_log(kvm, memslot, NULL);
 	}
 }
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index f57383941d03..c01dfc798c66 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -1530,6 +1530,7 @@ out:
 static int kvm_vm_ioctl_get_dirty_log_pr(struct kvm *kvm,
 					 struct kvm_dirty_log *log)
 {
+	struct kvm_memslots *slots;
 	struct kvm_memory_slot *memslot;
 	struct kvm_vcpu *vcpu;
 	ulong ga, ga_end;
@@ -1545,7 +1546,8 @@ static int kvm_vm_ioctl_get_dirty_log_pr(struct kvm *kvm,
 
 	/* If nothing is dirty, don't bother messing with page tables. */
 	if (is_dirty) {
-		memslot = id_to_memslot(kvm->memslots, log->slot);
+		slots = kvm_memslots(kvm);
+		memslot = id_to_memslot(slots, log->slot);
 
 		ga = memslot->base_gfn << PAGE_SHIFT;
 		ga_end = ga + (memslot->npages << PAGE_SHIFT);
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index d461f8a15c07..a05107e9b2bf 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -236,6 +236,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 {
 	int r;
 	unsigned long n;
+	struct kvm_memslots *slots;
 	struct kvm_memory_slot *memslot;
 	int is_dirty = 0;
 
@@ -245,7 +246,8 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	if (log->slot >= KVM_USER_MEM_SLOTS)
 		goto out;
 
-	memslot = id_to_memslot(kvm->memslots, log->slot);
+	slots = kvm_memslots(kvm);
+	memslot = id_to_memslot(slots, log->slot);
 	r = -ENOENT;
 	if (!memslot->dirty_bitmap)
 		goto out;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 457b908244f2..49e924daad7b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -7770,6 +7770,7 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
 				const struct kvm_memory_slot *old,
 				enum kvm_mr_change change)
 {
+	struct kvm_memslots *slots;
 	struct kvm_memory_slot *new;
 	int nr_mmu_pages = 0;
 
@@ -7791,7 +7792,8 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
 		kvm_mmu_change_mmu_pages(kvm, nr_mmu_pages);
 
 	/* It's OK to get 'new' slot here as it has already been installed */
-	new = id_to_memslot(kvm->memslots, mem->slot);
+	slots = kvm_memslots(kvm);
+	new = id_to_memslot(slots, mem->slot);
 
 	/*
 	 * Dirty logging tracks sptes in 4k granularity, meaning that large
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index e299763ef744..42df724071c0 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -734,7 +734,7 @@ static int check_memory_region_flags(struct kvm_userspace_memory_region *mem)
 static struct kvm_memslots *install_new_memslots(struct kvm *kvm,
 		struct kvm_memslots *slots)
 {
-	struct kvm_memslots *old_memslots = kvm->memslots;
+	struct kvm_memslots *old_memslots = kvm_memslots(kvm);
 
 	/*
 	 * Set the low bit in the generation, which disables SPTE caching
@@ -799,7 +799,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
 	if (mem->guest_phys_addr + mem->memory_size < mem->guest_phys_addr)
 		goto out;
 
-	slot = id_to_memslot(kvm->memslots, mem->slot);
+	slot = id_to_memslot(kvm_memslots(kvm), mem->slot);
 	base_gfn = mem->guest_phys_addr >> PAGE_SHIFT;
 	npages = mem->memory_size >> PAGE_SHIFT;
 
@@ -842,7 +842,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
 	if ((change == KVM_MR_CREATE) || (change == KVM_MR_MOVE)) {
 		/* Check for overlaps */
 		r = -EEXIST;
-		kvm_for_each_memslot(slot, kvm->memslots) {
+		kvm_for_each_memslot(slot, kvm_memslots(kvm)) {
 			if ((slot->id >= KVM_USER_MEM_SLOTS) ||
 			    (slot->id == mem->slot))
 				continue;
@@ -873,7 +873,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
 	slots = kvm_kvzalloc(sizeof(struct kvm_memslots));
 	if (!slots)
 		goto out_free;
-	memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));
+	memcpy(slots, kvm_memslots(kvm), sizeof(struct kvm_memslots));
 
 	if ((change == KVM_MR_DELETE) || (change == KVM_MR_MOVE)) {
 		slot = id_to_memslot(slots, mem->slot);
@@ -966,6 +966,7 @@ static int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
 int kvm_get_dirty_log(struct kvm *kvm,
 			struct kvm_dirty_log *log, int *is_dirty)
 {
+	struct kvm_memslots *slots;
 	struct kvm_memory_slot *memslot;
 	int r, i;
 	unsigned long n;
@@ -975,7 +976,8 @@ int kvm_get_dirty_log(struct kvm *kvm,
 	if (log->slot >= KVM_USER_MEM_SLOTS)
 		goto out;
 
-	memslot = id_to_memslot(kvm->memslots, log->slot);
+	slots = kvm_memslots(kvm);
+	memslot = id_to_memslot(slots, log->slot);
 	r = -ENOENT;
 	if (!memslot->dirty_bitmap)
 		goto out;
@@ -1024,6 +1026,7 @@ EXPORT_SYMBOL_GPL(kvm_get_dirty_log);
 int kvm_get_dirty_log_protect(struct kvm *kvm,
 			struct kvm_dirty_log *log, bool *is_dirty)
 {
+	struct kvm_memslots *slots;
 	struct kvm_memory_slot *memslot;
 	int r, i;
 	unsigned long n;
@@ -1034,7 +1037,8 @@ int kvm_get_dirty_log_protect(struct kvm *kvm,
 	if (log->slot >= KVM_USER_MEM_SLOTS)
 		goto out;
 
-	memslot = id_to_memslot(kvm->memslots, log->slot);
+	slots = kvm_memslots(kvm);
+	memslot = id_to_memslot(slots, log->slot);
 
 	dirty_bitmap = memslot->dirty_bitmap;
 	r = -ENOENT;
-- 
1.8.3.1



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/9] KVM: const-ify uses of struct kvm_userspace_memory_region
  2015-05-19 17:25 [PATCH 0/9] KVM: cleanups for memslots data structures Paolo Bonzini
  2015-05-19 17:25 ` [PATCH 1/9] KVM: introduce kvm_alloc/free_memslots Paolo Bonzini
  2015-05-19 17:25 ` [PATCH 2/9] KVM: use kvm_memslots whenever possible Paolo Bonzini
@ 2015-05-19 17:25 ` Paolo Bonzini
  2015-05-20  8:17   ` Takuya Yoshikawa
  2015-05-19 17:25 ` [PATCH 4/9] KVM: add memslots argument to kvm_arch_memslots_updated Paolo Bonzini
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 16+ messages in thread
From: Paolo Bonzini @ 2015-05-19 17:25 UTC (permalink / raw)
  To: linux-kernel, kvm; +Cc: Takuya Yoshikawa, Xiao Guangrong, rkrcmar

Architecture-specific helpers are not supposed to muck with
struct kvm_userspace_memory_region contents.  Add const to
enforce this.

In order to eliminate the only write in __kvm_set_memory_region,
the cleaning of deleted slots is pulled up from update_memslots
to __kvm_set_memory_region.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 arch/arm/kvm/mmu.c                 |  4 ++--
 arch/mips/kvm/mips.c               |  4 ++--
 arch/powerpc/include/asm/kvm_ppc.h |  8 ++++----
 arch/powerpc/kvm/book3s.c          |  4 ++--
 arch/powerpc/kvm/book3s_hv.c       |  4 ++--
 arch/powerpc/kvm/book3s_pr.c       |  4 ++--
 arch/powerpc/kvm/booke.c           |  4 ++--
 arch/powerpc/kvm/powerpc.c         |  4 ++--
 arch/s390/kvm/kvm-s390.c           |  4 ++--
 arch/x86/kvm/x86.c                 |  4 ++--
 include/linux/kvm_host.h           |  8 ++++----
 virt/kvm/kvm_main.c                | 22 +++++++++++-----------
 12 files changed, 37 insertions(+), 37 deletions(-)

diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 6f0f8f3ac7df..b5c023a37aec 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -1719,7 +1719,7 @@ out:
 }
 
 void kvm_arch_commit_memory_region(struct kvm *kvm,
-				   struct kvm_userspace_memory_region *mem,
+				   const struct kvm_userspace_memory_region *mem,
 				   const struct kvm_memory_slot *old,
 				   enum kvm_mr_change change)
 {
@@ -1734,7 +1734,7 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
 
 int kvm_arch_prepare_memory_region(struct kvm *kvm,
 				   struct kvm_memory_slot *memslot,
-				   struct kvm_userspace_memory_region *mem,
+				   const struct kvm_userspace_memory_region *mem,
 				   enum kvm_mr_change change)
 {
 	hva_t hva = mem->userspace_addr;
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index bc5ddd973b44..5963e2e8a6d7 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -198,14 +198,14 @@ int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot,
 
 int kvm_arch_prepare_memory_region(struct kvm *kvm,
 				   struct kvm_memory_slot *memslot,
-				   struct kvm_userspace_memory_region *mem,
+				   const struct kvm_userspace_memory_region *mem,
 				   enum kvm_mr_change change)
 {
 	return 0;
 }
 
 void kvm_arch_commit_memory_region(struct kvm *kvm,
-				   struct kvm_userspace_memory_region *mem,
+				   const struct kvm_userspace_memory_region *mem,
 				   const struct kvm_memory_slot *old,
 				   enum kvm_mr_change change)
 {
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index b8475daad884..aff563b5f001 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -182,9 +182,9 @@ extern int kvmppc_core_create_memslot(struct kvm *kvm,
 				      unsigned long npages);
 extern int kvmppc_core_prepare_memory_region(struct kvm *kvm,
 				struct kvm_memory_slot *memslot,
-				struct kvm_userspace_memory_region *mem);
+				const struct kvm_userspace_memory_region *mem);
 extern void kvmppc_core_commit_memory_region(struct kvm *kvm,
-				struct kvm_userspace_memory_region *mem,
+				const struct kvm_userspace_memory_region *mem,
 				const struct kvm_memory_slot *old);
 extern int kvm_vm_ioctl_get_smmu_info(struct kvm *kvm,
 				      struct kvm_ppc_smmu_info *info);
@@ -243,9 +243,9 @@ struct kvmppc_ops {
 	void (*flush_memslot)(struct kvm *kvm, struct kvm_memory_slot *memslot);
 	int (*prepare_memory_region)(struct kvm *kvm,
 				     struct kvm_memory_slot *memslot,
-				     struct kvm_userspace_memory_region *mem);
+				     const struct kvm_userspace_memory_region *mem);
 	void (*commit_memory_region)(struct kvm *kvm,
-				     struct kvm_userspace_memory_region *mem,
+				     const struct kvm_userspace_memory_region *mem,
 				     const struct kvm_memory_slot *old);
 	int (*unmap_hva)(struct kvm *kvm, unsigned long hva);
 	int (*unmap_hva_range)(struct kvm *kvm, unsigned long start,
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 453a8a47a467..60aa0726dccc 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -757,13 +757,13 @@ void kvmppc_core_flush_memslot(struct kvm *kvm, struct kvm_memory_slot *memslot)
 
 int kvmppc_core_prepare_memory_region(struct kvm *kvm,
 				struct kvm_memory_slot *memslot,
-				struct kvm_userspace_memory_region *mem)
+				const struct kvm_userspace_memory_region *mem)
 {
 	return kvm->arch.kvm_ops->prepare_memory_region(kvm, memslot, mem);
 }
 
 void kvmppc_core_commit_memory_region(struct kvm *kvm,
-				struct kvm_userspace_memory_region *mem,
+				const struct kvm_userspace_memory_region *mem,
 				const struct kvm_memory_slot *old)
 {
 	kvm->arch.kvm_ops->commit_memory_region(kvm, mem, old);
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 7bc6137ece74..e20d438edb51 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -2375,13 +2375,13 @@ static int kvmppc_core_create_memslot_hv(struct kvm_memory_slot *slot,
 
 static int kvmppc_core_prepare_memory_region_hv(struct kvm *kvm,
 					struct kvm_memory_slot *memslot,
-					struct kvm_userspace_memory_region *mem)
+					const struct kvm_userspace_memory_region *mem)
 {
 	return 0;
 }
 
 static void kvmppc_core_commit_memory_region_hv(struct kvm *kvm,
-				struct kvm_userspace_memory_region *mem,
+				const struct kvm_userspace_memory_region *mem,
 				const struct kvm_memory_slot *old)
 {
 	unsigned long npages = mem->memory_size >> PAGE_SHIFT;
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index c01dfc798c66..0873e766df1b 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -1573,13 +1573,13 @@ static void kvmppc_core_flush_memslot_pr(struct kvm *kvm,
 
 static int kvmppc_core_prepare_memory_region_pr(struct kvm *kvm,
 					struct kvm_memory_slot *memslot,
-					struct kvm_userspace_memory_region *mem)
+					const struct kvm_userspace_memory_region *mem)
 {
 	return 0;
 }
 
 static void kvmppc_core_commit_memory_region_pr(struct kvm *kvm,
-				struct kvm_userspace_memory_region *mem,
+				const struct kvm_userspace_memory_region *mem,
 				const struct kvm_memory_slot *old)
 {
 	return;
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 3872ab31c80a..518e3a8b351f 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1784,13 +1784,13 @@ int kvmppc_core_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot,
 
 int kvmppc_core_prepare_memory_region(struct kvm *kvm,
 				      struct kvm_memory_slot *memslot,
-				      struct kvm_userspace_memory_region *mem)
+				      const struct kvm_userspace_memory_region *mem)
 {
 	return 0;
 }
 
 void kvmppc_core_commit_memory_region(struct kvm *kvm,
-				struct kvm_userspace_memory_region *mem,
+				const struct kvm_userspace_memory_region *mem,
 				const struct kvm_memory_slot *old)
 {
 }
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 8cd1f80fdc70..5985bb2a332b 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -595,14 +595,14 @@ int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot,
 
 int kvm_arch_prepare_memory_region(struct kvm *kvm,
 				   struct kvm_memory_slot *memslot,
-				   struct kvm_userspace_memory_region *mem,
+				   const struct kvm_userspace_memory_region *mem,
 				   enum kvm_mr_change change)
 {
 	return kvmppc_core_prepare_memory_region(kvm, memslot, mem);
 }
 
 void kvm_arch_commit_memory_region(struct kvm *kvm,
-				   struct kvm_userspace_memory_region *mem,
+				   const struct kvm_userspace_memory_region *mem,
 				   const struct kvm_memory_slot *old,
 				   enum kvm_mr_change change)
 {
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index a05107e9b2bf..994f9c37f25f 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -2582,7 +2582,7 @@ int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot,
 /* Section: memory related */
 int kvm_arch_prepare_memory_region(struct kvm *kvm,
 				   struct kvm_memory_slot *memslot,
-				   struct kvm_userspace_memory_region *mem,
+				   const struct kvm_userspace_memory_region *mem,
 				   enum kvm_mr_change change)
 {
 	/* A few sanity checks. We can have memory slots which have to be
@@ -2600,7 +2600,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
 }
 
 void kvm_arch_commit_memory_region(struct kvm *kvm,
-				struct kvm_userspace_memory_region *mem,
+				const struct kvm_userspace_memory_region *mem,
 				const struct kvm_memory_slot *old,
 				enum kvm_mr_change change)
 {
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 49e924daad7b..c1b72b9bc250 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -7688,7 +7688,7 @@ void kvm_arch_memslots_updated(struct kvm *kvm)
 
 int kvm_arch_prepare_memory_region(struct kvm *kvm,
 				struct kvm_memory_slot *memslot,
-				struct kvm_userspace_memory_region *mem,
+				const struct kvm_userspace_memory_region *mem,
 				enum kvm_mr_change change)
 {
 	/*
@@ -7766,7 +7766,7 @@ static void kvm_mmu_slot_apply_flags(struct kvm *kvm,
 }
 
 void kvm_arch_commit_memory_region(struct kvm *kvm,
-				struct kvm_userspace_memory_region *mem,
+				const struct kvm_userspace_memory_region *mem,
 				const struct kvm_memory_slot *old,
 				enum kvm_mr_change change)
 {
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 87fd74a04005..fbced7015ebd 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -501,9 +501,9 @@ enum kvm_mr_change {
 };
 
 int kvm_set_memory_region(struct kvm *kvm,
-			  struct kvm_userspace_memory_region *mem);
+			  const struct kvm_userspace_memory_region *mem);
 int __kvm_set_memory_region(struct kvm *kvm,
-			    struct kvm_userspace_memory_region *mem);
+			    const struct kvm_userspace_memory_region *mem);
 void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free,
 			   struct kvm_memory_slot *dont);
 int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot,
@@ -511,10 +511,10 @@ int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot,
 void kvm_arch_memslots_updated(struct kvm *kvm);
 int kvm_arch_prepare_memory_region(struct kvm *kvm,
 				struct kvm_memory_slot *memslot,
-				struct kvm_userspace_memory_region *mem,
+				const struct kvm_userspace_memory_region *mem,
 				enum kvm_mr_change change);
 void kvm_arch_commit_memory_region(struct kvm *kvm,
-				struct kvm_userspace_memory_region *mem,
+				const struct kvm_userspace_memory_region *mem,
 				const struct kvm_memory_slot *old,
 				enum kvm_mr_change change);
 bool kvm_largepages_enabled(void);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 42df724071c0..fc2dbe1c34fc 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -676,8 +676,6 @@ static void update_memslots(struct kvm_memslots *slots,
 	WARN_ON(mslots[i].id != id);
 	if (!new->npages) {
 		WARN_ON(!mslots[i].npages);
-		new->base_gfn = 0;
-		new->flags = 0;
 		if (mslots[i].npages)
 			slots->used_slots--;
 	} else {
@@ -717,7 +715,7 @@ static void update_memslots(struct kvm_memslots *slots,
 	slots->id_to_index[mslots[i].id] = i;
 }
 
-static int check_memory_region_flags(struct kvm_userspace_memory_region *mem)
+static int check_memory_region_flags(const struct kvm_userspace_memory_region *mem)
 {
 	u32 valid_flags = KVM_MEM_LOG_DIRTY_PAGES;
 
@@ -767,7 +765,7 @@ static struct kvm_memslots *install_new_memslots(struct kvm *kvm,
  * Must be called holding kvm->slots_lock for write.
  */
 int __kvm_set_memory_region(struct kvm *kvm,
-			    struct kvm_userspace_memory_region *mem)
+			    const struct kvm_userspace_memory_region *mem)
 {
 	int r;
 	gfn_t base_gfn;
@@ -806,9 +804,6 @@ int __kvm_set_memory_region(struct kvm *kvm,
 	if (npages > KVM_MEM_MAX_NR_PAGES)
 		goto out;
 
-	if (!npages)
-		mem->flags &= ~KVM_MEM_LOG_DIRTY_PAGES;
-
 	new = old = *slot;
 
 	new.id = mem->slot;
@@ -834,10 +829,14 @@ int __kvm_set_memory_region(struct kvm *kvm,
 				goto out;
 			}
 		}
-	} else if (old.npages) {
+	} else {
+		if (!old.npages)
+			goto out;
+
 		change = KVM_MR_DELETE;
-	} else /* Modify a non-existent slot: disallowed. */
-		goto out;
+		new.base_gfn = 0;
+		new.flags = 0;
+	}
 
 	if ((change == KVM_MR_CREATE) || (change == KVM_MR_MOVE)) {
 		/* Check for overlaps */
@@ -944,7 +943,7 @@ out:
 EXPORT_SYMBOL_GPL(__kvm_set_memory_region);
 
 int kvm_set_memory_region(struct kvm *kvm,
-			  struct kvm_userspace_memory_region *mem)
+			  const struct kvm_userspace_memory_region *mem)
 {
 	int r;
 
@@ -960,6 +959,7 @@ static int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
 {
 	if (mem->slot >= KVM_USER_MEM_SLOTS)
 		return -EINVAL;
+
 	return kvm_set_memory_region(kvm, mem);
 }
 
-- 
1.8.3.1



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 4/9] KVM: add memslots argument to kvm_arch_memslots_updated
  2015-05-19 17:25 [PATCH 0/9] KVM: cleanups for memslots data structures Paolo Bonzini
                   ` (2 preceding siblings ...)
  2015-05-19 17:25 ` [PATCH 3/9] KVM: const-ify uses of struct kvm_userspace_memory_region Paolo Bonzini
@ 2015-05-19 17:25 ` Paolo Bonzini
  2015-05-19 17:25 ` [PATCH 5/9] KVM: add "new" argument to kvm_arch_commit_memory_region Paolo Bonzini
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Paolo Bonzini @ 2015-05-19 17:25 UTC (permalink / raw)
  To: linux-kernel, kvm; +Cc: Takuya Yoshikawa, Xiao Guangrong, rkrcmar

Prepare for the case of multiple address spaces.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 arch/arm/kvm/mmu.c                  | 2 +-
 arch/mips/include/asm/kvm_host.h    | 2 +-
 arch/powerpc/include/asm/kvm_host.h | 2 +-
 arch/s390/include/asm/kvm_host.h    | 2 +-
 arch/x86/kvm/x86.c                  | 2 +-
 include/linux/kvm_host.h            | 2 +-
 include/linux/kvm_types.h           | 1 +
 virt/kvm/kvm_main.c                 | 2 +-
 8 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index b5c023a37aec..e9ac084d21ea 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -1839,7 +1839,7 @@ int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot,
 	return 0;
 }
 
-void kvm_arch_memslots_updated(struct kvm *kvm)
+void kvm_arch_memslots_updated(struct kvm *kvm, struct kvm_memslots *slots)
 {
 }
 
diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 4c25823563fe..e8c8d9d0c45f 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -839,7 +839,7 @@ static inline void kvm_arch_hardware_unsetup(void) {}
 static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_free_memslot(struct kvm *kvm,
 		struct kvm_memory_slot *free, struct kvm_memory_slot *dont) {}
-static inline void kvm_arch_memslots_updated(struct kvm *kvm) {}
+static inline void kvm_arch_memslots_updated(struct kvm *kvm, struct kvm_memslots *slots) {}
 static inline void kvm_arch_flush_shadow_all(struct kvm *kvm) {}
 static inline void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
 		struct kvm_memory_slot *slot) {}
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index a193a13cf08b..d91f65b28e32 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -698,7 +698,7 @@ struct kvm_vcpu_arch {
 static inline void kvm_arch_hardware_disable(void) {}
 static inline void kvm_arch_hardware_unsetup(void) {}
 static inline void kvm_arch_sync_events(struct kvm *kvm) {}
-static inline void kvm_arch_memslots_updated(struct kvm *kvm) {}
+static inline void kvm_arch_memslots_updated(struct kvm *kvm, struct kvm_memslots *slots) {}
 static inline void kvm_arch_flush_shadow_all(struct kvm *kvm) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 static inline void kvm_arch_exit(void) {}
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 444c412307cb..3024acbe1f9d 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -636,7 +636,7 @@ static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 static inline void kvm_arch_free_memslot(struct kvm *kvm,
 		struct kvm_memory_slot *free, struct kvm_memory_slot *dont) {}
-static inline void kvm_arch_memslots_updated(struct kvm *kvm) {}
+static inline void kvm_arch_memslots_updated(struct kvm *kvm, struct kvm_memslots *slots) {}
 static inline void kvm_arch_flush_shadow_all(struct kvm *kvm) {}
 static inline void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
 		struct kvm_memory_slot *slot) {}
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index c1b72b9bc250..80b01f81809b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -7677,7 +7677,7 @@ out_free:
 	return -ENOMEM;
 }
 
-void kvm_arch_memslots_updated(struct kvm *kvm)
+void kvm_arch_memslots_updated(struct kvm *kvm, struct kvm_memslots *slots)
 {
 	/*
 	 * memslots->generation has been incremented.
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index fbced7015ebd..8815f1dffb77 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -508,7 +508,7 @@ void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free,
 			   struct kvm_memory_slot *dont);
 int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot,
 			    unsigned long npages);
-void kvm_arch_memslots_updated(struct kvm *kvm);
+void kvm_arch_memslots_updated(struct kvm *kvm, struct kvm_memslots *slots);
 int kvm_arch_prepare_memory_region(struct kvm *kvm,
 				struct kvm_memory_slot *memslot,
 				const struct kvm_userspace_memory_region *mem,
diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h
index 931da7e917cf..1b47a185c2f0 100644
--- a/include/linux/kvm_types.h
+++ b/include/linux/kvm_types.h
@@ -28,6 +28,7 @@ struct kvm_run;
 struct kvm_userspace_memory_region;
 struct kvm_vcpu;
 struct kvm_vcpu_init;
+struct kvm_memslots;
 
 enum kvm_mr_change;
 
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index fc2dbe1c34fc..4361204a6348 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -751,7 +751,7 @@ static struct kvm_memslots *install_new_memslots(struct kvm *kvm,
 	 */
 	slots->generation++;
 
-	kvm_arch_memslots_updated(kvm);
+	kvm_arch_memslots_updated(kvm, slots);
 
 	return old_memslots;
 }
-- 
1.8.3.1



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 5/9] KVM: add "new" argument to kvm_arch_commit_memory_region
  2015-05-19 17:25 [PATCH 0/9] KVM: cleanups for memslots data structures Paolo Bonzini
                   ` (3 preceding siblings ...)
  2015-05-19 17:25 ` [PATCH 4/9] KVM: add memslots argument to kvm_arch_memslots_updated Paolo Bonzini
@ 2015-05-19 17:25 ` Paolo Bonzini
  2015-05-19 17:25 ` [PATCH 6/9] KVM: pass kvm_memory_slot to gfn_to_page_many_atomic Paolo Bonzini
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Paolo Bonzini @ 2015-05-19 17:25 UTC (permalink / raw)
  To: linux-kernel, kvm; +Cc: Takuya Yoshikawa, Xiao Guangrong, rkrcmar

This lets the function access the new memory slot without going through
kvm_memslots and id_to_memslot.  It will simplify the code when more
than one address space will be supported.

Unfortunately, the "const"ness of the new argument must be casted
away in two places.  Fixing KVM to accept const struct kvm_memory_slot
pointers would require modifications in pretty much all architectures,
and is left for later.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 arch/arm/kvm/mmu.c                 |  1 +
 arch/mips/kvm/mips.c               |  1 +
 arch/powerpc/include/asm/kvm_ppc.h |  6 ++++--
 arch/powerpc/kvm/book3s.c          |  5 +++--
 arch/powerpc/kvm/book3s_hv.c       |  3 ++-
 arch/powerpc/kvm/book3s_pr.c       |  3 ++-
 arch/powerpc/kvm/booke.c           |  3 ++-
 arch/powerpc/kvm/powerpc.c         |  3 ++-
 arch/s390/kvm/kvm-s390.c           |  1 +
 arch/x86/include/asm/kvm_host.h    |  2 +-
 arch/x86/kvm/mmu.c                 |  6 ++++--
 arch/x86/kvm/x86.c                 | 13 +++++--------
 include/linux/kvm_host.h           |  1 +
 virt/kvm/kvm_main.c                |  2 +-
 14 files changed, 30 insertions(+), 20 deletions(-)

diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index e9ac084d21ea..7f473e6d3bf5 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -1721,6 +1721,7 @@ out:
 void kvm_arch_commit_memory_region(struct kvm *kvm,
 				   const struct kvm_userspace_memory_region *mem,
 				   const struct kvm_memory_slot *old,
+				   const struct kvm_memory_slot *new,
 				   enum kvm_mr_change change)
 {
 	/*
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index 5963e2e8a6d7..cd4c129ce743 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -207,6 +207,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
 void kvm_arch_commit_memory_region(struct kvm *kvm,
 				   const struct kvm_userspace_memory_region *mem,
 				   const struct kvm_memory_slot *old,
+				   const struct kvm_memory_slot *new,
 				   enum kvm_mr_change change)
 {
 	unsigned long npages = 0;
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index aff563b5f001..c6ef05bd0765 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -185,7 +185,8 @@ extern int kvmppc_core_prepare_memory_region(struct kvm *kvm,
 				const struct kvm_userspace_memory_region *mem);
 extern void kvmppc_core_commit_memory_region(struct kvm *kvm,
 				const struct kvm_userspace_memory_region *mem,
-				const struct kvm_memory_slot *old);
+				const struct kvm_memory_slot *old,
+				const struct kvm_memory_slot *new);
 extern int kvm_vm_ioctl_get_smmu_info(struct kvm *kvm,
 				      struct kvm_ppc_smmu_info *info);
 extern void kvmppc_core_flush_memslot(struct kvm *kvm,
@@ -246,7 +247,8 @@ struct kvmppc_ops {
 				     const struct kvm_userspace_memory_region *mem);
 	void (*commit_memory_region)(struct kvm *kvm,
 				     const struct kvm_userspace_memory_region *mem,
-				     const struct kvm_memory_slot *old);
+				     const struct kvm_memory_slot *old,
+				     const struct kvm_memory_slot *new);
 	int (*unmap_hva)(struct kvm *kvm, unsigned long hva);
 	int (*unmap_hva_range)(struct kvm *kvm, unsigned long start,
 			   unsigned long end);
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 60aa0726dccc..b6fe22a2e0b9 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -764,9 +764,10 @@ int kvmppc_core_prepare_memory_region(struct kvm *kvm,
 
 void kvmppc_core_commit_memory_region(struct kvm *kvm,
 				const struct kvm_userspace_memory_region *mem,
-				const struct kvm_memory_slot *old)
+				const struct kvm_memory_slot *old,
+				const struct kvm_memory_slot *new);
 {
-	kvm->arch.kvm_ops->commit_memory_region(kvm, mem, old);
+	kvm->arch.kvm_ops->commit_memory_region(kvm, mem, old, new);
 }
 
 int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index e20d438edb51..c3679b7e4343 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -2382,7 +2382,8 @@ static int kvmppc_core_prepare_memory_region_hv(struct kvm *kvm,
 
 static void kvmppc_core_commit_memory_region_hv(struct kvm *kvm,
 				const struct kvm_userspace_memory_region *mem,
-				const struct kvm_memory_slot *old)
+				const struct kvm_memory_slot *old,
+				const struct kvm_memory_slot *new)
 {
 	unsigned long npages = mem->memory_size >> PAGE_SHIFT;
 	struct kvm_memslots *slots;
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 0873e766df1b..64891b081ad5 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -1580,7 +1580,8 @@ static int kvmppc_core_prepare_memory_region_pr(struct kvm *kvm,
 
 static void kvmppc_core_commit_memory_region_pr(struct kvm *kvm,
 				const struct kvm_userspace_memory_region *mem,
-				const struct kvm_memory_slot *old)
+				const struct kvm_memory_slot *old,
+				const struct kvm_memory_slot *new)
 {
 	return;
 }
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 518e3a8b351f..cc5842657161 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1791,7 +1791,8 @@ int kvmppc_core_prepare_memory_region(struct kvm *kvm,
 
 void kvmppc_core_commit_memory_region(struct kvm *kvm,
 				const struct kvm_userspace_memory_region *mem,
-				const struct kvm_memory_slot *old)
+				const struct kvm_memory_slot *old,
+				const struct kvm_memory_slot *new)
 {
 }
 
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 5985bb2a332b..e5dde32fe71f 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -604,9 +604,10 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
 void kvm_arch_commit_memory_region(struct kvm *kvm,
 				   const struct kvm_userspace_memory_region *mem,
 				   const struct kvm_memory_slot *old,
+				   const struct kvm_memory_slot *new,
 				   enum kvm_mr_change change)
 {
-	kvmppc_core_commit_memory_region(kvm, mem, old);
+	kvmppc_core_commit_memory_region(kvm, mem, old, new);
 }
 
 void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 994f9c37f25f..8ad4b9a5667f 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -2602,6 +2602,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
 void kvm_arch_commit_memory_region(struct kvm *kvm,
 				const struct kvm_userspace_memory_region *mem,
 				const struct kvm_memory_slot *old,
+				const struct kvm_memory_slot *new,
 				enum kvm_mr_change change)
 {
 	int rc;
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index bbb8f4e7738a..780fcc8e7082 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -872,7 +872,7 @@ void kvm_mmu_reset_context(struct kvm_vcpu *vcpu);
 void kvm_mmu_slot_remove_write_access(struct kvm *kvm,
 				      struct kvm_memory_slot *memslot);
 void kvm_mmu_zap_collapsible_sptes(struct kvm *kvm,
-					struct kvm_memory_slot *memslot);
+				   const struct kvm_memory_slot *memslot);
 void kvm_mmu_slot_leaf_clear_dirty(struct kvm *kvm,
 				   struct kvm_memory_slot *memslot);
 void kvm_mmu_slot_largepage_remove_write_access(struct kvm *kvm,
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 49c34e632b91..1bf2ae9ca521 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -4621,10 +4621,12 @@ restart:
 }
 
 void kvm_mmu_zap_collapsible_sptes(struct kvm *kvm,
-			struct kvm_memory_slot *memslot)
+				   const struct kvm_memory_slot *memslot)
 {
+	/* FIXME: const-ify all uses of struct kvm_memory_slot.  */
 	spin_lock(&kvm->mmu_lock);
-	slot_handle_leaf(kvm, memslot, kvm_mmu_zap_collapsible_spte, true);
+	slot_handle_leaf(kvm, (struct kvm_memory_slot *)memslot,
+			 kvm_mmu_zap_collapsible_spte, true);
 	spin_unlock(&kvm->mmu_lock);
 }
 
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 80b01f81809b..d29c8d756baa 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -7768,13 +7768,12 @@ static void kvm_mmu_slot_apply_flags(struct kvm *kvm,
 void kvm_arch_commit_memory_region(struct kvm *kvm,
 				const struct kvm_userspace_memory_region *mem,
 				const struct kvm_memory_slot *old,
+				const struct kvm_memory_slot *new,
 				enum kvm_mr_change change)
 {
-	struct kvm_memslots *slots;
-	struct kvm_memory_slot *new;
 	int nr_mmu_pages = 0;
 
-	if ((mem->slot >= KVM_USER_MEM_SLOTS) && (change == KVM_MR_DELETE)) {
+	if (change == KVM_MR_DELETE && old->id >= KVM_USER_MEM_SLOTS) {
 		int ret;
 
 		ret = vm_munmap(old->userspace_addr,
@@ -7791,10 +7790,6 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
 	if (nr_mmu_pages)
 		kvm_mmu_change_mmu_pages(kvm, nr_mmu_pages);
 
-	/* It's OK to get 'new' slot here as it has already been installed */
-	slots = kvm_memslots(kvm);
-	new = id_to_memslot(slots, mem->slot);
-
 	/*
 	 * Dirty logging tracks sptes in 4k granularity, meaning that large
 	 * sptes have to be split.  If live migration is successful, the guest
@@ -7819,9 +7814,11 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
 	 * been zapped so no dirty logging staff is needed for old slot. For
 	 * KVM_MR_FLAGS_ONLY, the old slot is essentially the same one as the
 	 * new and it's also covered when dealing with the new slot.
+	 *
+	 * FIXME: const-ify all uses of struct kvm_memory_slot.
 	 */
 	if (change != KVM_MR_DELETE)
-		kvm_mmu_slot_apply_flags(kvm, new);
+		kvm_mmu_slot_apply_flags(kvm, (struct kvm_memory_slot *) new);
 }
 
 void kvm_arch_flush_shadow_all(struct kvm *kvm)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 8815f1dffb77..9bd3bc16be87 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -516,6 +516,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
 void kvm_arch_commit_memory_region(struct kvm *kvm,
 				const struct kvm_userspace_memory_region *mem,
 				const struct kvm_memory_slot *old,
+				const struct kvm_memory_slot *new,
 				enum kvm_mr_change change);
 bool kvm_largepages_enabled(void);
 void kvm_disable_largepages(void);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 4361204a6348..9f67c942d8ee 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -912,7 +912,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
 	update_memslots(slots, &new);
 	old_memslots = install_new_memslots(kvm, slots);
 
-	kvm_arch_commit_memory_region(kvm, mem, &old, change);
+	kvm_arch_commit_memory_region(kvm, mem, &old, &new, change);
 
 	kvm_free_memslot(kvm, &old, &new);
 	kvfree(old_memslots);
-- 
1.8.3.1



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 6/9] KVM: pass kvm_memory_slot to gfn_to_page_many_atomic
  2015-05-19 17:25 [PATCH 0/9] KVM: cleanups for memslots data structures Paolo Bonzini
                   ` (4 preceding siblings ...)
  2015-05-19 17:25 ` [PATCH 5/9] KVM: add "new" argument to kvm_arch_commit_memory_region Paolo Bonzini
@ 2015-05-19 17:25 ` Paolo Bonzini
  2015-05-19 17:25 ` [PATCH 7/9] KVM: remove __gfn_to_pfn Paolo Bonzini
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Paolo Bonzini @ 2015-05-19 17:25 UTC (permalink / raw)
  To: linux-kernel, kvm; +Cc: Takuya Yoshikawa, Xiao Guangrong, rkrcmar

The memory slot is already available from gfn_to_memslot_dirty_bitmap.
Isn't it a shame to look it up again?  Plus, it makes gfn_to_page_many_atomic
agnostic of multiple VCPU address spaces.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 arch/x86/kvm/mmu.c       | 6 ++++--
 include/linux/kvm_host.h | 4 ++--
 virt/kvm/kvm_main.c      | 6 +++---
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 1bf2ae9ca521..6a7e5b6246b1 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -2728,15 +2728,17 @@ static int direct_pte_prefetch_many(struct kvm_vcpu *vcpu,
 				    u64 *start, u64 *end)
 {
 	struct page *pages[PTE_PREFETCH_NUM];
+	struct kvm_memory_slot *slot;
 	unsigned access = sp->role.access;
 	int i, ret;
 	gfn_t gfn;
 
 	gfn = kvm_mmu_page_get_gfn(sp, start - sp->spt);
-	if (!gfn_to_memslot_dirty_bitmap(vcpu, gfn, access & ACC_WRITE_MASK))
+	slot = gfn_to_memslot_dirty_bitmap(vcpu, gfn, access & ACC_WRITE_MASK);
+	if (!slot)
 		return -1;
 
-	ret = gfn_to_page_many_atomic(vcpu->kvm, gfn, pages, end - start);
+	ret = gfn_to_page_many_atomic(slot, gfn, pages, end - start);
 	if (ret <= 0)
 		return -1;
 
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 9bd3bc16be87..a8bcbc9c6078 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -526,8 +526,8 @@ void kvm_arch_flush_shadow_all(struct kvm *kvm);
 void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
 				   struct kvm_memory_slot *slot);
 
-int gfn_to_page_many_atomic(struct kvm *kvm, gfn_t gfn, struct page **pages,
-			    int nr_pages);
+int gfn_to_page_many_atomic(struct kvm_memory_slot *slot, gfn_t gfn,
+			    struct page **pages, int nr_pages);
 
 struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn);
 unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 9f67c942d8ee..c57f44216a4e 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1428,13 +1428,13 @@ pfn_t gfn_to_pfn_memslot_atomic(struct kvm_memory_slot *slot, gfn_t gfn)
 }
 EXPORT_SYMBOL_GPL(gfn_to_pfn_memslot_atomic);
 
-int gfn_to_page_many_atomic(struct kvm *kvm, gfn_t gfn, struct page **pages,
-								  int nr_pages)
+int gfn_to_page_many_atomic(struct kvm_memory_slot *slot, gfn_t gfn,
+			    struct page **pages, int nr_pages)
 {
 	unsigned long addr;
 	gfn_t entry;
 
-	addr = gfn_to_hva_many(gfn_to_memslot(kvm, gfn), gfn, &entry);
+	addr = gfn_to_hva_many(slot, gfn, &entry);
 	if (kvm_is_error_hva(addr))
 		return -1;
 
-- 
1.8.3.1



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 7/9] KVM: remove __gfn_to_pfn
  2015-05-19 17:25 [PATCH 0/9] KVM: cleanups for memslots data structures Paolo Bonzini
                   ` (5 preceding siblings ...)
  2015-05-19 17:25 ` [PATCH 6/9] KVM: pass kvm_memory_slot to gfn_to_page_many_atomic Paolo Bonzini
@ 2015-05-19 17:25 ` Paolo Bonzini
  2015-05-19 17:25 ` [PATCH 8/9] KVM: x86: pass kvm_mmu_page to gfn_to_rmap Paolo Bonzini
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Paolo Bonzini @ 2015-05-19 17:25 UTC (permalink / raw)
  To: linux-kernel, kvm; +Cc: Takuya Yoshikawa, Xiao Guangrong, rkrcmar

Most of the function that wrap it can be rewritten without it, except
for gfn_to_pfn_prot.  Just inline it into gfn_to_pfn_prot, and rewrite
the other function on top of gfn_to_pfn_memslot*.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 virt/kvm/kvm_main.c | 39 +++++++++++++++------------------------
 1 file changed, 15 insertions(+), 24 deletions(-)

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index c57f44216a4e..53e66ef8b75e 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1387,33 +1387,11 @@ pfn_t __gfn_to_pfn_memslot(struct kvm_memory_slot *slot, gfn_t gfn, bool atomic,
 }
 EXPORT_SYMBOL_GPL(__gfn_to_pfn_memslot);
 
-static pfn_t __gfn_to_pfn(struct kvm *kvm, gfn_t gfn, bool atomic,
-			  bool write_fault, bool *writable)
-{
-	struct kvm_memory_slot *slot;
-
-	slot = gfn_to_memslot(kvm, gfn);
-
-	return __gfn_to_pfn_memslot(slot, gfn, atomic, NULL, write_fault,
-				    writable);
-}
-
-pfn_t gfn_to_pfn_atomic(struct kvm *kvm, gfn_t gfn)
-{
-	return __gfn_to_pfn(kvm, gfn, true, true, NULL);
-}
-EXPORT_SYMBOL_GPL(gfn_to_pfn_atomic);
-
-pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn)
-{
-	return __gfn_to_pfn(kvm, gfn, false, true, NULL);
-}
-EXPORT_SYMBOL_GPL(gfn_to_pfn);
-
 pfn_t gfn_to_pfn_prot(struct kvm *kvm, gfn_t gfn, bool write_fault,
 		      bool *writable)
 {
-	return __gfn_to_pfn(kvm, gfn, false, write_fault, writable);
+	return __gfn_to_pfn_memslot(gfn_to_memslot(kvm, gfn), gfn, false, NULL,
+				    write_fault, writable);
 }
 EXPORT_SYMBOL_GPL(gfn_to_pfn_prot);
 
@@ -1421,6 +1399,7 @@ pfn_t gfn_to_pfn_memslot(struct kvm_memory_slot *slot, gfn_t gfn)
 {
 	return __gfn_to_pfn_memslot(slot, gfn, false, NULL, true, NULL);
 }
+EXPORT_SYMBOL_GPL(gfn_to_pfn_memslot);
 
 pfn_t gfn_to_pfn_memslot_atomic(struct kvm_memory_slot *slot, gfn_t gfn)
 {
@@ -1428,6 +1407,18 @@ pfn_t gfn_to_pfn_memslot_atomic(struct kvm_memory_slot *slot, gfn_t gfn)
 }
 EXPORT_SYMBOL_GPL(gfn_to_pfn_memslot_atomic);
 
+pfn_t gfn_to_pfn_atomic(struct kvm *kvm, gfn_t gfn)
+{
+	return gfn_to_pfn_memslot_atomic(gfn_to_memslot(kvm, gfn), gfn);
+}
+EXPORT_SYMBOL_GPL(gfn_to_pfn_atomic);
+
+pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn)
+{
+	return gfn_to_pfn_memslot(gfn_to_memslot(kvm, gfn), gfn);
+}
+EXPORT_SYMBOL_GPL(gfn_to_pfn);
+
 int gfn_to_page_many_atomic(struct kvm_memory_slot *slot, gfn_t gfn,
 			    struct page **pages, int nr_pages)
 {
-- 
1.8.3.1



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 8/9] KVM: x86: pass kvm_mmu_page to gfn_to_rmap
  2015-05-19 17:25 [PATCH 0/9] KVM: cleanups for memslots data structures Paolo Bonzini
                   ` (6 preceding siblings ...)
  2015-05-19 17:25 ` [PATCH 7/9] KVM: remove __gfn_to_pfn Paolo Bonzini
@ 2015-05-19 17:25 ` Paolo Bonzini
  2015-05-20 20:09   ` Radim Krčmář
  2015-05-19 17:25 ` [PATCH 9/9] KVM: x86: pass struct kvm_mmu_page to account/unaccount_shadowed Paolo Bonzini
  2015-05-20 20:19 ` [PATCH 0/9] KVM: cleanups for memslots data structures Radim Krčmář
  9 siblings, 1 reply; 16+ messages in thread
From: Paolo Bonzini @ 2015-05-19 17:25 UTC (permalink / raw)
  To: linux-kernel, kvm; +Cc: Takuya Yoshikawa, Xiao Guangrong, rkrcmar

This is always available, and later we could also use the role to look
up the right memslots array.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 arch/x86/kvm/mmu.c       | 10 +++++-----
 arch/x86/kvm/mmu_audit.c |  7 ++++---
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 6a7e5b6246b1..ceed1c591bc5 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -1039,12 +1039,12 @@ static unsigned long *__gfn_to_rmap(gfn_t gfn, int level,
 /*
  * Take gfn and return the reverse mapping to it.
  */
-static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int level)
+static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, struct kvm_mmu_page *sp)
 {
 	struct kvm_memory_slot *slot;
 
 	slot = gfn_to_memslot(kvm, gfn);
-	return __gfn_to_rmap(gfn, level, slot);
+	return __gfn_to_rmap(gfn, sp->role.level, slot);
 }
 
 static bool rmap_can_add(struct kvm_vcpu *vcpu)
@@ -1062,7 +1062,7 @@ static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn)
 
 	sp = page_header(__pa(spte));
 	kvm_mmu_page_set_gfn(sp, spte - sp->spt, gfn);
-	rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp->role.level);
+	rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp);
 	return pte_list_add(vcpu, spte, rmapp);
 }
 
@@ -1074,7 +1074,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
 
 	sp = page_header(__pa(spte));
 	gfn = kvm_mmu_page_get_gfn(sp, spte - sp->spt);
-	rmapp = gfn_to_rmap(kvm, gfn, sp->role.level);
+	rmapp = gfn_to_rmap(kvm, gfn, sp);
 	pte_list_remove(spte, rmapp);
 }
 
@@ -1608,7 +1608,7 @@ static void rmap_recycle(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn)
 
 	sp = page_header(__pa(spte));
 
-	rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp->role.level);
+	rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp);
 
 	kvm_unmap_rmapp(vcpu->kvm, rmapp, NULL, gfn, sp->role.level, 0);
 	kvm_flush_remote_tlbs(vcpu->kvm);
diff --git a/arch/x86/kvm/mmu_audit.c b/arch/x86/kvm/mmu_audit.c
index 368d53497314..020d7faf9f46 100644
--- a/arch/x86/kvm/mmu_audit.c
+++ b/arch/x86/kvm/mmu_audit.c
@@ -146,7 +146,7 @@ static void inspect_spte_has_rmap(struct kvm *kvm, u64 *sptep)
 		return;
 	}
 
-	rmapp = gfn_to_rmap(kvm, gfn, rev_sp->role.level);
+	rmapp = gfn_to_rmap(kvm, gfn, rev_sp);
 	if (!*rmapp) {
 		if (!__ratelimit(&ratelimit_state))
 			return;
@@ -192,10 +192,11 @@ static void audit_write_protection(struct kvm *kvm, struct kvm_mmu_page *sp)
 	u64 *sptep;
 	struct rmap_iterator iter;
 
-	if (sp->role.direct || sp->unsync || sp->role.invalid)
+	if (sp->role.direct || sp->unsync || sp->role.invalid ||
+	    sp->role.level != PT_PAGE_TABLE_LEVEL)
 		return;
 
-	rmapp = gfn_to_rmap(kvm, sp->gfn, PT_PAGE_TABLE_LEVEL);
+	rmapp = gfn_to_rmap(kvm, sp->gfn, sp);
 
 	for_each_rmap_spte(rmapp, &iter, sptep)
 		if (is_writable_pte(*sptep))
-- 
1.8.3.1



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 9/9] KVM: x86: pass struct kvm_mmu_page to account/unaccount_shadowed
  2015-05-19 17:25 [PATCH 0/9] KVM: cleanups for memslots data structures Paolo Bonzini
                   ` (7 preceding siblings ...)
  2015-05-19 17:25 ` [PATCH 8/9] KVM: x86: pass kvm_mmu_page to gfn_to_rmap Paolo Bonzini
@ 2015-05-19 17:25 ` Paolo Bonzini
  2015-05-20  8:41   ` Takuya Yoshikawa
  2015-05-20 20:12   ` Radim Krčmář
  2015-05-20 20:19 ` [PATCH 0/9] KVM: cleanups for memslots data structures Radim Krčmář
  9 siblings, 2 replies; 16+ messages in thread
From: Paolo Bonzini @ 2015-05-19 17:25 UTC (permalink / raw)
  To: linux-kernel, kvm; +Cc: Takuya Yoshikawa, Xiao Guangrong, rkrcmar

Prepare for multiple address spaces this way, since a VCPU is not available
where unaccount_shadowed is called.  We will get to the right kvm_memslots
1truct through the role field in struct kvm_mmu_page.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 arch/x86/kvm/mmu.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index ceed1c591bc5..6ea24812007a 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -804,12 +804,14 @@ static struct kvm_lpage_info *lpage_info_slot(gfn_t gfn,
 	return &slot->arch.lpage_info[level - 2][idx];
 }
 
-static void account_shadowed(struct kvm *kvm, gfn_t gfn)
+static void account_shadowed(struct kvm *kvm, struct kvm_mmu_page *sp)
 {
 	struct kvm_memory_slot *slot;
 	struct kvm_lpage_info *linfo;
+	gfn_t gfn;
 	int i;
 
+	gfn = sp->gfn;
 	slot = gfn_to_memslot(kvm, gfn);
 	for (i = PT_DIRECTORY_LEVEL; i <= PT_MAX_HUGEPAGE_LEVEL; ++i) {
 		linfo = lpage_info_slot(gfn, slot, i);
@@ -818,12 +820,14 @@ static void account_shadowed(struct kvm *kvm, gfn_t gfn)
 	kvm->arch.indirect_shadow_pages++;
 }
 
-static void unaccount_shadowed(struct kvm *kvm, gfn_t gfn)
+static void unaccount_shadowed(struct kvm *kvm, struct kvm_mmu_page *sp)
 {
 	struct kvm_memory_slot *slot;
 	struct kvm_lpage_info *linfo;
+	gfn_t gfn;
 	int i;
 
+	gfn = sp->gfn;
 	slot = gfn_to_memslot(kvm, gfn);
 	for (i = PT_DIRECTORY_LEVEL; i <= PT_MAX_HUGEPAGE_LEVEL; ++i) {
 		linfo = lpage_info_slot(gfn, slot, i);
@@ -2131,7 +2135,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
 		if (level > PT_PAGE_TABLE_LEVEL && need_sync)
 			kvm_sync_pages(vcpu, gfn);
 
-		account_shadowed(vcpu->kvm, gfn);
+		account_shadowed(vcpu->kvm, sp);
 	}
 	sp->mmu_valid_gen = vcpu->kvm->arch.mmu_valid_gen;
 	init_shadow_page_table(sp);
@@ -2312,7 +2316,7 @@ static int kvm_mmu_prepare_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp,
 	kvm_mmu_unlink_parents(kvm, sp);
 
 	if (!sp->role.invalid && !sp->role.direct)
-		unaccount_shadowed(kvm, sp->gfn);
+		unaccount_shadowed(kvm, sp);
 
 	if (sp->unsync)
 		kvm_unlink_unsync_page(kvm, sp);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/9] KVM: introduce kvm_alloc/free_memslots
  2015-05-19 17:25 ` [PATCH 1/9] KVM: introduce kvm_alloc/free_memslots Paolo Bonzini
@ 2015-05-20  7:38   ` Takuya Yoshikawa
  0 siblings, 0 replies; 16+ messages in thread
From: Takuya Yoshikawa @ 2015-05-20  7:38 UTC (permalink / raw)
  To: Paolo Bonzini, linux-kernel, kvm; +Cc: Xiao Guangrong, rkrcmar

On 2015/05/20 2:25, Paolo Bonzini wrote:

> +static void kvm_free_memslots(struct kvm *kvm, struct kvm_memslots *slots)
> +{
> +	struct kvm_memory_slot *memslot;
> +
> +	if (!slots)
> +		return;
> +
> +	kvm_for_each_memslot(memslot, slots)
> +		kvm_free_memslot(kvm, memslot, NULL);
> +
> +	kvfree(slots);
>   }
>   
>   static struct kvm *kvm_create_vm(unsigned long type)
> @@ -472,17 +519,10 @@ static struct kvm *kvm_create_vm(unsigned long type)
>   	BUILD_BUG_ON(KVM_MEM_SLOTS_NUM > SHRT_MAX);
>   
>   	r = -ENOMEM;
> -	kvm->memslots = kvm_kvzalloc(sizeof(struct kvm_memslots));
> +	kvm->memslots = kvm_alloc_memslots();
>   	if (!kvm->memslots)
>   		goto out_err_no_srcu;
>   
> -	/*
> -	 * Init kvm generation close to the maximum to easily test the
> -	 * code of handling generation number wrap-around.
> -	 */
> -	kvm->memslots->generation = -150;
> -
> -	kvm_init_memslots_id(kvm);
>   	if (init_srcu_struct(&kvm->srcu))
>   		goto out_err_no_srcu;
>   	if (init_srcu_struct(&kvm->irq_srcu))
> @@ -523,7 +563,7 @@ out_err_no_srcu:
>   out_err_no_disable:
>   	for (i = 0; i < KVM_NR_BUSES; i++)
>   		kfree(kvm->buses[i]);
> -	kvfree(kvm->memslots);
> +	kvm_free_memslots(kvm, kvm->memslots);

Newly added code
+	kvm_for_each_memslot(memslot, slots)
+		kvm_free_memslot(kvm, memslot, NULL);
does nothing in effect, but looks better to be here since this
corresponds to kvm_alloc_memslots() part and may be safer for
future changes.

Other changes look like trivial transitions to the new
kvm_alloc/free_memslots.

Reviewed-by: Takuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp>

>   	kvm_arch_free_vm(kvm);
>   	return ERR_PTR(r);
>   }

	Takuya


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 3/9] KVM: const-ify uses of struct kvm_userspace_memory_region
  2015-05-19 17:25 ` [PATCH 3/9] KVM: const-ify uses of struct kvm_userspace_memory_region Paolo Bonzini
@ 2015-05-20  8:17   ` Takuya Yoshikawa
  0 siblings, 0 replies; 16+ messages in thread
From: Takuya Yoshikawa @ 2015-05-20  8:17 UTC (permalink / raw)
  To: Paolo Bonzini, linux-kernel, kvm; +Cc: Xiao Guangrong, rkrcmar

On 2015/05/20 2:25, Paolo Bonzini wrote:
> Architecture-specific helpers are not supposed to muck with
> struct kvm_userspace_memory_region contents.  Add const to
> enforce this.

Nice, this is what I wanted to do, but could not do, when I
cleaned up these functions a few years ago.

> 
> In order to eliminate the only write in __kvm_set_memory_region,
> the cleaning of deleted slots is pulled up from update_memslots
> to __kvm_set_memory_region.

-	if (!npages)
-		mem->flags &= ~KVM_MEM_LOG_DIRTY_PAGES;

Especially, removing this hard-to-understand lines is really
nice.

> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Reviewed-by: Takuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp>


	Takuya



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 9/9] KVM: x86: pass struct kvm_mmu_page to account/unaccount_shadowed
  2015-05-19 17:25 ` [PATCH 9/9] KVM: x86: pass struct kvm_mmu_page to account/unaccount_shadowed Paolo Bonzini
@ 2015-05-20  8:41   ` Takuya Yoshikawa
  2015-05-20 20:12   ` Radim Krčmář
  1 sibling, 0 replies; 16+ messages in thread
From: Takuya Yoshikawa @ 2015-05-20  8:41 UTC (permalink / raw)
  To: Paolo Bonzini, linux-kernel, kvm; +Cc: Xiao Guangrong, rkrcmar

On 2015/05/20 2:25, Paolo Bonzini wrote:
> Prepare for multiple address spaces this way, since a VCPU is not available
> where unaccount_shadowed is called.  We will get to the right kvm_memslots
> 1truct through the role field in struct kvm_mmu_page.

typo: s/1truct/struct/

Reviewed-by: Takuya Yoshikawa <yoshikawa_takuya_b1@lab.ntt.co.jp>

> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>


	Takuya


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 8/9] KVM: x86: pass kvm_mmu_page to gfn_to_rmap
  2015-05-19 17:25 ` [PATCH 8/9] KVM: x86: pass kvm_mmu_page to gfn_to_rmap Paolo Bonzini
@ 2015-05-20 20:09   ` Radim Krčmář
  0 siblings, 0 replies; 16+ messages in thread
From: Radim Krčmář @ 2015-05-20 20:09 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: linux-kernel, kvm, Takuya Yoshikawa, Xiao Guangrong

2015-05-19 19:25+0200, Paolo Bonzini:
> This is always available, and later we could also use the role to look
> up the right memslots array.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> diff --git a/arch/x86/kvm/mmu_audit.c b/arch/x86/kvm/mmu_audit.c
> @@ -192,10 +192,11 @@ static void audit_write_protection(struct kvm *kvm, struct kvm_mmu_page *sp)
>  	u64 *sptep;
>  	struct rmap_iterator iter;
>  
> -	if (sp->role.direct || sp->unsync || sp->role.invalid)
> +	if (sp->role.direct || sp->unsync || sp->role.invalid ||
> +	    sp->role.level != PT_PAGE_TABLE_LEVEL)
>  		return;
>  
> -	rmapp = gfn_to_rmap(kvm, sp->gfn, PT_PAGE_TABLE_LEVEL);

Why were we forcing PT_PAGE_TABLE_LEVEL for all levels?

Thanks.

> +	rmapp = gfn_to_rmap(kvm, sp->gfn, sp);
>  
>  	for_each_rmap_spte(rmapp, &iter, sptep)
>  		if (is_writable_pte(*sptep))

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 9/9] KVM: x86: pass struct kvm_mmu_page to account/unaccount_shadowed
  2015-05-19 17:25 ` [PATCH 9/9] KVM: x86: pass struct kvm_mmu_page to account/unaccount_shadowed Paolo Bonzini
  2015-05-20  8:41   ` Takuya Yoshikawa
@ 2015-05-20 20:12   ` Radim Krčmář
  1 sibling, 0 replies; 16+ messages in thread
From: Radim Krčmář @ 2015-05-20 20:12 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: linux-kernel, kvm, Takuya Yoshikawa, Xiao Guangrong

2015-05-19 19:25+0200, Paolo Bonzini:
> Prepare for multiple address spaces this way, since a VCPU is not available
> where unaccount_shadowed is called.  We will get to the right kvm_memslots
> 1truct through the role field in struct kvm_mmu_page.

struct kvm_mmu_page contains enough information to retrieve a memslot;
is it impractical to cache the memslot pointer there?

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 0/9] KVM: cleanups for memslots data structures
  2015-05-19 17:25 [PATCH 0/9] KVM: cleanups for memslots data structures Paolo Bonzini
                   ` (8 preceding siblings ...)
  2015-05-19 17:25 ` [PATCH 9/9] KVM: x86: pass struct kvm_mmu_page to account/unaccount_shadowed Paolo Bonzini
@ 2015-05-20 20:19 ` Radim Krčmář
  9 siblings, 0 replies; 16+ messages in thread
From: Radim Krčmář @ 2015-05-20 20:19 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: linux-kernel, kvm, Takuya Yoshikawa, Xiao Guangrong

2015-05-19 19:25+0200, Paolo Bonzini:
> These are extracted out of the SMM series, and they make
> some sense on their own.

[1-9/9] look good,
Reviewed-by: Radim Krčmář <rkrcmar@redhat.com>

The only possible difference in behavior that I noticed was in
audit_write_protection [8/9], and it didn't affect much.

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2015-05-20 20:19 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-19 17:25 [PATCH 0/9] KVM: cleanups for memslots data structures Paolo Bonzini
2015-05-19 17:25 ` [PATCH 1/9] KVM: introduce kvm_alloc/free_memslots Paolo Bonzini
2015-05-20  7:38   ` Takuya Yoshikawa
2015-05-19 17:25 ` [PATCH 2/9] KVM: use kvm_memslots whenever possible Paolo Bonzini
2015-05-19 17:25 ` [PATCH 3/9] KVM: const-ify uses of struct kvm_userspace_memory_region Paolo Bonzini
2015-05-20  8:17   ` Takuya Yoshikawa
2015-05-19 17:25 ` [PATCH 4/9] KVM: add memslots argument to kvm_arch_memslots_updated Paolo Bonzini
2015-05-19 17:25 ` [PATCH 5/9] KVM: add "new" argument to kvm_arch_commit_memory_region Paolo Bonzini
2015-05-19 17:25 ` [PATCH 6/9] KVM: pass kvm_memory_slot to gfn_to_page_many_atomic Paolo Bonzini
2015-05-19 17:25 ` [PATCH 7/9] KVM: remove __gfn_to_pfn Paolo Bonzini
2015-05-19 17:25 ` [PATCH 8/9] KVM: x86: pass kvm_mmu_page to gfn_to_rmap Paolo Bonzini
2015-05-20 20:09   ` Radim Krčmář
2015-05-19 17:25 ` [PATCH 9/9] KVM: x86: pass struct kvm_mmu_page to account/unaccount_shadowed Paolo Bonzini
2015-05-20  8:41   ` Takuya Yoshikawa
2015-05-20 20:12   ` Radim Krčmář
2015-05-20 20:19 ` [PATCH 0/9] KVM: cleanups for memslots data structures Radim Krčmář

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).