From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35773) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WDmWv-0000na-MA for qemu-devel@nongnu.org; Wed, 12 Feb 2014 22:00:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WDmWm-0002RH-Oa for qemu-devel@nongnu.org; Wed, 12 Feb 2014 22:00:01 -0500 Received: from e28smtp03.in.ibm.com ([122.248.162.3]:52224) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WDmWm-0002NK-1K for qemu-devel@nongnu.org; Wed, 12 Feb 2014 21:59:52 -0500 Received: from /spool/local by e28smtp03.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 13 Feb 2014 08:29:48 +0530 From: "Aneesh Kumar K.V" Date: Thu, 13 Feb 2014 08:29:28 +0530 Message-Id: <1392260368-24016-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com> In-Reply-To: <1390896003-3195-3-git-send-email-aneesh.kumar@linux.vnet.ibm.com> References: <1390896003-3195-3-git-send-email-aneesh.kumar@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH V10] target-ppc: Fix htab_mask calculation List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: agraf@suse.de, paulus@samba.org Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, "Aneesh Kumar K.V" From: "Aneesh Kumar K.V" 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: Aneesh Kumar K.V --- Changes from V9: * Fix TCG breakage hw/ppc/spapr.c | 8 +++++++- hw/ppc/spapr_hcall.c | 19 +++++++++++++++---- target-ppc/cpu.h | 1 + target-ppc/kvm.c | 4 +++- target-ppc/machine.c | 11 +++++++---- target-ppc/misc_helper.c | 4 +++- target-ppc/mmu_helper.c | 3 ++- 7 files changed, 38 insertions(+), 12 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index ac62c8f9294b..009bb0112cc0 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -748,7 +748,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); } diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index f755a5392317..c6e123b11ab0 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -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; } diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index bb847676a52e..b0f66e5104dd 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -961,6 +961,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 */ diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 781b72f1ea5a..c771ec11ed28 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -1029,7 +1029,9 @@ int kvm_arch_get_registers(CPUState *cs) return ret; } - ppc_store_sdr1(env, sregs.u.s.sdr1); + if (!env->external_htab) { + ppc_store_sdr1(env, sregs.u.s.sdr1); + } /* Sync SLB */ #ifdef TARGET_PPC64 diff --git a/target-ppc/machine.c b/target-ppc/machine.c index 12c174f7f3e6..2d46ceccca3a 100644 --- a/target-ppc/machine.c +++ b/target-ppc/machine.c @@ -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]); - ppc_store_sdr1(env, sdr1); + 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]; } - /* Restore htab_base and htab_mask variables */ - ppc_store_sdr1(env, env->spr[SPR_SDR1]); - + 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); diff --git a/target-ppc/misc_helper.c b/target-ppc/misc_helper.c index 616aab6fb67d..dc2ebfc4524b 100644 --- a/target-ppc/misc_helper.c +++ b/target-ppc/misc_helper.c @@ -38,7 +38,9 @@ void helper_store_dump_spr(CPUPPCState *env, uint32_t sprn) void helper_store_sdr1(CPUPPCState *env, target_ulong val) { - ppc_store_sdr1(env, val); + if (!env->external_htab) { + ppc_store_sdr1(env, val); + } } void helper_store_hid0_601(CPUPPCState *env, target_ulong val) diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c index 04a840b01697..8e2f8e736a12 100644 --- a/target-ppc/mmu_helper.c +++ b/target-ppc/mmu_helper.c @@ -2014,6 +2014,7 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr) void ppc_store_sdr1(CPUPPCState *env, target_ulong value) { LOG_MMU("%s: " TARGET_FMT_lx "\n", __func__, value); + assert(!env->external_htab); if (env->spr[SPR_SDR1] != value) { env->spr[SPR_SDR1] = value; #if defined(TARGET_PPC64) @@ -2025,7 +2026,7 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value) " stored in SDR1\n", htabsize); htabsize = 28; } - env->htab_mask = (1ULL << (htabsize + 18)) - 1; + env->htab_mask = (1ULL << (htabsize + 18 - 7)) - 1; env->htab_base = value & SDR_64_HTABORG; } else #endif /* defined(TARGET_PPC64) */ -- 1.8.3.2