diff options
author | Giacomo Travaglini <giacomo.travaglini@arm.com> | 2019-07-29 12:38:12 +0100 |
---|---|---|
committer | Giacomo Travaglini <giacomo.travaglini@arm.com> | 2019-08-05 15:50:57 +0000 |
commit | 361bc8b47260a55902764054d3ac25694ac93f8a (patch) | |
tree | e6929b787500aa227333b4fe90fc4047838ef8c0 /src/arch/arm/faults.cc | |
parent | fd1a8bed393a2ef48d584fcabeee4d98eda0e3fa (diff) | |
download | gem5-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/faults.cc')
-rw-r--r-- | src/arch/arm/faults.cc | 21 |
1 files changed, 18 insertions, 3 deletions
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 |