From patchwork Mon Apr 27 15:20:39 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 47620 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f198.google.com (mail-wi0-f198.google.com [209.85.212.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id BB0E620553 for ; Mon, 27 Apr 2015 15:23:52 +0000 (UTC) Received: by wixv7 with SMTP id v7sf19306745wix.0 for ; Mon, 27 Apr 2015 08:23:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding :subject:precedence:list-id:list-unsubscribe:list-archive:list-post :list-help:list-subscribe:errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=PM0jqVryHkcCLugzlh/wtKUys16CAq06Et+e5DWHNi0=; b=T3NljwJ4NZMm3yGWnhTYYO7tMmI2rUZhsqqM0325dS7/DMOTrMOECjTP7eYzzdY3rK 0pcDW04TBgaPiKtijQaASgruX4MtD8WVVDqB4OA+Y/VOMPFNH+CkYvNyLHHKkZ7DJyzN qnYWGTMpyByR16PlBJcCXv8PCr4DoVPKMg5EE6TbwQKOEThDQZKydlAyWbFfXmfQYv5O P6fdW2C/uzngiU2dFTOHUz1F6WwN+ZdNQZprlf5RPCwpTKyqrrd5B367liulKIhQUOMg 1JoQhidCHdyK9jVH6Q+cwzTRWhTd2qPPzI6jz0sNhhY008W6V6/UjZNtN3Bw6lu+zlNT eKYA== X-Gm-Message-State: ALoCoQmX0PuVY2Acd32SANHHsMKNPz2n/PLmeCYhanQ4sP7Y34m3cyCqHeVaqBIzmVqKh0LkDxFa X-Received: by 10.113.11.3 with SMTP id ee3mr7671255lbd.9.1430148231976; Mon, 27 Apr 2015 08:23:51 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.207.2 with SMTP id ls2ls139540lac.31.gmail; Mon, 27 Apr 2015 08:23:51 -0700 (PDT) X-Received: by 10.112.199.35 with SMTP id jh3mr10479975lbc.23.1430148231689; Mon, 27 Apr 2015 08:23:51 -0700 (PDT) Received: from mail-lb0-f176.google.com (mail-lb0-f176.google.com. [209.85.217.176]) by mx.google.com with ESMTPS id p10si14991110laa.17.2015.04.27.08.23.51 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 27 Apr 2015 08:23:51 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.176 as permitted sender) client-ip=209.85.217.176; Received: by lbbzk7 with SMTP id zk7so84984881lbb.0 for ; Mon, 27 Apr 2015 08:23:51 -0700 (PDT) X-Received: by 10.152.206.75 with SMTP id lm11mr10351383lac.41.1430148231571; Mon, 27 Apr 2015 08:23:51 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.67.65 with SMTP id l1csp1341346lbt; Mon, 27 Apr 2015 08:23:50 -0700 (PDT) X-Received: by 10.140.232.14 with SMTP id d14mr8025451qhc.79.1430148230214; Mon, 27 Apr 2015 08:23:50 -0700 (PDT) Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id b85si3583773qhc.78.2015.04.27.08.23.49 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 27 Apr 2015 08:23:50 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Received: from localhost ([::1]:55767 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ymksv-0000Zw-1v for patch@linaro.org; Mon, 27 Apr 2015 11:23:49 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37798) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ymkq9-0004Ar-GQ for qemu-devel@nongnu.org; Mon, 27 Apr 2015 11:20:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ymkq7-0003aq-Me for qemu-devel@nongnu.org; Mon, 27 Apr 2015 11:20:57 -0400 Received: from mnementh.archaic.org.uk ([2001:8b0:1d0::1]:34016) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ymkq7-0003Ym-F2 for qemu-devel@nongnu.org; Mon, 27 Apr 2015 11:20:55 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1Ymkpy-0008Rv-0P for qemu-devel@nongnu.org; Mon, 27 Apr 2015 16:20:46 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Mon, 27 Apr 2015 16:20:39 +0100 Message-Id: <1430148045-32400-12-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1430148045-32400-1-git-send-email-peter.maydell@linaro.org> References: <1430148045-32400-1-git-send-email-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:8b0:1d0::1 Subject: [Qemu-devel] [PULL 11/17] target-arm: Use correct memory attributes for page table walks 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+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.176 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 Factor out the page table walk memory accesses into their own function, so that we can specify the correct S/NS memory attributes for them. This will also provide a place to use the correct endianness and handle the need for a stage-2 translation when virtualization is supported. Signed-off-by: Peter Maydell Reviewed-by: Edgar E. Iglesias Reviewed-by: Alex Bennée --- target-arm/helper.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index a568299..a01ff7f 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -5129,6 +5129,29 @@ static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx, return true; } +/* All loads done in the course of a page table walk go through here. + * TODO: rather than ignoring errors from physical memory reads (which + * are external aborts in ARM terminology) we should propagate this + * error out so that we can turn it into a Data Abort if this walk + * was being done for a CPU load/store or an address translation instruction + * (but not if it was for a debug access). + */ +static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure) +{ + MemTxAttrs attrs = {}; + + attrs.secure = is_secure; + return address_space_ldl(cs->as, addr, attrs, NULL); +} + +static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure) +{ + MemTxAttrs attrs = {}; + + attrs.secure = is_secure; + return address_space_ldq(cs->as, addr, attrs, NULL); +} + static int get_phys_addr_v5(CPUARMState *env, uint32_t address, int access_type, ARMMMUIdx mmu_idx, hwaddr *phys_ptr, int *prot, target_ulong *page_size) @@ -5151,7 +5174,7 @@ static int get_phys_addr_v5(CPUARMState *env, uint32_t address, int access_type, code = 5; goto do_fault; } - desc = ldl_phys(cs->as, table); + desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx)); type = (desc & 3); domain = (desc >> 5) & 0x0f; if (regime_el(env, mmu_idx) == 1) { @@ -5187,7 +5210,7 @@ static int get_phys_addr_v5(CPUARMState *env, uint32_t address, int access_type, /* Fine pagetable. */ table = (desc & 0xfffff000) | ((address >> 8) & 0xffc); } - desc = ldl_phys(cs->as, table); + desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx)); switch (desc & 3) { case 0: /* Page translation fault. */ code = 7; @@ -5261,7 +5284,7 @@ static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type, code = 5; goto do_fault; } - desc = ldl_phys(cs->as, table); + desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx)); type = (desc & 3); if (type == 0 || (type == 3 && !arm_feature(env, ARM_FEATURE_PXN))) { /* Section translation fault, or attempt to use the encoding @@ -5310,7 +5333,7 @@ static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type, ns = extract32(desc, 3, 1); /* Lookup l2 entry. */ table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc); - desc = ldl_phys(cs->as, table); + desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx)); ap = ((desc >> 4) & 3) | ((desc >> 7) & 4); switch (desc & 3) { case 0: /* Page translation fault. */ @@ -5525,13 +5548,20 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address, descaddr = extract64(ttbr, 0, 48); descaddr &= ~((1ULL << (va_size - tsz - (granule_sz * (4 - level)))) - 1); - tableattrs = 0; + /* Secure accesses start with the page table in secure memory and + * can be downgraded to non-secure at any step. Non-secure accesses + * remain non-secure. We implement this by just ORing in the NSTable/NS + * bits at each step. + */ + tableattrs = regime_is_secure(env, mmu_idx) ? 0 : (1 << 4); for (;;) { uint64_t descriptor; + bool nstable; descaddr |= (address >> (granule_sz * (4 - level))) & descmask; descaddr &= ~7ULL; - descriptor = ldq_phys(cs->as, descaddr); + nstable = extract32(tableattrs, 4, 1); + descriptor = arm_ldq_ptw(cs, descaddr, !nstable); if (!(descriptor & 1) || (!(descriptor & 2) && (level == 3))) { /* Invalid, or the Reserved level 3 encoding */ @@ -5566,7 +5596,7 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address, if (extract32(tableattrs, 2, 1)) { attrs &= ~(1 << 4); } - attrs |= extract32(tableattrs, 4, 1) << 3; /* NS */ + attrs |= nstable << 3; /* NS */ break; } /* Here descaddr is the final physical address, and attributes @@ -5705,8 +5735,9 @@ static inline int get_phys_addr(CPUARMState *env, target_ulong address, { if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) { /* TODO: when we support EL2 we should here call ourselves recursively - * to do the stage 1 and then stage 2 translations. The ldl_phys - * calls for stage 1 will also need changing. + * to do the stage 1 and then stage 2 translations. The arm_ld*_ptw + * functions will also need changing to perform ARMMMUIdx_S2NS loads + * rather than direct physical memory loads when appropriate. * For non-EL2 CPUs a stage1+stage2 translation is just stage 1. */ assert(!arm_feature(env, ARM_FEATURE_EL2));