aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorSong Gao <gaosong@loongson.cn>2023-04-06 15:11:31 +0800
committerSong Gao <gaosong@loongson.cn>2023-05-15 19:09:33 +0800
commit7ef0eb35a4e6961d7e40f03f16ed241c95ae93f9 (patch)
treeddd4866838ad501e49382744c48e5fe6857736e9 /hw
parent646c39b220f789158313fee5d207f370e29c586a (diff)
downloadqemu-7ef0eb35a4e6961d7e40f03f16ed241c95ae93f9.zip
qemu-7ef0eb35a4e6961d7e40f03f16ed241c95ae93f9.tar.gz
qemu-7ef0eb35a4e6961d7e40f03f16ed241c95ae93f9.tar.bz2
hw/intc: Add NULL pointer check on LoongArch ipi device
When ipi mailbox is used, cpu_index is decoded from iocsr register. cpu maybe does not exist. This patch adds NULL pointer check on ipi device. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Song Gao <gaosong@loongson.cn> Message-Id: <20230512100421.1867848-4-gaosong@loongson.cn>
Diffstat (limited to 'hw')
-rw-r--r--hw/intc/loongarch_ipi.c40
-rw-r--r--hw/intc/trace-events1
2 files changed, 30 insertions, 11 deletions
diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
index 054e143..d6ab917 100644
--- a/hw/intc/loongarch_ipi.c
+++ b/hw/intc/loongarch_ipi.c
@@ -77,31 +77,42 @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr)
static void ipi_send(uint64_t val)
{
- int cpuid, data;
+ uint32_t cpuid;
+ uint8_t vector;
CPULoongArchState *env;
CPUState *cs;
LoongArchCPU *cpu;
- cpuid = (val >> 16) & 0x3ff;
+ cpuid = extract32(val, 16, 10);
+ if (cpuid >= LOONGARCH_MAX_CPUS) {
+ trace_loongarch_ipi_unsupported_cpuid("IOCSR_IPI_SEND", cpuid);
+ return;
+ }
+
/* IPI status vector */
- data = 1 << (val & 0x1f);
+ vector = extract8(val, 0, 5);
+
cs = qemu_get_cpu(cpuid);
cpu = LOONGARCH_CPU(cs);
env = &cpu->env;
address_space_stl(&env->address_space_iocsr, 0x1008,
- data, MEMTXATTRS_UNSPECIFIED, NULL);
-
+ BIT(vector), MEMTXATTRS_UNSPECIFIED, NULL);
}
static void mail_send(uint64_t val)
{
- int cpuid;
+ uint32_t cpuid;
hwaddr addr;
CPULoongArchState *env;
CPUState *cs;
LoongArchCPU *cpu;
- cpuid = (val >> 16) & 0x3ff;
+ cpuid = extract32(val, 16, 10);
+ if (cpuid >= LOONGARCH_MAX_CPUS) {
+ trace_loongarch_ipi_unsupported_cpuid("IOCSR_MAIL_SEND", cpuid);
+ return;
+ }
+
addr = 0x1020 + (val & 0x1c);
cs = qemu_get_cpu(cpuid);
cpu = LOONGARCH_CPU(cs);
@@ -111,14 +122,21 @@ static void mail_send(uint64_t val)
static void any_send(uint64_t val)
{
- int cpuid;
+ uint32_t cpuid;
hwaddr addr;
CPULoongArchState *env;
+ CPUState *cs;
+ LoongArchCPU *cpu;
+
+ cpuid = extract32(val, 16, 10);
+ if (cpuid >= LOONGARCH_MAX_CPUS) {
+ trace_loongarch_ipi_unsupported_cpuid("IOCSR_ANY_SEND", cpuid);
+ return;
+ }
- cpuid = (val >> 16) & 0x3ff;
addr = val & 0xffff;
- CPUState *cs = qemu_get_cpu(cpuid);
- LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+ cs = qemu_get_cpu(cpuid);
+ cpu = LOONGARCH_CPU(cs);
env = &cpu->env;
send_ipi_data(env, val, addr);
}
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 50cadfb..5c6094c 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -292,6 +292,7 @@ sh_intc_set(int id, int enable) "setting interrupt group %d to %d"
# loongarch_ipi.c
loongarch_ipi_read(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%"PRIx64
loongarch_ipi_write(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%"PRIx64
+loongarch_ipi_unsupported_cpuid(const char *s, uint32_t cpuid) "%s unsupported cpuid 0x%" PRIx32
# loongarch_pch_pic.c
loongarch_pch_pic_irq_handler(int irq, int level) "irq %d level %d"