Message ID | 20111221013420.GD8378@schlenkerla.am.freescale.net |
---|---|
State | New, archived |
Headers | show |
On 21.12.2011, at 02:34, Scott Wood wrote: > We'll use it on e500mc as well. > > Signed-off-by: Scott Wood <scottwood@freescale.com> > --- > arch/powerpc/include/asm/kvm_book3s.h | 3 ++ > arch/powerpc/include/asm/kvm_booke.h | 3 ++ > arch/powerpc/include/asm/kvm_ppc.h | 5 ++++ > arch/powerpc/kvm/book3s_64_mmu_hv.c | 26 +++++++++--------------- > arch/powerpc/kvm/powerpc.c | 34 +++++++++++++++++++++++++++++++++ > 5 files changed, 55 insertions(+), 16 deletions(-) > > diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h > index 60e069e..58c8bec 100644 > --- a/arch/powerpc/include/asm/kvm_book3s.h > +++ b/arch/powerpc/include/asm/kvm_book3s.h > @@ -448,4 +448,7 @@ static inline bool kvmppc_critical_section(struct kvm_vcpu *vcpu) > > #define INS_DCBZ 0x7c0007ec > > +/* LPIDs we support with this build -- runtime limit may be lower */ > +#define KVMPPC_NR_LPIDS (LPID_RSVD + 1) > + > #endif /* __ASM_KVM_BOOK3S_H__ */ > diff --git a/arch/powerpc/include/asm/kvm_booke.h b/arch/powerpc/include/asm/kvm_booke.h > index e20c162..138118e 100644 > --- a/arch/powerpc/include/asm/kvm_booke.h > +++ b/arch/powerpc/include/asm/kvm_booke.h > @@ -23,6 +23,9 @@ > #include <linux/types.h> > #include <linux/kvm_host.h> > > +/* LPIDs we support with this build -- runtime limit may be lower */ > +#define KVMPPC_NR_LPIDS 64 > + > static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val) > { > vcpu->arch.regs.gpr[num] = val; > diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h > index a61b5b5..5524f88 100644 > --- a/arch/powerpc/include/asm/kvm_ppc.h > +++ b/arch/powerpc/include/asm/kvm_ppc.h > @@ -202,4 +202,9 @@ int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu, > 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); > + > #endif /* __POWERPC_KVM_PPC_H__ */ > diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c > index 66d6452..45b6f0e 100644 > --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c > +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c > @@ -36,13 +36,11 @@ > > /* POWER7 has 10-bit LPIDs, PPC970 has 6-bit LPIDs */ > #define MAX_LPID_970 63 > -#define NR_LPIDS (LPID_RSVD + 1) > -unsigned long lpid_inuse[BITS_TO_LONGS(NR_LPIDS)]; > > long kvmppc_alloc_hpt(struct kvm *kvm) > { > unsigned long hpt; > - unsigned long lpid; > + long lpid; > struct revmap_entry *rev; > > /* Allocate guest's hashed page table */ > @@ -62,14 +60,9 @@ long kvmppc_alloc_hpt(struct kvm *kvm) > } > kvm->arch.revmap = rev; > > - /* Allocate the guest's logical partition ID */ > - do { > - lpid = find_first_zero_bit(lpid_inuse, NR_LPIDS); > - if (lpid >= NR_LPIDS) { > - pr_err("kvm_alloc_hpt: No LPIDs free\n"); > - goto out_freeboth; > - } > - } while (test_and_set_bit(lpid, lpid_inuse)); > + lpid = kvmppc_alloc_lpid(); > + if (lpid < 0) > + goto out_freeboth; > > kvm->arch.sdr1 = __pa(hpt) | (HPT_ORDER - 18); > kvm->arch.lpid = lpid; > @@ -86,7 +79,7 @@ long kvmppc_alloc_hpt(struct kvm *kvm) > > void kvmppc_free_hpt(struct kvm *kvm) > { > - clear_bit(kvm->arch.lpid, lpid_inuse); > + kvmppc_free_lpid(kvm->arch.lpid); > vfree(kvm->arch.revmap); > free_pages(kvm->arch.hpt_virt, HPT_ORDER - PAGE_SHIFT); > } > @@ -158,8 +151,7 @@ int kvmppc_mmu_hv_init(void) > if (!cpu_has_feature(CPU_FTR_HVMODE)) > return -EINVAL; > > - memset(lpid_inuse, 0, sizeof(lpid_inuse)); > - > + /* POWER7 has 10-bit LPIDs, PPC970 and e500mc have 6-bit LPIDs */ > if (cpu_has_feature(CPU_FTR_ARCH_206)) { > host_lpid = mfspr(SPRN_LPID); /* POWER7 */ > rsvd_lpid = LPID_RSVD; > @@ -168,9 +160,11 @@ int kvmppc_mmu_hv_init(void) > rsvd_lpid = MAX_LPID_970; > } > > - set_bit(host_lpid, lpid_inuse); > + kvmppc_init_lpid(rsvd_lpid + 1); > + > + kvmppc_claim_lpid(host_lpid); > /* rsvd_lpid is reserved for use in partition switching */ > - set_bit(rsvd_lpid, lpid_inuse); > + kvmppc_claim_lpid(rsvd_lpid); > > return 0; > } > diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c > index 64c738dc..42701e5 100644 > --- a/arch/powerpc/kvm/powerpc.c > +++ b/arch/powerpc/kvm/powerpc.c Paul, does this work for you? IIRC you need this code to be available from real mode, which powerpc.c isn't in, right? Alex > @@ -800,6 +800,40 @@ out: > return r; > } > > +static unsigned long lpid_inuse[BITS_TO_LONGS(KVMPPC_NR_LPIDS)]; > +static unsigned long nr_lpids; > + > +long kvmppc_alloc_lpid(void) > +{ > + long lpid; > + > + do { > + lpid = find_first_zero_bit(lpid_inuse, KVMPPC_NR_LPIDS); > + if (lpid >= nr_lpids) { > + pr_err("%s: No LPIDs free\n", __func__); > + return -ENOMEM; > + } > + } while (test_and_set_bit(lpid, lpid_inuse)); > + > + return lpid; > +} > + > +void kvmppc_claim_lpid(long lpid) > +{ > + set_bit(lpid, lpid_inuse); > +} > + > +void kvmppc_free_lpid(long lpid) > +{ > + clear_bit(lpid, lpid_inuse); > +} > + > +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)); > +} > + > int kvm_arch_init(void *opaque) > { > return 0; > -- > 1.7.7.rc3.4.g8d714 > > -- To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, Jan 09, 2012 at 04:35:52PM +0100, Alexander Graf wrote: > Paul, does this work for you? IIRC you need this code to be > available from real mode, which powerpc.c isn't in, right? We don't need to allocated LPIDs from real mode, so it should be OK. book3s_64_mmu_hv.c is not real mode code, and it gets compiled into the KVM module. Paul. -- To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 60e069e..58c8bec 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -448,4 +448,7 @@ static inline bool kvmppc_critical_section(struct kvm_vcpu *vcpu) #define INS_DCBZ 0x7c0007ec +/* LPIDs we support with this build -- runtime limit may be lower */ +#define KVMPPC_NR_LPIDS (LPID_RSVD + 1) + #endif /* __ASM_KVM_BOOK3S_H__ */ diff --git a/arch/powerpc/include/asm/kvm_booke.h b/arch/powerpc/include/asm/kvm_booke.h index e20c162..138118e 100644 --- a/arch/powerpc/include/asm/kvm_booke.h +++ b/arch/powerpc/include/asm/kvm_booke.h @@ -23,6 +23,9 @@ #include <linux/types.h> #include <linux/kvm_host.h> +/* LPIDs we support with this build -- runtime limit may be lower */ +#define KVMPPC_NR_LPIDS 64 + static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val) { vcpu->arch.regs.gpr[num] = val; diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index a61b5b5..5524f88 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -202,4 +202,9 @@ int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu, 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); + #endif /* __POWERPC_KVM_PPC_H__ */ diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 66d6452..45b6f0e 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -36,13 +36,11 @@ /* POWER7 has 10-bit LPIDs, PPC970 has 6-bit LPIDs */ #define MAX_LPID_970 63 -#define NR_LPIDS (LPID_RSVD + 1) -unsigned long lpid_inuse[BITS_TO_LONGS(NR_LPIDS)]; long kvmppc_alloc_hpt(struct kvm *kvm) { unsigned long hpt; - unsigned long lpid; + long lpid; struct revmap_entry *rev; /* Allocate guest's hashed page table */ @@ -62,14 +60,9 @@ long kvmppc_alloc_hpt(struct kvm *kvm) } kvm->arch.revmap = rev; - /* Allocate the guest's logical partition ID */ - do { - lpid = find_first_zero_bit(lpid_inuse, NR_LPIDS); - if (lpid >= NR_LPIDS) { - pr_err("kvm_alloc_hpt: No LPIDs free\n"); - goto out_freeboth; - } - } while (test_and_set_bit(lpid, lpid_inuse)); + lpid = kvmppc_alloc_lpid(); + if (lpid < 0) + goto out_freeboth; kvm->arch.sdr1 = __pa(hpt) | (HPT_ORDER - 18); kvm->arch.lpid = lpid; @@ -86,7 +79,7 @@ long kvmppc_alloc_hpt(struct kvm *kvm) void kvmppc_free_hpt(struct kvm *kvm) { - clear_bit(kvm->arch.lpid, lpid_inuse); + kvmppc_free_lpid(kvm->arch.lpid); vfree(kvm->arch.revmap); free_pages(kvm->arch.hpt_virt, HPT_ORDER - PAGE_SHIFT); } @@ -158,8 +151,7 @@ int kvmppc_mmu_hv_init(void) if (!cpu_has_feature(CPU_FTR_HVMODE)) return -EINVAL; - memset(lpid_inuse, 0, sizeof(lpid_inuse)); - + /* POWER7 has 10-bit LPIDs, PPC970 and e500mc have 6-bit LPIDs */ if (cpu_has_feature(CPU_FTR_ARCH_206)) { host_lpid = mfspr(SPRN_LPID); /* POWER7 */ rsvd_lpid = LPID_RSVD; @@ -168,9 +160,11 @@ int kvmppc_mmu_hv_init(void) rsvd_lpid = MAX_LPID_970; } - set_bit(host_lpid, lpid_inuse); + kvmppc_init_lpid(rsvd_lpid + 1); + + kvmppc_claim_lpid(host_lpid); /* rsvd_lpid is reserved for use in partition switching */ - set_bit(rsvd_lpid, lpid_inuse); + kvmppc_claim_lpid(rsvd_lpid); return 0; } diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 64c738dc..42701e5 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -800,6 +800,40 @@ out: return r; } +static unsigned long lpid_inuse[BITS_TO_LONGS(KVMPPC_NR_LPIDS)]; +static unsigned long nr_lpids; + +long kvmppc_alloc_lpid(void) +{ + long lpid; + + do { + lpid = find_first_zero_bit(lpid_inuse, KVMPPC_NR_LPIDS); + if (lpid >= nr_lpids) { + pr_err("%s: No LPIDs free\n", __func__); + return -ENOMEM; + } + } while (test_and_set_bit(lpid, lpid_inuse)); + + return lpid; +} + +void kvmppc_claim_lpid(long lpid) +{ + set_bit(lpid, lpid_inuse); +} + +void kvmppc_free_lpid(long lpid) +{ + clear_bit(lpid, lpid_inuse); +} + +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)); +} + int kvm_arch_init(void *opaque) { return 0;
We'll use it on e500mc as well. Signed-off-by: Scott Wood <scottwood@freescale.com> --- arch/powerpc/include/asm/kvm_book3s.h | 3 ++ arch/powerpc/include/asm/kvm_booke.h | 3 ++ arch/powerpc/include/asm/kvm_ppc.h | 5 ++++ arch/powerpc/kvm/book3s_64_mmu_hv.c | 26 +++++++++--------------- arch/powerpc/kvm/powerpc.c | 34 +++++++++++++++++++++++++++++++++ 5 files changed, 55 insertions(+), 16 deletions(-)