summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Nikoleris <nikos.nikoleris@arm.com>2018-01-04 15:14:26 +0000
committerNikos Nikoleris <nikos.nikoleris@arm.com>2018-02-07 16:14:39 +0000
commitf54e874d645a1ae66a4b5c963f9d6f42cf2ef2cb (patch)
tree867f34196f91c846ef78735d12732e700cf49e7b
parentc364f58da916a6a1cb66c3e0276e898d77e1021b (diff)
downloadgem5-f54e874d645a1ae66a4b5c963f9d6f42cf2ef2cb.tar.xz
arch-arm: Check cache maintenance insts for permission faults
In AArch32, data cache maintenance instructions that operate by VA do not generate permission faults. In AArch64, a data cache invalidate instruction can generate a permission fault when there are no write permissions to the specified VA. Data cache clean and data cache clean and invalidate instructions do not generate permission faults. Checks for external aborts are also bypassed for data cache maintenance instructions. Change-Id: Iea5bc665e4cf66d528e36b671535b66637c4b224 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/7827 Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
-rw-r--r--src/arch/arm/tlb.cc21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index 3aebe3d59..aeaf60bdd 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -603,6 +603,12 @@ TLB::translateSe(RequestPtr req, ThreadContext *tc, Mode mode,
Fault
TLB::checkPermissions(TlbEntry *te, RequestPtr req, Mode mode)
{
+ // a data cache maintenance instruction that operates by MVA does
+ // not generate a Data Abort exeception due to a Permission fault
+ if (req->isCacheMaintenance()) {
+ return NoFault;
+ }
+
Addr vaddr = req->getVaddr(); // 32-bit don't have to purify
Request::Flags flags = req->getFlags();
bool is_fetch = (mode == Execute);
@@ -778,12 +784,22 @@ TLB::checkPermissions64(TlbEntry *te, RequestPtr req, Mode mode,
{
assert(aarch64);
+ // A data cache maintenance instruction that operates by VA does
+ // not generate a Permission fault unless:
+ // * It is a data cache invalidate (dc ivac) which requires write
+ // permissions to the VA, or
+ // * It is executed from EL0
+ if (req->isCacheClean() && aarch64EL != EL0 && !isStage2) {
+ return NoFault;
+ }
+
Addr vaddr_tainted = req->getVaddr();
Addr vaddr = purifyTaggedAddr(vaddr_tainted, tc, aarch64EL, ttbcr);
Request::Flags flags = req->getFlags();
bool is_fetch = (mode == Execute);
- bool is_write = (mode == Write);
+ // Cache clean operations require read permissions to the specified VA
+ bool is_write = !req->isCacheClean() && mode == Write;
bool is_priv M5_VAR_USED = isPriv && !(flags & UserMode);
updateMiscReg(tc, curTranType);
@@ -1528,7 +1544,8 @@ TLB::setTestInterface(SimObject *_ti)
Fault
TLB::testTranslation(RequestPtr req, Mode mode, TlbEntry::DomainType domain)
{
- if (!test || !req->hasSize() || req->getSize() == 0) {
+ if (!test || !req->hasSize() || req->getSize() == 0 ||
+ req->isCacheMaintenance()) {
return NoFault;
} else {
return test->translationCheck(req, isPriv, mode, domain);