Giacomo Travaglini has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/35243 )

Change subject: arch-arm: Fix implementation of TLBI_VMALL instructions
......................................................................

arch-arm: Fix implementation of TLBI_VMALL instructions

Same as 73dfc5f89b81e622a2330b1b52e055cafcc9178b: there's a difference
on how AArch64 and AArch32 treat stage2 invalidation.

Change-Id: I6fede4d9cb82e4bae9163326d38db9351d2a3880
Signed-off-by: Giacomo Travaglini <[email protected]>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35243
Reviewed-by: Nikos Nikoleris <[email protected]>
Tested-by: kokoro <[email protected]>
---
M src/arch/arm/isa.cc
M src/arch/arm/tlb.cc
M src/arch/arm/tlb.hh
M src/arch/arm/tlbi_op.cc
M src/arch/arm/tlbi_op.hh
5 files changed, 77 insertions(+), 8 deletions(-)

Approvals:
  Nikos Nikoleris: Looks good to me, approved
  Giacomo Travaglini: Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index 1866319..217f432 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -1755,17 +1755,15 @@
                 return;
             }
           case MISCREG_TLBI_VMALLS12E1:
-            // @todo: handle VMID and stage 2 to enable Virtualization
             {
                 assert64();
                 scr = readMiscReg(MISCREG_SCR);

-                TLBIALL tlbiOp(EL1, haveSecurity && !scr.ns);
+                TLBIVMALL tlbiOp(EL1, haveSecurity && !scr.ns, true);
                 tlbiOp(tc);
                 return;
             }
           case MISCREG_TLBI_VMALLE1:
-            // @todo: handle VMID and stage 2 to enable Virtualization
             {
                 assert64();
                 scr = readMiscReg(MISCREG_SCR);
@@ -1773,22 +1771,20 @@
                 HCR hcr = readMiscReg(MISCREG_HCR_EL2);
                 bool is_host = (hcr.tge && hcr.e2h);
                 ExceptionLevel target_el = is_host ?  EL2 : EL1;
-                TLBIALL tlbiOp(target_el, haveSecurity && !scr.ns);
+ TLBIVMALL tlbiOp(target_el, haveSecurity && !scr.ns, false);
                 tlbiOp(tc);
                 return;
             }
           case MISCREG_TLBI_VMALLS12E1IS:
-            // @todo: handle VMID and stage 2 to enable Virtualization
             {
                 assert64();
                 scr = readMiscReg(MISCREG_SCR);

-                TLBIALL tlbiOp(EL1, haveSecurity && !scr.ns);
+                TLBIVMALL tlbiOp(EL1, haveSecurity && !scr.ns, true);
                 tlbiOp.broadcast(tc);
                 return;
             }
           case MISCREG_TLBI_VMALLE1IS:
-            // @todo: handle VMID and stage 2 to enable Virtualization
             {
                 assert64();
                 scr = readMiscReg(MISCREG_SCR);
@@ -1796,7 +1792,7 @@
                 HCR hcr = readMiscReg(MISCREG_HCR_EL2);
                 bool is_host = (hcr.tge && hcr.e2h);
                 ExceptionLevel target_el = is_host ?  EL2 : EL1;
-                TLBIALL tlbiOp(target_el, haveSecurity && !scr.ns);
+ TLBIVMALL tlbiOp(target_el, haveSecurity && !scr.ns, false);
                 tlbiOp.broadcast(tc);
                 return;
             }
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index 38aa38e..bad16d8 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -330,6 +330,36 @@
 }

 void
