dev-arm: Return translation fault in doReadCD

Reading the Context Descriptor (CD) might require a stage2
translation. At the moment doReadCD does not check for the
return value of the translateStage2.
This means that any stage2 fault will be silently discarded
and an invalid address will be used/returned.

By returning a translation result we make sure any error
happening in the second stage of translation will be properly
flagged

Change-Id: I2ecd43f7e23080bf8222bc3addfabbd027ee8feb
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
This commit is contained in:
Giacomo Travaglini
2024-03-06 11:57:51 +00:00
parent 4a4b775985
commit 3d1f68f205
2 changed files with 23 additions and 11 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2018-2019, 2021 Arm Limited
* Copyright (c) 2013, 2018-2019, 2021, 2024 Arm Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -632,7 +632,7 @@ SMMUTranslationProcess::findConfig(Yield &yield,
// Now fetch stage 1 config.
if (context.stage1Enable) {
ContextDescriptor cd;
doReadCD(yield, cd, ste, request.sid, request.ssid);
tr = doReadCD(yield, cd, ste, request.sid, request.ssid);
tc.ttb0 = cd.dw1.ttb0 << CD_TTB_SHIFT;
tc.ttb1 = cd.dw2.ttb1 << CD_TTB_SHIFT;
@@ -647,7 +647,7 @@ SMMUTranslationProcess::findConfig(Yield &yield,
tc.t0sz = 0;
}
return true;
return !tr.isFaulting();
}
void
@@ -1402,12 +1402,13 @@ SMMUTranslationProcess::doReadSTE(Yield &yield,
smmu.stats.steFetches++;
}
void
SMMUTranslationProcess::TranslResult
SMMUTranslationProcess::doReadCD(Yield &yield,
ContextDescriptor &cd,
const StreamTableEntry &ste,
uint32_t sid, uint32_t ssid)
{
TranslResult tr;
Addr cd_addr = 0;
if (ste.dw0.s1cdmax == 0) {
@@ -1426,8 +1427,13 @@ SMMUTranslationProcess::doReadCD(Yield &yield,
uint64_t l2_addr = (ste.dw0.s1ctxptr << ST_CD_ADDR_SHIFT) +
bits(ssid, 24, split) * sizeof(l2_ptr);
if (context.stage2Enable)
l2_addr = translateStage2(yield, l2_addr, false).addr;
if (context.stage2Enable) {
tr = translateStage2(yield, l2_addr, false);
if (tr.isFaulting())
return tr;
l2_addr = tr.addr;
}
DPRINTF(SMMUv3, "Read L1CD at %#x\n", l2_addr);
@@ -1443,8 +1449,13 @@ SMMUTranslationProcess::doReadCD(Yield &yield,
}
}
if (context.stage2Enable)
cd_addr = translateStage2(yield, cd_addr, false).addr;
if (context.stage2Enable) {
tr = translateStage2(yield, cd_addr, false);
if (tr.isFaulting())
return tr;
cd_addr = tr.addr;
}
DPRINTF(SMMUv3, "Read CD at %#x\n", cd_addr);
@@ -1464,6 +1475,7 @@ SMMUTranslationProcess::doReadCD(Yield &yield,
panic("CD @ %#x not valid\n", cd_addr);
smmu.stats.cdFetches++;
return tr;
}
void

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2018-2019 ARM Limited
* Copyright (c) 2013, 2018-2019, 2024 Arm Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -174,8 +174,8 @@ class SMMUTranslationProcess : public SMMUProcess
void sendEvent(Yield &yield, const SMMUEvent &ev);
void doReadSTE(Yield &yield, StreamTableEntry &ste, uint32_t sid);
void doReadCD(Yield &yield, ContextDescriptor &cd,
const StreamTableEntry &ste, uint32_t sid, uint32_t ssid);
TranslResult doReadCD(Yield &yield, ContextDescriptor &cd,
const StreamTableEntry &ste, uint32_t sid, uint32_t ssid);
void doReadConfig(Yield &yield, Addr addr, void *ptr, size_t size,
uint32_t sid, uint32_t ssid);
void doReadPTE(Yield &yield, Addr va, Addr addr, void *ptr,