All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] KVM: PPC: Book3S: Make LPID/nested LPID allocations dynamic
@ 2022-01-23 12:00 Nicholas Piggin
  2022-01-23 12:00 ` [PATCH 1/6] KVM: PPC: Remove kvmppc_claim_lpid Nicholas Piggin
                   ` (6 more replies)
  0 siblings, 7 replies; 13+ messages in thread
From: Nicholas Piggin @ 2022-01-23 12:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

With LPID width plumbed through from firmware, LPID allocations can now
be dynamic, which requires changing the fixed sized bitmap. Rather than
just dynamically sizing it, switch to IDA allocator.

Nested KVM stays with a fixed 12-bit LPID width for now, but it is also
moved to a more dynamic allocator. In future if nested LPID width is
advertised to a guest it will be simple to take advantage of it.

Thanks,
Nick

Nicholas Piggin (6):
  KVM: PPC: Remove kvmppc_claim_lpid
  KVM: PPC: Book3S HV: Update LPID allocator init for POWER9, Nested
  KVM: PPC: Book3S HV: Use IDA allocator for LPID allocator
  KVM: PPC: Book3S HV Nested: Change nested guest lookup to use idr
  KVM: PPC: Book3S Nested: Use explicit 4096 LPID maximum
  KVM: PPC: Book3S HV: Remove KVMPPC_NR_LPIDS

 arch/powerpc/include/asm/kvm_book3s_asm.h |   3 -
 arch/powerpc/include/asm/kvm_host.h       |  10 +-
 arch/powerpc/include/asm/kvm_ppc.h        |   1 -
 arch/powerpc/include/asm/reg.h            |   2 -
 arch/powerpc/kvm/book3s_64_mmu_hv.c       |  34 +++---
 arch/powerpc/kvm/book3s_hv_nested.c       | 134 +++++++++++-----------
 arch/powerpc/kvm/book3s_hv_rmhandlers.S   |   8 ++
 arch/powerpc/kvm/e500mc.c                 |   1 -
 arch/powerpc/kvm/powerpc.c                |  30 +++--
 arch/powerpc/mm/init_64.c                 |   3 +
 10 files changed, 121 insertions(+), 105 deletions(-)

-- 
2.23.0


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

* [PATCH 1/6] KVM: PPC: Remove kvmppc_claim_lpid
  2022-01-23 12:00 [PATCH 0/6] KVM: PPC: Book3S: Make LPID/nested LPID allocations dynamic Nicholas Piggin
@ 2022-01-23 12:00 ` Nicholas Piggin
  2022-01-23 12:00 ` [PATCH 2/6] KVM: PPC: Book3S HV: Update LPID allocator init for POWER9, Nested Nicholas Piggin
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Nicholas Piggin @ 2022-01-23 12:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

Removing kvmppc_claim_lpid makes the lpid allocator API a bit simpler to
change the underlying implementation in a future patch.

The host LPID is always 0, so that can be a detail of the allocator. If
the allocator range is restricted, that can reserve LPIDs at the top of
the range. This allows kvmppc_claim_lpid to be removed.
---
 arch/powerpc/include/asm/kvm_ppc.h  |  1 -
 arch/powerpc/kvm/book3s_64_mmu_hv.c | 14 ++++++--------
 arch/powerpc/kvm/e500mc.c           |  1 -
 arch/powerpc/kvm/powerpc.c          |  7 +------
 4 files changed, 7 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index a14dbcd1b8ce..7e22199a95c9 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -863,7 +863,6 @@ int kvm_vcpu_ioctl_dirty_tlb(struct kvm_vcpu *vcpu,
 			     struct kvm_dirty_tlb *cfg);
 
 long kvmppc_alloc_lpid(void);
-void kvmppc_claim_lpid(long lpid);
 void kvmppc_free_lpid(long lpid);
 void kvmppc_init_lpid(unsigned long nr_lpids);
 
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index 213232914367..09fc52b6f390 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -256,14 +256,15 @@ void kvmppc_map_vrma(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot,
 
 int kvmppc_mmu_hv_init(void)
 {
-	unsigned long host_lpid, rsvd_lpid;
+	unsigned long rsvd_lpid;
 
 	if (!mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))
 		return -EINVAL;
 
-	host_lpid = 0;
-	if (cpu_has_feature(CPU_FTR_HVMODE))
-		host_lpid = mfspr(SPRN_LPID);
+	if (cpu_has_feature(CPU_FTR_HVMODE)) {
+		if (WARN_ON(mfspr(SPRN_LPID) != 0))
+			return -EINVAL;
+	}
 
 	/* POWER8 and above have 12-bit LPIDs (10-bit in POWER7) */
 	if (cpu_has_feature(CPU_FTR_ARCH_207S))
@@ -271,11 +272,8 @@ int kvmppc_mmu_hv_init(void)
 	else
 		rsvd_lpid = LPID_RSVD_POWER7;
 
-	kvmppc_init_lpid(rsvd_lpid + 1);
-
-	kvmppc_claim_lpid(host_lpid);
 	/* rsvd_lpid is reserved for use in partition switching */
-	kvmppc_claim_lpid(rsvd_lpid);
+	kvmppc_init_lpid(rsvd_lpid);
 
 	return 0;
 }
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index 1c189b5aadcc..7087d8f2037a 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -398,7 +398,6 @@ static int __init kvmppc_e500mc_init(void)
 	 * allocator.
 	 */
 	kvmppc_init_lpid(KVMPPC_NR_LPIDS/threads_per_core);
-	kvmppc_claim_lpid(0); /* host */
 
 	r = kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), 0, THIS_MODULE);
 	if (r)
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 2ad0ccd202d5..102993462872 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -2472,12 +2472,6 @@ long kvmppc_alloc_lpid(void)
 }
 EXPORT_SYMBOL_GPL(kvmppc_alloc_lpid);
 
