Message ID | 20220123120043.3586018-6-npiggin@gmail.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
Series | KVM: PPC: Book3S: Make LPID/nested LPID allocations dynamic | expand |
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);
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);