Skip to content

Commit

Permalink
hw/intc/arm_gicv3_its: Drop TableDesc and CmdQDesc valid fields
Browse files Browse the repository at this point in the history
Currently we track in the TableDesc and CmdQDesc structs the state of
the GITS_BASER<n> and GITS_CBASER Valid bits.  However we aren't very
consistent abut checking the valid field: we test it in update_cte()
and update_dte(), but not anywhere else we look things up in tables.

The GIC specification says that it is UNPREDICTABLE if a guest fails
to set any of these Valid bits before enabling the ITS via
GITS_CTLR.Enabled.  So we can choose to handle Valid == 0 as
equivalent to a zero-length table.  This is in fact how we're already
catching this case in most of the table-access paths: when Valid is 0
we leave the num_entries fields in TableDesc or CmdQDesc set to zero,
and then the out-of-bounds check "index >= num_entries" that we have
to do anyway before doing any of these table lookups will always be
true, catching the no-valid-table case without any extra code.

So we can remove the checks on the valid field from update_cte()
and update_dte(): since these happen after the bounds check there
was never any case when the test could fail. That means the valid
fields would be entirely unused, so just remove them.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220201193207.2771604-11-peter.maydell@linaro.org
  • Loading branch information
pm215 committed Feb 8, 2022
1 parent 7eb5426 commit da4680c
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 19 deletions.
31 changes: 14 additions & 17 deletions hw/intc/arm_gicv3_its.c
Expand Up @@ -442,10 +442,6 @@ static bool update_cte(GICv3ITSState *s, uint16_t icid, const CTEntry *cte)
uint64_t cteval = 0;
MemTxResult res = MEMTX_OK;

if (!s->ct.valid) {
return true;
}

if (cte->valid) {
/* add mapping entry to collection table */
cteval = FIELD_DP64(cteval, CTE, VALID, 1);
Expand Down Expand Up @@ -504,15 +500,11 @@ static bool update_dte(GICv3ITSState *s, uint32_t devid, const DTEntry *dte)
uint64_t dteval = 0;
MemTxResult res = MEMTX_OK;

if (s->dt.valid) {
if (dte->valid) {
/* add mapping entry to device table */
dteval = FIELD_DP64(dteval, DTE, VALID, 1);
dteval = FIELD_DP64(dteval, DTE, SIZE, dte->size);
dteval = FIELD_DP64(dteval, DTE, ITTADDR, dte->ittaddr);
}
} else {
return true;
if (dte->valid) {
/* add mapping entry to device table */
dteval = FIELD_DP64(dteval, DTE, VALID, 1);
dteval = FIELD_DP64(dteval, DTE, SIZE, dte->size);
dteval = FIELD_DP64(dteval, DTE, ITTADDR, dte->ittaddr);
}

entry_addr = table_entry_addr(s, &s->dt, devid, &res);
Expand Down Expand Up @@ -901,16 +893,22 @@ static void extract_table_params(GICv3ITSState *s)
}

memset(td, 0, sizeof(*td));
td->valid = FIELD_EX64(value, GITS_BASER, VALID);
/*
* If GITS_BASER<n>.Valid is 0 for any <n> then we will not process
* interrupts. (GITS_TYPER.HCC is 0 for this implementation, so we
* do not have a special case where the GITS_BASER<n>.Valid bit is 0
* for the register corresponding to the Collection table but we
* still have to process interrupts using non-memory-backed
* Collection table entries.)
* The specification makes it UNPREDICTABLE to enable the ITS without
* marking each BASER<n> as valid. We choose to handle these as if
* the table was zero-sized, so commands using the table will fail
* and interrupts requested via GITS_TRANSLATER writes will be ignored.
* This happens automatically by leaving the num_entries field at
* zero, which will be caught by the bounds checks we have before
* every table lookup anyway.
*/
if (!td->valid) {
if (!FIELD_EX64(value, GITS_BASER, VALID)) {
continue;
}
td->page_sz = page_sz;
Expand All @@ -936,9 +934,8 @@ static void extract_cmdq_params(GICv3ITSState *s)
num_pages = FIELD_EX64(value, GITS_CBASER, SIZE) + 1;

memset(&s->cq, 0 , sizeof(s->cq));
s->cq.valid = FIELD_EX64(value, GITS_CBASER, VALID);

if (s->cq.valid) {
if (FIELD_EX64(value, GITS_CBASER, VALID)) {
s->cq.num_entries = (num_pages * GITS_PAGE_SIZE_4K) /
GITS_CMDQ_ENTRY_SIZE;
s->cq.base_addr = FIELD_EX64(value, GITS_CBASER, PHYADDR);
Expand Down
2 changes: 0 additions & 2 deletions include/hw/intc/arm_gicv3_its_common.h
Expand Up @@ -42,7 +42,6 @@
#define GITS_TRANSLATER 0x0040

typedef struct {
bool valid;
bool indirect;
uint16_t entry_sz;
uint32_t page_sz;
Expand All @@ -51,7 +50,6 @@ typedef struct {
} TableDesc;

typedef struct {
bool valid;
uint32_t num_entries;
uint64_t base_addr;
} CmdQDesc;
Expand Down

0 comments on commit da4680c

Please sign in to comment.