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 <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35242
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Giacomo Travaglini
2020-09-18 11:12:09 +01:00
parent 2fc4a0803d
commit e268bc35a4
4 changed files with 15 additions and 6 deletions

View File

@@ -1803,7 +1803,6 @@ ISA::setMiscReg(int misc_reg, RegVal val)
// VAEx(IS) and VALEx(IS) are the same because TLBs // VAEx(IS) and VALEx(IS) are the same because TLBs
// only store entries // only store entries
// from the last level of translation table walks // from the last level of translation table walks
// @todo: handle VMID to enable Virtualization
// AArch64 TLB Invalidate by VA, EL3 // AArch64 TLB Invalidate by VA, EL3
case MISCREG_TLBI_VAE3_Xt: case MISCREG_TLBI_VAE3_Xt:
case MISCREG_TLBI_VALE3_Xt: case MISCREG_TLBI_VALE3_Xt:
@@ -1895,7 +1894,6 @@ ISA::setMiscReg(int misc_reg, RegVal val)
return; return;
} }
// AArch64 TLB Invalidate by ASID, EL1 // AArch64 TLB Invalidate by ASID, EL1
// @todo: handle VMID to enable Virtualization
case MISCREG_TLBI_ASIDE1_Xt: case MISCREG_TLBI_ASIDE1_Xt:
{ {
assert64(); assert64();

View File

@@ -281,7 +281,7 @@ TLB::flush(const TLBIALL& tlbi_op)
const bool el_match = te->checkELMatch( const bool el_match = te->checkELMatch(
tlbi_op.targetEL, tlbi_op.inHost); tlbi_op.targetEL, tlbi_op.inHost);
if (te->valid && tlbi_op.secureLookup == !te->nstid && 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()); DPRINTF(TLB, " - %s\n", te->print());
te->valid = false; te->valid = false;
@@ -383,7 +383,7 @@ TLB::flush(const TLBIASID &tlbi_op)
te = &table[x]; te = &table[x];
if (te->valid && te->asid == tlbi_op.asid && if (te->valid && te->asid == tlbi_op.asid &&
tlbi_op.secureLookup == !te->nstid && 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->checkELMatch(tlbi_op.targetEL, tlbi_op.inHost)) {
te->valid = false; te->valid = false;

View File

@@ -47,6 +47,8 @@ TLBIALL::operator()(ThreadContext* tc)
{ {
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
inHost = (hcr.tge == 1 && hcr.e2h == 1); inHost = (hcr.tge == 1 && hcr.e2h == 1);
el2Enabled = EL2Enabled(tc);
getMMUPtr(tc)->flush(*this); getMMUPtr(tc)->flush(*this);
// If CheckerCPU is connected, need to notify it of a flush // If CheckerCPU is connected, need to notify it of a flush
@@ -59,12 +61,14 @@ TLBIALL::operator()(ThreadContext* tc)
void void
ITLBIALL::operator()(ThreadContext* tc) ITLBIALL::operator()(ThreadContext* tc)
{ {
el2Enabled = EL2Enabled(tc);
getMMUPtr(tc)->iflush(*this); getMMUPtr(tc)->iflush(*this);
} }
void void
DTLBIALL::operator()(ThreadContext* tc) DTLBIALL::operator()(ThreadContext* tc)
{ {
el2Enabled = EL2Enabled(tc);
getMMUPtr(tc)->dflush(*this); getMMUPtr(tc)->dflush(*this);
} }
@@ -87,6 +91,8 @@ TLBIASID::operator()(ThreadContext* tc)
{ {
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
inHost = (hcr.tge == 1 && hcr.e2h == 1); inHost = (hcr.tge == 1 && hcr.e2h == 1);
el2Enabled = EL2Enabled(tc);
getMMUPtr(tc)->flush(*this); getMMUPtr(tc)->flush(*this);
CheckerCPU *checker = tc->getCheckerCpuPtr(); CheckerCPU *checker = tc->getCheckerCpuPtr();
if (checker) { if (checker) {
@@ -97,12 +103,14 @@ TLBIASID::operator()(ThreadContext* tc)
void void
ITLBIASID::operator()(ThreadContext* tc) ITLBIASID::operator()(ThreadContext* tc)
{ {
el2Enabled = EL2Enabled(tc);
getMMUPtr(tc)->iflush(*this); getMMUPtr(tc)->iflush(*this);
} }
void void
DTLBIASID::operator()(ThreadContext* tc) DTLBIASID::operator()(ThreadContext* tc)
{ {
el2Enabled = EL2Enabled(tc);
getMMUPtr(tc)->dflush(*this); getMMUPtr(tc)->dflush(*this);
} }

View File

@@ -81,7 +81,7 @@ class TLBIALL : public TLBIOp
{ {
public: public:
TLBIALL(ExceptionLevel _targetEL, bool _secure) TLBIALL(ExceptionLevel _targetEL, bool _secure)
: TLBIOp(_targetEL, _secure), inHost(false) : TLBIOp(_targetEL, _secure), inHost(false), el2Enabled(false)
{} {}
void operator()(ThreadContext* tc) override; void operator()(ThreadContext* tc) override;
@@ -93,6 +93,7 @@ class TLBIALL : public TLBIOp
} }
bool inHost; bool inHost;
bool el2Enabled;
}; };
/** Instruction TLB Invalidate All */ /** Instruction TLB Invalidate All */
@@ -145,13 +146,15 @@ class TLBIASID : public TLBIOp
{ {
public: public:
TLBIASID(ExceptionLevel _targetEL, bool _secure, uint16_t _asid) 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; void operator()(ThreadContext* tc) override;
uint16_t asid; uint16_t asid;
bool inHost; bool inHost;
bool el2Enabled;
}; };
/** Instruction TLB Invalidate by ASID match */ /** Instruction TLB Invalidate by ASID match */