Re: [PATCH 2/6] KVM: PPC: Book3S HV: Update LPID allocator init for POWER9, Nested

2022-01-24 Thread Fabiano Rosas
Nicholas Piggin  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 
> ---

Reviewed-by: Fabiano Rosas 

>  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_LPID0x13F   /* 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 

[PATCH 2/6] KVM: PPC: Book3S HV: Update LPID allocator init for POWER9, Nested

2022-01-23 Thread 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 
---
 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_THREADS8
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_RSVD0xfff   /* Reserved LPID for partn switching */
 #defineSPRN_HMER   0x150   /* Hypervisor maintenance exception reg 
*/
 #define   HMER_DEBUG_TRIG  (1ul << (63 - 17)) /* Debug trigger */
 #defineSPRN_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_RSVD0xfff
+
 /*
  * 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