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 <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35243
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 10:33:24 +01:00
parent e268bc35a4
commit e9ee6b1c69
5 changed files with 77 additions and 8 deletions

View File

@@ -1755,17 +1755,15 @@ ISA::setMiscReg(int misc_reg, RegVal val)
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 @@ ISA::setMiscReg(int misc_reg, RegVal val)
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 @@ ISA::setMiscReg(int misc_reg, RegVal val)
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;
}

View File

@@ -329,6 +329,36 @@ TLB::flush(const TLBIALLEL &tlbi_op)
}
}
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)
{

View File

@@ -63,6 +63,7 @@ class TLB;
class TLBIALL;
class TLBIALLEL;
class TLBIVMALL;
class TLBIALLN;
class TLBIMVA;
class TLBIASID;
@@ -269,6 +270,11 @@ class TLB : public BaseTLB
*/
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
*/

View File

@@ -86,6 +86,21 @@ TLBIALLEL::operator()(ThreadContext* tc)
}
}
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)
{

View File

@@ -141,6 +141,28 @@ class TLBIALLEL : public TLBIOp
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
{