aboutsummaryrefslogtreecommitdiff
path: root/hw/intc/arm_gicv3_its.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2022-04-08 15:15:28 +0100
committerPeter Maydell <peter.maydell@linaro.org>2022-04-22 14:44:52 +0100
commitd4014320a430d2ac07f896b9ce38778258060deb (patch)
tree04a7d2a3453a00cc5e71f6088d66ef48a7d10f23 /hw/intc/arm_gicv3_its.c
parenta686e85d2b4a3b95d97d01dfa3fd4607f1216cf0 (diff)
hw/intc/arm_gicv3_its: Implement INV for virtual interrupts
Implement the ITS side of the handling of the INV command for virtual interrupts; as usual this calls into a redistributor function which we leave as a stub to fill in later. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20220408141550.1271295-20-peter.maydell@linaro.org
Diffstat (limited to 'hw/intc/arm_gicv3_its.c')
-rw-r--r--hw/intc/arm_gicv3_its.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
index aa0a62510e..f7c01c2be1 100644
--- a/hw/intc/arm_gicv3_its.c
+++ b/hw/intc/arm_gicv3_its.c
@@ -1090,6 +1090,7 @@ static ItsCmdResult process_inv(GICv3ITSState *s, const uint64_t *cmdpkt)
ITEntry ite;
DTEntry dte;
CTEntry cte;
+ VTEntry vte;
ItsCmdResult cmdres;
devid = FIELD_EX64(cmdpkt[0], INV_0, DEVICEID);
@@ -1118,8 +1119,19 @@ static ItsCmdResult process_inv(GICv3ITSState *s, const uint64_t *cmdpkt)
__func__, ite.inttype);
return CMD_CONTINUE;
}
- /* We will implement the vLPI invalidation in a later commit */
- g_assert_not_reached();
+
+ cmdres = lookup_vte(s, __func__, ite.vpeid, &vte);
+ if (cmdres != CMD_CONTINUE_OK) {
+ return cmdres;
+ }
+ if (!intid_in_lpi_range(ite.intid) ||
+ ite.intid >= (1ULL << (vte.vptsize + 1))) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: intid 0x%x out of range\n",
+ __func__, ite.intid);
+ return CMD_CONTINUE;
+ }
+ gicv3_redist_inv_vlpi(&s->gicv3->cpu[vte.rdbase], ite.intid,
+ vte.vptaddr << 16);
break;
default:
g_assert_not_reached();