aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h1
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_hv.c37
-rw-r--r--arch/powerpc/kvm/book3s_hv.c3
3 files changed, 25 insertions, 16 deletions
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 96753f3aac6d..941c2a3f231b 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -180,6 +180,7 @@ extern void kvm_spapr_tce_release_iommu_group(struct kvm *kvm,
180 struct iommu_group *grp); 180 struct iommu_group *grp);
181extern int kvmppc_switch_mmu_to_hpt(struct kvm *kvm); 181extern int kvmppc_switch_mmu_to_hpt(struct kvm *kvm);
182extern int kvmppc_switch_mmu_to_radix(struct kvm *kvm); 182extern int kvmppc_switch_mmu_to_radix(struct kvm *kvm);
183extern void kvmppc_setup_partition_table(struct kvm *kvm);
183 184
184extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, 185extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
185 struct kvm_create_spapr_tce_64 *args); 186 struct kvm_create_spapr_tce_64 *args);
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index 235319c2574e..966097232d21 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -1238,8 +1238,9 @@ static unsigned long resize_hpt_rehash_hpte(struct kvm_resize_hpt *resize,
1238 unsigned long vpte, rpte, guest_rpte; 1238 unsigned long vpte, rpte, guest_rpte;
1239 int ret; 1239 int ret;
1240 struct revmap_entry *rev; 1240 struct revmap_entry *rev;
1241 unsigned long apsize, psize, avpn, pteg, hash; 1241 unsigned long apsize, avpn, pteg, hash;
1242 unsigned long new_idx, new_pteg, replace_vpte; 1242 unsigned long new_idx, new_pteg, replace_vpte;
1243 int pshift;
1243 1244
1244 hptep = (__be64 *)(old->virt + (idx << 4)); 1245 hptep = (__be64 *)(old->virt + (idx << 4));
1245 1246
@@ -1298,8 +1299,8 @@ static unsigned long resize_hpt_rehash_hpte(struct kvm_resize_hpt *resize,
1298 goto out; 1299 goto out;
1299 1300
1300 rpte = be64_to_cpu(hptep[1]); 1301 rpte = be64_to_cpu(hptep[1]);
1301 psize = hpte_base_page_size(vpte, rpte); 1302 pshift = kvmppc_hpte_base_page_shift(vpte, rpte);
1302 avpn = HPTE_V_AVPN_VAL(vpte) & ~((psize - 1) >> 23); 1303 avpn = HPTE_V_AVPN_VAL(vpte) & ~(((1ul << pshift) - 1) >> 23);
1303 pteg = idx / HPTES_PER_GROUP; 1304 pteg = idx / HPTES_PER_GROUP;
1304 if (vpte & HPTE_V_SECONDARY) 1305 if (vpte & HPTE_V_SECONDARY)
1305 pteg = ~pteg; 1306 pteg = ~pteg;
@@ -1311,20 +1312,20 @@ static unsigned long resize_hpt_rehash_hpte(struct kvm_resize_hpt *resize,
1311 offset = (avpn & 0x1f) << 23; 1312 offset = (avpn & 0x1f) << 23;
1312 vsid = avpn >> 5; 1313 vsid = avpn >> 5;
1313 /* We can find more bits from the pteg value */ 1314 /* We can find more bits from the pteg value */
1314 if (psize < (1ULL << 23)) 1315 if (pshift < 23)
1315 offset |= ((vsid ^ pteg) & old_hash_mask) * psize; 1316 offset |= ((vsid ^ pteg) & old_hash_mask) << pshift;
1316 1317
1317 hash = vsid ^ (offset / psize); 1318 hash = vsid ^ (offset >> pshift);
1318 } else { 1319 } else {
1319 unsigned long offset, vsid; 1320 unsigned long offset, vsid;
1320 1321
1321 /* We only have 40 - 23 bits of seg_off in avpn */ 1322 /* We only have 40 - 23 bits of seg_off in avpn */
1322 offset = (avpn & 0x1ffff) << 23; 1323 offset = (avpn & 0x1ffff) << 23;
1323 vsid = avpn >> 17; 1324 vsid = avpn >> 17;
1324 if (psize < (1ULL << 23)) 1325 if (pshift < 23)
1325 offset |= ((vsid ^ (vsid << 25) ^ pteg) & old_hash_mask) * psize; 1326 offset |= ((vsid ^ (vsid << 25) ^ pteg) & old_hash_mask) << pshift;
1326 1327
1327 hash = vsid ^ (vsid << 25) ^ (offset / psize); 1328 hash = vsid ^ (vsid << 25) ^ (offset >> pshift);
1328 } 1329 }
1329 1330
1330 new_pteg = hash & new_hash_mask; 1331 new_pteg = hash & new_hash_mask;
@@ -1801,6 +1802,7 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
1801 ssize_t nb; 1802 ssize_t nb;
1802 long int err, ret; 1803 long int err, ret;
1803 int mmu_ready; 1804 int mmu_ready;
1805 int pshift;
1804 1806
1805 if (!access_ok(VERIFY_READ, buf, count)) 1807 if (!access_ok(VERIFY_READ, buf, count))
1806 return -EFAULT; 1808 return -EFAULT;
@@ -1855,6 +1857,9 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
1855 err = -EINVAL; 1857 err = -EINVAL;
1856 if (!(v & HPTE_V_VALID)) 1858 if (!(v & HPTE_V_VALID))
1857 goto out; 1859 goto out;
1860 pshift = kvmppc_hpte_base_page_shift(v, r);
1861 if (pshift <= 0)
1862 goto out;
1858 lbuf += 2; 1863 lbuf += 2;
1859 nb += HPTE_SIZE; 1864 nb += HPTE_SIZE;
1860 1865
@@ -1869,14 +1874,18 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
1869 goto out; 1874 goto out;
1870 } 1875 }
1871 if (!mmu_ready && is_vrma_hpte(v)) { 1876 if (!mmu_ready && is_vrma_hpte(v)) {
1872 unsigned long psize = hpte_base_page_size(v, r); 1877 unsigned long senc, lpcr;
1873 unsigned long senc = slb_pgsize_encoding(psize);
1874 unsigned long lpcr;
1875 1878
1879 senc = slb_pgsize_encoding(1ul << pshift);
1876 kvm->arch.vrma_slb_v = senc | SLB_VSID_B_1T | 1880 kvm->arch.vrma_slb_v = senc | SLB_VSID_B_1T |
1877 (VRMA_VSID << SLB_VSID_SHIFT_1T); 1881 (VRMA_VSID << SLB_VSID_SHIFT_1T);
1878 lpcr = senc << (LPCR_VRMASD_SH - 4); 1882 if (!cpu_has_feature(CPU_FTR_ARCH_300)) {
1879 kvmppc_update_lpcr(kvm, lpcr, LPCR_VRMASD); 1883 lpcr = senc << (LPCR_VRMASD_SH - 4);
1884 kvmppc_update_lpcr(kvm, lpcr,
1885 LPCR_VRMASD);
1886 } else {
1887 kvmppc_setup_partition_table(kvm);
1888 }
1880 mmu_ready = 1; 1889 mmu_ready = 1;
1881 } 1890 }
1882 ++i; 1891 ++i;
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 79ea3d9269db..2d46037ce936 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -120,7 +120,6 @@ MODULE_PARM_DESC(h_ipi_redirect, "Redirect H_IPI wakeup to a free host core");
120 120
121static void kvmppc_end_cede(struct kvm_vcpu *vcpu); 121static void kvmppc_end_cede(struct kvm_vcpu *vcpu);
122static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu); 122static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu);
123static void kvmppc_setup_partition_table(struct kvm *kvm);
124 123
125static inline struct kvm_vcpu *next_runnable_thread(struct kvmppc_vcore *vc, 124static inline struct kvm_vcpu *next_runnable_thread(struct kvmppc_vcore *vc,
126 int *ip) 125 int *ip)
@@ -3574,7 +3573,7 @@ static void kvmppc_mmu_destroy_hv(struct kvm_vcpu *vcpu)
3574 return; 3573 return;
3575} 3574}
3576 3575
3577static void kvmppc_setup_partition_table(struct kvm *kvm) 3576void kvmppc_setup_partition_table(struct kvm *kvm)
3578{ 3577{
3579 unsigned long dw0, dw1; 3578 unsigned long dw0, dw1;
3580 3579