arch-arm: Hyp routed undef fault need to change its syndrome

If undefined instruction has to be routed to EL2, the HSR register
must change the HSR.EC and HSR.ISS accordingly, which means not using
the EL1 exception syndrome, but the unknown reason one (EC=0, ISS=0)

Change-Id: I1540c713ab545bf307c1dad3ae305de4178443f4
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/6621
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
Giacomo Travaglini
2017-12-01 13:24:29 +00:00
parent f9d6cf7eff
commit 0049df179f
2 changed files with 27 additions and 8 deletions

View File

@@ -391,6 +391,7 @@ ArmFault::setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg)
uint32_t value;
uint32_t exc_class = (uint32_t) ec(tc);
uint32_t issVal = iss();
assert(!from64 || ArmSystem::highestELIs64(tc));
value = exc_class << 26;
@@ -438,12 +439,15 @@ ArmFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
from64 = true;
// Determine target exception level
if (ArmSystem::haveSecurity(tc) && routeToMonitor(tc))
if (ArmSystem::haveSecurity(tc) && routeToMonitor(tc)) {
toEL = EL3;
else if (ArmSystem::haveVirtualization(tc) && routeToHyp(tc))
} else if (ArmSystem::haveVirtualization(tc) && routeToHyp(tc)) {
toEL = EL2;
else
hypRouted = true;
} else {
toEL = opModeToEL(nextMode());
}
if (fromEL > toEL)
toEL = fromEL;
@@ -486,12 +490,14 @@ ArmFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
armInst->annotateFault(this);
}
if (have_security && routeToMonitor(tc))
if (have_security && routeToMonitor(tc)) {
cpsr.mode = MODE_MON;
else if (have_virtualization && routeToHyp(tc))
} else if (have_virtualization && routeToHyp(tc)) {
cpsr.mode = MODE_HYP;
else
hypRouted = true;
} else {
cpsr.mode = nextMode();
}
// Ensure Secure state if initially in Monitor mode
if (have_security && saved_cpsr.mode == MODE_MON) {
@@ -747,6 +753,12 @@ UndefinedInstruction::routeToHyp(ThreadContext *tc) const
uint32_t
UndefinedInstruction::iss() const
{
// If UndefinedInstruction is routed to hypervisor, iss field is 0.
if (hypRouted) {
return 0;
}
if (overrideEc == EC_INVALID)
return issRaw;
@@ -836,7 +848,12 @@ SecureMonitorCall::iss() const
ExceptionClass
UndefinedInstruction::ec(ThreadContext *tc) const
{
return (overrideEc != EC_INVALID) ? overrideEc : vals.ec;
// If UndefinedInstruction is routed to hypervisor,
// HSR.EC field is 0.
if (hypRouted)
return EC_UNKNOWN;
else
return (overrideEc != EC_INVALID) ? overrideEc : vals.ec;
}

View File

@@ -73,6 +73,8 @@ class ArmFault : public FaultBase
ExceptionLevel toEL; // Target exception level
OperatingMode fromMode; // Source operating mode
bool hypRouted; // True if the fault has been routed to Hypervisor
Addr getVector(ThreadContext *tc);
Addr getVector64(ThreadContext *tc);
@@ -173,7 +175,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) {}
fromEL(EL0), toEL(EL0), fromMode(MODE_UNDEFINED), hypRouted(false) {}
// Returns the actual syndrome register to use based on the target
// exception level