diff options
author | Jiaxun Yang | 2021-01-12 02:25:27 +0100 |
---|---|---|
committer | Philippe Mathieu-Daudé | 2021-02-21 18:41:46 +0100 |
commit | 6902759965852ae9fc099bb32af8f8dc4a098733 (patch) | |
tree | 84686cad27f5cccb802aa3c51a1f25d0b01c9e11 /hw/intc | |
parent | hw/mips/boston: Use bootloader helper to set GCRs (diff) | |
download | qemu-6902759965852ae9fc099bb32af8f8dc4a098733.tar.gz qemu-6902759965852ae9fc099bb32af8f8dc4a098733.tar.xz qemu-6902759965852ae9fc099bb32af8f8dc4a098733.zip |
hw/intc/loongson_liointc: Fix per core ISR handling
Per core ISR is a set of 32-bit registers spaced by 8 bytes.
This patch fixed calculation of it's size and also added check
of alignment at reading & writing.
Fixes: Coverity CID 1438965 and CID 1438967
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Reviewed-by: Huacai Chen <chenhuacai@kernel.org>
Message-Id: <20210112012527.28927-1-jiaxun.yang@flygoat.com>
[PMD: Added Coverity CID]
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Diffstat (limited to 'hw/intc')
-rw-r--r-- | hw/intc/loongson_liointc.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/hw/intc/loongson_liointc.c b/hw/intc/loongson_liointc.c index f823d484e0..cc11b544cb 100644 --- a/hw/intc/loongson_liointc.c +++ b/hw/intc/loongson_liointc.c @@ -41,7 +41,7 @@ #define R_IEN_CLR 0x2c #define R_ISR_SIZE 0x8 #define R_START 0x40 -#define R_END 0x64 +#define R_END (R_START + R_ISR_SIZE * NUM_CORES) struct loongson_liointc { SysBusDevice parent_obj; @@ -125,7 +125,12 @@ liointc_read(void *opaque, hwaddr addr, unsigned int size) } if (addr >= R_START && addr < R_END) { - int core = (addr - R_START) / R_ISR_SIZE; + hwaddr offset = addr - R_START; + int core = offset / R_ISR_SIZE; + + if (offset % R_ISR_SIZE) { + goto out; + } r = p->per_core_isr[core]; goto out; } @@ -169,7 +174,12 @@ liointc_write(void *opaque, hwaddr addr, } if (addr >= R_START && addr < R_END) { - int core = (addr - R_START) / R_ISR_SIZE; + hwaddr offset = addr - R_START; + int core = offset / R_ISR_SIZE; + + if (offset % R_ISR_SIZE) { + goto out; + } p->per_core_isr[core] = value; goto out; } |