arm: Check TLB stage 2 permissions in AArch64

This fixes a bug where stage 2 lookups used the AArch32
permissions rules even if we were executing in AArch64 mode.

Change-Id: Ia40758f0599667ca7ca15268bd3bf051342c24c1
This commit is contained in:
Dylan Johnson 2016-08-02 10:38:03 +01:00
parent bce923c189
commit c15711725d

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010-2013 ARM Limited * Copyright (c) 2010-2013, 2016 ARM Limited
* All rights reserved * All rights reserved
* *
* The license below extends only to copyright in the software and shall * The license below extends only to copyright in the software and shall
@ -60,6 +60,17 @@ Stage2LookUp::getTe(ThreadContext *tc, TlbEntry *destTe)
functional, false, tranType); functional, false, tranType);
// Call finish if we're done already // Call finish if we're done already
if ((fault != NoFault) || (stage2Te != NULL)) { if ((fault != NoFault) || (stage2Te != NULL)) {
// Since we directly requested the table entry (which we need later on
// to merge the attributes) then we've skipped some stage2 permissions
// checking. So call translate on stage 2 to do the checking. As the
// entry is now in the TLB this should always hit the cache.
if (fault == NoFault) {
if (inAArch64(tc))
fault = stage2Tlb->checkPermissions64(stage2Te, &req, mode, tc);
else
fault = stage2Tlb->checkPermissions(stage2Te, &req, mode);
}
mergeTe(&req, mode); mergeTe(&req, mode);
*destTe = stage1Te; *destTe = stage1Te;
} }
@ -69,14 +80,6 @@ Stage2LookUp::getTe(ThreadContext *tc, TlbEntry *destTe)
void void
Stage2LookUp::mergeTe(RequestPtr req, BaseTLB::Mode mode) Stage2LookUp::mergeTe(RequestPtr req, BaseTLB::Mode mode)
{ {
// Since we directly requested the table entry (which we need later on to
// merge the attributes) then we've skipped some stage 2 permissinos
// checking. So call translate on stage 2 to do the checking. As the entry
// is now in the TLB this should always hit the cache.
if (fault == NoFault) {
fault = stage2Tlb->checkPermissions(stage2Te, req, mode);
}
// Check again that we haven't got a fault // Check again that we haven't got a fault
if (fault == NoFault) { if (fault == NoFault) {
assert(stage2Te != NULL); assert(stage2Te != NULL);