From 0049df179f3b5f57218b91e98390c1aacaa27c2e Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Fri, 1 Dec 2017 13:24:29 +0000 Subject: 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 Reviewed-by: Nikos Nikoleris Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/6621 Maintainer: Andreas Sandberg --- src/arch/arm/faults.cc | 31 ++++++++++++++++++++++++------- src/arch/arm/faults.hh | 4 +++- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index 8d019d58a..d143056b1 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -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; } diff --git a/src/arch/arm/faults.hh b/src/arch/arm/faults.hh index 3191ceb88..fa6740a1a 100644 --- a/src/arch/arm/faults.hh +++ b/src/arch/arm/faults.hh @@ -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 -- cgit v1.2.3