arch-arm: Prefer haveEL over haveSecurity and haveVirtualization
The Arm architecture reference manual pseudocode checks for the presence of an exception level (EL) over "security" and "virtualization" Change-Id: Ia91a9d1848eddc40776627208386a13afdaafda3 Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/51009 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -314,8 +314,8 @@ ArmFault::getVector(ThreadContext *tc)
|
||||
|
||||
// Check for invalid modes
|
||||
CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);
|
||||
assert(ArmSystem::haveSecurity(tc) || cpsr.mode != MODE_MON);
|
||||
assert(ArmSystem::haveVirtualization(tc) || cpsr.mode != MODE_HYP);
|
||||
assert(ArmSystem::haveEL(tc, EL3) || cpsr.mode != MODE_MON);
|
||||
assert(ArmSystem::haveEL(tc, EL2) || cpsr.mode != MODE_HYP);
|
||||
|
||||
switch (cpsr.mode)
|
||||
{
|
||||
@@ -330,7 +330,7 @@ ArmFault::getVector(ThreadContext *tc)
|
||||
if (sctlr.v) {
|
||||
base = HighVecs;
|
||||
} else {
|
||||
base = ArmSystem::haveSecurity(tc) ?
|
||||
base = ArmSystem::haveEL(tc, EL3) ?
|
||||
tc->readMiscReg(MISCREG_VBAR) : 0;
|
||||
}
|
||||
break;
|
||||
@@ -345,11 +345,11 @@ ArmFault::getVector64(ThreadContext *tc)
|
||||
Addr vbar;
|
||||
switch (toEL) {
|
||||
case EL3:
|
||||
assert(ArmSystem::haveSecurity(tc));
|
||||
assert(ArmSystem::haveEL(tc, EL3));
|
||||
vbar = tc->readMiscReg(MISCREG_VBAR_EL3);
|
||||
break;
|
||||
case EL2:
|
||||
assert(ArmSystem::haveVirtualization(tc));
|
||||
assert(ArmSystem::haveEL(tc, EL2));
|
||||
vbar = tc->readMiscReg(MISCREG_VBAR_EL2);
|
||||
break;
|
||||
case EL1:
|
||||
@@ -448,10 +448,10 @@ ArmFault::update(ThreadContext *tc)
|
||||
|
||||
// Determine target exception level (aarch64) or target execution
|
||||
// mode (aarch32).
|
||||
if (ArmSystem::haveSecurity(tc) && routeToMonitor(tc)) {
|
||||
if (ArmSystem::haveEL(tc, EL3) && routeToMonitor(tc)) {
|
||||
toMode = MODE_MON;
|
||||
toEL = EL3;
|
||||
} else if (ArmSystem::haveVirtualization(tc) && routeToHyp(tc)) {
|
||||
} else if (ArmSystem::haveEL(tc, EL2) && routeToHyp(tc)) {
|
||||
toMode = MODE_HYP;
|
||||
toEL = EL2;
|
||||
hypRouted = true;
|
||||
@@ -510,7 +510,7 @@ ArmFault::invoke32(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
return;
|
||||
|
||||
// ARMv7 (ARM ARM issue C B1.9)
|
||||
bool have_security = ArmSystem::haveSecurity(tc);
|
||||
bool have_security = ArmSystem::haveEL(tc, EL3);
|
||||
|
||||
FaultBase::invoke(tc);
|
||||
if (!FullSystem)
|
||||
@@ -613,7 +613,7 @@ ArmFault::invoke32(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
setSyndrome(tc, MISCREG_HSR);
|
||||
break;
|
||||
case MODE_HYP:
|
||||
assert(ArmSystem::haveVirtualization(tc));
|
||||
assert(ArmSystem::haveEL(tc, EL2));
|
||||
tc->setMiscReg(MISCREG_SPSR_HYP, saved_cpsr);
|
||||
setSyndrome(tc, MISCREG_HSR);
|
||||
break;
|
||||
@@ -648,12 +648,12 @@ ArmFault::invoke64(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
spsr_idx = MISCREG_SPSR_EL1;
|
||||
break;
|
||||
case EL2:
|
||||
assert(ArmSystem::haveVirtualization(tc));
|
||||
assert(ArmSystem::haveEL(tc, EL2));
|
||||
elr_idx = MISCREG_ELR_EL2;
|
||||
spsr_idx = MISCREG_SPSR_EL2;
|
||||
break;
|
||||
case EL3:
|
||||
assert(ArmSystem::haveSecurity(tc));
|
||||
assert(ArmSystem::haveEL(tc, EL3));
|
||||
elr_idx = MISCREG_ELR_EL3;
|
||||
spsr_idx = MISCREG_SPSR_EL3;
|
||||
break;
|
||||
@@ -766,8 +766,8 @@ Reset::getVector(ThreadContext *tc)
|
||||
|
||||
// Check for invalid modes
|
||||
[[maybe_unused]] CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);
|
||||
assert(ArmSystem::haveSecurity(tc) || cpsr.mode != MODE_MON);
|
||||
assert(ArmSystem::haveVirtualization(tc) || cpsr.mode != MODE_HYP);
|
||||
assert(ArmSystem::haveEL(tc, EL3) || cpsr.mode != MODE_MON);
|
||||
assert(ArmSystem::haveEL(tc, EL2) || cpsr.mode != MODE_HYP);
|
||||
|
||||
// RVBAR is aliased (implemented as) MVBAR in gem5, since the two
|
||||
// are mutually exclusive; there is no need to check here for
|
||||
@@ -790,8 +790,8 @@ Reset::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
getMPIDR(dynamic_cast<ArmSystem*>(tc->getSystemPtr()), tc));
|
||||
|
||||
// Unless we have SMC code to get us there, boot in HYP!
|
||||
if (ArmSystem::haveVirtualization(tc) &&
|
||||
!ArmSystem::haveSecurity(tc)) {
|
||||
if (ArmSystem::haveEL(tc, EL2) &&
|
||||
!ArmSystem::haveEL(tc, EL3)) {
|
||||
CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
|
||||
cpsr.mode = MODE_HYP;
|
||||
tc->setMiscReg(MISCREG_CPSR, cpsr);
|
||||
@@ -1215,7 +1215,7 @@ template<class T>
|
||||
bool
|
||||
AbortFault<T>::abortDisable(ThreadContext *tc)
|
||||
{
|
||||
if (ArmSystem::haveSecurity(tc)) {
|
||||
if (ArmSystem::haveEL(tc, EL3)) {
|
||||
SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR);
|
||||
return (!scr.ns || scr.aw);
|
||||
}
|
||||
@@ -1472,7 +1472,7 @@ VirtualDataAbort::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
bool
|
||||
Interrupt::routeToMonitor(ThreadContext *tc) const
|
||||
{
|
||||
assert(ArmSystem::haveSecurity(tc));
|
||||
assert(ArmSystem::haveEL(tc, EL3));
|
||||
SCR scr = 0;
|
||||
if (from64)
|
||||
scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
|
||||
@@ -1492,7 +1492,7 @@ Interrupt::routeToHyp(ThreadContext *tc) const
|
||||
bool
|
||||
Interrupt::abortDisable(ThreadContext *tc)
|
||||
{
|
||||
if (ArmSystem::haveSecurity(tc)) {
|
||||
if (ArmSystem::haveEL(tc, EL3)) {
|
||||
SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR);
|
||||
return (!scr.ns || scr.aw);
|
||||
}
|
||||
@@ -1505,7 +1505,7 @@ VirtualInterrupt::VirtualInterrupt()
|
||||
bool
|
||||
FastInterrupt::routeToMonitor(ThreadContext *tc) const
|
||||
{
|
||||
assert(ArmSystem::haveSecurity(tc));
|
||||
assert(ArmSystem::haveEL(tc, EL3));
|
||||
SCR scr = 0;
|
||||
if (from64)
|
||||
scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
|
||||
@@ -1525,7 +1525,7 @@ FastInterrupt::routeToHyp(ThreadContext *tc) const
|
||||
bool
|
||||
FastInterrupt::abortDisable(ThreadContext *tc)
|
||||
{
|
||||
if (ArmSystem::haveSecurity(tc)) {
|
||||
if (ArmSystem::haveEL(tc, EL3)) {
|
||||
SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR);
|
||||
return (!scr.ns || scr.aw);
|
||||
}
|
||||
@@ -1535,9 +1535,9 @@ FastInterrupt::abortDisable(ThreadContext *tc)
|
||||
bool
|
||||
FastInterrupt::fiqDisable(ThreadContext *tc)
|
||||
{
|
||||
if (ArmSystem::haveVirtualization(tc)) {
|
||||
if (ArmSystem::haveEL(tc, EL2)) {
|
||||
return true;
|
||||
} else if (ArmSystem::haveSecurity(tc)) {
|
||||
} else if (ArmSystem::haveEL(tc, EL3)) {
|
||||
SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR);
|
||||
return (!scr.ns || scr.fw);
|
||||
}
|
||||
@@ -1587,7 +1587,7 @@ SystemError::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
bool
|
||||
SystemError::routeToMonitor(ThreadContext *tc) const
|
||||
{
|
||||
assert(ArmSystem::haveSecurity(tc));
|
||||
assert(ArmSystem::haveEL(tc, EL3));
|
||||
assert(from64);
|
||||
SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
|
||||
return scr.ea || fromEL == EL3;
|
||||
@@ -1659,11 +1659,11 @@ HardwareBreakpoint::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
elr_idx = MISCREG_ELR_EL1;
|
||||
break;
|
||||
case EL2:
|
||||
assert(ArmSystem::haveVirtualization(tc));
|
||||
assert(ArmSystem::haveEL(tc, EL2));
|
||||
elr_idx = MISCREG_ELR_EL2;
|
||||
break;
|
||||
case EL3:
|
||||
assert(ArmSystem::haveSecurity(tc));
|
||||
assert(ArmSystem::haveEL(tc, EL3));
|
||||
elr_idx = MISCREG_ELR_EL3;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -99,13 +99,13 @@ MiscRegOp64::trap(ThreadContext *tc, MiscRegIndex misc_reg,
|
||||
}
|
||||
|
||||
// Check for traps to hypervisor
|
||||
if ((ArmSystem::haveVirtualization(tc) && el <= EL2) &&
|
||||
if ((ArmSystem::haveEL(tc, EL2) && el <= EL2) &&
|
||||
checkEL2Trap(tc, misc_reg, el, ec, immediate)) {
|
||||
return std::make_shared<HypervisorTrap>(machInst, immediate, ec);
|
||||
}
|
||||
|
||||
// Check for traps to secure monitor
|
||||
if ((ArmSystem::haveSecurity(tc) && el <= EL3) &&
|
||||
if ((ArmSystem::haveEL(tc, EL3) && el <= EL3) &&
|
||||
checkEL3Trap(tc, misc_reg, el, ec, immediate)) {
|
||||
return std::make_shared<SecureMonitorTrap>(machInst, immediate, ec);
|
||||
}
|
||||
|
||||
@@ -700,7 +700,7 @@ ArmStaticInst::checkFPAdvSIMDTrap64(ThreadContext *tc, CPSR cpsr) const
|
||||
}
|
||||
}
|
||||
|
||||
if (ArmSystem::haveSecurity(tc)) {
|
||||
if (ArmSystem::haveEL(tc, EL3)) {
|
||||
CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
|
||||
if (cptr_en_check.tfp) {
|
||||
return advSIMDFPAccessTrap64(EL3);
|
||||
@@ -728,8 +728,8 @@ ArmStaticInst::checkAdvSIMDOrFPEnabled32(ThreadContext *tc,
|
||||
NSACR nsacr, FPEXC fpexc,
|
||||
bool fpexc_check, bool advsimd) const
|
||||
{
|
||||
const bool have_virtualization = ArmSystem::haveVirtualization(tc);
|
||||
const bool have_security = ArmSystem::haveSecurity(tc);
|
||||
const bool have_virtualization = ArmSystem::haveEL(tc, EL2);
|
||||
const bool have_security = ArmSystem::haveEL(tc, EL3);
|
||||
const bool is_secure = isSecure(tc);
|
||||
const ExceptionLevel cur_el = currEL(tc);
|
||||
|
||||
@@ -1051,7 +1051,7 @@ ArmStaticInst::checkSveEnabled(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
|
||||
}
|
||||
|
||||
// Check if access disabled in CPTR_EL3
|
||||
if (ArmSystem::haveSecurity(tc)) {
|
||||
if (ArmSystem::haveEL(tc, EL3)) {
|
||||
CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
|
||||
if (!cptr_en_check.ez)
|
||||
return sveAccessTrap(EL3);
|
||||
|
||||
@@ -227,7 +227,7 @@ class ArmStaticInst : public StaticInst
|
||||
uint8_t byteMask, bool affectState, bool nmfi, ThreadContext *tc)
|
||||
{
|
||||
bool privileged = (cpsr.mode != MODE_USER);
|
||||
bool haveVirt = ArmSystem::haveVirtualization(tc);
|
||||
bool haveVirt = ArmSystem::haveEL(tc, EL2);
|
||||
bool isSecure = ArmISA::isSecure(tc);
|
||||
|
||||
uint32_t bitMask = 0;
|
||||
|
||||
@@ -152,7 +152,7 @@ let {{
|
||||
HSTR hstr = Hstr;
|
||||
CPSR cpsr = Cpsr;
|
||||
|
||||
if (ArmSystem::haveVirtualization(xc->tcBase()) && hstr.tjdbx &&
|
||||
if (ArmSystem::haveEL(xc->tcBase(), EL2) && hstr.tjdbx &&
|
||||
!isSecure(xc->tcBase()) && (cpsr.mode != MODE_HYP)) {
|
||||
fault = std::make_shared<HypervisorTrap>(machInst, op1, EC_TRAPPED_BXJ);
|
||||
}
|
||||
|
||||
@@ -489,8 +489,8 @@ let {{
|
||||
faultAddr = EA;
|
||||
HCR hcr = Hcr64;
|
||||
SCR scr = Scr64;
|
||||
if (el == EL1 && ArmSystem::haveVirtualization(xc->tcBase()) &&
|
||||
hcr.vm && (scr.ns || !ArmSystem::haveSecurity(xc->tcBase()))) {
|
||||
if (el == EL1 && ArmSystem::haveEL(xc->tcBase(), EL2) &&
|
||||
hcr.vm && (scr.ns || !ArmSystem::haveEL(xc->tcBase(), EL3))) {
|
||||
memAccessFlags = memAccessFlags | Request::CLEAN;
|
||||
}
|
||||
System *sys = xc->tcBase()->getSystemPtr();
|
||||
|
||||
@@ -124,10 +124,10 @@ let {{
|
||||
SCR scr = Scr;
|
||||
|
||||
// Filter out the various cases where this instruction isn't defined
|
||||
if (!FullSystem || !ArmSystem::haveVirtualization(xc->tcBase()) ||
|
||||
if (!FullSystem || !ArmSystem::haveEL(xc->tcBase(), EL2) ||
|
||||
(cpsr.mode == MODE_USER) ||
|
||||
(isSecure(xc->tcBase()) && !IsSecureEL2Enabled(xc->tcBase())) ||
|
||||
(ArmSystem::haveSecurity(xc->tcBase()) ? !scr.hce : hcr.hcd)) {
|
||||
(ArmSystem::haveEL(xc->tcBase(), EL3) ? !scr.hce : hcr.hcd)) {
|
||||
fault = disabledFault();
|
||||
} else {
|
||||
fault = std::make_shared<HypervisorCall>(machInst, imm);
|
||||
|
||||
@@ -99,7 +99,7 @@ let {{
|
||||
SCR scr = Scr64;
|
||||
CPSR cpsr = Cpsr;
|
||||
|
||||
if (!ArmSystem::haveSecurity(xc->tcBase()) || inUserMode(cpsr) || scr.smd) {
|
||||
if (!ArmSystem::haveEL(xc->tcBase(), EL3) || inUserMode(cpsr) || scr.smd) {
|
||||
fault = disabledFault();
|
||||
} else {
|
||||
fault = std::make_shared<SecureMonitorCall>(machInst);
|
||||
|
||||
@@ -542,7 +542,7 @@ std::pair<bool, bool>
|
||||
MMU::s2PermBits64(TlbEntry *te, const RequestPtr &req, Mode mode,
|
||||
ThreadContext *tc, CachedState &state, bool r, bool w, bool x)
|
||||
{
|
||||
assert(ArmSystem::haveVirtualization(tc) && state.aarch64EL != EL2);
|
||||
assert(ArmSystem::haveEL(tc, EL2) && state.aarch64EL != EL2);
|
||||
|
||||
// In stage 2 we use the hypervisor access permission bits.
|
||||
// The following permissions are described in ARM DDI 0487A.f
|
||||
|
||||
@@ -1321,7 +1321,7 @@ snsBankedIndex(MiscRegIndex reg, ThreadContext *tc, bool ns)
|
||||
{
|
||||
int reg_as_int = static_cast<int>(reg);
|
||||
if (miscRegInfo[reg][MISCREG_BANKED]) {
|
||||
reg_as_int += (ArmSystem::haveSecurity(tc) &&
|
||||
reg_as_int += (ArmSystem::haveEL(tc, EL3) &&
|
||||
!ArmSystem::highestELIs64(tc) && !ns) ? 2 : 1;
|
||||
}
|
||||
return reg_as_int;
|
||||
@@ -1387,7 +1387,7 @@ canReadAArch64SysReg(MiscRegIndex reg, HCR hcr, SCR scr, CPSR cpsr,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool secure = ArmSystem::haveSecurity(tc) && !scr.ns;
|
||||
bool secure = ArmSystem::haveEL(tc, EL3) && !scr.ns;
|
||||
bool el2_host = EL2Enabled(tc) && hcr.e2h;
|
||||
|
||||
switch (currEL(cpsr)) {
|
||||
@@ -1423,7 +1423,7 @@ canWriteAArch64SysReg(MiscRegIndex reg, HCR hcr, SCR scr, CPSR cpsr,
|
||||
return false;
|
||||
ExceptionLevel el = currEL(cpsr);
|
||||
|
||||
bool secure = ArmSystem::haveSecurity(tc) && !scr.ns;
|
||||
bool secure = ArmSystem::haveEL(tc, EL3) && !scr.ns;
|
||||
bool el2_host = EL2Enabled(tc) && hcr.e2h;
|
||||
|
||||
switch (el) {
|
||||
|
||||
@@ -328,8 +328,8 @@ std::pair<bool, bool>
|
||||
ELStateUsingAArch32K(ThreadContext *tc, ExceptionLevel el, bool secure)
|
||||
{
|
||||
// Return true if the specified EL is in aarch32 state.
|
||||
const bool have_el3 = ArmSystem::haveSecurity(tc);
|
||||
const bool have_el2 = ArmSystem::haveVirtualization(tc);
|
||||
const bool have_el3 = ArmSystem::haveEL(tc, EL3);
|
||||
const bool have_el2 = ArmSystem::haveEL(tc, EL2);
|
||||
|
||||
panic_if(el == EL2 && !have_el2, "Asking for EL2 when it doesn't exist");
|
||||
panic_if(el == EL3 && !have_el3, "Asking for EL3 when it doesn't exist");
|
||||
@@ -1250,8 +1250,8 @@ isUnpriviledgeAccess(ThreadContext *tc)
|
||||
// NV Extension not implemented yet
|
||||
bool have_nv_ext = false;
|
||||
bool unpriv_el1 = currEL(tc) == EL1 &&
|
||||
!(ArmSystem::haveVirtualization(tc) &&
|
||||
have_nv_ext && hcr.nv == 1 && hcr.nv1 == 1);
|
||||
!(ArmSystem::haveEL(tc, EL2) &&
|
||||
have_nv_ext && hcr.nv == 1 && hcr.nv1 == 1);
|
||||
bool unpriv_el2 = ArmSystem::haveEL(tc, EL2) && HaveVirtHostExt(tc) &&
|
||||
currEL(tc) == EL2 && hcr.e2h == 1 && hcr.tge == 1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user