arch, arm: Effect of AT instructions on descriptor handling
authorAnouk Van Laer <anouk.vanlaer@arm.com>
Fri, 19 Oct 2018 10:19:08 +0000 (11:19 +0100)
committerAnouk Van Laer <anouk.vanlaer@arm.com>
Mon, 5 Nov 2018 09:56:17 +0000 (09:56 +0000)
Some address translation instructions will stop translation after
the 1st stage and intercept the IPA, even in the presence of
stage 2 (eg AT S1E1).  However, in the case of a TLB miss, the
table descriptors still need to be translated from IPA to PA to
avoid fetching the wrong addresses.  This commit splits whether
IPA->PA translation is required for the VA and/or for the table
descriptors.

Change-Id: Ie53cdc00585f116150256f1d833460931b3bfb7d
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/13781
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>

src/arch/arm/tlb.cc
src/arch/arm/tlb.hh

index 79eef1b8d33c9dfda12fbcdcbb21d9e1afddd3a1..ac18ef1f49d68024fcda734b95c822525012ea8a 100644 (file)
@@ -75,7 +75,7 @@ using namespace ArmISA;
 
 TLB::TLB(const ArmTLBParams *p)
     : BaseTLB(p), table(new TlbEntry[p->size]), size(p->size),
-      isStage2(p->is_stage2), stage2Req(false), _attr(0),
+      isStage2(p->is_stage2), stage2Req(false), stage2DescReq(false), _attr(0),
       directToStage2(false), tableWalker(p->walker), stage2Tlb(NULL),
       stage2Mmu(NULL), test(nullptr), rangeMRU(1),
       aarch64(false), aarch64EL(EL0), isPriv(false), isSecure(false),
@@ -393,6 +393,7 @@ TLB::takeOverFrom(BaseTLB *_otlb)
         haveLPAE = otlb->haveLPAE;
         directToStage2 = otlb->directToStage2;
         stage2Req = otlb->stage2Req;
+        stage2DescReq = otlb->stage2DescReq;
 
         /* Sync the stage2 MMU if they exist in both
          * the old CPU and the new
@@ -415,6 +416,7 @@ TLB::serialize(CheckpointOut &cp) const
     SERIALIZE_SCALAR(haveLPAE);
     SERIALIZE_SCALAR(directToStage2);
     SERIALIZE_SCALAR(stage2Req);
+    SERIALIZE_SCALAR(stage2DescReq);
 
     int num_entries = size;
     SERIALIZE_SCALAR(num_entries);
@@ -431,6 +433,7 @@ TLB::unserialize(CheckpointIn &cp)
     UNSERIALIZE_SCALAR(haveLPAE);
     UNSERIALIZE_SCALAR(directToStage2);
     UNSERIALIZE_SCALAR(stage2Req);
+    UNSERIALIZE_SCALAR(stage2DescReq);
 
     int num_entries;
     UNSERIALIZE_SCALAR(num_entries);
@@ -1310,12 +1313,15 @@ TLB::updateMiscReg(ThreadContext *tc, ArmTranslationType tranType)
                         (hcr.vm && !isHyp && !isSecure &&
                          !(tranType & S1CTran) && (aarch64EL < EL2) &&
                          !(tranType & S1E1Tran)); // <--- FIX THIS HACK
+            stage2DescReq = isStage2 ||  (hcr.vm && !isHyp && !isSecure &&
+                            (aarch64EL < EL2));
             directToStage2 = !isStage2 && stage2Req && !sctlr.m;
         } else {
             vmid           = 0;
             isHyp          = false;
             directToStage2 = false;
             stage2Req      = false;
+            stage2DescReq  = false;
         }
     } else {  // AArch32
         sctlr  = tc->readMiscReg(snsBankedIndex(MISCREG_SCTLR, tc,
@@ -1357,12 +1363,14 @@ TLB::updateMiscReg(ThreadContext *tc, ArmTranslationType tranType)
             // compute it for every translation.
             stage2Req      = hcr.vm && !isStage2 && !isHyp && !isSecure &&
                              !(tranType & S1CTran);
+            stage2DescReq  = hcr.vm && !isStage2 && !isHyp && !isSecure;
             directToStage2 = stage2Req && !sctlr.m;
         } else {
             vmid           = 0;
             stage2Req      = false;
             isHyp          = false;
             directToStage2 = false;
+            stage2DescReq  = false;
         }
     }
     miscRegValid = true;
@@ -1440,7 +1448,7 @@ TLB::getTE(TlbEntry **te, const RequestPtr &req, ThreadContext *tc, Mode mode,
         Fault fault;
         fault = tableWalker->walk(req, tc, asid, vmid, isHyp, mode,
                                   translation, timing, functional, is_secure,
-                                  tranType, stage2Req);
+                                  tranType, stage2DescReq);
         // for timing mode, return and wait for table walk,
         if (timing || fault != NoFault) {
             return fault;
index 336b31b78c69a1d990a35ea86b174da1a85d7580..637240abb90c7c962c3485fb3e1644cd402ebe13 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2013, 2016 ARM Limited
+ * Copyright (c) 2010-2013, 2016, 2018 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -152,6 +152,10 @@ class TLB : public BaseTLB
     int size;            // TLB Size
     bool isStage2;       // Indicates this TLB is part of the second stage MMU
     bool stage2Req;      // Indicates whether a stage 2 lookup is also required
+    // Indicates whether a stage 2 lookup of the table descriptors is required.
+    // Certain address translation instructions will intercept the IPA but the
+    // table descriptors still need to be translated by the stage2.
+    bool stage2DescReq;
     uint64_t _attr;      // Memory attributes for last accessed TLB entry
     bool directToStage2; // Indicates whether all translation requests should
                          // be routed directly to the stage 2 TLB