From patchwork Sun Mar 8 08:44:21 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 447682 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 9F0B91401DC for ; Sun, 8 Mar 2015 19:45:52 +1100 (AEDT) Received: from localhost ([::1]:37845 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YUWqL-0005d0-Oe for incoming@patchwork.ozlabs.org; Sun, 08 Mar 2015 04:45:49 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43899) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YUWpb-0004V9-CF for qemu-devel@nongnu.org; Sun, 08 Mar 2015 04:45:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YUWpX-0004b9-U9 for qemu-devel@nongnu.org; Sun, 08 Mar 2015 04:45:03 -0400 Received: from cantor2.suse.de ([195.135.220.15]:33720 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YUWpX-0004ay-K3; Sun, 08 Mar 2015 04:44:59 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 06926AC64; Sun, 8 Mar 2015 08:44:58 +0000 (UTC) From: Alexander Graf To: qemu-ppc@nongnu.org Date: Sun, 8 Mar 2015 09:44:21 +0100 Message-Id: <1425804297-53727-3-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.8.1.4 In-Reply-To: <1425804297-53727-1-git-send-email-agraf@suse.de> References: <1425804297-53727-1-git-send-email-agraf@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] X-Received-From: 195.135.220.15 Cc: peter.maydell@linaro.org, qemu-devel@nongnu.org, "Aneesh Kumar K.V" Subject: [Qemu-devel] [PULL 02/38] target-ppc: Use right page size with hash table lookup 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" We look at two sizes specified in ISA (4K, 64K). If not found matching, we consider it 16MB. Without this patch we would fail to lookup address above 16MB range. Below 16MB happened to work before because the kernel have a liner mapping and we always looked up hash for 0xc000000000000000. The actual real address was computed by using the 16MB offset with the real address found with the above hash. Without Fix: (gdb) x/16x 0xc000000001000000 0xc000000001000000 : Cannot access memory at address 0xc000000001000000 (gdb) With Fix: (gdb) x/16x 0xc000000001000000 0xc000000001000000 : 0x00000000 0x00000000 0x00000000 0x00000000 0xc000000001000010 : 0x00000000 0x00000000 0x00000000 0x00000000 0xc000000001000020 : 0x00000000 0x00000000 0x00000000 0x00000000 0xc000000001000030 : 0x00000000 0x00000000 0x00000000 0x00000000 Signed-off-by: Aneesh Kumar K.V Reviewed-by: David Gibson Signed-off-by: Alexander Graf --- target-ppc/cpu.h | 1 + target-ppc/mmu-hash64.c | 37 ++++++++++++++++++++++++++----------- target-ppc/mmu-hash64.h | 3 +++ 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index aae33a9..b706b9f 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -45,6 +45,7 @@ # define TARGET_VIRT_ADDR_SPACE_BITS 64 #endif +#define TARGET_PAGE_BITS_64K 16 #define TARGET_PAGE_BITS_16M 24 #else /* defined (TARGET_PPC64) */ diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c index b0278c9..971751f 100644 --- a/target-ppc/mmu-hash64.c +++ b/target-ppc/mmu-hash64.c @@ -388,6 +388,24 @@ static hwaddr ppc_hash64_pteg_search(CPUPPCState *env, hwaddr hash, return -1; } +static uint64_t ppc_hash64_page_shift(ppc_slb_t *slb) +{ + uint64_t epnshift; + + /* Page size according to the SLB, which we use to generate the + * EPN for hash table lookup.. When we implement more recent MMU + * extensions this might be different from the actual page size + * encoded in the PTE */ + if ((slb->vsid & SLB_VSID_LLP_MASK) == SLB_VSID_4K) { + epnshift = TARGET_PAGE_BITS; + } else if ((slb->vsid & SLB_VSID_LLP_MASK) == SLB_VSID_64K) { + epnshift = TARGET_PAGE_BITS_64K; + } else { + epnshift = TARGET_PAGE_BITS_16M; + } + return epnshift; +} + static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env, ppc_slb_t *slb, target_ulong eaddr, ppc_hash_pte64_t *pte) @@ -396,12 +414,7 @@ static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env, hwaddr hash; uint64_t vsid, epnshift, epnmask, epn, ptem; - /* Page size according to the SLB, which we use to generate the - * EPN for hash table lookup.. When we implement more recent MMU - * extensions this might be different from the actual page size - * encoded in the PTE */ - epnshift = (slb->vsid & SLB_VSID_L) - ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS; + epnshift = ppc_hash64_page_shift(slb); epnmask = ~((1ULL << epnshift) - 1); if (slb->vsid & SLB_VSID_B) { @@ -448,12 +461,14 @@ static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env, static hwaddr ppc_hash64_pte_raddr(ppc_slb_t *slb, ppc_hash_pte64_t pte, target_ulong eaddr) { + hwaddr mask; + int target_page_bits; hwaddr rpn = pte.pte1 & HPTE64_R_RPN; - /* FIXME: Add support for SLLP extended page sizes */ - int target_page_bits = (slb->vsid & SLB_VSID_L) - ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS; - hwaddr mask = (1ULL << target_page_bits) - 1; - + /* + * We support 4K, 64K and 16M now + */ + target_page_bits = ppc_hash64_page_shift(slb); + mask = (1ULL << target_page_bits) - 1; return (rpn & ~mask) | (eaddr & mask); } diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h index 49e385d..291750f 100644 --- a/target-ppc/mmu-hash64.h +++ b/target-ppc/mmu-hash64.h @@ -37,6 +37,9 @@ void ppc_hash64_store_hpte(CPUPPCState *env, target_ulong index, #define SLB_VSID_C 0x0000000000000080ULL /* class */ #define SLB_VSID_LP 0x0000000000000030ULL #define SLB_VSID_ATTR 0x0000000000000FFFULL +#define SLB_VSID_LLP_MASK (SLB_VSID_L | SLB_VSID_LP) +#define SLB_VSID_4K 0x0000000000000000ULL +#define SLB_VSID_64K 0x0000000000000110ULL /* * Hash page table definitions