From: Andrew Jones <drjones@redhat.com>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org
Subject: [Qemu-devel] [PATCH 2/2] tcg-arm: more instruction execution control
Date: Tue, 13 Jan 2015 16:48:11 +0100 [thread overview]
Message-ID: <1421164091-19989-3-git-send-email-drjones@redhat.com> (raw)
In-Reply-To: <1421164091-19989-1-git-send-email-drjones@redhat.com>
Cleanup XN/PXN handling in get_phys_addr_lpae, and implement all but
EL2 support of the following ARMv8 sections
D4.5.1 Memory access control: Access permissions for instruction
execution
G4.7.2 Execute-never restrictions on instruction fetching
G4.7.2 matches the ARMv7 section B3.7.2 when long-descriptors are used.
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
v3:
- correct logic for (is_user && !(ap & 1)) case
- base on "user doesn't need R/W access to exec" patch
v2: correct assert in el2 case
I didn't test this with secure mode (I didn't even check if that's
currently possible), but I did test all other EL1&0 XN controls with
both tcg-arm (cortex-a15) and tcg-aarch64 (cortex-a57) by hacking up
some tests with kvm-unit-tests/arm[64]. I also booted Linux (just
up to looking for a rootfs) with both.
target-arm/helper.c | 80 +++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 66 insertions(+), 14 deletions(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 7c30a2669a0f2..715e0f47bec7d 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -4516,6 +4516,69 @@ static inline int check_ap(CPUARMState *env, int ap, int domain_prot,
}
}
+/* Check section/page execution permission.
+ *
+ * Returns PAGE_EXEC if execution is permitted, otherwise zero.
+ *
+ * Supports AArch64, AArch32, and v7-LPAE. Doesn't yet support
+ * EL2. Actually, for v7-LPAE, we'd also need to emulate Virt
+ * Extensions to truly have WXN/UWXN. We don't support checking
+ * for that yet, so we just assume we have them.
+ *
+ * @env : CPUARMState
+ * @is_user : 0 for privileged access, 1 for user
+ * @ap : Access permissions (AP[2:1]) from descriptor
+ * @ns : (NSTable || NS) from descriptors
+ * @xn : ([U]XNTable || [U]XN) from descriptors
+ * @pxn : (PXNTable || PXN) from descriptors
+ */
+static int check_xn_lpae(CPUARMState *env, int is_user, int ap,
+ int ns, int xn, int pxn)
+{
+ int wxn;
+
+ switch (arm_current_el(env)) {
+ case 0:
+ case 1:
+ wxn = env->cp15.sctlr_el[1] & SCTLR_WXN;
+ if (arm_el_is_aa64(env, 1)) {
+ if (is_user && !(ap & 1)) {
+ wxn = 0;
+ }
+ pxn = pxn || ((ap & 1) && !(ap & 2));
+ xn = is_user ? xn : pxn;
+ } else {
+ int uwxn = env->cp15.sctlr_el[1] & SCTLR_UWXN;
+ pxn = pxn || (uwxn && (ap & 1) && !(ap & 2));
+ xn = xn || (!is_user && pxn) || (is_user && !(ap & 1));
+ }
+ if (arm_is_secure(env)) {
+ xn = xn || (ns && (env->cp15.scr_el3 & SCR_SIF));
+ }
+ break;
+ case 2:
+ /* TODO actually support EL2 */
+ assert(false);
+
+ if (arm_el_is_aa64(env, 2)) {
+ wxn = env->cp15.sctlr_el[2] & SCTLR_WXN;
+ } else {
+ /* wxn = HSCTLR.WXN */
+ }
+ break;
+ case 3:
+ if (arm_el_is_aa64(env, 3)) {
+ wxn = env->cp15.sctlr_el[3] & SCTLR_WXN;
+ } else {
+ wxn = 0;
+ }
+ xn = xn || (ns && (env->cp15.scr_el3 & SCR_SIF));
+ break;
+ }
+
+ return xn || (!(ap & 2) && wxn) ? 0 : PAGE_EXEC;
+}
+
static bool get_level1_table_address(CPUARMState *env, uint32_t *table,
uint32_t address)
{
@@ -4941,7 +5004,7 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
if (extract32(tableattrs, 2, 1)) {
attrs &= ~(1 << 4);
}
- /* Since we're always in the Non-secure state, NSTable is ignored. */
+ attrs |= extract32(tableattrs, 4, 1) << 3; /* NS */
break;
}
/* Here descaddr is the final physical address, and attributes
@@ -4962,19 +5025,8 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
*prot |= !(ap & 2) ? PAGE_WRITE : 0;
}
- *prot |= PAGE_EXEC;
- if ((arm_feature(env, ARM_FEATURE_V8) && is_user && (attrs & (1 << 12))) ||
- (!arm_feature(env, ARM_FEATURE_V8) && (attrs & (1 << 12))) ||
- (!arm_el_is_aa64(env, 1) && is_user && !(ap & 1)) ||
- (!is_user && (attrs & (1 << 11)))) {
- /* XN/UXN or PXN. Since we only implement EL0/EL1 we unconditionally
- * treat XN/UXN as UXN for v8.
- */
- if (access_type == 2) {
- goto do_fault;
- }
- *prot &= ~PAGE_EXEC;
- }
+ *prot |= check_xn_lpae(env, is_user, ap, extract32(attrs, 3, 1),
+ extract32(attrs, 12, 1), extract32(attrs, 11, 1));
if ((*prot == 0)
|| (!(*prot & PAGE_WRITE) && access_type == 1)
--
1.9.3
next prev parent reply other threads:[~2015-01-13 15:48 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-13 15:48 [Qemu-devel] [PATCH 0/2] tcg-arm: fix and extend instruction execution control Andrew Jones
2015-01-13 15:48 ` [Qemu-devel] [PATCH 1/2] tcg-aarch64: user doesn't need R/W access to exec Andrew Jones
2015-01-16 14:52 ` Peter Maydell
2015-01-19 17:25 ` Andrew Jones
2015-01-13 15:48 ` Andrew Jones [this message]
2015-01-16 16:16 ` [Qemu-devel] [PATCH 2/2] tcg-arm: more instruction execution control Peter Maydell
2015-01-16 19:02 ` Peter Maydell
2015-01-19 17:40 ` Andrew Jones
2015-01-19 17:40 ` Andrew Jones
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1421164091-19989-3-git-send-email-drjones@redhat.com \
--to=drjones@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).