diff options
author | Heyi Guo <guoheyi@linux.alibaba.com> | 2021-01-14 22:16:18 +0800 |
---|---|---|
committer | Manish Pandey <manish.pandey2@arm.com> | 2021-02-03 11:12:07 +0000 |
commit | deb18901d127bf4252e87a4b597ef7bd2b1e58b1 (patch) | |
tree | a592788170762ccf28a952d453c2a8e5cc7d7dc2 /drivers/arm | |
parent | 60cd8030bfe7da4cd5edd04df25ad359aa22c7c0 (diff) | |
download | arm-trusted-firmware-deb18901d127bf4252e87a4b597ef7bd2b1e58b1.tar.gz |
drivers/gicv3: fix potential GICD context override with ESPI enabled
RESTORE/SAVE_GICD_EREGS uses (int_id - (MIN_ESPI_ID - MIN_SPI_ID)) to
get the context array index for ESPI, which will override the space of
standard SPI starting from (MIN_SPI_ID + MIN_SPI_ID).
However, using TOTAL_SPI_INTR_NUM to replace the above MIN_SPI_ID
cannot totally fix the issue, for TOTAL_SPI_INTR_NUM is not well
aligned and the array index will be rounded down by the shifting
operation if being shifted more than 2 bits. It will cause buffer
override again when the existing maximum SPI reaches 1019.
So round up TOTAL_SPI_INTR_NUM with (1 << REG##R_SHIFT) for GICD
context arrays.
Signed-off-by: Heyi Guo <guoheyi@linux.alibaba.com>
Change-Id: I5be2837c42f381a62f8d46a4ecd778009b1fe059
Diffstat (limited to 'drivers/arm')
-rw-r--r-- | drivers/arm/gic/v3/gicv3_main.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index fb62f4894..65145d597 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -70,7 +70,8 @@ static bool is_sgi_ppi(unsigned int id); for (unsigned int int_id = MIN_ESPI_ID; int_id < (intr_num);\ int_id += (1U << REG##R_SHIFT)) { \ gicd_write_##reg((base), int_id, \ - (ctx)->gicd_##reg[(int_id - (MIN_ESPI_ID - MIN_SPI_ID))\ + (ctx)->gicd_##reg[(int_id - (MIN_ESPI_ID - \ + round_up(TOTAL_SPI_INTR_NUM, 1U << REG##R_SHIFT)))\ >> REG##R_SHIFT]); \ } \ } while (false) @@ -79,7 +80,8 @@ static bool is_sgi_ppi(unsigned int id); do { \ for (unsigned int int_id = MIN_ESPI_ID; int_id < (intr_num);\ int_id += (1U << REG##R_SHIFT)) { \ - (ctx)->gicd_##reg[(int_id - (MIN_ESPI_ID - MIN_SPI_ID))\ + (ctx)->gicd_##reg[(int_id - (MIN_ESPI_ID - \ + round_up(TOTAL_SPI_INTR_NUM, 1U << REG##R_SHIFT)))\ >> REG##R_SHIFT] = gicd_read_##reg((base), int_id);\ } \ } while (false) |