Commit f3c75d42 authored by Aneesh Kumar K.V's avatar Aneesh Kumar K.V Committed by Alexander Graf
Browse files

target-ppc: Fix htab_mask calculation



Correctly update the htab_mask using the return value of
KVM_PPC_ALLOCATE_HTAB ioctl. Also we don't update sdr1
on GET_SREGS for HV. We check for external htab and if
found true, we don't need to update sdr1

Signed-off-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
[ fixed pte group offset computation in ppc_hash64_htab_lookup() that
  caused TCG to fail, Greg Kurz <gkurz@linux.vnet.ibm.com> ]
Signed-off-by: default avatarGreg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
parent 3707cd62
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -749,7 +749,13 @@ static void spapr_cpu_reset(void *opaque)
        env->external_htab = (void *)1;
    }
    env->htab_base = -1;
    env->htab_mask = HTAB_SIZE(spapr) - 1;
    /*
     * htab_mask is the mask used to normalize hash value to PTEG index.
     * htab_shift is log2 of hash table size.
     * We have 8 hpte per group, and each hpte is 16 bytes.
     * ie have 128 bytes per hpte entry.
     */
    env->htab_mask = (1ULL << ((spapr)->htab_shift - 7)) - 1;
    env->spr[SPR_SDR1] = (target_ulong)(uintptr_t)spapr->htab |
        (spapr->htab_shift - 18);
}
+15 −4
Original line number Diff line number Diff line
@@ -40,6 +40,17 @@ static target_ulong compute_tlbie_rb(target_ulong v, target_ulong r,
    return rb;
}

static inline bool valid_pte_index(CPUPPCState *env, target_ulong pte_index)
{
    /*
     * hash value/pteg group index is normalized by htab_mask
     */
    if (((pte_index & ~7ULL) / HPTES_PER_GROUP) & ~env->htab_mask) {
        return false;
    }
    return true;
}

static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                            target_ulong opcode, target_ulong *args)
{
@@ -91,7 +102,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,

    pteh &= ~0x60ULL;

    if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {
    if (!valid_pte_index(env, pte_index)) {
        return H_PARAMETER;
    }
    if (likely((flags & H_EXACT) == 0)) {
@@ -136,7 +147,7 @@ static RemoveResult remove_hpte(CPUPPCState *env, target_ulong ptex,
    hwaddr hpte;
    target_ulong v, r, rb;

    if ((ptex * HASH_PTE_SIZE_64) & ~env->htab_mask) {
    if (!valid_pte_index(env, ptex)) {
        return REMOVE_PARM;
    }

@@ -262,7 +273,7 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr,
    hwaddr hpte;
    target_ulong v, r, rb;

    if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {
    if (!valid_pte_index(env, pte_index)) {
        return H_PARAMETER;
    }

@@ -299,7 +310,7 @@ static target_ulong h_read(PowerPCCPU *cpu, sPAPREnvironment *spapr,
    uint8_t *hpte;
    int i, ridx, n_entries = 1;

    if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {
    if (!valid_pte_index(env, pte_index)) {
        return H_PARAMETER;
    }

+1 −0
Original line number Diff line number Diff line
@@ -966,6 +966,7 @@ struct CPUPPCState {
#endif
    /* segment registers */
    hwaddr htab_base;
    /* mask used to normalize hash value to PTEG index */
    hwaddr htab_mask;
    target_ulong sr[32];
    /* externally stored hash table */
+3 −1
Original line number Diff line number Diff line
@@ -1031,7 +1031,9 @@ int kvm_arch_get_registers(CPUState *cs)
            return ret;
        }

        if (!env->external_htab) {
            ppc_store_sdr1(env, sregs.u.s.sdr1);
        }

        /* Sync SLB */
#ifdef TARGET_PPC64
+7 −4
Original line number Diff line number Diff line
@@ -70,7 +70,9 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
        qemu_get_betls(f, &env->pb[i]);
    for (i = 0; i < 1024; i++)
        qemu_get_betls(f, &env->spr[i]);
    if (!env->external_htab) {
        ppc_store_sdr1(env, sdr1);
    }
    qemu_get_be32s(f, &env->vscr);
    qemu_get_be64s(f, &env->spe_acc);
    qemu_get_be32s(f, &env->spe_fscr);
@@ -179,9 +181,10 @@ static int cpu_post_load(void *opaque, int version_id)
        env->IBAT[1][i+4] = env->spr[SPR_IBAT4U + 2*i + 1];
    }

    if (!env->external_htab) {
        /* Restore htab_base and htab_mask variables */
        ppc_store_sdr1(env, env->spr[SPR_SDR1]);

    }
    hreg_compute_hflags(env);
    hreg_compute_mem_idx(env);

Loading