From patchwork Thu Jun 28 14:35:58 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 9676 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id CBB7623E1B for ; Thu, 28 Jun 2012 14:36:16 +0000 (UTC) Received: from mail-yw0-f47.google.com (mail-yw0-f47.google.com [209.85.213.47]) by fiordland.canonical.com (Postfix) with ESMTP id 7D5D3A1893D for ; Thu, 28 Jun 2012 14:36:16 +0000 (UTC) Received: by yhjj56 with SMTP id j56so2362748yhj.20 for ; Thu, 28 Jun 2012 07:36:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=mNB+MO9okx1c5467JADuNoeFH8NtVjY85TJ4/4X3zQY=; b=ZF9w8up6e6gzucaCVc9UM8lkR748nK4WQhSEEHpdOCuFHE8RBfiZavpPBfBd8Ewrjb R/iyhhJwUsEJHKucAU+38NrZePm+DcfS3bF87Hheph1mTabI0q7ejYOyl7K2C/shiQUa 21anoVtDihmxS/OtLsvoheoCeVjkP03XCK0yYJ3jNUpj/oKiCAyQUkFnPGsARbuOhNpt LltPwYAwB+JKcqSTVeARzGNSvqtZ6NZxIAkHU/x/rXBnzw5aEnnYdiDr/eOoxtQi720J llZB12k93/BMkPPITaS++giQAU3fv0O3R1pUjJok3Aq+J+MFu7Wbitg4F+8flpzIuvW/ 20cg== Received: by 10.42.155.73 with SMTP id t9mr662244icw.48.1340894175463; Thu, 28 Jun 2012 07:36:15 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.24.148 with SMTP id v20csp43439ibb; Thu, 28 Jun 2012 07:36:12 -0700 (PDT) Received: by 10.236.165.102 with SMTP id d66mr3600838yhl.54.1340894171220; Thu, 28 Jun 2012 07:36:11 -0700 (PDT) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk. [81.2.115.146]) by mx.google.com with ESMTPS id b27si18641822yhn.56.2012.06.28.07.36.10 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 28 Jun 2012 07:36:11 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 81.2.115.146 as permitted sender) client-ip=81.2.115.146; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 81.2.115.146 as permitted sender) smtp.mail=pm215@archaic.org.uk Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.72) (envelope-from ) id 1SkFpG-0008MQ-Eu; Thu, 28 Jun 2012 15:36:06 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 05/13] target-arm: Implement privileged-execute-never (PXN) Date: Thu, 28 Jun 2012 15:35:58 +0100 Message-Id: <1340894166-32105-6-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1340894166-32105-1-git-send-email-peter.maydell@linaro.org> References: <1340894166-32105-1-git-send-email-peter.maydell@linaro.org> X-Gm-Message-State: ALoCoQn0Bir1fyrN3Hxe2iFTRRlaqH9v+5Gbd2APqlaLC8qxU5XyzIOSQA2biJk6ptlnfVPhfPdz Implement the privileged-execute-never (PXN) translation table bit. It is implementation-defined whether this is implemented, so we give it its own ARM_FEATURE_ flag. LPAE requires PXN, so add also an LPAE feature flag and the implication logic, as a placeholder for actually implementing LPAE at a later date. Signed-off-by: Peter Maydell --- target-arm/cpu.c | 4 ++++ target-arm/cpu.h | 2 ++ target-arm/helper.c | 32 ++++++++++++++++++++------------ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/target-arm/cpu.c b/target-arm/cpu.c index ae57953..526e725 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -192,6 +192,9 @@ void arm_cpu_realize(ARMCPU *cpu) if (arm_feature(env, ARM_FEATURE_VFP3)) { set_feature(env, ARM_FEATURE_VFP); } + if (arm_feature(env, ARM_FEATURE_LPAE)) { + set_feature(env, ARM_FEATURE_PXN); + } register_cp_regs_for_features(cpu); } @@ -532,6 +535,7 @@ static void cortex_a15_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V7MP); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); + set_feature(&cpu->env, ARM_FEATURE_LPAE); cpu->midr = 0x412fc0f1; cpu->reset_fpsid = 0x410430f0; cpu->mvfr0 = 0x10110222; diff --git a/target-arm/cpu.h b/target-arm/cpu.h index aadfca0..82cad4b 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -386,6 +386,8 @@ enum arm_features { ARM_FEATURE_CACHE_DIRTY_REG, /* 1136/1176 cache dirty status register */ ARM_FEATURE_CACHE_BLOCK_OPS, /* v6 optional cache block operations */ ARM_FEATURE_MPIDR, /* has cp15 MPIDR */ + ARM_FEATURE_PXN, /* has Privileged Execute Never bit */ + ARM_FEATURE_LPAE, /* has Large Physical Address Extension */ }; static inline int arm_feature(CPUARMState *env, int feature) diff --git a/target-arm/helper.c b/target-arm/helper.c index ca5d8e9..6ef0b1d 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1935,9 +1935,10 @@ static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type, uint32_t table; uint32_t desc; uint32_t xn; + uint32_t pxn = 0; int type; int ap; - int domain; + int domain = 0; int domain_prot; uint32_t phys_addr; @@ -1946,27 +1947,27 @@ static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type, table = get_level1_table_address(env, address); desc = ldl_phys(table); type = (desc & 3); - if (type == 0) { - /* Section translation fault. */ + if (type == 0 || (type == 3 && !arm_feature(env, ARM_FEATURE_PXN))) { + /* Section translation fault, or attempt to use the encoding + * which is Reserved on implementations without PXN. + */ code = 5; - domain = 0; goto do_fault; - } else if (type == 2 && (desc & (1 << 18))) { - /* Supersection. */ - domain = 0; - } else { - /* Section or page. */ + } + if ((type == 1) || !(desc & (1 << 18))) { + /* Page or Section. */ domain = (desc >> 5) & 0x0f; } domain_prot = (env->cp15.c3 >> (domain * 2)) & 3; if (domain_prot == 0 || domain_prot == 2) { - if (type == 2) + if (type != 1) { code = 9; /* Section domain fault. */ - else + } else { code = 11; /* Page domain fault. */ + } goto do_fault; } - if (type == 2) { + if (type != 1) { if (desc & (1 << 18)) { /* Supersection. */ phys_addr = (desc & 0xff000000) | (address & 0x00ffffff); @@ -1978,8 +1979,12 @@ static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type, } ap = ((desc >> 10) & 3) | ((desc >> 13) & 4); xn = desc & (1 << 4); + pxn = desc & 1; code = 13; } else { + if (arm_feature(env, ARM_FEATURE_PXN)) { + pxn = (desc >> 2) & 1; + } /* Lookup l2 entry. */ table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc); desc = ldl_phys(table); @@ -2007,6 +2012,9 @@ static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type, if (domain_prot == 3) { *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; } else { + if (pxn && !is_user) { + xn = 1; + } if (xn && access_type == 2) goto do_fault;