arch-arm: Hyp routed undef fault need to change its syndrome
authorGiacomo Travaglini <giacomo.travaglini@arm.com>
Fri, 1 Dec 2017 13:24:29 +0000 (13:24 +0000)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Thu, 21 Dec 2017 13:25:24 +0000 (13:25 +0000)
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>

src/arch/arm/faults.cc
src/arch/arm/faults.hh

index 8d019d58ac13c42f70049257dd1983db130756fb..d143056b17c16a92903e61a1cd3d39f943390a6f 100644 (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;
 }
 
 
index 3191ceb88570243c609a53f4203b9d0796fd15c6..fa6740a1ada84552020486d1fb3c84968780de7a 100644 (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