[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 11/61] hw/intc/arm_gicv3_its: Factor out "find ITE given devid, ev
From: |
Peter Maydell |
Subject: |
[PULL 11/61] hw/intc/arm_gicv3_its: Factor out "find ITE given devid, eventid" |
Date: |
Fri, 22 Apr 2022 11:03:42 +0100 |
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
---
hw/intc/arm_gicv3_its.c | 124 +++++++++++++++++++++-------------------
1 file changed, 64 insertions(+), 60 deletions(-)
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
index 179a9b032c2..4a029d754ad 100644
--- a/hw/intc/arm_gicv3_its.c
+++ b/hw/intc/arm_gicv3_its.c
@@ -314,6 +314,60 @@ out:
return res;
}
+/*
+ * 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 lookup_ite(GICv3ITSState *s, const char *who,
+ uint32_t devid, uint32_t eventid, ITEntry *ite,
+ DTEntry *dte)
+{
+ uint64_t num_eventids;
+
+ if (devid >= s->dt.num_entries) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: invalid command attributes: devid %d>=%d",
+ who, 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", who, 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", who, eventid, num_eventids);
+ return CMD_CONTINUE;
+ }
+
+ if (get_ite(s, eventid, dte, ite) != MEMTX_OK) {
+ return CMD_STALL;
+ }
+
+ 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:-
@@ -325,42 +379,17 @@ out:
static ItsCmdResult do_process_its_cmd(GICv3ITSState *s, uint32_t devid,
uint32_t eventid, ItsCmdType cmd)
{
- uint64_t num_eventids;
DTEntry dte;
CTEntry cte;
ITEntry ite;
+ ItsCmdResult cmdres;
- 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;
+ cmdres = lookup_ite(s, __func__, devid, eventid, &ite, &dte);
+ if (cmdres != CMD_CONTINUE_OK) {
+ return cmdres;
}
- 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, &ite) != MEMTX_OK) {
- return CMD_STALL;
- }
-
- if (!ite.valid || ite.inttype != ITE_INTTYPE_PHYSICAL) {
+ 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;
+ cmdres = lookup_ite(s, __func__, devid, eventid, &old_ite, &dte);
+ if (cmdres != CMD_CONTINUE_OK) {
+ return cmdres;
}
- 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;
- }
-
- 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__);
--
2.25.1
- [PULL 12/61] hw/intc/arm_gicv3_its: Factor out CTE lookup sequence, (continued)
- [PULL 12/61] hw/intc/arm_gicv3_its: Factor out CTE lookup sequence, Peter Maydell, 2022/04/22
- [PULL 10/61] hw/intc/arm_gicv3_its: Distinguish success and error cases of CMD_CONTINUE, Peter Maydell, 2022/04/22
- [PULL 05/61] target/arm/cpu.c: ignore VIRQ and VFIQ if no EL2, Peter Maydell, 2022/04/22
- [PULL 06/61] hw/intc/arm_gicv3_its: Factor out "is intid a valid LPI ID?", Peter Maydell, 2022/04/22
- [PULL 09/61] hw/intc/arm_gicv3_its: Implement VMAPP, Peter Maydell, 2022/04/22
- [PULL 17/61] hw/intc/arm_gicv3_its: Implement VSYNC, Peter Maydell, 2022/04/22
- [PULL 15/61] hw/intc/arm_gicv3: Keep pointers to every connected ITS, Peter Maydell, 2022/04/22
- [PULL 03/61] hw/intc/arm_gicv3: Insist that redist region capacity matches CPU count, Peter Maydell, 2022/04/22
- [PULL 02/61] hw/intc/arm_gicv3: Sanity-check num-cpu property, Peter Maydell, 2022/04/22
- [PULL 08/61] hw/intc/arm_gicv3_its: Implement VMAPI and VMAPTI, Peter Maydell, 2022/04/22
- [PULL 11/61] hw/intc/arm_gicv3_its: Factor out "find ITE given devid, eventid",
Peter Maydell <=
- [PULL 13/61] hw/intc/arm_gicv3_its: Split out process_its_cmd() physical interrupt code, Peter Maydell, 2022/04/22
- [PULL 19/61] hw/intc/arm_gicv3_its: Implement INV for virtual interrupts, Peter Maydell, 2022/04/22
- [PULL 14/61] hw/intc/arm_gicv3_its: Handle virtual interrupts in process_its_cmd(), Peter Maydell, 2022/04/22
- [PULL 21/61] hw/intc/arm_gicv3_its: Implement VINVALL, Peter Maydell, 2022/04/22
- [PULL 20/61] hw/intc/arm_gicv3_its: Implement VMOVI, Peter Maydell, 2022/04/22
- [PULL 26/61] hw/intc/arm_gicv3_cpuif: Don't recalculate maintenance irq unnecessarily, Peter Maydell, 2022/04/22
- [PULL 24/61] hw/intc/arm_gicv3_cpuif: Split "update vIRQ/vFIQ" from gicv3_cpuif_virt_update(), Peter Maydell, 2022/04/22
- [PULL 16/61] hw/intc/arm_gicv3_its: Implement VMOVP, Peter Maydell, 2022/04/22
- [PULL 18/61] hw/intc/arm_gicv3_its: Implement INV command properly, Peter Maydell, 2022/04/22
- [PULL 22/61] hw/intc/arm_gicv3: Implement GICv4's new redistributor frame, Peter Maydell, 2022/04/22