Loading arch/powerpc/include/asm/kvm_book3s.h +3 −0 Original line number Diff line number Diff line Loading @@ -452,4 +452,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__ */ arch/powerpc/include/asm/kvm_booke.h +3 −0 Original line number Diff line number Diff line Loading @@ -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.gpr[num] = val; Loading arch/powerpc/include/asm/kvm_ppc.h +5 −0 Original line number Diff line number Diff line Loading @@ -204,4 +204,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__ */ arch/powerpc/kvm/book3s_64_mmu_hv.c +10 −16 Original line number Diff line number Diff line Loading @@ -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; struct kvmppc_linear_info *li; Loading Loading @@ -72,14 +70,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"); lpid = kvmppc_alloc_lpid(); if (lpid < 0) goto out_freeboth; } } while (test_and_set_bit(lpid, lpid_inuse)); kvm->arch.sdr1 = __pa(hpt) | (HPT_ORDER - 18); kvm->arch.lpid = lpid; Loading @@ -96,7 +89,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); if (kvm->arch.hpt_li) kvm_release_hpt(kvm->arch.hpt_li); Loading Loading @@ -171,8 +164,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; Loading @@ -181,9 +173,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; } Loading arch/powerpc/kvm/powerpc.c +34 −0 Original line number Diff line number Diff line Loading @@ -799,6 +799,40 @@ long kvm_arch_vm_ioctl(struct file *filp, 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; Loading Loading
arch/powerpc/include/asm/kvm_book3s.h +3 −0 Original line number Diff line number Diff line Loading @@ -452,4 +452,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__ */
arch/powerpc/include/asm/kvm_booke.h +3 −0 Original line number Diff line number Diff line Loading @@ -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.gpr[num] = val; Loading
arch/powerpc/include/asm/kvm_ppc.h +5 −0 Original line number Diff line number Diff line Loading @@ -204,4 +204,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__ */
arch/powerpc/kvm/book3s_64_mmu_hv.c +10 −16 Original line number Diff line number Diff line Loading @@ -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; struct kvmppc_linear_info *li; Loading Loading @@ -72,14 +70,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"); lpid = kvmppc_alloc_lpid(); if (lpid < 0) goto out_freeboth; } } while (test_and_set_bit(lpid, lpid_inuse)); kvm->arch.sdr1 = __pa(hpt) | (HPT_ORDER - 18); kvm->arch.lpid = lpid; Loading @@ -96,7 +89,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); if (kvm->arch.hpt_li) kvm_release_hpt(kvm->arch.hpt_li); Loading Loading @@ -171,8 +164,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; Loading @@ -181,9 +173,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; } Loading
arch/powerpc/kvm/powerpc.c +34 −0 Original line number Diff line number Diff line Loading @@ -799,6 +799,40 @@ long kvm_arch_vm_ioctl(struct file *filp, 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; Loading