+TLB::flush(const TLBIVMALL &tlbi_op)
+{
+    DPRINTF(TLB, "Flushing all TLB entries (%s lookup)\n",
+            (tlbi_op.secureLookup ? "secure" : "non-secure"));
+    int x = 0;
+    TlbEntry *te;
+    while (x < size) {
+        te = &table[x];
+        const bool el_match = te->checkELMatch(
+            tlbi_op.targetEL, tlbi_op.inHost);
+        if (te->valid && tlbi_op.secureLookup == !te->nstid &&
+            (te->vmid == vmid || !tlbi_op.el2Enabled) && el_match) {
+
+            DPRINTF(TLB, " -  %s\n", te->print());
+            te->valid = false;
+            stats.flushedEntries++;
+        }
+        ++x;
+    }
+
+    stats.flushTlb++;
+
+ // If there's a second stage TLB (and we're not it) then flush it as well
+    // if we're currently in hyp mode
+    if (!isStage2 && tlbi_op.stage2) {
+        stage2Tlb->flush(tlbi_op.makeStage2());
+    }
+}
+
+void
 TLB::flush(const TLBIALLN &tlbi_op)
 {
     bool hyp = tlbi_op.targetEL == EL2;
diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh
index b05c9ba..c157a26 100644
--- a/src/arch/arm/tlb.hh
+++ b/src/arch/arm/tlb.hh
@@ -63,6 +63,7 @@

 class TLBIALL;
 class TLBIALLEL;
+class TLBIVMALL;
 class TLBIALLN;
 class TLBIMVA;
 class TLBIASID;
@@ -269,6 +270,11 @@
      */
     void flush(const TLBIALLEL &tlbi_op);

+    /** Implementaton of AArch64 TLBI VMALLE1(IS)/VMALLS112E1(IS)
+     * instructions
+     */
+    void flush(const TLBIVMALL &tlbi_op);
+
/** Remove all entries in the non secure world, depending on whether they
      *  were allocated in hyp mode or not
      */
diff --git a/src/arch/arm/tlbi_op.cc b/src/arch/arm/tlbi_op.cc
index bb5153d..bd784ce 100644
--- a/src/arch/arm/tlbi_op.cc
+++ b/src/arch/arm/tlbi_op.cc
@@ -87,6 +87,21 @@
 }

 void
+TLBIVMALL::operator()(ThreadContext* tc)
+{
+    HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
+    inHost = (hcr.tge == 1 && hcr.e2h == 1);
+
+    getMMUPtr(tc)->flush(*this);
+
+    // If CheckerCPU is connected, need to notify it of a flush
+    CheckerCPU *checker = tc->getCheckerCpuPtr();
+    if (checker) {
+        getMMUPtr(checker)->flush(*this);
+    }
+}
+
+void
 TLBIASID::operator()(ThreadContext* tc)
 {
     HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
diff --git a/src/arch/arm/tlbi_op.hh b/src/arch/arm/tlbi_op.hh
index 888cd99..cab0e52 100644
--- a/src/arch/arm/tlbi_op.hh
+++ b/src/arch/arm/tlbi_op.hh
@@ -141,6 +141,28 @@
     bool inHost;
 };

+/** Implementaton of AArch64 TLBI VMALLE1(IS)/VMALLS112E1(IS) instructions */
+class TLBIVMALL : public TLBIOp
+{
+  public:
+    TLBIVMALL(ExceptionLevel _targetEL, bool _secure, bool _stage2)
+      : TLBIOp(_targetEL, _secure), inHost(false), el2Enabled(false),
+        stage2(_stage2)
+    {}
+
+    void operator()(ThreadContext* tc) override;
+
+    TLBIVMALL
+    makeStage2() const
+    {
+        return TLBIVMALL(EL1, secureLookup, false);
+    }
+
+    bool inHost;
+    bool el2Enabled;
+    bool stage2;
+};
+
 /** TLB Invalidate by ASID match */
 class TLBIASID : public TLBIOp
 {

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/35243
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I6fede4d9cb82e4bae9163326d38db9351d2a3880
Gerrit-Change-Number: 35243
Gerrit-PatchSet: 9
Gerrit-Owner: Giacomo Travaglini <[email protected]>
Gerrit-Reviewer: Giacomo Travaglini <[email protected]>
Gerrit-Reviewer: Nikos Nikoleris <[email protected]>
Gerrit-Reviewer: kokoro <[email protected]>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to