-void kvmppc_claim_lpid(long lpid)
-{
-	set_bit(lpid, lpid_inuse);
-}
-EXPORT_SYMBOL_GPL(kvmppc_claim_lpid);
-
 void kvmppc_free_lpid(long lpid)
 {
 	clear_bit(lpid, lpid_inuse);
@@ -2488,6 +2482,7 @@ void kvmppc_init_lpid(unsigned long nr_lpids_param)
 {
 	nr_lpids = min_t(unsigned long, KVMPPC_NR_LPIDS, nr_lpids_param);
 	memset(lpid_inuse, 0, sizeof(lpid_inuse));
+	set_bit(0, lpid_inuse); /* The host LPID must always be 0 */
 }
 EXPORT_SYMBOL_GPL(kvmppc_init_lpid);
 
-- 
2.23.0


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

* [PATCH 2/6] KVM: PPC: Book3S HV: Update LPID allocator init for POWER9, Nested
  2022-01-23 12:00 [PATCH 0/6] KVM: PPC: Book3S: Make LPID/nested LPID allocations dynamic Nicholas Piggin
  2022-01-23 12:00 ` [PATCH 1/6] KVM: PPC: Remove kvmppc_claim_lpid Nicholas Piggin
@ 2022-01-23 12:00 ` Nicholas Piggin
  2022-01-24 22:13   ` Fabiano Rosas
  2022-01-23 12:00 ` [PATCH 3/6] KVM: PPC: Book3S HV: Use IDA allocator for LPID allocator Nicholas Piggin
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Nicholas Piggin @ 2022-01-23 12:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

The LPID allocator init is changed to:
- use mmu_lpid_bits rather than hard-coding;
- use KVM_MAX_NESTED_GUESTS for nested hypervisors;
- not reserve the top LPID on POWER9 and newer CPUs.

The reserved LPID is made a POWER7/8-specific detail.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/include/asm/kvm_book3s_asm.h |  2 +-
 arch/powerpc/include/asm/reg.h            |  2 --
 arch/powerpc/kvm/book3s_64_mmu_hv.c       | 29 ++++++++++++++++-------
 arch/powerpc/kvm/book3s_hv_rmhandlers.S   |  8 +++++++
 arch/powerpc/mm/init_64.c                 |  3 +++
 5 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h
index b6d31bff5209..e6bda70b1d93 100644
--- a/arch/powerpc/include/asm/kvm_book3s_asm.h
+++ b/arch/powerpc/include/asm/kvm_book3s_asm.h
@@ -15,7 +15,7 @@
 #define XICS_IPI		2	/* interrupt source # for IPIs */
 
 /* LPIDs we support with this build -- runtime limit may be lower */
-#define KVMPPC_NR_LPIDS			(LPID_RSVD + 1)
+#define KVMPPC_NR_LPIDS			(1UL << 12)
 
 /* Maximum number of threads per physical core */
 #define MAX_SMT_THREADS		8
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 1e14324c5190..1e8b2e04e626 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -473,8 +473,6 @@
 #ifndef SPRN_LPID
 #define SPRN_LPID	0x13F	/* Logical Partition Identifier */
 #endif
-#define   LPID_RSVD_POWER7	0x3ff	/* Reserved LPID for partn switching */
-#define   LPID_RSVD		0xfff	/* Reserved LPID for partn switching */
 #define	SPRN_HMER	0x150	/* Hypervisor maintenance exception reg */
 #define   HMER_DEBUG_TRIG	(1ul << (63 - 17)) /* Debug trigger */
 #define	SPRN_HMEER	0x151	/* Hyp maintenance exception enable reg */
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index 09fc52b6f390..5be92d5bc099 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -256,7 +256,7 @@ void kvmppc_map_vrma(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot,
 
 int kvmppc_mmu_hv_init(void)
 {
-	unsigned long rsvd_lpid;
+	unsigned long nr_lpids;
 
 	if (!mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))
 		return -EINVAL;
@@ -264,16 +264,29 @@ int kvmppc_mmu_hv_init(void)
 	if (cpu_has_feature(CPU_FTR_HVMODE)) {
 		if (WARN_ON(mfspr(SPRN_LPID) != 0))
 			return -EINVAL;
+		nr_lpids = 1UL << mmu_lpid_bits;
+	} else {
+		nr_lpids = KVM_MAX_NESTED_GUESTS;
 	}
 
-	/* POWER8 and above have 12-bit LPIDs (10-bit in POWER7) */
-	if (cpu_has_feature(CPU_FTR_ARCH_207S))
-		rsvd_lpid = LPID_RSVD;
-	else
-		rsvd_lpid = LPID_RSVD_POWER7;
+	if (nr_lpids > KVMPPC_NR_LPIDS)
+		nr_lpids = KVMPPC_NR_LPIDS;
+
+	if (!cpu_has_feature(CPU_FTR_ARCH_300)) {
+		/* POWER7 has 10-bit LPIDs, POWER8 has 12-bit LPIDs */
+		if (cpu_has_feature(CPU_FTR_ARCH_207S))
+			WARN_ON(nr_lpids != 1UL << 12);
+		else
+			WARN_ON(nr_lpids != 1UL << 10);
+
+		/*
+		 * Reserve the last implemented LPID use in partition
+		 * switching for POWER7 and POWER8.
+		 */
+		nr_lpids -= 1;
+	}
 
-	/* rsvd_lpid is reserved for use in partition switching */
-	kvmppc_init_lpid(rsvd_lpid);
+	kvmppc_init_lpid(nr_lpids);
 
 	return 0;
 }
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index d185dee26026..0c552885a032 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -50,6 +50,14 @@
 #define STACK_SLOT_UAMOR	(SFS-88)
 #define STACK_SLOT_FSCR		(SFS-96)
 
+/*
+ * Use the last LPID (all implemented LPID bits = 1) for partition switching.
+ * This is reserved in the LPID allocator. POWER7 only implements 0x3ff, but
+ * we write 0xfff into the LPID SPR anyway, which seems to work and just
+ * ignores the top bits.
+ */
+#define   LPID_RSVD		0xfff
+
 /*
  * Call kvmppc_hv_entry in real mode.
  * Must be called with interrupts hard-disabled.
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 35f46bf54281..ad1a41e3ff1c 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -371,6 +371,9 @@ void register_page_bootmem_memmap(unsigned long section_nr,
 
 #ifdef CONFIG_PPC_BOOK3S_64
 unsigned int mmu_lpid_bits;
+#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+EXPORT_SYMBOL_GPL(mmu_lpid_bits);
+#endif
 unsigned int mmu_pid_bits;
 
 static bool disable_radix = !IS_ENABLED(CONFIG_PPC_RADIX_MMU_DEFAULT);
-- 
2.23.0


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

* [PATCH 3/6] KVM: PPC: Book3S HV: Use IDA allocator for LPID allocator
  2022-01-23 12:00 [PATCH 0/6] KVM: PPC: Book3S: Make LPID/nested LPID allocations dynamic Nicholas Piggin
  2022-01-23 12:00 ` [PATCH 1/6] KVM: PPC: Remove kvmppc_claim_lpid Nicholas Piggin
  2022-01-23 12:00 ` [PATCH 2/6] KVM: PPC: Book3S HV: Update LPID allocator init for POWER9, Nested Nicholas Piggin
@ 2022-01-23 12:00 ` Nicholas Piggin
  2022-01-24 22:13   ` Fabiano Rosas
  2022-01-23 12:00 ` [PATCH 4/6] KVM: PPC: Book3S HV Nested: Change nested guest lookup to use idr Nicholas Piggin
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Nicholas Piggin @ 2022-01-23 12:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

This removes the fixed-size lpid_inuse array.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/kvm/powerpc.c | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 102993462872..c527a5751b46 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -2453,20 +2453,22 @@ long kvm_arch_vm_ioctl(struct file *filp,
 	return r;
 }
 
-static unsigned long lpid_inuse[BITS_TO_LONGS(KVMPPC_NR_LPIDS)];
+static DEFINE_IDA(lpid_inuse);
 static unsigned long nr_lpids;
 
 long kvmppc_alloc_lpid(void)
 {
-	long lpid;
+	int lpid;
 
-	do {
-		lpid = find_first_zero_bit(lpid_inuse, KVMPPC_NR_LPIDS);
-		if (lpid >= nr_lpids) {
+	/* The host LPID must always be 0 (allocation starts at 1) */
+	lpid = ida_alloc_range(&lpid_inuse, 1, nr_lpids - 1, GFP_KERNEL);
+	if (lpid < 0) {
+		if (lpid == -ENOMEM)
+			pr_err("%s: Out of memory\n", __func__);
+		else
 			pr_err("%s: No LPIDs free\n", __func__);
-			return -ENOMEM;
-		}
-	} while (test_and_set_bit(lpid, lpid_inuse));
+		return -ENOMEM;
+	}
 
 	return lpid;
 }
@@ -2474,15 +2476,14 @@ EXPORT_SYMBOL_GPL(kvmppc_alloc_lpid);
 
 void kvmppc_free_lpid(long lpid)
 {
-	clear_bit(lpid, lpid_inuse);
+	ida_free(&lpid_inuse, lpid);
 }
 EXPORT_SYMBOL_GPL(kvmppc_free_lpid);
 
+/* nr_lpids_param includes the host LPID */
 void kvmppc_init_lpid(unsigned long nr_lpids_param)
 {
-	nr_lpids = min_t(unsigned long, KVMPPC_NR_LPIDS, nr_lpids_param);
-	memset(lpid_inuse, 0, sizeof(lpid_inuse));
-	set_bit(0, lpid_inuse); /* The host LPID must always be 0 */
+	nr_lpids = nr_lpids_param;
 }
 EXPORT_SYMBOL_GPL(kvmppc_init_lpid);
 
-- 
2.23.0


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

* [PATCH 4/6] KVM: PPC: Book3S HV Nested: Change nested guest lookup to use idr
  2022-01-23 12:00 [PATCH 0/6] KVM: PPC: Book3S: Make LPID/nested LPID allocations dynamic Nicholas Piggin
                   ` (2 preceding siblings ...)
  2022-01-23 12:00 ` [PATCH 3/6] KVM: PPC: Book3S HV: Use IDA allocator for LPID allocator Nicholas Piggin
