linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: paulus@samba.org, aik@ozlabs.ru, benh@kernel.crashing.org
Cc: bharata@linux.vnet.ibm.com, linuxppc-dev@lists.ozlabs.org,
	David Gibson <david@gibson.dropbear.id.au>
Subject: [RFCv2 20/25] powerpc/kvm: Make MMU notifier handlers more flexible
Date: Tue,  8 Mar 2016 14:08:57 +1100	[thread overview]
Message-ID: <1457406542-6210-21-git-send-email-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <1457406542-6210-1-git-send-email-david@gibson.dropbear.id.au>

KVM on powerpc uses several MMU notifiers to update guest page tables and
reverse mappings based on host MM events.  At these always act on the
guest's main active hash table and reverse mappings.

However, for HPT resizing we're going to need these to sometimes operate
on a tentative hash table or reverse mapping for an in-progress or
recently completed resize.

To allow that, extend the MMU notifier helper functions to take extra
parameters for the HPT to operate on.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 arch/powerpc/kvm/book3s_64_mmu_hv.c | 65 +++++++++++++++++++++++++------------
 1 file changed, 44 insertions(+), 21 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index d2f04ee..db070ad 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -720,14 +720,38 @@ static void kvmppc_rmap_reset(struct kvm *kvm)
 	srcu_read_unlock(&kvm->srcu, srcu_idx);
 }
 
+static int kvm_handle_hva_range_slot(struct kvm *kvm,
+				     struct kvm_hpt_info *hpt,
+				     struct kvm_memory_slot *memslot,
+				     unsigned long *rmap,
+				     gfn_t gfn_start, gfn_t gfn_end,
+				     int (*handler)(struct kvm *kvm,
+						    struct kvm_hpt_info *hpt,
+						    unsigned long *rmapp,
+						    unsigned long gfn))
+{
+	int ret;
+	int retval = 0;
+	gfn_t gfn;
+
+	for (gfn = gfn_start; gfn < gfn_end; ++gfn) {
+		gfn_t gfn_offset = gfn - memslot->base_gfn;
+
+		ret = handler(kvm, hpt, &rmap[gfn_offset], gfn);
+		retval |= ret;
+	}
+
+	return retval;
+}
+
 static int kvm_handle_hva_range(struct kvm *kvm,
 				unsigned long start,
 				unsigned long end,
 				int (*handler)(struct kvm *kvm,
+					       struct kvm_hpt_info *hpt,
 					       unsigned long *rmapp,
 					       unsigned long gfn))
 {
-	int ret;
 	int retval = 0;
 	struct kvm_memslots *slots;
 	struct kvm_memory_slot *memslot;
@@ -749,28 +773,27 @@ static int kvm_handle_hva_range(struct kvm *kvm,
 		gfn = hva_to_gfn_memslot(hva_start, memslot);
 		gfn_end = hva_to_gfn_memslot(hva_end + PAGE_SIZE - 1, memslot);
 
-		for (; gfn < gfn_end; ++gfn) {
-			gfn_t gfn_offset = gfn - memslot->base_gfn;
-
-			ret = handler(kvm, &memslot->arch.rmap[gfn_offset], gfn);
-			retval |= ret;
-		}
+		retval |= kvm_handle_hva_range_slot(kvm, &kvm->arch.hpt,
+						    memslot, memslot->arch.rmap,
+						    gfn, gfn_end, handler);
 	}
 
 	return retval;
 }
 
 static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
-			  int (*handler)(struct kvm *kvm, unsigned long *rmapp,
+			  int (*handler)(struct kvm *kvm,
+					 struct kvm_hpt_info *hpt,
+					 unsigned long *rmapp,
 					 unsigned long gfn))
 {
 	return kvm_handle_hva_range(kvm, hva, hva + 1, handler);
 }
 
