From 35337cc391245f251bfb9134f181c33e6375d6c1 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 6 Oct 2017 16:46:49 +0100 Subject: target/arm: Implement security attribute lookups for memory accesses Implement the security attribute lookups for memory accesses in the get_phys_addr() functions, causing these to generate various kinds of SecureFault for bad accesses. The major subtlety in this code relates to handling of the case when the security attributes the SAU assigns to the address don't match the current security state of the CPU. In the ARM ARM pseudocode for validating instruction accesses, the security attributes of the address determine whether the Secure or NonSecure MPU state is used. At face value, handling this would require us to encode the relevant bits of state into mmu_idx for both S and NS at once, which would result in our needing 16 mmu indexes. Fortunately we don't actually need to do this because a mismatch between address attributes and CPU state means either: * some kind of fault (usually a SecureFault, but in theory perhaps a UserFault for unaligned access to Device memory) * execution of the SG instruction in NS state from a Secure & NonSecure code region The purpose of SG is simply to flip the CPU into Secure state, so we can handle it by emulating execution of that instruction directly in arm_v7m_cpu_do_interrupt(), which means we can treat all the mismatch cases as "throw an exception" and we don't need to encode the state of the other MPU bank into our mmu_idx values. This commit doesn't include the actual emulation of SG; it also doesn't include implementation of the IDAU, which is a per-board way to specify hard-coded memory attributes for addresses, which override the CPU-internal SAU if they specify a more secure setting than the SAU is programmed to. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 1506092407-26985-15-git-send-email-peter.maydell@linaro.org --- target/arm/internals.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'target/arm/internals.h') diff --git a/target/arm/internals.h b/target/arm/internals.h index 18be3702f2..fd9a7e8181 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -71,6 +71,21 @@ FIELD(V7M_EXCRET, DCRS, 5, 1) FIELD(V7M_EXCRET, S, 6, 1) FIELD(V7M_EXCRET, RES1, 7, 25) /* including the must-be-1 prefix */ +/* We use a few fake FSR values for internal purposes in M profile. + * M profile cores don't have A/R format FSRs, but currently our + * get_phys_addr() code assumes A/R profile and reports failures via + * an A/R format FSR value. We then translate that into the proper + * M profile exception and FSR status bit in arm_v7m_cpu_do_interrupt(). + * Mostly the FSR values we use for this are those defined for v7PMSA, + * since we share some of that codepath. A few kinds of fault are + * only for M profile and have no A/R equivalent, though, so we have + * to pick a value from the reserved range (which we never otherwise + * generate) to use for these. + * These values will never be visible to the guest. + */ +#define M_FAKE_FSR_NSC_EXEC 0xf /* NS executing in S&NSC memory */ +#define M_FAKE_FSR_SFAULT 0xe /* SecureFault INVTRAN, INVEP or AUVIOL */ + /* * For AArch64, map a given EL to an index in the banked_spsr array. * Note that this mapping and the AArch32 mapping defined in bank_number() -- cgit v1.2.3