@ 2022-01-23 12:00 ` Nicholas Piggin
  2022-01-24 22:14   ` Fabiano Rosas
  2022-01-23 12:00 ` [PATCH 5/6] KVM: PPC: Book3S Nested: Use explicit 4096 LPID maximum Nicholas Piggin
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Nicholas Piggin @ 2022-01-23 12:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

This removes the fixed sized kvm->arch.nested_guests array.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/include/asm/kvm_host.h |   3 +-
 arch/powerpc/kvm/book3s_hv_nested.c | 110 +++++++++++++++-------------
 2 files changed, 59 insertions(+), 54 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index d9bf60bf0816..5fd0564e5c94 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -326,8 +326,7 @@ struct kvm_arch {
 	struct list_head uvmem_pfns;
 	struct mutex mmu_setup_lock;	/* nests inside vcpu mutexes */
 	u64 l1_ptcr;
-	int max_nested_lpid;
-	struct kvm_nested_guest *nested_guests[KVM_MAX_NESTED_GUESTS];
+	struct idr kvm_nested_guest_idr;
 	/* This array can grow quite large, keep it at the end */
 	struct kvmppc_vcore *vcores[KVM_MAX_VCORES];
 #endif
diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c
index 9d373f8963ee..1eff969b095c 100644
--- a/arch/powerpc/kvm/book3s_hv_nested.c
+++ b/arch/powerpc/kvm/book3s_hv_nested.c
@@ -521,11 +521,6 @@ static void kvmhv_set_nested_ptbl(struct kvm_nested_guest *gp)
 	kvmhv_set_ptbl_entry(gp->shadow_lpid, dw0, gp->process_table);
 }
 
-void kvmhv_vm_nested_init(struct kvm *kvm)
-{
-	kvm->arch.max_nested_lpid = -1;
-}
-
 /*
  * Handle the H_SET_PARTITION_TABLE hcall.
  * r4 = guest real address of partition table + log_2(size) - 12
@@ -660,6 +655,35 @@ static void kvmhv_update_ptbl_cache(struct kvm_nested_guest *gp)
 	kvmhv_set_nested_ptbl(gp);
 }
 
+void kvmhv_vm_nested_init(struct kvm *kvm)
+{
+	idr_init(&kvm->arch.kvm_nested_guest_idr);
+}
+
+static struct kvm_nested_guest *__find_nested(struct kvm *kvm, int lpid)
+{
+	return idr_find(&kvm->arch.kvm_nested_guest_idr, lpid);
+}
+
+static bool __prealloc_nested(struct kvm *kvm, int lpid)
+{
+	if (idr_alloc(&kvm->arch.kvm_nested_guest_idr,
+				NULL, lpid, lpid + 1, GFP_KERNEL) != lpid)
+		return false;
+	return true;
+}
+
+static void __add_nested(struct kvm *kvm, int lpid, struct kvm_nested_guest *gp)
+{
+	if (idr_replace(&kvm->arch.kvm_nested_guest_idr, gp, lpid))
+		WARN_ON(1);
+}
+
+static void __remove_nested(struct kvm *kvm, int lpid)
+{
+	idr_remove(&kvm->arch.kvm_nested_guest_idr, lpid);
+}
+
 static struct kvm_nested_guest *kvmhv_alloc_nested(struct kvm *kvm, unsigned int lpid)
 {
 	struct kvm_nested_guest *gp;
@@ -720,13 +744,8 @@ static void kvmhv_remove_nested(struct kvm_nested_guest *gp)
 	long ref;
 
 	spin_lock(&kvm->mmu_lock);
-	if (gp == kvm->arch.nested_guests[lpid]) {
-		kvm->arch.nested_guests[lpid] = NULL;
-		if (lpid == kvm->arch.max_nested_lpid) {
-			while (--lpid >= 0 && !kvm->arch.nested_guests[lpid])
-				;
-			kvm->arch.max_nested_lpid = lpid;
-		}
+	if (gp == __find_nested(kvm, lpid)) {
+		__remove_nested(kvm, lpid);
 		--gp->refcnt;
 	}
 	ref = gp->refcnt;
@@ -743,24 +762,22 @@ static void kvmhv_remove_nested(struct kvm_nested_guest *gp)
  */
 void kvmhv_release_all_nested(struct kvm *kvm)
 {
-	int i;
+	int lpid;
 	struct kvm_nested_guest *gp;
 	struct kvm_nested_guest *freelist = NULL;
 	struct kvm_memory_slot *memslot;
 	int srcu_idx, bkt;
 
 	spin_lock(&kvm->mmu_lock);
-	for (i = 0; i <= kvm->arch.max_nested_lpid; i++) {
-		gp = kvm->arch.nested_guests[i];
-		if (!gp)
-			continue;
-		kvm->arch.nested_guests[i] = NULL;
+	idr_for_each_entry(&kvm->arch.kvm_nested_guest_idr, gp, lpid) {
+		__remove_nested(kvm, lpid);
 		if (--gp->refcnt == 0) {
 			gp->next = freelist;
 			freelist = gp;
 		}
 	}
-	kvm->arch.max_nested_lpid = -1;
+	idr_destroy(&kvm->arch.kvm_nested_guest_idr);
+	/* idr is empty and may be reused at this point */
 	spin_unlock(&kvm->mmu_lock);
 	while ((gp = freelist) != NULL) {
 		freelist = gp->next;
@@ -797,7 +814,7 @@ struct kvm_nested_guest *kvmhv_get_nested(struct kvm *kvm, int l1_lpid,
 		return NULL;
 
 	spin_lock(&kvm->mmu_lock);
-	gp = kvm->arch.nested_guests[l1_lpid];
+	gp = __find_nested(kvm, l1_lpid);
 	if (gp)
 		++gp->refcnt;
 	spin_unlock(&kvm->mmu_lock);
@@ -808,17 +825,19 @@ struct kvm_nested_guest *kvmhv_get_nested(struct kvm *kvm, int l1_lpid,
 	newgp = kvmhv_alloc_nested(kvm, l1_lpid);
 	if (!newgp)
 		return NULL;
+
+	if (!__prealloc_nested(kvm, l1_lpid)) {
+		kvmhv_release_nested(newgp);
+		return NULL;
+	}
+
 	spin_lock(&kvm->mmu_lock);
-	if (kvm->arch.nested_guests[l1_lpid]) {
-		/* someone else beat us to it */
-		gp = kvm->arch.nested_guests[l1_lpid];
-	} else {
-		kvm->arch.nested_guests[l1_lpid] = newgp;
+	gp = __find_nested(kvm, l1_lpid);
+	if (!gp) {
+		__add_nested(kvm, l1_lpid, newgp);
 		++newgp->refcnt;
 		gp = newgp;
 		newgp = NULL;
-		if (l1_lpid > kvm->arch.max_nested_lpid)
-			kvm->arch.max_nested_lpid = l1_lpid;
 	}
 	++gp->refcnt;
 	spin_unlock(&kvm->mmu_lock);
@@ -841,20 +860,13 @@ void kvmhv_put_nested(struct kvm_nested_guest *gp)
 		kvmhv_release_nested(gp);
 }
 
-static struct kvm_nested_guest *kvmhv_find_nested(struct kvm *kvm, int lpid)
-{
-	if (lpid > kvm->arch.max_nested_lpid)
-		return NULL;
-	return kvm->arch.nested_guests[lpid];
-}
-
 pte_t *find_kvm_nested_guest_pte(struct kvm *kvm, unsigned long lpid,
 				 unsigned long ea, unsigned *hshift)
 {
 	struct kvm_nested_guest *gp;
 	pte_t *pte;
 
-	gp = kvmhv_find_nested(kvm, lpid);
+	gp = __find_nested(kvm, lpid);
 	if (!gp)
 		return NULL;
 
@@ -960,7 +972,7 @@ static void kvmhv_remove_nest_rmap(struct kvm *kvm, u64 n_rmap,
 
 	gpa = n_rmap & RMAP_NESTED_GPA_MASK;
 	lpid = (n_rmap & RMAP_NESTED_LPID_MASK) >> RMAP_NESTED_LPID_SHIFT;
-	gp = kvmhv_find_nested(kvm, lpid);
+	gp = __find_nested(kvm, lpid);
 	if (!gp)
 		return;
 
@@ -1152,16 +1164,13 @@ static void kvmhv_emulate_tlbie_all_lpid(struct kvm_vcpu *vcpu, int ric)
 {
 	struct kvm *kvm = vcpu->kvm;
 	struct kvm_nested_guest *gp;
-	int i;
+	int lpid;
 
 	spin_lock(&kvm->mmu_lock);
-	for (i = 0; i <= kvm->arch.max_nested_lpid; i++) {
-		gp = kvm->arch.nested_guests[i];
-		if (gp) {
-			spin_unlock(&kvm->mmu_lock);
-			kvmhv_emulate_tlbie_lpid(vcpu, gp, ric);
-			spin_lock(&kvm->mmu_lock);
-		}
+	idr_for_each_entry(&kvm->arch.kvm_nested_guest_idr, gp, lpid) {
+		spin_unlock(&kvm->mmu_lock);
+		kvmhv_emulate_tlbie_lpid(vcpu, gp, ric);
+		spin_lock(&kvm->mmu_lock);
 	}
 	spin_unlock(&kvm->mmu_lock);
 }
@@ -1313,7 +1322,7 @@ long do_h_rpt_invalidate_pat(struct kvm_vcpu *vcpu, unsigned long lpid,
 	 * H_ENTER_NESTED call. Since we can't differentiate this case from
 	 * the invalid case, we ignore such flush requests and return success.
 	 */
-	if (!kvmhv_find_nested(vcpu->kvm, lpid))
+	if (!__find_nested(vcpu->kvm, lpid))
 		return H_SUCCESS;
 
 	/*
@@ -1657,15 +1666,12 @@ long int kvmhv_nested_page_fault(struct kvm_vcpu *vcpu)
 
 int kvmhv_nested_next_lpid(struct kvm *kvm, int lpid)
 {
-	int ret = -1;
+	int ret = lpid + 1;
 
 	spin_lock(&kvm->mmu_lock);
-	while (++lpid <= kvm->arch.max_nested_lpid) {
-		if (kvm->arch.nested_guests[lpid]) {
-			ret = lpid;
-			break;
-		}
-	}
+	if (!idr_get_next(&kvm->arch.kvm_nested_guest_idr, &ret))
+		ret = -1;
 	spin_unlock(&kvm->mmu_lock);
+
 	return ret;
 }
-- 
2.23.0


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

* [PATCH 5/6] KVM: PPC: Book3S Nested: Use explicit 4096 LPID maximum
  2022-01-23 12:00 [PATCH 0/6] KVM: PPC: Book3S: Make LPID/nested LPID allocations dynamic Nicholas Piggin
                   ` (3 preceding siblings ...)
  2022-01-23 12:00 ` [PATCH 4/6] KVM: PPC: Book3S HV Nested: Change nested guest lookup to use idr Nicholas Piggin
@ 2022-01-23 12:00 ` Nicholas Piggin
  2022-01-24 22:15   ` Fabiano Rosas
  2022-01-23 12:00 ` [PATCH 6/6] KVM: PPC: Book3S HV: Remove KVMPPC_NR_LPIDS Nicholas Piggin
  2022-05-24 10:51 ` [PATCH 0/6] KVM: PPC: Book3S: Make LPID/nested LPID allocations dynamic Michael Ellerman
  6 siblings, 1 reply; 13+ messages in thread
From: Nicholas Piggin @ 2022-01-23 12:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

Rather than tie this to KVMPPC_NR_LPIDS which is becoming more dynamic,
fix it to 4096 (12-bits) explicitly for now.

kvmhv_get_nested() does not have to check against KVM_MAX_NESTED_GUESTS
because the L1 partition table registration hcall already did that, and
it checks against the partition table size.

This patch also puts all the partition table size calculations into the
same form, using 12 for the architected size field shift and 4 for the
shift corresponding to the partition table entry size.

Signed-of-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/include/asm/kvm_host.h |  7 ++++++-
 arch/powerpc/kvm/book3s_64_mmu_hv.c |  2 +-
 arch/powerpc/kvm/book3s_hv_nested.c | 24 +++++++++++-------------
 3 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 5fd0564e5c94..e6fb03884dcc 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -34,7 +34,12 @@
 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
 #include <asm/kvm_book3s_asm.h>		/* for MAX_SMT_THREADS */
 #define KVM_MAX_VCPU_IDS	(MAX_SMT_THREADS * KVM_MAX_VCORES)
-#define KVM_MAX_NESTED_GUESTS	KVMPPC_NR_LPIDS
+
+/*
+ * Limit the nested partition table to 4096 entries (because that's what
+ * hardware supports). Both guest and host use this value.
+ */
+#define KVM_MAX_NESTED_GUESTS_SHIFT	12
 
 #else
 #define KVM_MAX_VCPU_IDS	KVM_MAX_VCPUS
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index 5be92d5bc099..f983fb36cbf2 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -266,7 +266,7 @@ int kvmppc_mmu_hv_init(void)
 			return -EINVAL;
 		nr_lpids = 1UL << mmu_lpid_bits;
 	} else {
-		nr_lpids = KVM_MAX_NESTED_GUESTS;
+		nr_lpids = 1UL << KVM_MAX_NESTED_GUESTS_SHIFT;
 	}
 
 	if (nr_lpids > KVMPPC_NR_LPIDS)
diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c
index 1eff969b095c..75169e0753ce 100644
--- a/arch/powerpc/kvm/book3s_hv_nested.c
+++ b/arch/powerpc/kvm/book3s_hv_nested.c
@@ -439,10 +439,11 @@ long kvmhv_nested_init(void)
 	if (!radix_enabled())
 		return -ENODEV;
 
-	/* find log base 2 of KVMPPC_NR_LPIDS, rounding up */
-	ptb_order = __ilog2(KVMPPC_NR_LPIDS - 1) + 1;
-	if (ptb_order < 8)
-		ptb_order = 8;
+	/* Partition table entry is 1<<4 bytes in size, hence the 4. */
+	ptb_order = KVM_MAX_NESTED_GUESTS_SHIFT + 4;
+	/* Minimum partition table size is 1<<12 bytes */
+	if (ptb_order < 12)
+		ptb_order = 12;
 	pseries_partition_tb = kmalloc(sizeof(struct patb_entry) << ptb_order,
 				       GFP_KERNEL);
 	if (!pseries_partition_tb) {
@@ -450,7 +451,7 @@ long kvmhv_nested_init(void)
 		return -ENOMEM;
 	}
 
-	ptcr = __pa(pseries_partition_tb) | (ptb_order - 8);
+	ptcr = __pa(pseries_partition_tb) | (ptb_order - 12);
 	rc = plpar_hcall_norets(H_SET_PARTITION_TABLE, ptcr);
 	if (rc != H_SUCCESS) {
 		pr_err("kvm-hv: Parent hypervisor does not support nesting (rc=%ld)\n",
@@ -534,16 +535,14 @@ long kvmhv_set_partition_table(struct kvm_vcpu *vcpu)
 	long ret = H_SUCCESS;
 
 	srcu_idx = srcu_read_lock(&kvm->srcu);
-	/*
-	 * Limit the partition table to 4096 entries (because that's what
-	 * hardware supports), and check the base address.
-	 */
-	if ((ptcr & PRTS_MASK) > 12 - 8 ||
+	/* Check partition size and base address. */
+	if ((ptcr & PRTS_MASK) + 12 - 4 > KVM_MAX_NESTED_GUESTS_SHIFT ||
 	    !kvm_is_visible_gfn(vcpu->kvm, (ptcr & PRTB_MASK) >> PAGE_SHIFT))
 		ret = H_PARAMETER;
 	srcu_read_unlock(&kvm->srcu, srcu_idx);
 	if (ret == H_SUCCESS)
 		kvm->arch.l1_ptcr = ptcr;
+
 	return ret;
 }
 
@@ -639,7 +638,7 @@ static void kvmhv_update_ptbl_cache(struct kvm_nested_guest *gp)
 
 	ret = -EFAULT;
 	ptbl_addr = (kvm->arch.l1_ptcr & PRTB_MASK) + (gp->l1_lpid << 4);
-	if (gp->l1_lpid < (1ul << ((kvm->arch.l1_ptcr & PRTS_MASK) + 8))) {
+	if (gp->l1_lpid < (1ul << ((kvm->arch.l1_ptcr & PRTS_MASK) + 12 - 4))) {
 		int srcu_idx = srcu_read_lock(&kvm->srcu);
 		ret = kvm_read_guest(kvm, ptbl_addr,
 				     &ptbl_entry, sizeof(ptbl_entry));
@@ -809,8 +808,7 @@ struct kvm_nested_guest *kvmhv_get_nested(struct kvm *kvm, int l1_lpid,
 {
 	struct kvm_nested_guest *gp, *newgp;
 
-	if (l1_lpid >= KVM_MAX_NESTED_GUESTS ||
-	    l1_lpid >= (1ul << ((kvm->arch.l1_ptcr & PRTS_MASK) + 12 - 4)))
+	if (l1_lpid >= (1ul << ((kvm->arch.l1_ptcr & PRTS_MASK) + 12 - 4)))
 		return NULL;
 
 	spin_lock(&kvm->mmu_lock);
-- 
2.23.0


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

* [PATCH 6/6] KVM: PPC: Book3S HV: Remove KVMPPC_NR_LPIDS
  2022-01-23 12:00 [PATCH 0/6] KVM: PPC: Book3S: Make LPID/nested LPID allocations dynamic Nicholas Piggin
                   ` (4 preceding siblings ...)
  2022-01-23 12:00 ` [PATCH 5/6] KVM: PPC: Book3S Nested: Use explicit 4096 LPID maximum Nicholas Piggin
@ 2022-01-23 12:00 ` Nicholas Piggin
  2022-01-24 22:15   ` Fabiano Rosas
  2022-05-24 10:51 ` [PATCH 0/6] KVM: PPC: Book3S: Make LPID/nested LPID allocations dynamic Michael Ellerman
  6 siblings, 1 reply; 13+ messages in thread
