aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2022-01-07 17:07:59 +0000
committerPeter Maydell <peter.maydell@linaro.org>2022-01-07 17:07:59 +0000
commitb87fab1c8e8977e8ea1233bafdbfa37090eefabf (patch)
treed0391de612f7864b90d126160e9f139d01fd40fc
parent764d6ba10cce25d20ef9f3e11a83a9783dadf65f (diff)
downloadqemu-b87fab1c8e8977e8ea1233bafdbfa37090eefabf.zip
qemu-b87fab1c8e8977e8ea1233bafdbfa37090eefabf.tar.gz
qemu-b87fab1c8e8977e8ea1233bafdbfa37090eefabf.tar.bz2
hw/intc/arm_gicv3_its: Correct handling of MAPI
The MAPI command takes arguments DeviceID, EventID, ICID, and is defined to be equivalent to MAPTI DeviceID, EventID, EventID, ICID. (That is, where MAPTI takes an explicit pINTID, MAPI uses the EventID as the pINTID.) We didn't quite get this right. In particular the error checks for MAPI include "EventID does not specify a valid LPI identifier", which is the same as MAPTI's error check for the pINTID field. QEMU's code skips the pINTID error check entirely in the MAPI case. We can fix this bug and in the process simplify the code by switching to the obvious implementation of setting pIntid = eventid early if ignore_pInt is true. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r--hw/intc/arm_gicv3_its.c18
1 files changed, 7 insertions, 11 deletions
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
index 15eb72a..6f21c56 100644
--- a/hw/intc/arm_gicv3_its.c
+++ b/hw/intc/arm_gicv3_its.c
@@ -354,7 +354,9 @@ static bool process_mapti(GICv3ITSState *s, uint64_t value, uint32_t offset,
eventid = (value & EVENTID_MASK);
- if (!ignore_pInt) {
+ if (ignore_pInt) {
+ pIntid = eventid;
+ } else {
pIntid = ((value & pINTID_MASK) >> pINTID_SHIFT);
}
@@ -377,14 +379,12 @@ static bool process_mapti(GICv3ITSState *s, uint64_t value, uint32_t offset,
max_eventid = (1UL << (((dte >> 1U) & SIZE_MASK) + 1));
- if (!ignore_pInt) {
- max_Intid = (1ULL << (GICD_TYPER_IDBITS + 1)) - 1;
- }
+ max_Intid = (1ULL << (GICD_TYPER_IDBITS + 1)) - 1;
if ((devid > s->dt.max_ids) || (icid > s->ct.max_ids)
|| !dte_valid || (eventid > max_eventid) ||
- (!ignore_pInt && (((pIntid < GICV3_LPI_INTID_START) ||
- (pIntid > max_Intid)) && (pIntid != INTID_SPURIOUS)))) {
+ (((pIntid < GICV3_LPI_INTID_START) || (pIntid > max_Intid)) &&
+ (pIntid != INTID_SPURIOUS))) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: invalid command attributes "
"devid %d or icid %d or eventid %d or pIntid %d or"
@@ -400,11 +400,7 @@ static bool process_mapti(GICv3ITSState *s, uint64_t value, uint32_t offset,
IteEntry ite = {};
ite.itel = FIELD_DP64(ite.itel, ITE_L, VALID, dte_valid);
ite.itel = FIELD_DP64(ite.itel, ITE_L, INTTYPE, ITE_INTTYPE_PHYSICAL);
- if (ignore_pInt) {
- ite.itel = FIELD_DP64(ite.itel, ITE_L, INTID, eventid);
- } else {
- ite.itel = FIELD_DP64(ite.itel, ITE_L, INTID, pIntid);
- }
+ ite.itel = FIELD_DP64(ite.itel, ITE_L, INTID, pIntid);
ite.itel = FIELD_DP64(ite.itel, ITE_L, DOORBELL, INTID_SPURIOUS);
ite.iteh = FIELD_DP32(ite.iteh, ITE_H, ICID, icid);