From patchwork Thu Feb 20 17:52:17 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kurz X-Patchwork-Id: 322280 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 2596D2C02FC for ; Fri, 21 Feb 2014 04:54:59 +1100 (EST) Received: from localhost ([::1]:39988 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WGXpp-0000nD-3L for incoming@patchwork.ozlabs.org; Thu, 20 Feb 2014 12:54:57 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41723) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WGXnY-0005LV-Ur for qemu-devel@nongnu.org; Thu, 20 Feb 2014 12:52:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WGXnK-0001ut-Ie for qemu-devel@nongnu.org; Thu, 20 Feb 2014 12:52:36 -0500 Received: from e06smtp18.uk.ibm.com ([195.75.94.114]:55559) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WGXnK-0001uj-8X for qemu-devel@nongnu.org; Thu, 20 Feb 2014 12:52:22 -0500 Received: from /spool/local by e06smtp18.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 20 Feb 2014 17:52:21 -0000 Received: from d06dlp03.portsmouth.uk.ibm.com (9.149.20.15) by e06smtp18.uk.ibm.com (192.168.101.148) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 20 Feb 2014 17:52:20 -0000 Received: from b06cxnps4075.portsmouth.uk.ibm.com (d06relay12.portsmouth.uk.ibm.com [9.149.109.197]) by d06dlp03.portsmouth.uk.ibm.com (Postfix) with ESMTP id 18A0C1B08066; Thu, 20 Feb 2014 17:51:58 +0000 (GMT) Received: from d06av07.portsmouth.uk.ibm.com (d06av07.portsmouth.uk.ibm.com [9.149.37.248]) by b06cxnps4075.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id s1KHq7Fx56098988; Thu, 20 Feb 2014 17:52:07 GMT Received: from d06av07.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av07.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id s1KHqJSY019572; Thu, 20 Feb 2014 12:52:19 -0500 Received: from smtp.lab.toulouse-stg.fr.ibm.com (srv01.lab.toulouse-stg.fr.ibm.com [9.101.4.1]) by d06av07.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id s1KHqJdw019569; Thu, 20 Feb 2014 12:52:19 -0500 Received: from bahia.local (icon-9-167-234-77.megacenter.de.ibm.com [9.167.234.77]) by smtp.lab.toulouse-stg.fr.ibm.com (Postfix) with ESMTP id 4AF95210FFE; Thu, 20 Feb 2014 18:52:18 +0100 (CET) To: agraf@suse.de, aneesh.kumar@linux.vnet.ibm.com From: Greg Kurz Date: Thu, 20 Feb 2014 18:52:17 +0100 Message-ID: <20140220175217.23576.56206.stgit@bahia.local> In-Reply-To: <20140220175210.23576.10431.stgit@bahia.local> References: <20140220175210.23576.10431.stgit@bahia.local> User-Agent: StGit/0.16 MIME-Version: 1.0 X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 14022017-6892-0000-0000-000007E03CFB X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 195.75.94.114 Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH 1/4] target-ppc: Fix htab_mask calculation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 [ fixed pte group offset computation in ppc_hash64_htab_lookup() that caused TCG to fail, Greg Kurz ] Signed-off-by: Greg Kurz --- 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-hash64.c | 4 ++-- target-ppc/mmu_helper.c | 3 ++- 8 files changed, 40 insertions(+), 14 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 0989ed6..8ac4d8a 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -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); } diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 3ffcc65..d19e3fc 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 7ccf4c6..44ade0c 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -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 */ diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 33d69d2..969ebdd 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -1031,7 +1031,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 12c174f..2d46cec 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 616aab6..dc2ebfc 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-hash64.c b/target-ppc/mmu-hash64.c index c1c33b0..739dece 100644 --- a/target-ppc/mmu-hash64.c +++ b/target-ppc/mmu-hash64.c @@ -375,7 +375,7 @@ static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env, " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx " hash=" TARGET_FMT_plx "\n", env->htab_base, env->htab_mask, vsid, ptem, hash); - pteg_off = (hash * HASH_PTEG_SIZE_64) & env->htab_mask; + pteg_off = (hash & env->htab_mask) * HASH_PTEG_SIZE_64; pte_offset = ppc_hash64_pteg_search(env, pteg_off, 0, ptem, pte); if (pte_offset == -1) { @@ -385,7 +385,7 @@ static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env, " hash=" TARGET_FMT_plx "\n", env->htab_base, env->htab_mask, vsid, ptem, ~hash); - pteg_off = (~hash * HASH_PTEG_SIZE_64) & env->htab_mask; + pteg_off = (~hash & env->htab_mask) * HASH_PTEG_SIZE_64; pte_offset = ppc_hash64_pteg_search(env, pteg_off, 1, ptem, pte); } diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c index 04a840b..8e2f8e7 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) */