-static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp,
-			   unsigned long gfn)
+static int kvm_unmap_rmapp(struct kvm *kvm, struct kvm_hpt_info *hpt,
+			   unsigned long *rmapp, unsigned long gfn)
 {
-	struct revmap_entry *rev = kvm->arch.hpt.rev;
+	struct revmap_entry *rev = hpt->rev;
 	unsigned long h, i, j;
 	__be64 *hptep;
 	unsigned long ptel, psize, rcbits;
@@ -788,7 +811,7 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp,
 		 * rmap chain lock.
 		 */
 		i = *rmapp & KVMPPC_RMAP_INDEX;
-		hptep = (__be64 *) (kvm->arch.hpt.virt + (i << 4));
+		hptep = (__be64 *) (hpt->virt + (i << 4));
 		if (!try_lock_hpte(hptep, HPTE_V_HVLOCK)) {
 			/* unlock rmap before spinning on the HPTE lock */
 			unlock_rmap(rmapp);
@@ -861,16 +884,16 @@ void kvmppc_core_flush_memslot_hv(struct kvm *kvm,
 		 * thus the present bit can't go from 0 to 1.
 		 */
 		if (*rmapp & KVMPPC_RMAP_PRESENT)
-			kvm_unmap_rmapp(kvm, rmapp, gfn);
+			kvm_unmap_rmapp(kvm, &kvm->arch.hpt, rmapp, gfn);
 		++rmapp;
 		++gfn;
 	}
 }
 
-static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
-			 unsigned long gfn)
+static int kvm_age_rmapp(struct kvm *kvm, struct kvm_hpt_info *hpt,
+			 unsigned long *rmapp, unsigned long gfn)
 {
-	struct revmap_entry *rev = kvm->arch.hpt.rev;
+	struct revmap_entry *rev = hpt->rev;
 	unsigned long head, i, j;
 	__be64 *hptep;
 	int ret = 0;
@@ -888,7 +911,7 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
 
 	i = head = *rmapp & KVMPPC_RMAP_INDEX;
 	do {
-		hptep = (__be64 *) (kvm->arch.hpt.virt + (i << 4));
+		hptep = (__be64 *) (hpt->virt + (i << 4));
 		j = rev[i].forw;
 
 		/* If this HPTE isn't referenced, ignore it */
@@ -925,10 +948,10 @@ int kvm_age_hva_hv(struct kvm *kvm, unsigned long start, unsigned long end)
 	return kvm_handle_hva_range(kvm, start, end, kvm_age_rmapp);
 }
 
-static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
-			      unsigned long gfn)
+static int kvm_test_age_rmapp(struct kvm *kvm, struct kvm_hpt_info *hpt,
+			      unsigned long *rmapp, unsigned long gfn)
 {
-	struct revmap_entry *rev = kvm->arch.hpt.rev;
+	struct revmap_entry *rev = hpt->rev;
 	unsigned long head, i, j;
 	unsigned long *hp;
 	int ret = 1;
@@ -943,7 +966,7 @@ static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
 	if (*rmapp & KVMPPC_RMAP_PRESENT) {
 		i = head = *rmapp & KVMPPC_RMAP_INDEX;
 		do {
-			hp = (unsigned long *)(kvm->arch.hpt.virt + (i << 4));
+			hp = (unsigned long *)(hpt->virt + (i << 4));
 			j = rev[i].forw;
 			if (be64_to_cpu(hp[1]) & HPTE_R_R)
 				goto out;
-- 
2.5.0

  parent reply	other threads:[~2016-03-08  3:09 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-08  3:08 [RFCv2 00/25] PAPR HPT resizing, guest side & host side preliminaries David Gibson
2016-03-08  3:08 ` [RFCv2 01/25] powerpc/mm: Clean up error handling for htab_remove_mapping David Gibson
2016-03-08  3:08 ` [RFCv2 02/25] powerpc/mm: Handle removing maybe-present bolted HPTEs David Gibson
2016-03-08  3:08 ` [RFCv2 03/25] powerpc/mm: Clean up memory hotplug failure paths David Gibson
2016-03-08  3:08 ` [RFCv2 04/25] powerpc/mm: Split hash page table sizing heuristic into a helper David Gibson
2016-03-08  3:08 ` [RFCv2 05/25] pseries: Add hypercall wrappers for hash page table resizing David Gibson
2016-03-08  3:08 ` [RFCv2 06/25] pseries: Add support for hash " David Gibson
2016-03-08  3:08 ` [RFCv2 07/25] pseries: Advertise HPT resizing support via CAS David Gibson
2016-03-08  3:08 ` [RFCv2 08/25] pseries: Automatically resize HPT for memory hot add/remove David Gibson
2016-03-08  3:08 ` [RFCv2 09/25] powerpc/kvm: Corectly report KVM_CAP_PPC_ALLOC_HTAB David Gibson
2016-03-08  3:08 ` [RFCv2 10/25] powerpc/kvm: Add capability flag for hashed page table resizing David Gibson
2016-03-08  3:08 ` [RFCv2 11/25] powerpc/kvm: Rename kvm_alloc_hpt() for clarity David Gibson
2016-03-08  3:08 ` [RFCv2 12/25] powerpc/kvm: Gather HPT related variables into sub-structure David Gibson
2016-03-08  3:08 ` [RFCv2 13/25] powerpc/kvm: Don't store values derivable from HPT order David Gibson
2016-03-08  3:08 ` [RFCv2 14/25] powerpc/kvm: Split HPT allocation from activation David Gibson
2016-03-08  3:08 ` [RFCv2 15/25] powerpc/kvm: Allow KVM_PPC_ALLOCATE_HTAB ioctl() to change HPT size David Gibson
2016-03-08  3:08 ` [RFCv2 16/25] powerpc/kvm: HPT resizing stub implementation David Gibson
2016-03-08  3:08 ` [RFCv2 17/25] powerpc/kvm: Advertise availablity of HPT resizing on KVM HV David Gibson
2016-03-08  3:08 ` [RFCv2 18/25] powerpc/kvm: Outline of HPT resizing implementation David Gibson
2016-03-08  3:08 ` [RFCv2 19/25] powerpc/kbm: Allocations for HPT resizing David Gibson
2016-03-08  3:08 ` David Gibson [this message]
2016-03-08  3:08 ` [RFCv2 21/25] powerpc/kvm: Make MMU notifiers HPT resize aware David Gibson
2016-03-08  3:08 ` [RFCv2 22/25] powerpc/kvm: Exclude HPT resizes when collecting the dirty log David Gibson
2016-03-08  3:09 ` [RFCv2 23/25] powerpc/kvm: Rehashing for HPT resizing David Gibson
2016-03-08  3:09 ` [RFCv2 24/25] powerpc/kvm: HPT resize pivot David Gibson
2016-03-08  3:09 ` [RFCv2 25/25] powerpc/kvm: Harvest RC bits from old HPT after HPT resize David Gibson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1457406542-6210-21-git-send-email-david@gibson.dropbear.id.au \
    --to=david@gibson.dropbear.id.au \
    --cc=aik@ozlabs.ru \
    --cc=benh@kernel.crashing.org \
    --cc=bharata@linux.vnet.ibm.com \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=paulus@samba.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).