PPC KVM fixes for 4.15
One commit here, that fixes a couple of bugs relating to the patch series that enables HPT guests to run on a radix host on POWER9 systems. This patch series went upstream in the 4.15 merge window, so no stable backport is required. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJaGKSnAAoJEJ2a6ncsY3GfF7MIANLLhznEMrWq8jw4g95WsJU1 MkDGwp8kIdhIOM9HD6JRskoJZB5Mws2BWlQ5PSaVFxO6v6eUgNLaRb/UBxC1r7gU 1f9/8corY4BNkezSdJqTL7Xgp13KjTU726OwYAqCPEyCSPEc9ciMyeIgyZuv2dPa Pju+u4tnA+9JJyskgNL+/ybOOZwVat91VmNUVRq29zP6+zo1tmIDxrQchy6Bqui/ 7Wg298G+yjAkJ8ktQu69ACk+0oEBGUOcLUlraqGSr9auR+b0nJ1PAGCDRaONdwgE +X+OE+t+UC6rU+coUXMwO+Id0X7HMdsLQd3066ODEtD55g8MIVZ126Wt8xDmj5o= =GSTh -----END PGP SIGNATURE----- Merge tag 'kvm-ppc-fixes-4.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc into kvm-master PPC KVM fixes for 4.15 One commit here, that fixes a couple of bugs relating to the patch series that enables HPT guests to run on a radix host on POWER9 systems. This patch series went upstream in the 4.15 merge window, so no stable backport is required.
This commit is contained in:
@ -180,6 +180,7 @@ extern void kvm_spapr_tce_release_iommu_group(struct kvm *kvm,
|
||||
struct iommu_group *grp);
|
||||
extern int kvmppc_switch_mmu_to_hpt(struct kvm *kvm);
|
||||
extern int kvmppc_switch_mmu_to_radix(struct kvm *kvm);
|
||||
extern void kvmppc_setup_partition_table(struct kvm *kvm);
|
||||
|
||||
extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
|
||||
struct kvm_create_spapr_tce_64 *args);
|
||||
|
@ -1238,8 +1238,9 @@ static unsigned long resize_hpt_rehash_hpte(struct kvm_resize_hpt *resize,
|
||||
unsigned long vpte, rpte, guest_rpte;
|
||||
int ret;
|
||||
struct revmap_entry *rev;
|
||||
unsigned long apsize, psize, avpn, pteg, hash;
|
||||
unsigned long apsize, avpn, pteg, hash;
|
||||
unsigned long new_idx, new_pteg, replace_vpte;
|
||||
int pshift;
|
||||
|
||||
hptep = (__be64 *)(old->virt + (idx << 4));
|
||||
|
||||
@ -1298,8 +1299,8 @@ static unsigned long resize_hpt_rehash_hpte(struct kvm_resize_hpt *resize,
|
||||
goto out;
|
||||
|
||||
rpte = be64_to_cpu(hptep[1]);
|
||||
psize = hpte_base_page_size(vpte, rpte);
|
||||
avpn = HPTE_V_AVPN_VAL(vpte) & ~((psize - 1) >> 23);
|
||||
pshift = kvmppc_hpte_base_page_shift(vpte, rpte);
|
||||
avpn = HPTE_V_AVPN_VAL(vpte) & ~(((1ul << pshift) - 1) >> 23);
|
||||
pteg = idx / HPTES_PER_GROUP;
|
||||
if (vpte & HPTE_V_SECONDARY)
|
||||
pteg = ~pteg;
|
||||
@ -1311,20 +1312,20 @@ static unsigned long resize_hpt_rehash_hpte(struct kvm_resize_hpt *resize,
|
||||
offset = (avpn & 0x1f) << 23;
|
||||
vsid = avpn >> 5;
|
||||
/* We can find more bits from the pteg value */
|
||||
if (psize < (1ULL << 23))
|
||||
offset |= ((vsid ^ pteg) & old_hash_mask) * psize;
|
||||
if (pshift < 23)
|
||||
offset |= ((vsid ^ pteg) & old_hash_mask) << pshift;
|
||||
|
||||
hash = vsid ^ (offset / psize);
|
||||
hash = vsid ^ (offset >> pshift);
|
||||
} else {
|
||||
unsigned long offset, vsid;
|
||||
|
||||
/* We only have 40 - 23 bits of seg_off in avpn */
|
||||
offset = (avpn & 0x1ffff) << 23;
|
||||
vsid = avpn >> 17;
|
||||
if (psize < (1ULL << 23))
|
||||
offset |= ((vsid ^ (vsid << 25) ^ pteg) & old_hash_mask) * psize;
|
||||
if (pshift < 23)
|
||||
offset |= ((vsid ^ (vsid << 25) ^ pteg) & old_hash_mask) << pshift;
|
||||
|
||||
hash = vsid ^ (vsid << 25) ^ (offset / psize);
|
||||
hash = vsid ^ (vsid << 25) ^ (offset >> pshift);
|
||||
}
|
||||
|
||||
new_pteg = hash & new_hash_mask;
|
||||
@ -1801,6 +1802,7 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
|
||||
ssize_t nb;
|
||||
long int err, ret;
|
||||
int mmu_ready;
|
||||
int pshift;
|
||||
|
||||
if (!access_ok(VERIFY_READ, buf, count))
|
||||
return -EFAULT;
|
||||
@ -1855,6 +1857,9 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
|
||||
err = -EINVAL;
|
||||
if (!(v & HPTE_V_VALID))
|
||||
goto out;
|
||||
pshift = kvmppc_hpte_base_page_shift(v, r);
|
||||
if (pshift <= 0)
|
||||
goto out;
|
||||
lbuf += 2;
|
||||
nb += HPTE_SIZE;
|
||||
|
||||
@ -1869,14 +1874,18 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
|
||||
goto out;
|
||||
}
|
||||
if (!mmu_ready && is_vrma_hpte(v)) {
|
||||
unsigned long psize = hpte_base_page_size(v, r);
|
||||
unsigned long senc = slb_pgsize_encoding(psize);
|
||||
unsigned long lpcr;
|
||||
unsigned long senc, lpcr;
|
||||
|
||||
senc = slb_pgsize_encoding(1ul << pshift);
|
||||
kvm->arch.vrma_slb_v = senc | SLB_VSID_B_1T |
|
||||
(VRMA_VSID << SLB_VSID_SHIFT_1T);
|
||||
lpcr = senc << (LPCR_VRMASD_SH - 4);
|
||||
kvmppc_update_lpcr(kvm, lpcr, LPCR_VRMASD);
|
||||
if (!cpu_has_feature(CPU_FTR_ARCH_300)) {
|
||||
lpcr = senc << (LPCR_VRMASD_SH - 4);
|
||||
kvmppc_update_lpcr(kvm, lpcr,
|
||||
LPCR_VRMASD);
|
||||
} else {
|
||||
kvmppc_setup_partition_table(kvm);
|
||||
}
|
||||
mmu_ready = 1;
|
||||
}
|
||||
++i;
|
||||
|
@ -120,7 +120,6 @@ MODULE_PARM_DESC(h_ipi_redirect, "Redirect H_IPI wakeup to a free host core");
|
||||
|
||||
static void kvmppc_end_cede(struct kvm_vcpu *vcpu);
|
||||
static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu);
|
||||
static void kvmppc_setup_partition_table(struct kvm *kvm);
|
||||
|
||||
static inline struct kvm_vcpu *next_runnable_thread(struct kvmppc_vcore *vc,
|
||||
int *ip)
|
||||
@ -3574,7 +3573,7 @@ static void kvmppc_mmu_destroy_hv(struct kvm_vcpu *vcpu)
|
||||
return;
|
||||
}
|
||||
|
||||
static void kvmppc_setup_partition_table(struct kvm *kvm)
|
||||
void kvmppc_setup_partition_table(struct kvm *kvm)
|
||||
{
|
||||
unsigned long dw0, dw1;
|
||||
|
||||
|
Reference in New Issue
Block a user