diff options
author | Jim Shu <jim.shu@sifive.com> | 2022-11-27 16:57:46 +0000 |
---|---|---|
committer | Alistair Francis <alistair.francis@wdc.com> | 2023-01-06 10:42:55 +1000 |
commit | bb22d391121fc0de42a04d1ed99f602441ea70e1 (patch) | |
tree | da761478b364b76f2e1230a618cb500f505a2dde /hw/intc | |
parent | 592f0a9429b924bc7eec0aee60afa391f7ca96b2 (diff) | |
download | qemu-bb22d391121fc0de42a04d1ed99f602441ea70e1.zip qemu-bb22d391121fc0de42a04d1ed99f602441ea70e1.tar.gz qemu-bb22d391121fc0de42a04d1ed99f602441ea70e1.tar.bz2 |
hw/intc: sifive_plic: fix out-of-bound access of source_priority array
If the number of interrupt is not multiple of 32, PLIC will have
out-of-bound access to source_priority array. Compute the number of
interrupt in the last word to avoid this out-of-bound access of array.
Signed-off-by: Jim Shu <jim.shu@sifive.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Message-Id: <20221127165753.30533-1-jim.shu@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'hw/intc')
-rw-r--r-- | hw/intc/sifive_plic.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c index b4949be..0c76965 100644 --- a/hw/intc/sifive_plic.c +++ b/hw/intc/sifive_plic.c @@ -78,6 +78,7 @@ static uint32_t sifive_plic_claimed(SiFivePLICState *plic, uint32_t addrid) uint32_t max_irq = 0; uint32_t max_prio = plic->target_priority[addrid]; int i, j; + int num_irq_in_word = 32; for (i = 0; i < plic->bitfield_words; i++) { uint32_t pending_enabled_not_claimed = @@ -88,7 +89,16 @@ static uint32_t sifive_plic_claimed(SiFivePLICState *plic, uint32_t addrid) continue; } - for (j = 0; j < 32; j++) { + if (i == (plic->bitfield_words - 1)) { + /* + * If plic->num_sources is not multiple of 32, num-of-irq in last + * word is not 32. Compute the num-of-irq of last word to avoid + * out-of-bound access of source_priority array. + */ + num_irq_in_word = plic->num_sources - ((plic->bitfield_words - 1) << 5); + } + + for (j = 0; j < num_irq_in_word; j++) { int irq = (i << 5) + j; uint32_t prio = plic->source_priority[irq]; int enabled = pending_enabled_not_claimed & (1 << j); |