summaryrefslogtreecommitdiffstats
path: root/hw/intc/loongson_liointc.c
diff options
context:
space:
mode:
authorJiaxun Yang2021-01-12 02:25:27 +0100
committerPhilippe Mathieu-Daudé2021-02-21 18:41:46 +0100
commit6902759965852ae9fc099bb32af8f8dc4a098733 (patch)
tree84686cad27f5cccb802aa3c51a1f25d0b01c9e11 /hw/intc/loongson_liointc.c
parenthw/mips/boston: Use bootloader helper to set GCRs (diff)
downloadqemu-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/loongson_liointc.c')
-rw-r--r--hw/intc/loongson_liointc.c16
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;
}