From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-arm@nongnu.org, qemu-devel@nongnu.org
Cc: "Richard Henderson" <rth@twiddle.net>,
"Alex Bennée" <alex.bennee@linaro.org>
Subject: [Qemu-devel] [PATCH 6/7] target/arm: Factor MPU lookup code out of get_phys_addr_pmsav8()
Date: Fri, 1 Dec 2017 18:44:38 +0000 [thread overview]
Message-ID: <1512153879-5291-7-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1512153879-5291-1-git-send-email-peter.maydell@linaro.org>
For the TT instruction we're going to need to do an MPU lookup that
also tells us which MPU region the access hit. This requires us
to do the MPU lookup without first doing the SAU security access
check, so pull the MPU lookup parts of get_phys_addr_pmsav8()
out into their own function.
The TT instruction also needs to know the MPU region number which
the lookup hit, so provide this information to the caller of the
MPU lookup code, even though get_phys_addr_pmsav8() doesn't
need to know it.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/helper.c | 130 +++++++++++++++++++++++++++++++---------------------
1 file changed, 79 insertions(+), 51 deletions(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 14ab1f4..be8d797 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -9351,67 +9351,28 @@ static void v8m_security_lookup(CPUARMState *env, uint32_t address,
}
}
-static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
- hwaddr *phys_ptr, MemTxAttrs *txattrs,
- int *prot, uint32_t *fsr)
+static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
+ hwaddr *phys_ptr, MemTxAttrs *txattrs,
+ int *prot, uint32_t *fsr, uint32_t *mregion)
{
+ /* Perform a PMSAv8 MPU lookup (without also doing the SAU check
+ * that a full phys-to-virt translation does).
+ * mregion is (if not NULL) set to the region number which matched,
+ * or -1 if no region number is returned (MPU off, address did not
+ * hit a region, address hit in multiple regions).
+ */
ARMCPU *cpu = arm_env_get_cpu(env);
bool is_user = regime_is_user(env, mmu_idx);
uint32_t secure = regime_is_secure(env, mmu_idx);
int n;
int matchregion = -1;
bool hit = false;
- V8M_SAttributes sattrs = {};
*phys_ptr = address;
*prot = 0;
-
- if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
- v8m_security_lookup(env, address, access_type, mmu_idx, &sattrs);
- if (access_type == MMU_INST_FETCH) {
- /* Instruction fetches always use the MMU bank and the
- * transaction attribute determined by the fetch address,
- * regardless of CPU state. This is painful for QEMU
- * to handle, because it would mean we need to encode
- * into the mmu_idx not just the (user, negpri) information
- * for the current security state but also that for the
- * other security state, which would balloon the number
- * of mmu_idx values needed alarmingly.
- * Fortunately we can avoid this because it's not actually
- * possible to arbitrarily execute code from memory with
- * the wrong security attribute: it will always generate
- * an exception of some kind or another, apart from the
- * special case of an NS CPU executing an SG instruction
- * in S&NSC memory. So we always just fail the translation
- * here and sort things out in the exception handler
- * (including possibly emulating an SG instruction).
- */
- if (sattrs.ns != !secure) {
- *fsr = sattrs.nsc ? M_FAKE_FSR_NSC_EXEC : M_FAKE_FSR_SFAULT;
- return true;
- }
- } else {
- /* For data accesses we always use the MMU bank indicated
- * by the current CPU state, but the security attributes
- * might downgrade a secure access to nonsecure.
- */
- if (sattrs.ns) {
- txattrs->secure = false;
- } else if (!secure) {
- /* NS access to S memory must fault.
- * Architecturally we should first check whether the
- * MPU information for this address indicates that we
- * are doing an unaligned access to Device memory, which
- * should generate a UsageFault instead. QEMU does not
- * currently check for that kind of unaligned access though.
- * If we added it we would need to do so as a special case
- * for M_FAKE_FSR_SFAULT in arm_v7m_cpu_do_interrupt().
- */
- *fsr = M_FAKE_FSR_SFAULT;
- return true;
- }
- }
+ if (mregion) {
+ *mregion = -1;
}
/* Unlike the ARM ARM pseudocode, we don't need to check whether this
@@ -9500,12 +9461,79 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
/* We don't need to look the attribute up in the MAIR0/MAIR1
* registers because that only tells us about cacheability.
*/
+ if (mregion) {
+ *mregion = matchregion;
+ }
}
*fsr = 0x00d; /* Permission fault */
return !(*prot & (1 << access_type));
}
+
+static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
+ hwaddr *phys_ptr, MemTxAttrs *txattrs,
+ int *prot, uint32_t *fsr)
+{
+ uint32_t secure = regime_is_secure(env, mmu_idx);
+ V8M_SAttributes sattrs = {};
+
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
+ v8m_security_lookup(env, address, access_type, mmu_idx, &sattrs);
+ if (access_type == MMU_INST_FETCH) {
+ /* Instruction fetches always use the MMU bank and the
+ * transaction attribute determined by the fetch address,
+ * regardless of CPU state. This is painful for QEMU
+ * to handle, because it would mean we need to encode
+ * into the mmu_idx not just the (user, negpri) information
+ * for the current security state but also that for the
+ * other security state, which would balloon the number
+ * of mmu_idx values needed alarmingly.
+ * Fortunately we can avoid this because it's not actually
+ * possible to arbitrarily execute code from memory with
+ * the wrong security attribute: it will always generate
+ * an exception of some kind or another, apart from the
+ * special case of an NS CPU executing an SG instruction
+ * in S&NSC memory. So we always just fail the translation
+ * here and sort things out in the exception handler
+ * (including possibly emulating an SG instruction).
+ */
+ if (sattrs.ns != !secure) {
+ *fsr = sattrs.nsc ? M_FAKE_FSR_NSC_EXEC : M_FAKE_FSR_SFAULT;
+ *phys_ptr = address;
+ *prot = 0;
+ return true;
+ }
+ } else {
+ /* For data accesses we always use the MMU bank indicated
+ * by the current CPU state, but the security attributes
+ * might downgrade a secure access to nonsecure.
+ */
+ if (sattrs.ns) {
+ txattrs->secure = false;
+ } else if (!secure) {
+ /* NS access to S memory must fault.
+ * Architecturally we should first check whether the
+ * MPU information for this address indicates that we
+ * are doing an unaligned access to Device memory, which
+ * should generate a UsageFault instead. QEMU does not
+ * currently check for that kind of unaligned access though.
+ * If we added it we would need to do so as a special case
+ * for M_FAKE_FSR_SFAULT in arm_v7m_cpu_do_interrupt().
+ */
+ *fsr = M_FAKE_FSR_SFAULT;
+ *phys_ptr = address;
+ *prot = 0;
+ return true;
+ }
+ }
+ }
+
+ return pmsav8_mpu_lookup(env, address, access_type, mmu_idx, phys_ptr,
+ txattrs, prot, fsr, NULL);
+}
+
static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
MMUAccessType access_type, ARMMMUIdx mmu_idx,
hwaddr *phys_ptr, int *prot, uint32_t *fsr)
--
2.7.4
next prev parent reply other threads:[~2017-12-01 18:44 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-01 18:44 [Qemu-devel] [PATCH 0/7] armv8m: Implement TT, and other bugfixes Peter Maydell
2017-12-01 18:44 ` [Qemu-devel] [PATCH 1/7] target/arm: Handle SPSEL and current stack being out of sync in MSP/PSP reads Peter Maydell
2017-12-03 14:58 ` Richard Henderson
2017-12-05 18:54 ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
2017-12-01 18:44 ` [Qemu-devel] [PATCH 2/7] target/arm: Allow explicit writes to CONTROL.SPSEL in Handler mode Peter Maydell
2017-12-03 15:03 ` Richard Henderson
2017-12-01 18:44 ` [Qemu-devel] [PATCH 3/7] target/arm: Add missing M profile case to regime_is_user() Peter Maydell
2017-12-03 15:04 ` Richard Henderson
2017-12-05 18:58 ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
2017-12-01 18:44 ` [Qemu-devel] [PATCH 4/7] target/arm: Split M profile MNegPri mmu index into user and priv Peter Maydell
2017-12-03 15:09 ` Richard Henderson
2017-12-05 21:23 ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
2017-12-07 11:07 ` Peter Maydell
2017-12-07 14:15 ` Philippe Mathieu-Daudé
2017-12-01 18:44 ` [Qemu-devel] [PATCH 5/7] target/arm: Create new arm_v7m_mmu_idx_for_secstate_and_priv() Peter Maydell
2017-12-03 15:12 ` Richard Henderson
2017-12-05 21:24 ` Philippe Mathieu-Daudé
2017-12-01 18:44 ` Peter Maydell [this message]
2017-12-03 15:16 ` [Qemu-devel] [PATCH 6/7] target/arm: Factor MPU lookup code out of get_phys_addr_pmsav8() Richard Henderson
2017-12-05 21:27 ` Philippe Mathieu-Daudé
2017-12-01 18:44 ` [Qemu-devel] [PATCH 7/7] target/arm: Implement TT instruction Peter Maydell
2017-12-03 16:04 ` Richard Henderson
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=1512153879-5291-7-git-send-email-peter.maydell@linaro.org \
--to=peter.maydell@linaro.org \
--cc=alex.bennee@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
/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).