aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2022-04-08 15:15:20 +0100
committerPeter Maydell <peter.maydell@linaro.org>2022-04-22 09:24:43 +0100
commitf0175135e74bc979573f170e83abfc536aed03de (patch)
treed85b1a4cfaa4334af69d96d91506b556d9fde7d8 /hw
parent93f4fdcd4d98c0de8e056e08016bce7d71a91100 (diff)
hw/intc/arm_gicv3_its: Factor out "find ITE given devid, eventid"
The operation of finding an interrupt table entry given a (DeviceID, EventID) pair is necessary in multiple different ITS commands. The process requires first using the DeviceID as an index into the device table to find the DTE, and then useng the EventID as an index into the interrupt table specified by that DTE to find the ITE. We also need to handle all the possible error cases: indexes out of range, table memory not readable, table entries not valid. Factor this out into a separate lookup_ite() function which we can then call from the places where we were previously open-coding this sequence. We'll also need this for some of the new GICv4.0 commands. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20220408141550.1271295-12-peter.maydell@linaro.org
Diffstat (limited to 'hw')
-rw-r--r--hw/intc/arm_gicv3_its.c104
1 files changed, 54 insertions, 50 deletions
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
index 179a9b032c..4a029d754a 100644
--- a/hw/intc/arm_gicv3_its.c
+++ b/hw/intc/arm_gicv3_its.c
@@ -315,52 +315,81 @@ out:
}
/*
- * This function handles the processing of following commands based on
- * the ItsCmdType parameter passed:-
- * 1. triggering of lpi interrupt translation via ITS INT command
- * 2. triggering of lpi interrupt translation via gits_translater register
- * 3. handling of ITS CLEAR command
- * 4. handling of ITS DISCARD command
+ * Given a (DeviceID, EventID), look up the corresponding ITE, including
+ * checking for the various invalid-value cases. If we find a valid ITE,
+ * fill in @ite and @dte and return CMD_CONTINUE_OK. Otherwise return
+ * CMD_STALL or CMD_CONTINUE as appropriate (and the contents of @ite
+ * should not be relied on).
+ *
+ * The string @who is purely for the LOG_GUEST_ERROR messages,
+ * and should indicate the name of the calling function or similar.
*/
-static ItsCmdResult do_process_its_cmd(GICv3ITSState *s, uint32_t devid,
- uint32_t eventid, ItsCmdType cmd)
+static ItsCmdResult lookup_ite(GICv3ITSState *s, const char *who,
+ uint32_t devid, uint32_t eventid, ITEntry *ite,
+ DTEntry *dte)
{
uint64_t num_eventids;
- DTEntry dte;
- CTEntry cte;
- ITEntry ite;
if (devid >= s->dt.num_entries) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: invalid command attributes: devid %d>=%d",
- __func__, devid, s->dt.num_entries);
+ who, devid, s->dt.num_entries);
return CMD_CONTINUE;
}
- if (get_dte(s, devid, &dte) != MEMTX_OK) {
+ if (get_dte(s, devid, dte) != MEMTX_OK) {
return CMD_STALL;
}
- if (!dte.valid) {
+ if (!dte->valid) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: invalid command attributes: "
- "invalid dte for %d\n", __func__, devid);
+ "invalid dte for %d\n", who, devid);
return CMD_CONTINUE;
}
- num_eventids = 1ULL << (dte.size + 1);
+ num_eventids = 1ULL << (dte->size + 1);
if (eventid >= num_eventids) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: invalid command attributes: eventid %d >= %"
- PRId64 "\n",
- __func__, eventid, num_eventids);
+ PRId64 "\n", who, eventid, num_eventids);
return CMD_CONTINUE;
}
- if (get_ite(s, eventid, &dte, &ite) != MEMTX_OK) {
+ if (get_ite(s, eventid, dte, ite) != MEMTX_OK) {
return CMD_STALL;
}
- if (!ite.valid || ite.inttype != ITE_INTTYPE_PHYSICAL) {
+ if (!ite->valid) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: invalid command attributes: invalid ITE\n", who);
+ return CMD_CONTINUE;
+ }
+
+ return CMD_CONTINUE_OK;
+}
+
+/*
+ * This function handles the processing of following commands based on
+ * the ItsCmdType parameter passed:-
+ * 1. triggering of lpi interrupt translation via ITS INT command
+ * 2. triggering of lpi interrupt translation via gits_translater register
+ * 3. handling of ITS CLEAR command
+ * 4. handling of ITS DISCARD command
+ */
+static ItsCmdResult do_process_its_cmd(GICv3ITSState *s, uint32_t devid,
+ uint32_t eventid, ItsCmdType cmd)
+{
+ DTEntry dte;
+ CTEntry cte;
+ ITEntry ite;
+ ItsCmdResult cmdres;
+
+ cmdres = lookup_ite(s, __func__, devid, eventid, &ite, &dte);
+ if (cmdres != CMD_CONTINUE_OK) {
+ return cmdres;
+ }
+
+ if (ite.inttype != ITE_INTTYPE_PHYSICAL) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: invalid command attributes: invalid ITE\n",
__func__);
@@ -740,10 +769,10 @@ static ItsCmdResult process_movi(GICv3ITSState *s, const uint64_t *cmdpkt)
{
uint32_t devid, eventid;
uint16_t new_icid;
- uint64_t num_eventids;
DTEntry dte;
CTEntry old_cte, new_cte;
ITEntry old_ite;
+ ItsCmdResult cmdres;
devid = FIELD_EX64(cmdpkt[0], MOVI_0, DEVICEID);
eventid = FIELD_EX64(cmdpkt[1], MOVI_1, EVENTID);
@@ -751,37 +780,12 @@ static ItsCmdResult process_movi(GICv3ITSState *s, const uint64_t *cmdpkt)
trace_gicv3_its_cmd_movi(devid, eventid, new_icid);
- if (devid >= s->dt.num_entries) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: invalid command attributes: devid %d>=%d",
- __func__, devid, s->dt.num_entries);
- return CMD_CONTINUE;
- }
- if (get_dte(s, devid, &dte) != MEMTX_OK) {
- return CMD_STALL;
- }
-
- if (!dte.valid) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: invalid command attributes: "
- "invalid dte for %d\n", __func__, devid);
- return CMD_CONTINUE;
- }
-
- num_eventids = 1ULL << (dte.size + 1);
- if (eventid >= num_eventids) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: invalid command attributes: eventid %d >= %"
- PRId64 "\n",
- __func__, eventid, num_eventids);
- return CMD_CONTINUE;
- }
-
- if (get_ite(s, eventid, &dte, &old_ite) != MEMTX_OK) {
- return CMD_STALL;
+ cmdres = lookup_ite(s, __func__, devid, eventid, &old_ite, &dte);
+ if (cmdres != CMD_CONTINUE_OK) {
+ return cmdres;
}
- if (!old_ite.valid || old_ite.inttype != ITE_INTTYPE_PHYSICAL) {
+ if (old_ite.inttype != ITE_INTTYPE_PHYSICAL) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: invalid command attributes: invalid ITE\n",
__func__);