From e268bc35a42cb67896f93e641832104902e11896 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Fri, 18 Sep 2020 11:12:09 +0100 Subject: [PATCH] arch-arm: Add el2Enabled cached variable Several TLB invalidation instructions rely on VMID matching. This is only applicable is EL2 is implemented and enabled in the current state. The code prior to this patch was making the now invalid assumption that we shouldn't consider the VMID if we are doing a secure lookup. This is because in the past if we were in secure mode we were sure EL2 was not enabled. This is fishy and not valid anymore anyway after the introduction of secure EL2. Change-Id: I9a1368f8ed19279ed3c4b2da9fcdf0db799bc514 Signed-off-by: Giacomo Travaglini Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35242 Reviewed-by: Nikos Nikoleris Tested-by: kokoro --- src/arch/arm/isa.cc | 2 -- src/arch/arm/tlb.cc | 4 ++-- src/arch/arm/tlbi_op.cc | 8 ++++++++ src/arch/arm/tlbi_op.hh | 7 +++++-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index 3607c2988..1866319ed 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -1803,7 +1803,6 @@ ISA::setMiscReg(int misc_reg, RegVal val) // VAEx(IS) and VALEx(IS) are the same because TLBs // only store entries // from the last level of translation table walks - // @todo: handle VMID to enable Virtualization // AArch64 TLB Invalidate by VA, EL3 case MISCREG_TLBI_VAE3_Xt: case MISCREG_TLBI_VALE3_Xt: @@ -1895,7 +1894,6 @@ ISA::setMiscReg(int misc_reg, RegVal val) return; } // AArch64 TLB Invalidate by ASID, EL1 - // @todo: handle VMID to enable Virtualization case MISCREG_TLBI_ASIDE1_Xt: { assert64(); diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc index 0e6118697..38aa38ed0 100644 --- a/src/arch/arm/tlb.cc +++ b/src/arch/arm/tlb.cc @@ -281,7 +281,7 @@ TLB::flush(const TLBIALL& tlbi_op) 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.secureLookup) && el_match) { + (te->vmid == vmid || tlbi_op.el2Enabled) && el_match) { DPRINTF(TLB, " - %s\n", te->print()); te->valid = false; @@ -383,7 +383,7 @@ TLB::flush(const TLBIASID &tlbi_op) te = &table[x]; if (te->valid && te->asid == tlbi_op.asid && tlbi_op.secureLookup == !te->nstid && - (te->vmid == vmid || tlbi_op.secureLookup) && + (te->vmid == vmid || tlbi_op.el2Enabled) && te->checkELMatch(tlbi_op.targetEL, tlbi_op.inHost)) { te->valid = false; diff --git a/src/arch/arm/tlbi_op.cc b/src/arch/arm/tlbi_op.cc index be7a78b2f..bb5153dd8 100644 --- a/src/arch/arm/tlbi_op.cc +++ b/src/arch/arm/tlbi_op.cc @@ -47,6 +47,8 @@ TLBIALL::operator()(ThreadContext* tc) { HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); inHost = (hcr.tge == 1 && hcr.e2h == 1); + el2Enabled = EL2Enabled(tc); + getMMUPtr(tc)->flush(*this); // If CheckerCPU is connected, need to notify it of a flush @@ -59,12 +61,14 @@ TLBIALL::operator()(ThreadContext* tc) void ITLBIALL::operator()(ThreadContext* tc) { + el2Enabled = EL2Enabled(tc); getMMUPtr(tc)->iflush(*this); } void DTLBIALL::operator()(ThreadContext* tc) { + el2Enabled = EL2Enabled(tc); getMMUPtr(tc)->dflush(*this); } @@ -87,6 +91,8 @@ TLBIASID::operator()(ThreadContext* tc) { HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); inHost = (hcr.tge == 1 && hcr.e2h == 1); + el2Enabled = EL2Enabled(tc); + getMMUPtr(tc)->flush(*this); CheckerCPU *checker = tc->getCheckerCpuPtr(); if (checker) { @@ -97,12 +103,14 @@ TLBIASID::operator()(ThreadContext* tc) void ITLBIASID::operator()(ThreadContext* tc) { + el2Enabled = EL2Enabled(tc); getMMUPtr(tc)->iflush(*this); } void DTLBIASID::operator()(ThreadContext* tc) { + el2Enabled = EL2Enabled(tc); getMMUPtr(tc)->dflush(*this); } diff --git a/src/arch/arm/tlbi_op.hh b/src/arch/arm/tlbi_op.hh index 8b405871d..888cd99d1 100644 --- a/src/arch/arm/tlbi_op.hh +++ b/src/arch/arm/tlbi_op.hh @@ -81,7 +81,7 @@ class TLBIALL : public TLBIOp { public: TLBIALL(ExceptionLevel _targetEL, bool _secure) - : TLBIOp(_targetEL, _secure), inHost(false) + : TLBIOp(_targetEL, _secure), inHost(false), el2Enabled(false) {} void operator()(ThreadContext* tc) override; @@ -93,6 +93,7 @@ class TLBIALL : public TLBIOp } bool inHost; + bool el2Enabled; }; /** Instruction TLB Invalidate All */ @@ -145,13 +146,15 @@ class TLBIASID : public TLBIOp { public: TLBIASID(ExceptionLevel _targetEL, bool _secure, uint16_t _asid) - : TLBIOp(_targetEL, _secure), asid(_asid), inHost(false) + : TLBIOp(_targetEL, _secure), asid(_asid), inHost(false), + el2Enabled(false) {} void operator()(ThreadContext* tc) override; uint16_t asid; bool inHost; + bool el2Enabled; }; /** Instruction TLB Invalidate by ASID match */ -- 2.30.2