summaryrefslogtreecommitdiff
path: root/src/arch/arm
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
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')
-rw-r--r--src/arch/arm/ArmISA.py4
-rw-r--r--src/arch/arm/ArmSystem.py4
-rw-r--r--src/arch/arm/faults.cc21
-rw-r--r--src/arch/arm/faults.hh5
-rw-r--r--src/arch/arm/insts/misc64.cc2
-rw-r--r--src/arch/arm/insts/static_inst.cc3
-rw-r--r--src/arch/arm/isa.cc33
-rw-r--r--src/arch/arm/isa.hh5
-rw-r--r--src/arch/arm/isa/formats/aarch64.isa4
-rw-r--r--src/arch/arm/isa/insts/data64.isa22
-rw-r--r--src/arch/arm/miscregs.cc7
-rw-r--r--src/arch/arm/miscregs.hh8
-rw-r--r--src/arch/arm/miscregs_types.hh6
-rw-r--r--src/arch/arm/system.cc3
-rw-r--r--src/arch/arm/system.hh8
-rw-r--r--src/arch/arm/tlb.cc30
-rw-r--r--src/arch/arm/tlb.hh2
17 files changed, 140 insertions, 27 deletions
diff --git a/src/arch/arm/ArmISA.py b/src/arch/arm/ArmISA.py
index 3d30e5f6e..3c1f7dd11 100644
--- a/src/arch/arm/ArmISA.py
+++ b/src/arch/arm/ArmISA.py
@@ -105,8 +105,8 @@ class ArmISA(SimObject):
# 4K | 64K | !16K | !BigEndEL0 | !SNSMem | !BigEnd | 8b ASID | 40b PA
id_aa64mmfr0_el1 = Param.UInt64(0x0000000000f00002,
"AArch64 Memory Model Feature Register 0")
- # HPDS
- id_aa64mmfr1_el1 = Param.UInt64(0x0000000000001000,
+ # PAN | HPDS
+ id_aa64mmfr1_el1 = Param.UInt64(0x0000000000101000,
"AArch64 Memory Model Feature Register 1")
id_aa64mmfr2_el1 = Param.UInt64(0x0000000000000000,
"AArch64 Memory Model Feature Register 2")
diff --git a/src/arch/arm/ArmSystem.py b/src/arch/arm/ArmSystem.py
index ec30e0bf6..daf94a97e 100644
--- a/src/arch/arm/ArmSystem.py
+++ b/src/arch/arm/ArmSystem.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2012-2013, 2015-2018 ARM Limited
+# Copyright (c) 2009, 2012-2013, 2015-2019 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
@@ -86,6 +86,8 @@ class ArmSystem(System):
"True if SVE is implemented (ARMv8)")
sve_vl = Param.SveVectorLength(1,
"SVE vector length in quadwords (128-bit)")
+ have_pan = Param.Bool(True,
+ "True if Priviledge Access Never is implemented (ARMv8.1)")
semihosting = Param.ArmSemihosting(NULL,
"Enable support for the Arm semihosting by settings this parameter")
diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc
index a03c91703..0f279fab4 100644
--- a/src/arch/arm/faults.cc
+++ b/src/arch/arm/faults.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012-2014, 2016-2018 ARM Limited
+ * Copyright (c) 2010, 2012-2014, 2016-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -448,6 +448,21 @@ ArmFault::update(ThreadContext *tc)
if (fromEL > toEL)
toEL = fromEL;
+ // Check for Set Priviledge Access Never, if PAN is supported
+ AA64MMFR1 mmfr1 = tc->readMiscReg(MISCREG_ID_AA64MMFR1_EL1);
+ if (mmfr1.pan) {
+ if (toEL == EL1) {
+ const SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR_EL1);
+ span = !sctlr.span;
+ }
+
+ const HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
+ if (toEL == EL2 && hcr.e2h && hcr.tge) {
+ const SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR_EL2);
+ span = !sctlr.span;
+ }
+ }
+
to64 = ELIs64(tc, toEL);
// The fault specific informations have been updated; it is
@@ -536,6 +551,7 @@ ArmFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
}
cpsr.it1 = cpsr.it2 = 0;
cpsr.j = 0;
+ cpsr.pan = span ? 1 : saved_cpsr.pan;
tc->setMiscReg(MISCREG_CPSR, cpsr);
// Make sure mailbox sets to one always
@@ -635,7 +651,6 @@ ArmFault::invoke64(ThreadContext *tc, const StaticInstPtr &inst)
spsr.q = 0;
spsr.it1 = 0;
spsr.j = 0;
- spsr.res0_23_22 = 0;
spsr.ge = 0;
spsr.it2 = 0;
spsr.t = 0;
@@ -645,7 +660,6 @@ ArmFault::invoke64(ThreadContext *tc, const StaticInstPtr &inst)
spsr.it2 = it.top6;
spsr.it1 = it.bottom2;
// Force some bitfields to 0
- spsr.res0_23_22 = 0;
spsr.ss = 0;
}
tc->setMiscReg(spsr_idx, spsr);
@@ -670,6 +684,7 @@ ArmFault::invoke64(ThreadContext *tc, const StaticInstPtr &inst)
cpsr.daif = 0xf;
cpsr.il = 0;
cpsr.ss = 0;
+ cpsr.pan = span ? 1 : spsr.pan;
tc->setMiscReg(MISCREG_CPSR, cpsr);
// If we have a valid instruction then use it to annotate this fault with
diff --git a/src/arch/arm/faults.hh b/src/arch/arm/faults.hh
index d14983d28..5e68875f5 100644
--- a/src/arch/arm/faults.hh
+++ b/src/arch/arm/faults.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012-2013, 2016-2018 ARM Limited
+ * Copyright (c) 2010, 2012-2013, 2016-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -82,6 +82,7 @@ class ArmFault : public FaultBase
bool faultUpdated;
bool hypRouted; // True if the fault has been routed to Hypervisor
+ bool span; // True if the fault is setting the PSTATE.PAN bit
virtual Addr getVector(ThreadContext *tc);
Addr getVector64(ThreadContext *tc);
@@ -200,7 +201,7 @@ class ArmFault : public FaultBase
ArmFault(ExtMachInst _machInst = 0, uint32_t _iss = 0) :
machInst(_machInst), issRaw(_iss), from64(false), to64(false),
fromEL(EL0), toEL(EL0), fromMode(MODE_UNDEFINED),
- faultUpdated(false), hypRouted(false) {}
+ faultUpdated(false), hypRouted(false), span(false) {}
// Returns the actual syndrome register to use based on the target
// exception level
diff --git a/src/arch/arm/insts/misc64.cc b/src/arch/arm/insts/misc64.cc
index cf625ebef..2d0422f62 100644
--- a/src/arch/arm/insts/misc64.cc
+++ b/src/arch/arm/insts/misc64.cc
@@ -327,6 +327,8 @@ MiscRegImmOp64::miscRegImm() const
{
if (dest == MISCREG_SPSEL) {
return imm & 0x1;
+ } else if (dest == MISCREG_PAN) {
+ return (imm & 0x1) << 22;
} else {
panic("Not a valid PSTATE field register\n");
}
diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc
index cc0e8f3f2..ec705909c 100644
--- a/src/arch/arm/insts/static_inst.cc
+++ b/src/arch/arm/insts/static_inst.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2014, 2016-2018 ARM Limited
+ * Copyright (c) 2010-2014, 2016-2019 ARM Limited
* Copyright (c) 2013 Advanced Micro Devices, Inc.
* All rights reserved
*
@@ -1129,6 +1129,7 @@ ArmStaticInst::getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const
new_cpsr.nz = spsr.nz;
new_cpsr.c = spsr.c;
new_cpsr.v = spsr.v;
+ new_cpsr.pan = spsr.pan;
if (new_cpsr.width) {
// aarch32
const ITSTATE it = getRestoredITBits(tc, spsr);
diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index cdc44cdb9..23738c6ae 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2018 ARM Limited
+ * Copyright (c) 2010-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -91,6 +91,7 @@ ISA::ISA(Params *p)
haveLargeAsid64 = system->haveLargeAsid64();
physAddrRange = system->physAddrRange();
haveSVE = system->haveSVE();
+ havePAN = system->havePAN();
sveVL = system->sveVL();
} else {
highestELIs64 = true; // ArmSystem::highestELIs64 does the same
@@ -99,6 +100,7 @@ ISA::ISA(Params *p)
haveLargeAsid64 = false;
physAddrRange = 32; // dummy value
haveSVE = true;
+ havePAN = false;
sveVL = p->sve_vl_se;
}
@@ -391,6 +393,10 @@ ISA::initID64(const ArmISAParams *p)
miscRegs[MISCREG_ID_AA64ISAR0_EL1] = insertBits(
miscRegs[MISCREG_ID_AA64ISAR0_EL1], 19, 4,
haveCrypto ? 0x1112 : 0x0);
+ // PAN
+ miscRegs[MISCREG_ID_AA64MMFR1_EL1] = insertBits(
+ miscRegs[MISCREG_ID_AA64MMFR1_EL1], 23, 20,
+ havePAN ? 0x1 : 0x0);
}
void
@@ -640,6 +646,10 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
{
return miscRegs[MISCREG_CPSR] & 0xc;
}
+ case MISCREG_PAN:
+ {
+ return miscRegs[MISCREG_CPSR] & 0x400000;
+ }
case MISCREG_L2CTLR:
{
// mostly unimplemented, just set NumCPUs field from sim and return
@@ -1880,6 +1890,17 @@ ISA::setMiscReg(int misc_reg, RegVal val, ThreadContext *tc)
misc_reg = MISCREG_CPSR;
}
break;
+ case MISCREG_PAN:
+ {
+ // PAN is affecting data accesses
+ getDTBPtr(tc)->invalidateMiscReg();
+
+ CPSR cpsr = miscRegs[MISCREG_CPSR];
+ cpsr.pan = (uint8_t) ((CPSR) newVal).pan;
+ newVal = cpsr;
+ misc_reg = MISCREG_CPSR;
+ }
+ break;
case MISCREG_AT_S1E1R_Xt:
case MISCREG_AT_S1E1W_Xt:
case MISCREG_AT_S1E0R_Xt:
@@ -2020,9 +2041,13 @@ ISA::setMiscReg(int misc_reg, RegVal val, ThreadContext *tc)
case MISCREG_SPSR_EL3:
case MISCREG_SPSR_EL2:
case MISCREG_SPSR_EL1:
- // Force bits 23:21 to 0
- newVal = val & ~(0x7 << 21);
- break;
+ {
+ RegVal spsr_mask = havePAN ?
+ ~(0x5 << 21) : ~(0x7 << 21);
+
+ newVal = val & spsr_mask;
+ break;
+ }
case MISCREG_L2CTLR:
warn("miscreg L2CTLR (%s) written with %#x. ignored...\n",
miscRegName[misc_reg], uint32_t(val));
diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh
index b4689d74e..63051cd83 100644
--- a/src/arch/arm/isa.hh
+++ b/src/arch/arm/isa.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012-2018 ARM Limited
+ * Copyright (c) 2010, 2012-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -95,6 +95,7 @@ namespace ArmISA
bool haveGICv3CPUInterface;
uint8_t physAddrRange;
bool haveSVE;
+ bool havePAN;
/** SVE vector length in quadwords */
unsigned sveVL;
@@ -686,6 +687,7 @@ namespace ArmISA
SERIALIZE_SCALAR(physAddrRange);
SERIALIZE_SCALAR(haveSVE);
SERIALIZE_SCALAR(sveVL);
+ SERIALIZE_SCALAR(havePAN);
}
void unserialize(CheckpointIn &cp)
{
@@ -702,6 +704,7 @@ namespace ArmISA
UNSERIALIZE_SCALAR(physAddrRange);
UNSERIALIZE_SCALAR(haveSVE);
UNSERIALIZE_SCALAR(sveVL);
+ UNSERIALIZE_SCALAR(havePAN);
}
void startup(ThreadContext *tc);
diff --git a/src/arch/arm/isa/formats/aarch64.isa b/src/arch/arm/isa/formats/aarch64.isa
index 144ff88ca..82770ebc6 100644
--- a/src/arch/arm/isa/formats/aarch64.isa
+++ b/src/arch/arm/isa/formats/aarch64.isa
@@ -392,6 +392,10 @@ namespace Aarch64
// MSR immediate: moving immediate value to selected
// bits of the PSTATE
switch (op1 << 3 | op2) {
+ case 0x4:
+ // PAN
+ return new MsrImm64(
+ machInst, MISCREG_PAN, crm);
case 0x5:
// SP
return new MsrImm64(
diff --git a/src/arch/arm/isa/insts/data64.isa b/src/arch/arm/isa/insts/data64.isa
index b3e03d67d..bb0334372 100644
--- a/src/arch/arm/isa/insts/data64.isa
+++ b/src/arch/arm/isa/insts/data64.isa
@@ -512,13 +512,21 @@ let {{
def buildMsrImmInst(mnem, inst_name, code):
global header_output, decoder_output, exec_output
msrImmPermission = '''
- if (!canWriteAArch64SysReg(
- (MiscRegIndex) xc->tcBase()->flattenRegId(
- RegId(MiscRegClass, dest)).index(),
- Scr64, Cpsr, xc->tcBase())) {
- return std::make_shared<UndefinedInstruction>(
- machInst, 0, EC_TRAPPED_MSR_MRS_64,
- mnemonic);
+ auto misc_index = (MiscRegIndex) xc->tcBase()->flattenRegId(
+ RegId(MiscRegClass, dest)).index();
+
+ if (!miscRegInfo[misc_index][MISCREG_IMPLEMENTED]) {
+ return std::make_shared<UndefinedInstruction>(
+ machInst, false,
+ mnemonic);
+ }
+
+ if (!canWriteAArch64SysReg(misc_index,
+ Scr64, Cpsr, xc->tcBase())) {
+
+ return std::make_shared<UndefinedInstruction>(
+ machInst, 0, EC_TRAPPED_MSR_MRS_64,
+ mnemonic);
}
'''
diff --git a/src/arch/arm/miscregs.cc b/src/arch/arm/miscregs.cc
index 5fd7d2c53..7283b205f 100644
--- a/src/arch/arm/miscregs.cc
+++ b/src/arch/arm/miscregs.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2013, 2015-2018 ARM Limited
+ * Copyright (c) 2010-2013, 2015-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -1984,6 +1984,8 @@ decodeAArch64SysReg(unsigned op0, unsigned op1,
return MISCREG_SPSEL;
case 2:
return MISCREG_CURRENTEL;
+ case 3:
+ return MISCREG_PAN;
}
break;
case 6:
@@ -4057,6 +4059,9 @@ ISA::initializeMiscRegMetadata()
.allPrivileges().exceptUserMode();
InitReg(MISCREG_CURRENTEL)
.allPrivileges().exceptUserMode().writes(0);
+ InitReg(MISCREG_PAN)
+ .allPrivileges().exceptUserMode()
+ .implemented(havePAN);
InitReg(MISCREG_NZCV)
.allPrivileges();
InitReg(MISCREG_DAIF)
diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh
index feef79e73..a95168bf3 100644
--- a/src/arch/arm/miscregs.hh
+++ b/src/arch/arm/miscregs.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2018 ARM Limited
+ * Copyright (c) 2010-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -930,6 +930,9 @@ namespace ArmISA
MISCREG_VSESR_EL2,
MISCREG_VDISR_EL2,
+ // PSTATE
+ MISCREG_PAN,
+
// Total number of Misc Registers: Physical + Dummy
NUM_MISCREGS
};
@@ -1854,6 +1857,9 @@ namespace ArmISA
"disr_el1",
"vsesr_el2",
"vdisr_el2",
+
+ // PSTATE
+ "pan",
};
static_assert(sizeof(miscRegName) / sizeof(*miscRegName) == NUM_MISCREGS,
diff --git a/src/arch/arm/miscregs_types.hh b/src/arch/arm/miscregs_types.hh
index c0eafdaac..0d6775ec9 100644
--- a/src/arch/arm/miscregs_types.hh
+++ b/src/arch/arm/miscregs_types.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2018 ARM Limited
+ * Copyright (c) 2010-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -55,7 +55,7 @@ namespace ArmISA
Bitfield<27> q;
Bitfield<26, 25> it1;
Bitfield<24> j;
- Bitfield<23, 22> res0_23_22;
+ Bitfield<22> pan;
Bitfield<21> ss; // AArch64
Bitfield<20> il; // AArch64
Bitfield<19, 16> ge;
@@ -322,6 +322,8 @@ namespace ArmISA
Bitfield<25> ee; // Exception Endianness
Bitfield<24> e0e; // Endianness of explicit data accesses at EL0
// (AArch64 SCTLR_EL1 only)
+ Bitfield<23> span; // Set Priviledge Access Never on taking
+ // an exception
Bitfield<23> xp; // Extended page table enable (dropped in ARMv7)
Bitfield<22> u; // Alignment (dropped in ARMv7)
Bitfield<21> fi; // Fast interrupts configuration enable
diff --git a/src/arch/arm/system.cc b/src/arch/arm/system.cc
index aa487767f..874e3b021 100644
--- a/src/arch/arm/system.cc
+++ b/src/arch/arm/system.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012-2013, 2015,2017-2018 ARM Limited
+ * Copyright (c) 2010, 2012-2013, 2015,2017-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -73,6 +73,7 @@ ArmSystem::ArmSystem(Params *p)
_haveLargeAsid64(p->have_large_asid_64),
_haveSVE(p->have_sve),
_sveVL(p->sve_vl),
+ _havePAN(p->have_pan),
_m5opRange(p->m5ops_base ?
RangeSize(p->m5ops_base, 0x10000) :
AddrRange(1, 0)), // Create an empty range if disabled
diff --git a/src/arch/arm/system.hh b/src/arch/arm/system.hh
index 263dd289e..e09f47706 100644
--- a/src/arch/arm/system.hh
+++ b/src/arch/arm/system.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012-2013, 2015-2018 ARM Limited
+ * Copyright (c) 2010, 2012-2013, 2015-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -130,6 +130,9 @@ class ArmSystem : public System
/** SVE vector length at reset, in quadwords */
const unsigned _sveVL;
+ /** True if Priviledge Access Never is implemented */
+ const unsigned _havePAN;
+
/**
* Range for memory-mapped m5 pseudo ops. The range will be
* invalid/empty if disabled.
@@ -241,6 +244,9 @@ class ArmSystem : public System
/** Returns the SVE vector length at reset, in quadwords */
unsigned sveVL() const { return _sveVL; }
+ /** Returns true if Priviledge Access Never is implemented */
+ bool havePAN() const { return _havePAN; }
+
/** Returns the supported physical address range in bits if the highest
* implemented exception level is 64 bits (ARMv8) */
uint8_t physAddrRange64() const { return _physAddrRange64; }
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,
diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh
index a84e945f4..ea78a21b5 100644
--- a/src/arch/arm/tlb.hh
+++ b/src/arch/arm/tlb.hh
@@ -244,6 +244,8 @@ class TLB : public BaseTLB
Fault checkPermissions(TlbEntry *te, const RequestPtr &req, Mode mode);
Fault checkPermissions64(TlbEntry *te, const RequestPtr &req, Mode mode,
ThreadContext *tc);
+ bool checkPAN(ThreadContext *tc, uint8_t ap, const RequestPtr &req,
+ Mode mode);
/** Reset the entire TLB