From: Nicholas Piggin @ 2022-01-23 12:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

KVMPPC_NR_LPIDS no longer represents any size restriction on the
LPID space and can be removed. A CPU with more than 12 LPID bits
implemented will now be able to create more than 4095 guests.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/include/asm/kvm_book3s_asm.h | 3 ---
 arch/powerpc/kvm/book3s_64_mmu_hv.c       | 3 ---
 2 files changed, 6 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h
index e6bda70b1d93..c8882d9b86c2 100644
--- a/arch/powerpc/include/asm/kvm_book3s_asm.h
+++ b/arch/powerpc/include/asm/kvm_book3s_asm.h
@@ -14,9 +14,6 @@
 #define XICS_MFRR		0xc
 #define XICS_IPI		2	/* interrupt source # for IPIs */
 
-/* LPIDs we support with this build -- runtime limit may be lower */
-#define KVMPPC_NR_LPIDS			(1UL << 12)
-
 /* Maximum number of threads per physical core */
 #define MAX_SMT_THREADS		8
 
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index f983fb36cbf2..aafd2a74304c 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -269,9 +269,6 @@ int kvmppc_mmu_hv_init(void)
 		nr_lpids = 1UL << KVM_MAX_NESTED_GUESTS_SHIFT;
 	}
 
-	if (nr_lpids > KVMPPC_NR_LPIDS)
-		nr_lpids = KVMPPC_NR_LPIDS;
-
 	if (!cpu_has_feature(CPU_FTR_ARCH_300)) {
 		/* POWER7 has 10-bit LPIDs, POWER8 has 12-bit LPIDs */
 		if (cpu_has_feature(CPU_FTR_ARCH_207S))
-- 
2.23.0


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

* Re: [PATCH 2/6] KVM: PPC: Book3S HV: Update LPID allocator init for POWER9, Nested
  2022-01-23 12:00 ` [PATCH 2/6] KVM: PPC: Book3S HV: Update LPID allocator init for POWER9, Nested Nicholas Piggin
@ 2022-01-24 22:13   ` Fabiano Rosas
  0 siblings, 0 replies; 13+ messages in thread
From: Fabiano Rosas @ 2022-01-24 22:13 UTC (permalink / raw)
  To: Nicholas Piggin, linuxppc-dev; +Cc: Nicholas Piggin

Nicholas Piggin <npiggin@gmail.com> writes:

> The LPID allocator init is changed to:
> - use mmu_lpid_bits rather than hard-coding;
> - use KVM_MAX_NESTED_GUESTS for nested hypervisors;
> - not reserve the top LPID on POWER9 and newer CPUs.
>
> The reserved LPID is made a POWER7/8-specific detail.
>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---

Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com>

>  arch/powerpc/include/asm/kvm_book3s_asm.h |  2 +-
>  arch/powerpc/include/asm/reg.h            |  2 --
>  arch/powerpc/kvm/book3s_64_mmu_hv.c       | 29 ++++++++++++++++-------
>  arch/powerpc/kvm/book3s_hv_rmhandlers.S   |  8 +++++++
>  arch/powerpc/mm/init_64.c                 |  3 +++
>  5 files changed, 33 insertions(+), 11 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h
> index b6d31bff5209..e6bda70b1d93 100644
> --- a/arch/powerpc/include/asm/kvm_book3s_asm.h
> +++ b/arch/powerpc/include/asm/kvm_book3s_asm.h
> @@ -15,7 +15,7 @@
>  #define XICS_IPI		2	/* interrupt source # for IPIs */
>
>  /* LPIDs we support with this build -- runtime limit may be lower */
> -#define KVMPPC_NR_LPIDS			(LPID_RSVD + 1)
> +#define KVMPPC_NR_LPIDS			(1UL << 12)
>
>  /* Maximum number of threads per physical core */
>  #define MAX_SMT_THREADS		8
> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
> index 1e14324c5190..1e8b2e04e626 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -473,8 +473,6 @@
>  #ifndef SPRN_LPID
>  #define SPRN_LPID	0x13F	/* Logical Partition Identifier */
>  #endif
> -#define   LPID_RSVD_POWER7	0x3ff	/* Reserved LPID for partn switching */
> -#define   LPID_RSVD		0xfff	/* Reserved LPID for partn switching */
>  #define	SPRN_HMER	0x150	/* Hypervisor maintenance exception reg */
>  #define   HMER_DEBUG_TRIG	(1ul << (63 - 17)) /* Debug trigger */
>  #define	SPRN_HMEER	0x151	/* Hyp maintenance exception enable reg */
> diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
> index 09fc52b6f390..5be92d5bc099 100644
> --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
> +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
> @@ -256,7 +256,7 @@ void kvmppc_map_vrma(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot,
>
>  int kvmppc_mmu_hv_init(void)
>  {
> -	unsigned long rsvd_lpid;
> +	unsigned long nr_lpids;
>
>  	if (!mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))
>  		return -EINVAL;
> @@ -264,16 +264,29 @@ int kvmppc_mmu_hv_init(void)
>  	if (cpu_has_feature(CPU_FTR_HVMODE)) {
>  		if (WARN_ON(mfspr(SPRN_LPID) != 0))
>  			return -EINVAL;
> +		nr_lpids = 1UL << mmu_lpid_bits;
> +	} else {
> +		nr_lpids = KVM_MAX_NESTED_GUESTS;
>  	}
>
> -	/* POWER8 and above have 12-bit LPIDs (10-bit in POWER7) */
> -	if (cpu_has_feature(CPU_FTR_ARCH_207S))
> -		rsvd_lpid = LPID_RSVD;
> -	else
> -		rsvd_lpid = LPID_RSVD_POWER7;
> +	if (nr_lpids > KVMPPC_NR_LPIDS)
> +		nr_lpids = KVMPPC_NR_LPIDS;
> +
> +	if (!cpu_has_feature(CPU_FTR_ARCH_300)) {
> +		/* POWER7 has 10-bit LPIDs, POWER8 has 12-bit LPIDs */
> +		if (cpu_has_feature(CPU_FTR_ARCH_207S))
> +			WARN_ON(nr_lpids != 1UL << 12);
> +		else
> +			WARN_ON(nr_lpids != 1UL << 10);
> +
> +		/*
> +		 * Reserve the last implemented LPID use in partition
> +		 * switching for POWER7 and POWER8.
> +		 */
> +		nr_lpids -= 1;
> +	}
>
> -	/* rsvd_lpid is reserved for use in partition switching */
> -	kvmppc_init_lpid(rsvd_lpid);
> +	kvmppc_init_lpid(nr_lpids);
>
>  	return 0;
>  }
> diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> index d185dee26026..0c552885a032 100644
> --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> @@ -50,6 +50,14 @@
>  #define STACK_SLOT_UAMOR	(SFS-88)
>  #define STACK_SLOT_FSCR		(SFS-96)
>
> +/*
> + * Use the last LPID (all implemented LPID bits = 1) for partition switching.
> + * This is reserved in the LPID allocator. POWER7 only implements 0x3ff, but
> + * we write 0xfff into the LPID SPR anyway, which seems to work and just
> + * ignores the top bits.
> + */
> +#define   LPID_RSVD		0xfff
> +
>  /*
>   * Call kvmppc_hv_entry in real mode.
>   * Must be called with interrupts hard-disabled.
> diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
> index 35f46bf54281..ad1a41e3ff1c 100644
> --- a/arch/powerpc/mm/init_64.c
> +++ b/arch/powerpc/mm/init_64.c
> @@ -371,6 +371,9 @@ void register_page_bootmem_memmap(unsigned long section_nr,
>
>  #ifdef CONFIG_PPC_BOOK3S_64
>  unsigned int mmu_lpid_bits;
> +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
> +EXPORT_SYMBOL_GPL(mmu_lpid_bits);
> +#endif
>  unsigned int mmu_pid_bits;
>
>  static bool disable_radix = !IS_ENABLED(CONFIG_PPC_RADIX_MMU_DEFAULT);

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

* Re: [PATCH 3/6] KVM: PPC: Book3S HV: Use IDA allocator for LPID allocator
  2022-01-23 12:00 ` [PATCH 3/6] KVM: PPC: Book3S HV: Use IDA allocator for LPID allocator Nicholas Piggin
@ 2022-01-24 22:13   ` Fabiano Rosas
  0 siblings, 0 replies; 13+ messages in thread
From: Fabiano Rosas @ 2022-01-24 22:13 UTC (permalink / raw)
  To: Nicholas Piggin, linuxppc-dev; +Cc: Nicholas Piggin

Nicholas Piggin <npiggin@gmail.com> writes:

> This removes the fixed-size lpid_inuse array.
>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---

Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com>

>  arch/powerpc/kvm/powerpc.c | 25 +++++++++++++------------
>  1 file changed, 13 insertions(+), 12 deletions(-)
>
> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
> index 102993462872..c527a5751b46 100644
> --- a/arch/powerpc/kvm/powerpc.c
> +++ b/arch/powerpc/kvm/powerpc.c
> @@ -2453,20 +2453,22 @@ long kvm_arch_vm_ioctl(struct file *filp,
>  	return r;
>  }
>
> -static unsigned long lpid_inuse[BITS_TO_LONGS(KVMPPC_NR_LPIDS)];
> +static DEFINE_IDA(lpid_inuse);
>  static unsigned long nr_lpids;
>
>  long kvmppc_alloc_lpid(void)
>  {
> -	long lpid;
> +	int lpid;
>
> -	do {
> -		lpid = find_first_zero_bit(lpid_inuse, KVMPPC_NR_LPIDS);
> -		if (lpid >= nr_lpids) {
> +	/* The host LPID must always be 0 (allocation starts at 1) */
> +	lpid = ida_alloc_range(&lpid_inuse, 1, nr_lpids - 1, GFP_KERNEL);
> +	if (lpid < 0) {
> +		if (lpid == -ENOMEM)
> +			pr_err("%s: Out of memory\n", __func__);
> +		else
>  			pr_err("%s: No LPIDs free\n", __func__);
> -			return -ENOMEM;
> -		}
> -	} while (test_and_set_bit(lpid, lpid_inuse));
> +		return -ENOMEM;
> +	}
>
>  	return lpid;
>  }
> @@ -2474,15 +2476,14 @@ EXPORT_SYMBOL_GPL(kvmppc_alloc_lpid);
>
>  void kvmppc_free_lpid(long lpid)
>  {
> -	clear_bit(lpid, lpid_inuse);
> +	ida_free(&lpid_inuse, lpid);
>  }
>  EXPORT_SYMBOL_GPL(kvmppc_free_lpid);
>
> +/* nr_lpids_param includes the host LPID */
>  void kvmppc_init_lpid(unsigned long nr_lpids_param)
>  {
> -	nr_lpids = min_t(unsigned long, KVMPPC_NR_LPIDS, nr_lpids_param);
> -	memset(lpid_inuse, 0, sizeof(lpid_inuse));
> -	set_bit(0, lpid_inuse); /* The host LPID must always be 0 */
> +	nr_lpids = nr_lpids_param;
>  }
>  EXPORT_SYMBOL_GPL(kvmppc_init_lpid);

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

