Commit 3d089f84 authored by David Gibson's avatar David Gibson Committed by Paul Mackerras

KVM: PPC: Book3S HV: Don't store values derivable from HPT order

Currently the kvm_hpt_info structure stores the hashed page table's order,
and also the number of HPTEs it contains and a mask for its size.  The
last two can be easily derived from the order, so remove them and just
calculate them as necessary with a couple of helper inlines.
Signed-off-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
Reviewed-by: default avatarThomas Huth <thuth@redhat.com>
Signed-off-by: default avatarPaul Mackerras <paulus@ozlabs.org>
parent 3f9d4f5a
...@@ -356,6 +356,18 @@ extern void kvmppc_mmu_debugfs_init(struct kvm *kvm); ...@@ -356,6 +356,18 @@ extern void kvmppc_mmu_debugfs_init(struct kvm *kvm);
extern void kvmhv_rm_send_ipi(int cpu); extern void kvmhv_rm_send_ipi(int cpu);
static inline unsigned long kvmppc_hpt_npte(struct kvm_hpt_info *hpt)
{
/* HPTEs are 2**4 bytes long */
return 1UL << (hpt->order - 4);
}
static inline unsigned long kvmppc_hpt_mask(struct kvm_hpt_info *hpt)
{
/* 128 (2**7) bytes in each HPTEG */
return (1UL << (hpt->order - 7)) - 1;
}
#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */
#endif /* __ASM_KVM_BOOK3S_64_H__ */ #endif /* __ASM_KVM_BOOK3S_64_H__ */
...@@ -246,8 +246,6 @@ struct kvm_hpt_info { ...@@ -246,8 +246,6 @@ struct kvm_hpt_info {
unsigned long virt; unsigned long virt;
/* Array of reverse mapping entries for each guest HPTE */ /* Array of reverse mapping entries for each guest HPTE */
struct revmap_entry *rev; struct revmap_entry *rev;
unsigned long npte;
unsigned long mask;
/* Guest HPT size is 2**(order) bytes */ /* Guest HPT size is 2**(order) bytes */
u32 order; u32 order;
/* 1 if HPT allocated with CMA, 0 otherwise */ /* 1 if HPT allocated with CMA, 0 otherwise */
......
...@@ -83,15 +83,11 @@ long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp) ...@@ -83,15 +83,11 @@ long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp)
kvm->arch.hpt.virt = hpt; kvm->arch.hpt.virt = hpt;
kvm->arch.hpt.order = order; kvm->arch.hpt.order = order;
/* HPTEs are 2**4 bytes long */
kvm->arch.hpt.npte = 1ul << (order - 4);
/* 128 (2**7) bytes in each HPTEG */
kvm->arch.hpt.mask = (1ul << (order - 7)) - 1;
atomic64_set(&kvm->arch.mmio_update, 0); atomic64_set(&kvm->arch.mmio_update, 0);
/* Allocate reverse map array */ /* Allocate reverse map array */
rev = vmalloc(sizeof(struct revmap_entry) * kvm->arch.hpt.npte); rev = vmalloc(sizeof(struct revmap_entry) * kvmppc_hpt_npte(&kvm->arch.hpt));
if (!rev) { if (!rev) {
pr_err("kvmppc_alloc_hpt: Couldn't alloc reverse map array\n"); pr_err("kvmppc_alloc_hpt: Couldn't alloc reverse map array\n");
goto out_freehpt; goto out_freehpt;
...@@ -196,8 +192,8 @@ void kvmppc_map_vrma(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot, ...@@ -196,8 +192,8 @@ void kvmppc_map_vrma(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot,
if (npages > 1ul << (40 - porder)) if (npages > 1ul << (40 - porder))
npages = 1ul << (40 - porder); npages = 1ul << (40 - porder);
/* Can't use more than 1 HPTE per HPTEG */ /* Can't use more than 1 HPTE per HPTEG */
if (npages > kvm->arch.hpt.mask + 1) if (npages > kvmppc_hpt_mask(&kvm->arch.hpt) + 1)
npages = kvm->arch.hpt.mask + 1; npages = kvmppc_hpt_mask(&kvm->arch.hpt) + 1;
hp0 = HPTE_V_1TB_SEG | (VRMA_VSID << (40 - 16)) | hp0 = HPTE_V_1TB_SEG | (VRMA_VSID << (40 - 16)) |
HPTE_V_BOLTED | hpte0_pgsize_encoding(psize); HPTE_V_BOLTED | hpte0_pgsize_encoding(psize);
...@@ -207,7 +203,8 @@ void kvmppc_map_vrma(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot, ...@@ -207,7 +203,8 @@ void kvmppc_map_vrma(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot,
for (i = 0; i < npages; ++i) { for (i = 0; i < npages; ++i) {
addr = i << porder; addr = i << porder;
/* can't use hpt_hash since va > 64 bits */ /* can't use hpt_hash since va > 64 bits */
hash = (i ^ (VRMA_VSID ^ (VRMA_VSID << 25))) & kvm->arch.hpt.mask; hash = (i ^ (VRMA_VSID ^ (VRMA_VSID << 25)))
& kvmppc_hpt_mask(&kvm->arch.hpt);
/* /*
* We assume that the hash table is empty and no * We assume that the hash table is empty and no
* vcpus are using it at this stage. Since we create * vcpus are using it at this stage. Since we create
...@@ -1327,7 +1324,7 @@ static ssize_t kvm_htab_read(struct file *file, char __user *buf, ...@@ -1327,7 +1324,7 @@ static ssize_t kvm_htab_read(struct file *file, char __user *buf,
/* Skip uninteresting entries, i.e. clean on not-first pass */ /* Skip uninteresting entries, i.e. clean on not-first pass */
if (!first_pass) { if (!first_pass) {
while (i < kvm->arch.hpt.npte && while (i < kvmppc_hpt_npte(&kvm->arch.hpt) &&
!hpte_dirty(revp, hptp)) { !hpte_dirty(revp, hptp)) {
++i; ++i;
hptp += 2; hptp += 2;
...@@ -1337,7 +1334,7 @@ static ssize_t kvm_htab_read(struct file *file, char __user *buf, ...@@ -1337,7 +1334,7 @@ static ssize_t kvm_htab_read(struct file *file, char __user *buf,
hdr.index = i; hdr.index = i;
/* Grab a series of valid entries */ /* Grab a series of valid entries */
while (i < kvm->arch.hpt.npte && while (i < kvmppc_hpt_npte(&kvm->arch.hpt) &&
hdr.n_valid < 0xffff && hdr.n_valid < 0xffff &&
nb + HPTE_SIZE < count && nb + HPTE_SIZE < count &&
record_hpte(flags, hptp, hpte, revp, 1, first_pass)) { record_hpte(flags, hptp, hpte, revp, 1, first_pass)) {
...@@ -1353,7 +1350,7 @@ static ssize_t kvm_htab_read(struct file *file, char __user *buf, ...@@ -1353,7 +1350,7 @@ static ssize_t kvm_htab_read(struct file *file, char __user *buf,
++revp; ++revp;
} }
/* Now skip invalid entries while we can */ /* Now skip invalid entries while we can */
while (i < kvm->arch.hpt.npte && while (i < kvmppc_hpt_npte(&kvm->arch.hpt) &&
hdr.n_invalid < 0xffff && hdr.n_invalid < 0xffff &&
record_hpte(flags, hptp, hpte, revp, 0, first_pass)) { record_hpte(flags, hptp, hpte, revp, 0, first_pass)) {
/* found an invalid entry */ /* found an invalid entry */
...@@ -1374,7 +1371,7 @@ static ssize_t kvm_htab_read(struct file *file, char __user *buf, ...@@ -1374,7 +1371,7 @@ static ssize_t kvm_htab_read(struct file *file, char __user *buf,
} }
/* Check if we've wrapped around the hash table */ /* Check if we've wrapped around the hash table */
if (i >= kvm->arch.hpt.npte) { if (i >= kvmppc_hpt_npte(&kvm->arch.hpt)) {
i = 0; i = 0;
ctx->first_pass = 0; ctx->first_pass = 0;
break; break;
...@@ -1433,8 +1430,8 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf, ...@@ -1433,8 +1430,8 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
err = -EINVAL; err = -EINVAL;
i = hdr.index; i = hdr.index;
if (i >= kvm->arch.hpt.npte || if (i >= kvmppc_hpt_npte(&kvm->arch.hpt) ||
i + hdr.n_valid + hdr.n_invalid > kvm->arch.hpt.npte) i + hdr.n_valid + hdr.n_invalid > kvmppc_hpt_npte(&kvm->arch.hpt))
break; break;
hptp = (__be64 *)(kvm->arch.hpt.virt + (i * HPTE_SIZE)); hptp = (__be64 *)(kvm->arch.hpt.virt + (i * HPTE_SIZE));
...@@ -1625,7 +1622,8 @@ static ssize_t debugfs_htab_read(struct file *file, char __user *buf, ...@@ -1625,7 +1622,8 @@ static ssize_t debugfs_htab_read(struct file *file, char __user *buf,
kvm = p->kvm; kvm = p->kvm;
i = p->hpt_index; i = p->hpt_index;
hptp = (__be64 *)(kvm->arch.hpt.virt + (i * HPTE_SIZE)); hptp = (__be64 *)(kvm->arch.hpt.virt + (i * HPTE_SIZE));
for (; len != 0 && i < kvm->arch.hpt.npte; ++i, hptp += 2) { for (; len != 0 && i < kvmppc_hpt_npte(&kvm->arch.hpt);
++i, hptp += 2) {
if (!(be64_to_cpu(hptp[0]) & (HPTE_V_VALID | HPTE_V_ABSENT))) if (!(be64_to_cpu(hptp[0]) & (HPTE_V_VALID | HPTE_V_ABSENT)))
continue; continue;
......
...@@ -292,7 +292,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, ...@@ -292,7 +292,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
/* Find and lock the HPTEG slot to use */ /* Find and lock the HPTEG slot to use */
do_insert: do_insert:
if (pte_index >= kvm->arch.hpt.npte) if (pte_index >= kvmppc_hpt_npte(&kvm->arch.hpt))
return H_PARAMETER; return H_PARAMETER;
if (likely((flags & H_EXACT) == 0)) { if (likely((flags & H_EXACT) == 0)) {
pte_index &= ~7UL; pte_index &= ~7UL;
...@@ -469,7 +469,7 @@ long kvmppc_do_h_remove(struct kvm *kvm, unsigned long flags, ...@@ -469,7 +469,7 @@ long kvmppc_do_h_remove(struct kvm *kvm, unsigned long flags,
if (kvm_is_radix(kvm)) if (kvm_is_radix(kvm))
return H_FUNCTION; return H_FUNCTION;
if (pte_index >= kvm->arch.hpt.npte) if (pte_index >= kvmppc_hpt_npte(&kvm->arch.hpt))
return H_PARAMETER; return H_PARAMETER;
hpte = (__be64 *)(kvm->arch.hpt.virt + (pte_index << 4)); hpte = (__be64 *)(kvm->arch.hpt.virt + (pte_index << 4));
while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) while (!try_lock_hpte(hpte, HPTE_V_HVLOCK))
...@@ -557,7 +557,7 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) ...@@ -557,7 +557,7 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu)
break; break;
} }
if (req != 1 || flags == 3 || if (req != 1 || flags == 3 ||
pte_index >= kvm->arch.hpt.npte) { pte_index >= kvmppc_hpt_npte(&kvm->arch.hpt)) {
/* parameter error */ /* parameter error */
args[j] = ((0xa0 | flags) << 56) + pte_index; args[j] = ((0xa0 | flags) << 56) + pte_index;
ret = H_PARAMETER; ret = H_PARAMETER;
...@@ -657,7 +657,7 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags, ...@@ -657,7 +657,7 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags,
if (kvm_is_radix(kvm)) if (kvm_is_radix(kvm))
return H_FUNCTION; return H_FUNCTION;
if (pte_index >= kvm->arch.hpt.npte) if (pte_index >= kvmppc_hpt_npte(&kvm->arch.hpt))
return H_PARAMETER; return H_PARAMETER;
hpte = (__be64 *)(kvm->arch.hpt.virt + (pte_index << 4)); hpte = (__be64 *)(kvm->arch.hpt.virt + (pte_index << 4));
...@@ -728,7 +728,7 @@ long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long flags, ...@@ -728,7 +728,7 @@ long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long flags,
if (kvm_is_radix(kvm)) if (kvm_is_radix(kvm))
return H_FUNCTION; return H_FUNCTION;
if (pte_index >= kvm->arch.hpt.npte) if (pte_index >= kvmppc_hpt_npte(&kvm->arch.hpt))
return H_PARAMETER; return H_PARAMETER;
if (flags & H_READ_4) { if (flags & H_READ_4) {
pte_index &= ~3; pte_index &= ~3;
...@@ -769,7 +769,7 @@ long kvmppc_h_clear_ref(struct kvm_vcpu *vcpu, unsigned long flags, ...@@ -769,7 +769,7 @@ long kvmppc_h_clear_ref(struct kvm_vcpu *vcpu, unsigned long flags,
if (kvm_is_radix(kvm)) if (kvm_is_radix(kvm))
return H_FUNCTION; return H_FUNCTION;
if (pte_index >= kvm->arch.hpt.npte) if (pte_index >= kvmppc_hpt_npte(&kvm->arch.hpt))
return H_PARAMETER; return H_PARAMETER;
rev = real_vmalloc_addr(&kvm->arch.hpt.rev[pte_index]); rev = real_vmalloc_addr(&kvm->arch.hpt.rev[pte_index]);
...@@ -817,7 +817,7 @@ long kvmppc_h_clear_mod(struct kvm_vcpu *vcpu, unsigned long flags, ...@@ -817,7 +817,7 @@ long kvmppc_h_clear_mod(struct kvm_vcpu *vcpu, unsigned long flags,
if (kvm_is_radix(kvm)) if (kvm_is_radix(kvm))
return H_FUNCTION; return H_FUNCTION;
if (pte_index >= kvm->arch.hpt.npte) if (pte_index >= kvmppc_hpt_npte(&kvm->arch.hpt))
return H_PARAMETER; return H_PARAMETER;
rev = real_vmalloc_addr(&kvm->arch.hpt.rev[pte_index]); rev = real_vmalloc_addr(&kvm->arch.hpt.rev[pte_index]);
...@@ -970,7 +970,7 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v, ...@@ -970,7 +970,7 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v,
somask = (1UL << 28) - 1; somask = (1UL << 28) - 1;
vsid = (slb_v & ~SLB_VSID_B) >> SLB_VSID_SHIFT; vsid = (slb_v & ~SLB_VSID_B) >> SLB_VSID_SHIFT;
} }
hash = (vsid ^ ((eaddr & somask) >> pshift)) & kvm->arch.hpt.mask; hash = (vsid ^ ((eaddr & somask) >> pshift)) & kvmppc_hpt_mask(&kvm->arch.hpt);
avpn = slb_v & ~(somask >> 16); /* also includes B */ avpn = slb_v & ~(somask >> 16); /* also includes B */
avpn |= (eaddr & somask) >> 16; avpn |= (eaddr & somask) >> 16;
...@@ -1017,7 +1017,7 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v, ...@@ -1017,7 +1017,7 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v,
if (val & HPTE_V_SECONDARY) if (val & HPTE_V_SECONDARY)
break; break;
val |= HPTE_V_SECONDARY; val |= HPTE_V_SECONDARY;
hash = hash ^ kvm->arch.hpt.mask; hash = hash ^ kvmppc_hpt_mask(&kvm->arch.hpt);
} }
return -1; return -1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment