hw/intc/arm_gicv3_its: Zero initialize local DTEntry etc structs

In the GICv3 ITS model, we have a common coding pattern which has a
local C struct like "DTEntry dte", which is a C representation of an
in-guest-memory data structure, and we call a function such as
get_dte() to read guest memory and fill in the C struct.  These
functions to read in the struct sometimes have cases where they will
leave early and not fill in the whole struct (for instance get_dte()
will set "dte->valid = false" and nothing else for the case where it
is passed an entry_addr implying that there is no L2 table entry for
the DTE).  This then causes potential use of uninitialized memory
later, for instance when we call a trace event which prints all the
fields of the struct.  Sufficiently advanced compilers may produce
-Wmaybe-uninitialized warnings about this, especially if LTO is
enabled.

Rather than trying to carefully separate out these trace events into
"only the 'valid' field is initialized" and "all fields can be
printed", zero-init all the structs when we define them. None of
these structs are large (the biggest is 24 bytes) and having
consistent behaviour is less likely to be buggy.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2718
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20241213182337.3343068-1-peter.maydell@linaro.org
This commit is contained in:
Peter Maydell 2024-12-13 18:23:37 +00:00
parent daae2280ca
commit 9678b9c505

View File

@ -465,7 +465,7 @@ static ItsCmdResult lookup_vte(GICv3ITSState *s, const char *who,
static ItsCmdResult process_its_cmd_phys(GICv3ITSState *s, const ITEntry *ite, static ItsCmdResult process_its_cmd_phys(GICv3ITSState *s, const ITEntry *ite,
int irqlevel) int irqlevel)
{ {
CTEntry cte; CTEntry cte = {};
ItsCmdResult cmdres; ItsCmdResult cmdres;
cmdres = lookup_cte(s, __func__, ite->icid, &cte); cmdres = lookup_cte(s, __func__, ite->icid, &cte);
@ -479,7 +479,7 @@ static ItsCmdResult process_its_cmd_phys(GICv3ITSState *s, const ITEntry *ite,
static ItsCmdResult process_its_cmd_virt(GICv3ITSState *s, const ITEntry *ite, static ItsCmdResult process_its_cmd_virt(GICv3ITSState *s, const ITEntry *ite,
int irqlevel) int irqlevel)
{ {
VTEntry vte; VTEntry vte = {};
ItsCmdResult cmdres; ItsCmdResult cmdres;
cmdres = lookup_vte(s, __func__, ite->vpeid, &vte); cmdres = lookup_vte(s, __func__, ite->vpeid, &vte);
@ -514,8 +514,8 @@ static ItsCmdResult process_its_cmd_virt(GICv3ITSState *s, const ITEntry *ite,
static ItsCmdResult do_process_its_cmd(GICv3ITSState *s, uint32_t devid, static ItsCmdResult do_process_its_cmd(GICv3ITSState *s, uint32_t devid,
uint32_t eventid, ItsCmdType cmd) uint32_t eventid, ItsCmdType cmd)
{ {
DTEntry dte; DTEntry dte = {};
ITEntry ite; ITEntry ite = {};
ItsCmdResult cmdres; ItsCmdResult cmdres;
int irqlevel; int irqlevel;
@ -583,8 +583,8 @@ static ItsCmdResult process_mapti(GICv3ITSState *s, const uint64_t *cmdpkt,
uint32_t pIntid = 0; uint32_t pIntid = 0;
uint64_t num_eventids; uint64_t num_eventids;
uint16_t icid = 0; uint16_t icid = 0;
DTEntry dte; DTEntry dte = {};
ITEntry ite; ITEntry ite = {};
devid = (cmdpkt[0] & DEVID_MASK) >> DEVID_SHIFT; devid = (cmdpkt[0] & DEVID_MASK) >> DEVID_SHIFT;
eventid = cmdpkt[1] & EVENTID_MASK; eventid = cmdpkt[1] & EVENTID_MASK;
@ -651,8 +651,8 @@ static ItsCmdResult process_vmapti(GICv3ITSState *s, const uint64_t *cmdpkt,
{ {
uint32_t devid, eventid, vintid, doorbell, vpeid; uint32_t devid, eventid, vintid, doorbell, vpeid;
uint32_t num_eventids; uint32_t num_eventids;
DTEntry dte; DTEntry dte = {};
ITEntry ite; ITEntry ite = {};
if (!its_feature_virtual(s)) { if (!its_feature_virtual(s)) {
return CMD_CONTINUE; return CMD_CONTINUE;
@ -761,7 +761,7 @@ static bool update_cte(GICv3ITSState *s, uint16_t icid, const CTEntry *cte)
static ItsCmdResult process_mapc(GICv3ITSState *s, const uint64_t *cmdpkt) static ItsCmdResult process_mapc(GICv3ITSState *s, const uint64_t *cmdpkt)
{ {
uint16_t icid; uint16_t icid;
CTEntry cte; CTEntry cte = {};
icid = cmdpkt[2] & ICID_MASK; icid = cmdpkt[2] & ICID_MASK;
cte.valid = cmdpkt[2] & CMD_FIELD_VALID_MASK; cte.valid = cmdpkt[2] & CMD_FIELD_VALID_MASK;
@ -822,7 +822,7 @@ static bool update_dte(GICv3ITSState *s, uint32_t devid, const DTEntry *dte)
static ItsCmdResult process_mapd(GICv3ITSState *s, const uint64_t *cmdpkt) static ItsCmdResult process_mapd(GICv3ITSState *s, const uint64_t *cmdpkt)
{ {
uint32_t devid; uint32_t devid;
DTEntry dte; DTEntry dte = {};
devid = (cmdpkt[0] & DEVID_MASK) >> DEVID_SHIFT; devid = (cmdpkt[0] & DEVID_MASK) >> DEVID_SHIFT;
dte.size = cmdpkt[1] & SIZE_MASK; dte.size = cmdpkt[1] & SIZE_MASK;
@ -886,9 +886,9 @@ static ItsCmdResult process_movi(GICv3ITSState *s, const uint64_t *cmdpkt)
{ {
uint32_t devid, eventid; uint32_t devid, eventid;
uint16_t new_icid; uint16_t new_icid;
DTEntry dte; DTEntry dte = {};
CTEntry old_cte, new_cte; CTEntry old_cte = {}, new_cte = {};
ITEntry old_ite; ITEntry old_ite = {};
ItsCmdResult cmdres; ItsCmdResult cmdres;
devid = FIELD_EX64(cmdpkt[0], MOVI_0, DEVICEID); devid = FIELD_EX64(cmdpkt[0], MOVI_0, DEVICEID);
@ -965,7 +965,7 @@ static bool update_vte(GICv3ITSState *s, uint32_t vpeid, const VTEntry *vte)
static ItsCmdResult process_vmapp(GICv3ITSState *s, const uint64_t *cmdpkt) static ItsCmdResult process_vmapp(GICv3ITSState *s, const uint64_t *cmdpkt)
{ {
VTEntry vte; VTEntry vte = {};
uint32_t vpeid; uint32_t vpeid;
if (!its_feature_virtual(s)) { if (!its_feature_virtual(s)) {
@ -1030,7 +1030,7 @@ static void vmovp_callback(gpointer data, gpointer opaque)
*/ */
GICv3ITSState *s = data; GICv3ITSState *s = data;
VmovpCallbackData *cbdata = opaque; VmovpCallbackData *cbdata = opaque;
VTEntry vte; VTEntry vte = {};
ItsCmdResult cmdres; ItsCmdResult cmdres;
cmdres = lookup_vte(s, __func__, cbdata->vpeid, &vte); cmdres = lookup_vte(s, __func__, cbdata->vpeid, &vte);
@ -1085,9 +1085,9 @@ static ItsCmdResult process_vmovi(GICv3ITSState *s, const uint64_t *cmdpkt)
{ {
uint32_t devid, eventid, vpeid, doorbell; uint32_t devid, eventid, vpeid, doorbell;
bool doorbell_valid; bool doorbell_valid;
DTEntry dte; DTEntry dte = {};
ITEntry ite; ITEntry ite = {};
VTEntry old_vte, new_vte; VTEntry old_vte = {}, new_vte = {};
ItsCmdResult cmdres; ItsCmdResult cmdres;
if (!its_feature_virtual(s)) { if (!its_feature_virtual(s)) {
@ -1186,10 +1186,10 @@ static ItsCmdResult process_vinvall(GICv3ITSState *s, const uint64_t *cmdpkt)
static ItsCmdResult process_inv(GICv3ITSState *s, const uint64_t *cmdpkt) static ItsCmdResult process_inv(GICv3ITSState *s, const uint64_t *cmdpkt)
{ {
uint32_t devid, eventid; uint32_t devid, eventid;
ITEntry ite; ITEntry ite = {};
DTEntry dte; DTEntry dte = {};
CTEntry cte; CTEntry cte = {};
VTEntry vte; VTEntry vte = {};
ItsCmdResult cmdres; ItsCmdResult cmdres;
devid = FIELD_EX64(cmdpkt[0], INV_0, DEVICEID); devid = FIELD_EX64(cmdpkt[0], INV_0, DEVICEID);