* Re: [PATCH 4/6] KVM: PPC: Book3S HV Nested: Change nested guest lookup to use idr
  2022-01-23 12:00 ` [PATCH 4/6] KVM: PPC: Book3S HV Nested: Change nested guest lookup to use idr Nicholas Piggin
@ 2022-01-24 22:14   ` Fabiano Rosas
  0 siblings, 0 replies; 13+ messages in thread
From: Fabiano Rosas @ 2022-01-24 22:14 UTC (permalink / raw)
  To: Nicholas Piggin, linuxppc-dev; +Cc: Nicholas Piggin

Nicholas Piggin <npiggin@gmail.com> writes:

> This removes the fixed sized kvm->arch.nested_guests array.
>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---

Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com>

>  arch/powerpc/include/asm/kvm_host.h |   3 +-
>  arch/powerpc/kvm/book3s_hv_nested.c | 110 +++++++++++++++-------------
>  2 files changed, 59 insertions(+), 54 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
> index d9bf60bf0816..5fd0564e5c94 100644
> --- a/arch/powerpc/include/asm/kvm_host.h
> +++ b/arch/powerpc/include/asm/kvm_host.h
> @@ -326,8 +326,7 @@ struct kvm_arch {
>  	struct list_head uvmem_pfns;
>  	struct mutex mmu_setup_lock;	/* nests inside vcpu mutexes */
>  	u64 l1_ptcr;
> -	int max_nested_lpid;
> -	struct kvm_nested_guest *nested_guests[KVM_MAX_NESTED_GUESTS];
> +	struct idr kvm_nested_guest_idr;
>  	/* This array can grow quite large, keep it at the end */
>  	struct kvmppc_vcore *vcores[KVM_MAX_VCORES];
>  #endif
> diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c
> index 9d373f8963ee..1eff969b095c 100644
> --- a/arch/powerpc/kvm/book3s_hv_nested.c
> +++ b/arch/powerpc/kvm/book3s_hv_nested.c
> @@ -521,11 +521,6 @@ static void kvmhv_set_nested_ptbl(struct kvm_nested_guest *gp)
>  	kvmhv_set_ptbl_entry(gp->shadow_lpid, dw0, gp->process_table);
>  }
>
> -void kvmhv_vm_nested_init(struct kvm *kvm)
> -{
> -	kvm->arch.max_nested_lpid = -1;
> -}
> -
>  /*
>   * Handle the H_SET_PARTITION_TABLE hcall.
>   * r4 = guest real address of partition table + log_2(size) - 12
> @@ -660,6 +655,35 @@ static void kvmhv_update_ptbl_cache(struct kvm_nested_guest *gp)
>  	kvmhv_set_nested_ptbl(gp);
>  }
>
> +void kvmhv_vm_nested_init(struct kvm *kvm)
> +{
> +	idr_init(&kvm->arch.kvm_nested_guest_idr);
> +}
> +
> +static struct kvm_nested_guest *__find_nested(struct kvm *kvm, int lpid)
> +{
> +	return idr_find(&kvm->arch.kvm_nested_guest_idr, lpid);
> +}
> +
> +static bool __prealloc_nested(struct kvm *kvm, int lpid)
> +{
> +	if (idr_alloc(&kvm->arch.kvm_nested_guest_idr,
> +				NULL, lpid, lpid + 1, GFP_KERNEL) != lpid)
> +		return false;
> +	return true;
> +}
> +
> +static void __add_nested(struct kvm *kvm, int lpid, struct kvm_nested_guest *gp)
> +{
> +	if (idr_replace(&kvm->arch.kvm_nested_guest_idr, gp, lpid))
> +		WARN_ON(1);
> +}
> +
> +static void __remove_nested(struct kvm *kvm, int lpid)
> +{
> +	idr_remove(&kvm->arch.kvm_nested_guest_idr, lpid);
> +}
> +
>  static struct kvm_nested_guest *kvmhv_alloc_nested(struct kvm *kvm, unsigned int lpid)
>  {
>  	struct kvm_nested_guest *gp;
> @@ -720,13 +744,8 @@ static void kvmhv_remove_nested(struct kvm_nested_guest *gp)
>  	long ref;
>
>  	spin_lock(&kvm->mmu_lock);
> -	if (gp == kvm->arch.nested_guests[lpid]) {
> -		kvm->arch.nested_guests[lpid] = NULL;
> -		if (lpid == kvm->arch.max_nested_lpid) {
> -			while (--lpid >= 0 && !kvm->arch.nested_guests[lpid])
> -				;
> -			kvm->arch.max_nested_lpid = lpid;
> -		}
> +	if (gp == __find_nested(kvm, lpid)) {
> +		__remove_nested(kvm, lpid);
>  		--gp->refcnt;
>  	}
>  	ref = gp->refcnt;
> @@ -743,24 +762,22 @@ static void kvmhv_remove_nested(struct kvm_nested_guest *gp)
>   */
>  void kvmhv_release_all_nested(struct kvm *kvm)
>  {
> -	int i;
> +	int lpid;
>  	struct kvm_nested_guest *gp;
>  	struct kvm_nested_guest *freelist = NULL;
>  	struct kvm_memory_slot *memslot;
>  	int srcu_idx, bkt;
>
>  	spin_lock(&kvm->mmu_lock);
> -	for (i = 0; i <= kvm->arch.max_nested_lpid; i++) {
> -		gp = kvm->arch.nested_guests[i];
> -		if (!gp)
> -			continue;
> -		kvm->arch.nested_guests[i] = NULL;
> +	idr_for_each_entry(&kvm->arch.kvm_nested_guest_idr, gp, lpid) {
> +		__remove_nested(kvm, lpid);
>  		if (--gp->refcnt == 0) {
>  			gp->next = freelist;
>  			freelist = gp;
>  		}
>  	}
> -	kvm->arch.max_nested_lpid = -1;
> +	idr_destroy(&kvm->arch.kvm_nested_guest_idr);
> +	/* idr is empty and may be reused at this point */
>  	spin_unlock(&kvm->mmu_lock);
>  	while ((gp = freelist) != NULL) {
>  		freelist = gp->next;
> @@ -797,7 +814,7 @@ struct kvm_nested_guest *kvmhv_get_nested(struct kvm *kvm, int l1_lpid,
>  		return NULL;
>
>  	spin_lock(&kvm->mmu_lock);
> -	gp = kvm->arch.nested_guests[l1_lpid];
> +	gp = __find_nested(kvm, l1_lpid);
>  	if (gp)
>  		++gp->refcnt;
>  	spin_unlock(&kvm->mmu_lock);
> @@ -808,17 +825,19 @@ struct kvm_nested_guest *kvmhv_get_nested(struct kvm *kvm, int l1_lpid,
>  	newgp = kvmhv_alloc_nested(kvm, l1_lpid);
>  	if (!newgp)
>  		return NULL;
> +
> +	if (!__prealloc_nested(kvm, l1_lpid)) {
> +		kvmhv_release_nested(newgp);
> +		return NULL;
> +	}
> +
>  	spin_lock(&kvm->mmu_lock);
> -	if (kvm->arch.nested_guests[l1_lpid]) {
> -		/* someone else beat us to it */
> -		gp = kvm->arch.nested_guests[l1_lpid];
> -	} else {
> -		kvm->arch.nested_guests[l1_lpid] = newgp;
> +	gp = __find_nested(kvm, l1_lpid);
> +	if (!gp) {
> +		__add_nested(kvm, l1_lpid, newgp);
>  		++newgp->refcnt;
>  		gp = newgp;
>  		newgp = NULL;
> -		if (l1_lpid > kvm->arch.max_nested_lpid)
> -			kvm->arch.max_nested_lpid = l1_lpid;
>  	}
>  	++gp->refcnt;
>  	spin_unlock(&kvm->mmu_lock);
> @@ -841,20 +860,13 @@ void kvmhv_put_nested(struct kvm_nested_guest *gp)
>  		kvmhv_release_nested(gp);
>  }
>
> -static struct kvm_nested_guest *kvmhv_find_nested(struct kvm *kvm, int lpid)
> -{
> -	if (lpid > kvm->arch.max_nested_lpid)
> -		return NULL;
> -	return kvm->arch.nested_guests[lpid];
> -}
> -
>  pte_t *find_kvm_nested_guest_pte(struct kvm *kvm, unsigned long lpid,
>  				 unsigned long ea, unsigned *hshift)
>  {
>  	struct kvm_nested_guest *gp;
>  	pte_t *pte;
>
> -	gp = kvmhv_find_nested(kvm, lpid);
> +	gp = __find_nested(kvm, lpid);
>  	if (!gp)
>  		return NULL;
>
> @@ -960,7 +972,7 @@ static void kvmhv_remove_nest_rmap(struct kvm *kvm, u64 n_rmap,
>
>  	gpa = n_rmap & RMAP_NESTED_GPA_MASK;
>  	lpid = (n_rmap & RMAP_NESTED_LPID_MASK) >> RMAP_NESTED_LPID_SHIFT;
> -	gp = kvmhv_find_nested(kvm, lpid);
> +	gp = __find_nested(kvm, lpid);
>  	if (!gp)
>  		return;
>
> @@ -1152,16 +1164,13 @@ static void kvmhv_emulate_tlbie_all_lpid(struct kvm_vcpu *vcpu, int ric)
>  {
>  	struct kvm *kvm = vcpu->kvm;
>  	struct kvm_nested_guest *gp;
> -	int i;
> +	int lpid;
>
>  	spin_lock(&kvm->mmu_lock);
> -	for (i = 0; i <= kvm->arch.max_nested_lpid; i++) {
> -		gp = kvm->arch.nested_guests[i];
> -		if (gp) {
> -			spin_unlock(&kvm->mmu_lock);
> -			kvmhv_emulate_tlbie_lpid(vcpu, gp, ric);
> -			spin_lock(&kvm->mmu_lock);
> -		}
> +	idr_for_each_entry(&kvm->arch.kvm_nested_guest_idr, gp, lpid) {
> +		spin_unlock(&kvm->mmu_lock);
> +		kvmhv_emulate_tlbie_lpid(vcpu, gp, ric);
> +		spin_lock(&kvm->mmu_lock);
>  	}
>  	spin_unlock(&kvm->mmu_lock);
>  }
> @@ -1313,7 +1322,7 @@ long do_h_rpt_invalidate_pat(struct kvm_vcpu *vcpu, unsigned long lpid,
>  	 * H_ENTER_NESTED call. Since we can't differentiate this case from
>  	 * the invalid case, we ignore such flush requests and return success.
>  	 */
> -	if (!kvmhv_find_nested(vcpu->kvm, lpid))
> +	if (!__find_nested(vcpu->kvm, lpid))
>  		return H_SUCCESS;
>
>  	/*
> @@ -1657,15 +1666,12 @@ long int kvmhv_nested_page_fault(struct kvm_vcpu *vcpu)
>
>  int kvmhv_nested_next_lpid(struct kvm *kvm, int lpid)
>  {
> -	int ret = -1;
> +	int ret = lpid + 1;
>
>  	spin_lock(&kvm->mmu_lock);
> -	while (++lpid <= kvm->arch.max_nested_lpid) {
> -		if (kvm->arch.nested_guests[lpid]) {
> -			ret = lpid;
> -			break;
> -		}
> -	}
> +	if (!idr_get_next(&kvm->arch.kvm_nested_guest_idr, &ret))
> +		ret = -1;
>  	spin_unlock(&kvm->mmu_lock);
> +
>  	return ret;
>  }

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

* Re: [PATCH 5/6] KVM: PPC: Book3S Nested: Use explicit 4096 LPID maximum
  2022-01-23 12:00 ` [PATCH 5/6] KVM: PPC: Book3S Nested: Use explicit 4096 LPID maximum Nicholas Piggin
@ 2022-01-24 22:15   ` Fabiano Rosas
  0 siblings, 0 replies; 13+ messages in thread
From: Fabiano Rosas @ 2022-01-24 22:15 UTC (permalink / raw)
  To: Nicholas Piggin, linuxppc-dev; +Cc: Nicholas Piggin

Nicholas Piggin <npiggin@gmail.com> writes:

> Rather than tie this to KVMPPC_NR_LPIDS which is becoming more dynamic,
> fix it to 4096 (12-bits) explicitly for now.
>
> kvmhv_get_nested() does not have to check against KVM_MAX_NESTED_GUESTS
> because the L1 partition table registration hcall already did that, and
> it checks against the partition table size.
>
> This patch also puts all the partition table size calculations into the
> same form, using 12 for the architected size field shift and 4 for the
> shift corresponding to the partition table entry size.
>
> Signed-of-by: Nicholas Piggin <npiggin@gmail.com>

Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com>

> ---
>  arch/powerpc/include/asm/kvm_host.h |  7 ++++++-
>  arch/powerpc/kvm/book3s_64_mmu_hv.c |  2 +-
>  arch/powerpc/kvm/book3s_hv_nested.c | 24 +++++++++++-------------
>  3 files changed, 18 insertions(+), 15 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
> index 5fd0564e5c94..e6fb03884dcc 100644
> --- a/arch/powerpc/include/asm/kvm_host.h
> +++ b/arch/powerpc/include/asm/kvm_host.h
> @@ -34,7 +34,12 @@
>  #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
>  #include <asm/kvm_book3s_asm.h>		/* for MAX_SMT_THREADS */
>  #define KVM_MAX_VCPU_IDS	(MAX_SMT_THREADS * KVM_MAX_VCORES)
> -#define KVM_MAX_NESTED_GUESTS	KVMPPC_NR_LPIDS
> +
> +/*
> + * Limit the nested partition table to 4096 entries (because that's what
> + * hardware supports). Both guest and host use this value.
> + */
> +#define KVM_MAX_NESTED_GUESTS_SHIFT	12
>
>  #else
>  #define KVM_MAX_VCPU_IDS	KVM_MAX_VCPUS
> diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
> index 5be92d5bc099..f983fb36cbf2 100644
> --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
> +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
> @@ -266,7 +266,7 @@ int kvmppc_mmu_hv_init(void)
>  			return -EINVAL;
>  		nr_lpids = 1UL << mmu_lpid_bits;
>  	} else {
> -		nr_lpids = KVM_MAX_NESTED_GUESTS;
> +		nr_lpids = 1UL << KVM_MAX_NESTED_GUESTS_SHIFT;
>  	}
>
>  	if (nr_lpids > KVMPPC_NR_LPIDS)
> diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c
> index 1eff969b095c..75169e0753ce 100644
> --- a/arch/powerpc/kvm/book3s_hv_nested.c
> +++ b/arch/powerpc/kvm/book3s_hv_nested.c
> @@ -439,10 +439,11 @@ long kvmhv_nested_init(void)
>  	if (!radix_enabled())
>  		return -ENODEV;
>
> -	/* find log base 2 of KVMPPC_NR_LPIDS, rounding up */
> -	ptb_order = __ilog2(KVMPPC_NR_LPIDS - 1) + 1;
> -	if (ptb_order < 8)
> -		ptb_order = 8;
> +	/* Partition table entry is 1<<4 bytes in size, hence the 4. */
> +	ptb_order = KVM_MAX_NESTED_GUESTS_SHIFT + 4;
> +	/* Minimum partition table size is 1<<12 bytes */
> +	if (ptb_order < 12)
> +		ptb_order = 12;
>  	pseries_partition_tb = kmalloc(sizeof(struct patb_entry) << ptb_order,
>  				       GFP_KERNEL);
>  	if (!pseries_partition_tb) {
> @@ -450,7 +451,7 @@ long kvmhv_nested_init(void)
>  		return -ENOMEM;
>  	}
>
> -	ptcr = __pa(pseries_partition_tb) | (ptb_order - 8);
> +	ptcr = __pa(pseries_partition_tb) | (ptb_order - 12);
>  	rc = plpar_hcall_norets(H_SET_PARTITION_TABLE, ptcr);
>  	if (rc != H_SUCCESS) {
>  		pr_err("kvm-hv: Parent hypervisor does not support nesting (rc=%ld)\n",
> @@ -534,16 +535,14 @@ long kvmhv_set_partition_table(struct kvm_vcpu *vcpu)
>  	long ret = H_SUCCESS;
>
>  	srcu_idx = srcu_read_lock(&kvm->srcu);
> -	/*
> -	 * Limit the partition table to 4096 entries (because that's what
> -	 * hardware supports), and check the base address.
> -	 */
> -	if ((ptcr & PRTS_MASK) > 12 - 8 ||
> +	/* Check partition size and base address. */
> +	if ((ptcr & PRTS_MASK) + 12 - 4 > KVM_MAX_NESTED_GUESTS_SHIFT ||
>  	    !kvm_is_visible_gfn(vcpu->kvm, (ptcr & PRTB_MASK) >> PAGE_SHIFT))
>  		ret = H_PARAMETER;
>  	srcu_read_unlock(&kvm->srcu, srcu_idx);
>  	if (ret == H_SUCCESS)
>  		kvm->arch.l1_ptcr = ptcr;
> +
>  	return ret;
>  }
>
> @@ -639,7 +638,7 @@ static void kvmhv_update_ptbl_cache(struct kvm_nested_guest *gp)
>
>  	ret = -EFAULT;
>  	ptbl_addr = (kvm->arch.l1_ptcr & PRTB_MASK) + (gp->l1_lpid << 4);
> -	if (gp->l1_lpid < (1ul << ((kvm->arch.l1_ptcr & PRTS_MASK) + 8))) {
> +	if (gp->l1_lpid < (1ul << ((kvm->arch.l1_ptcr & PRTS_MASK) + 12 - 4))) {
>  		int srcu_idx = srcu_read_lock(&kvm->srcu);
>  		ret = kvm_read_guest(kvm, ptbl_addr,
>  				     &ptbl_entry, sizeof(ptbl_entry));
> @@ -809,8 +808,7 @@ struct kvm_nested_guest *kvmhv_get_nested(struct kvm *kvm, int l1_lpid,
>  {
>  	struct kvm_nested_guest *gp, *newgp;
>
> -	if (l1_lpid >= KVM_MAX_NESTED_GUESTS ||
> -	    l1_lpid >= (1ul << ((kvm->arch.l1_ptcr & PRTS_MASK) + 12 - 4)))
> +	if (l1_lpid >= (1ul << ((kvm->arch.l1_ptcr & PRTS_MASK) + 12 - 4)))
>  		return NULL;
>
>  	spin_lock(&kvm->mmu_lock);

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

* Re: [PATCH 6/6] KVM: PPC: Book3S HV: Remove KVMPPC_NR_LPIDS
  2022-01-23 12:00 ` [PATCH 6/6] KVM: PPC: Book3S HV: Remove KVMPPC_NR_LPIDS Nicholas Piggin
@ 2022-01-24 22:15   ` Fabiano Rosas
  0 siblings, 0 replies; 13+ messages in thread
From: Fabiano Rosas @ 2022-01-24 22:15 UTC (permalink / raw)
  To: Nicholas Piggin, linuxppc-dev; +Cc: Nicholas Piggin

Nicholas Piggin <npiggin@gmail.com> writes:

> KVMPPC_NR_LPIDS no longer represents any size restriction on the
> LPID space and can be removed. A CPU with more than 12 LPID bits
> implemented will now be able to create more than 4095 guests.
>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>

Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com>

> ---
>  arch/powerpc/include/asm/kvm_book3s_asm.h | 3 ---
>  arch/powerpc/kvm/book3s_64_mmu_hv.c       | 3 ---
>  2 files changed, 6 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h
> index e6bda70b1d93..c8882d9b86c2 100644
> --- a/arch/powerpc/include/asm/kvm_book3s_asm.h
> +++ b/arch/powerpc/include/asm/kvm_book3s_asm.h
> @@ -14,9 +14,6 @@
>  #define XICS_MFRR		0xc
>  #define XICS_IPI		2	/* interrupt source # for IPIs */
>
> -/* LPIDs we support with this build -- runtime limit may be lower */
> -#define KVMPPC_NR_LPIDS			(1UL << 12)
> -
>  /* Maximum number of threads per physical core */
>  #define MAX_SMT_THREADS		8
>
> diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
> index f983fb36cbf2..aafd2a74304c 100644
> --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
> +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
> @@ -269,9 +269,6 @@ int kvmppc_mmu_hv_init(void)
>  		nr_lpids = 1UL << KVM_MAX_NESTED_GUESTS_SHIFT;
>  	}
>
> -	if (nr_lpids > KVMPPC_NR_LPIDS)
> -		nr_lpids = KVMPPC_NR_LPIDS;
> -
>  	if (!cpu_has_feature(CPU_FTR_ARCH_300)) {
>  		/* POWER7 has 10-bit LPIDs, POWER8 has 12-bit LPIDs */
>  		if (cpu_has_feature(CPU_FTR_ARCH_207S))

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

* Re: [PATCH 0/6] KVM: PPC: Book3S: Make LPID/nested LPID allocations dynamic
  2022-01-23 12:00 [PATCH 0/6] KVM: PPC: Book3S: Make LPID/nested LPID allocations dynamic Nicholas Piggin
                   ` (5 preceding siblings ...)
  2022-01-23 12:00 ` [PATCH 6/6] KVM: PPC: Book3S HV: Remove KVMPPC_NR_LPIDS Nicholas Piggin
@ 2022-05-24 10:51 ` Michael Ellerman
  6 siblings, 0 replies; 13+ messages in thread
From: Michael Ellerman @ 2022-05-24 10:51 UTC (permalink / raw)
  To: Nicholas Piggin, linuxppc-dev

On Sun, 23 Jan 2022 22:00:37 +1000, Nicholas Piggin wrote:
> With LPID width plumbed through from firmware, LPID allocations can now
> be dynamic, which requires changing the fixed sized bitmap. Rather than
> just dynamically sizing it, switch to IDA allocator.
> 
> Nested KVM stays with a fixed 12-bit LPID width for now, but it is also
> moved to a more dynamic allocator. In future if nested LPID width is
> advertised to a guest it will be simple to take advantage of it.
> 
> [...]

Applied to powerpc/topic/ppc-kvm.

[1/6] KVM: PPC: Remove kvmppc_claim_lpid
      https://git.kernel.org/powerpc/c/18827eeef022df43c1fdeca0fde00ca09405dff1
[2/6] KVM: PPC: Book3S HV: Update LPID allocator init for POWER9, Nested
      https://git.kernel.org/powerpc/c/5d506f159b2b9d0c9bee9bb43ccafb4f291143c2
[3/6] KVM: PPC: Book3S HV: Use IDA allocator for LPID allocator
      https://git.kernel.org/powerpc/c/6ba2a2924dcf6026de5078ba7025248a580d8bde
[4/6] KVM: PPC: Book3S HV Nested: Change nested guest lookup to use idr
      https://git.kernel.org/powerpc/c/c0f00a18e2a8c350a9d263aaf9a2c8bc86caa1b0
[5/6] KVM: PPC: Book3S Nested: Use explicit 4096 LPID maximum
      https://git.kernel.org/powerpc/c/03a2e65f54b3acae37f0992133d2f4d1d35f4200
[6/6] KVM: PPC: Book3S HV: Remove KVMPPC_NR_LPIDS
      https://git.kernel.org/powerpc/c/f104df7d519ff1aa92c7ec87e124c88d4e7574cd

cheers

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

end of thread, other threads:[~2022-05-24 10:57 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-23 12:00 [PATCH 0/6] KVM: PPC: Book3S: Make LPID/nested LPID allocations dynamic Nicholas Piggin
2022-01-23 12:00 ` [PATCH 1/6] KVM: PPC: Remove kvmppc_claim_lpid Nicholas Piggin
2022-01-23 12:00 ` [PATCH 2/6] KVM: PPC: Book3S HV: Update LPID allocator init for POWER9, Nested Nicholas Piggin
2022-01-24 22:13   ` Fabiano Rosas
2022-01-23 12:00 ` [PATCH 3/6] KVM: PPC: Book3S HV: Use IDA allocator for LPID allocator Nicholas Piggin
2022-01-24 22:13   ` Fabiano Rosas
2022-01-23 12:00 ` [PATCH 4/6] KVM: PPC: Book3S HV Nested: Change nested guest lookup to use idr Nicholas Piggin
2022-01-24 22:14   ` Fabiano Rosas
2022-01-23 12:00 ` [PATCH 5/6] KVM: PPC: Book3S Nested: Use explicit 4096 LPID maximum Nicholas Piggin
2022-01-24 22:15   ` Fabiano Rosas
2022-01-23 12:00 ` [PATCH 6/6] KVM: PPC: Book3S HV: Remove KVMPPC_NR_LPIDS Nicholas Piggin
2022-01-24 22:15   ` Fabiano Rosas
2022-05-24 10:51 ` [PATCH 0/6] KVM: PPC: Book3S: Make LPID/nested LPID allocations dynamic Michael Ellerman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.