summaryrefslogtreecommitdiff
path: root/src/arch/arm/tlb.cc
diff options
context:
space:
mode:
authorGiacomo Travaglini <giacomo.travaglini@arm.com>2019-07-29 12:38:12 +0100
committerGiacomo Travaglini <giacomo.travaglini@arm.com>2019-08-05 15:50:57 +0000
commit361bc8b47260a55902764054d3ac25694ac93f8a (patch)
treee6929b787500aa227333b4fe90fc4047838ef8c0 /src/arch/arm/tlb.cc
parentfd1a8bed393a2ef48d584fcabeee4d98eda0e3fa (diff)
downloadgem5-361bc8b47260a55902764054d3ac25694ac93f8a.tar.xz
arch-arm: Implement ARMv8.1-PAN, Privileged access never
ARMv8.1-PAN adds a new bit to PSTATE. When the value of this PAN state bit is 1, any privileged data access from EL1 or EL2 to a virtual memory address that is accessible at EL0 generates a Permission fault. This feature is mandatory in ARMv8.1 implementations. This feature is supported in AArch64 and AArch32 states. The ID_AA64MMFR1_EL1.PAN, ID_MMFR3_EL1.PAN, and ID_MMFR3.PAN fields identify the support for ARMv8.1-PAN. Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Change-Id: I94a76311711739dd2394c72944d88ba9321fd159 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/19729 Maintainer: Andreas Sandberg <andreas.sandberg@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'src/arch/arm/tlb.cc')
-rw-r--r--src/arch/arm/tlb.cc30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index 872f351c6..848bd5b26 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -904,6 +904,11 @@ TLB::checkPermissions64(TlbEntry *te, const RequestPtr &req, Mode mode,
break;
case EL1:
{
+ if (checkPAN(tc, ap, req, mode)) {
+ grant = false;
+ break;
+ }
+
uint8_t perm = (ap << 2) | (xn << 1) | pxn;
switch (perm) {
case 0:
@@ -938,6 +943,11 @@ TLB::checkPermissions64(TlbEntry *te, const RequestPtr &req, Mode mode,
}
break;
case EL2:
+ if (checkPAN(tc, ap, req, mode)) {
+ grant = false;
+ break;
+ }
+ M5_FALLTHROUGH;
case EL3:
{
uint8_t perm = (ap & 0x2) | xn;
@@ -989,6 +999,26 @@ TLB::checkPermissions64(TlbEntry *te, const RequestPtr &req, Mode mode,
return NoFault;
}
+bool
+TLB::checkPAN(ThreadContext *tc, uint8_t ap, const RequestPtr &req, Mode mode)
+{
+ // The PAN bit has no effect on:
+ // 1) Instruction accesses.
+ // 2) Data Cache instructions other than DC ZVA
+ // 3) Address translation instructions, other than ATS1E1RP and
+ // ATS1E1WP when ARMv8.2-ATS1E1 is implemented. (Unimplemented in
+ // gem5)
+ // 4) Unprivileged instructions (Unimplemented in gem5)
+ AA64MMFR1 mmfr1 = tc->readMiscReg(MISCREG_ID_AA64MMFR1_EL1);
+ if (mmfr1.pan && cpsr.pan && (ap & 0x1) && mode != Execute &&
+ (!req->isCacheMaintenance() ||
+ (req->getFlags() & Request::CACHE_BLOCK_ZERO))) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
Fault
TLB::translateFs(const RequestPtr &req, ThreadContext *tc, Mode mode,
Translation *translation, bool &delay, bool timing,