From c15711725db358a2222de5964b8ba4c3216b0572 Mon Sep 17 00:00:00 2001 From: Dylan Johnson Date: Tue, 2 Aug 2016 10:38:03 +0100 Subject: [PATCH] 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 --- src/arch/arm/stage2_lookup.cc | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/arch/arm/stage2_lookup.cc b/src/arch/arm/stage2_lookup.cc index 59cacd527..04d50afbf 100755 --- a/src/arch/arm/stage2_lookup.cc +++ b/src/arch/arm/stage2_lookup.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 ARM Limited + * Copyright (c) 2010-2013, 2016 ARM Limited * All rights reserved * * 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); // Call finish if we're done already 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); *destTe = stage1Te; } @@ -69,14 +80,6 @@ Stage2LookUp::getTe(ThreadContext *tc, TlbEntry *destTe) void 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 if (fault == NoFault) { assert(stage2Te != NULL);