* [PATCH 1/3] hw/loongarch/virt: Modify ipi as percpu device
@ 2023-04-06 10:00 Song Gao
2023-04-06 10:00 ` [PATCH 2/3] hw/intc: Add NULL pointer check on LoongArch ipi device Song Gao
` (3 more replies)
0 siblings, 4 replies; 15+ messages in thread
From: Song Gao @ 2023-04-06 10:00 UTC (permalink / raw)
To: qemu-devel; +Cc: richard.henderson, philmd, maobibo, yangxiaojuan
ipi is used to communicate between cpus, this patch modified
loongarch ipi device as percpu deivce, so that there are
2 MemoryRegions with ipi device, rather than 2*cpus
MemoryRegions, which may be large than QDEV_MAX_MMIO if
more cpus are added on loongarch virt machine.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
hw/intc/loongarch_ipi.c | 32 ++++++++++----------------------
hw/loongarch/virt.c | 12 ++++++------
include/hw/intc/loongarch_ipi.h | 10 ++++------
include/hw/loongarch/virt.h | 1 -
4 files changed, 20 insertions(+), 35 deletions(-)
diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
index aa4bf9eb74..0563d83a35 100644
--- a/hw/intc/loongarch_ipi.c
+++ b/hw/intc/loongarch_ipi.c
@@ -201,27 +201,17 @@ static const MemoryRegionOps loongarch_ipi64_ops = {
static void loongarch_ipi_init(Object *obj)
{
- int cpu;
- LoongArchMachineState *lams;
LoongArchIPI *s = LOONGARCH_IPI(obj);
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
- Object *machine = qdev_get_machine();
- ObjectClass *mc = object_get_class(machine);
- /* 'lams' should be initialized */
- if (!strcmp(MACHINE_CLASS(mc)->name, "none")) {
- return;
- }
- lams = LOONGARCH_MACHINE(machine);
- for (cpu = 0; cpu < MAX_IPI_CORE_NUM; cpu++) {
- memory_region_init_io(&s->ipi_iocsr_mem[cpu], obj, &loongarch_ipi_ops,
- &lams->ipi_core[cpu], "loongarch_ipi_iocsr", 0x48);
- sysbus_init_mmio(sbd, &s->ipi_iocsr_mem[cpu]);
- memory_region_init_io(&s->ipi64_iocsr_mem[cpu], obj, &loongarch_ipi64_ops,
- &lams->ipi_core[cpu], "loongarch_ipi64_iocsr", 0x118);
- sysbus_init_mmio(sbd, &s->ipi64_iocsr_mem[cpu]);
- qdev_init_gpio_out(DEVICE(obj), &lams->ipi_core[cpu].irq, 1);
- }
+ memory_region_init_io(&s->ipi_iocsr_mem, obj, &loongarch_ipi_ops,
+ &s->ipi_core, "loongarch_ipi_iocsr", 0x48);
+ sysbus_init_mmio(sbd, &s->ipi_iocsr_mem);
+
+ memory_region_init_io(&s->ipi64_iocsr_mem, obj, &loongarch_ipi64_ops,
+ &s->ipi_core, "loongarch_ipi64_iocsr", 0x118);
+ sysbus_init_mmio(sbd, &s->ipi64_iocsr_mem);
+ qdev_init_gpio_out(DEVICE(obj), &s->ipi_core.irq, 1);
}
static const VMStateDescription vmstate_ipi_core = {
@@ -233,7 +223,7 @@ static const VMStateDescription vmstate_ipi_core = {
VMSTATE_UINT32(en, IPICore),
VMSTATE_UINT32(set, IPICore),
VMSTATE_UINT32(clear, IPICore),
- VMSTATE_UINT32_ARRAY(buf, IPICore, MAX_IPI_MBX_NUM * 2),
+ VMSTATE_UINT32_ARRAY(buf, IPICore, 2),
VMSTATE_END_OF_LIST()
}
};
@@ -243,9 +233,7 @@ static const VMStateDescription vmstate_loongarch_ipi = {
.version_id = 0,
.minimum_version_id = 0,
.fields = (VMStateField[]) {
- VMSTATE_STRUCT_ARRAY(ipi_core, LoongArchMachineState,
- MAX_IPI_CORE_NUM, 0,
- vmstate_ipi_core, IPICore),
+ VMSTATE_STRUCT(ipi_core, LoongArchIPI, 0, vmstate_ipi_core, IPICore),
VMSTATE_END_OF_LIST()
}
};
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index f4bf14c1c8..c8a01b1fb6 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -565,9 +565,6 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
CPUState *cpu_state;
int cpu, pin, i, start, num;
- ipi = qdev_new(TYPE_LOONGARCH_IPI);
- sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
-
extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
@@ -598,15 +595,18 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
lacpu = LOONGARCH_CPU(cpu_state);
env = &(lacpu->env);
+ ipi = qdev_new(TYPE_LOONGARCH_IPI);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
+
/* connect ipi irq to cpu irq */
- qdev_connect_gpio_out(ipi, cpu, qdev_get_gpio_in(cpudev, IRQ_IPI));
+ qdev_connect_gpio_out(ipi, 0, qdev_get_gpio_in(cpudev, IRQ_IPI));
/* IPI iocsr memory region */
memory_region_add_subregion(&env->system_iocsr, SMP_IPI_MAILBOX,
sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
- cpu * 2));
+ 0));
memory_region_add_subregion(&env->system_iocsr, MAIL_SEND_ADDR,
sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
- cpu * 2 + 1));
+ 1));
/* extioi iocsr memory region */
memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi),
diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h
index 0ee48fca55..664e050b92 100644
--- a/include/hw/intc/loongarch_ipi.h
+++ b/include/hw/intc/loongarch_ipi.h
@@ -28,9 +28,6 @@
#define MAIL_SEND_OFFSET 0
#define ANY_SEND_OFFSET (IOCSR_ANY_SEND - IOCSR_MAIL_SEND)
-#define MAX_IPI_CORE_NUM 4
-#define MAX_IPI_MBX_NUM 4
-
#define TYPE_LOONGARCH_IPI "loongarch_ipi"
OBJECT_DECLARE_SIMPLE_TYPE(LoongArchIPI, LOONGARCH_IPI)
@@ -40,14 +37,15 @@ typedef struct IPICore {
uint32_t set;
uint32_t clear;
/* 64bit buf divide into 2 32bit buf */
- uint32_t buf[MAX_IPI_MBX_NUM * 2];
+ uint32_t buf[2];
qemu_irq irq;
} IPICore;
struct LoongArchIPI {
SysBusDevice parent_obj;
- MemoryRegion ipi_iocsr_mem[MAX_IPI_CORE_NUM];
- MemoryRegion ipi64_iocsr_mem[MAX_IPI_CORE_NUM];
+ MemoryRegion ipi_iocsr_mem;
+ MemoryRegion ipi64_iocsr_mem;
+ IPICore ipi_core;
};
#endif
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 7ae8a91229..54a9f595bb 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -36,7 +36,6 @@ struct LoongArchMachineState {
/*< private >*/
MachineState parent_obj;
- IPICore ipi_core[MAX_IPI_CORE_NUM];
MemoryRegion lowmem;
MemoryRegion highmem;
MemoryRegion isa_io;
--
2.31.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 2/3] hw/intc: Add NULL pointer check on LoongArch ipi device
2023-04-06 10:00 [PATCH 1/3] hw/loongarch/virt: Modify ipi as percpu device Song Gao
@ 2023-04-06 10:00 ` Song Gao
2023-04-26 1:37 ` Song Gao
2023-05-11 19:03 ` Philippe Mathieu-Daudé
2023-04-06 10:00 ` [PATCH 3/3] hw/loongarch/virt: Set max 256 cpus support on loongarch virt machine Song Gao
` (2 subsequent siblings)
3 siblings, 2 replies; 15+ messages in thread
From: Song Gao @ 2023-04-06 10:00 UTC (permalink / raw)
To: qemu-devel; +Cc: richard.henderson, philmd, maobibo, yangxiaojuan
When ipi mailbox is used, cpu index is decoded from iocsr register.
cpu maybe does not exist. This patch adss NULL pointer check on
ipi device.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
hw/intc/loongarch_ipi.c | 31 +++++++++++++++++++------------
1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
index 0563d83a35..39e899df46 100644
--- a/hw/intc/loongarch_ipi.c
+++ b/hw/intc/loongarch_ipi.c
@@ -86,11 +86,12 @@ static void ipi_send(uint64_t val)
/* IPI status vector */
data = 1 << (val & 0x1f);
cs = qemu_get_cpu(cpuid);
- cpu = LOONGARCH_CPU(cs);
- env = &cpu->env;
- address_space_stl(&env->address_space_iocsr, 0x1008,
- data, MEMTXATTRS_UNSPECIFIED, NULL);
-
+ if (cs) {
+ cpu = LOONGARCH_CPU(cs);
+ env = &cpu->env;
+ address_space_stl(&env->address_space_iocsr, 0x1008,
+ data, MEMTXATTRS_UNSPECIFIED, NULL);
+ }
}
static void mail_send(uint64_t val)
@@ -104,9 +105,11 @@ static void mail_send(uint64_t val)
cpuid = (val >> 16) & 0x3ff;
addr = 0x1020 + (val & 0x1c);
cs = qemu_get_cpu(cpuid);
- cpu = LOONGARCH_CPU(cs);
- env = &cpu->env;
- send_ipi_data(env, val, addr);
+ if (cs) {
+ cpu = LOONGARCH_CPU(cs);
+ env = &cpu->env;
+ send_ipi_data(env, val, addr);
+ }
}
static void any_send(uint64_t val)
@@ -114,13 +117,17 @@ static void any_send(uint64_t val)
int cpuid;
hwaddr addr;
CPULoongArchState *env;
+ CPUState *cs;
+ LoongArchCPU *cpu;
cpuid = (val >> 16) & 0x3ff;
addr = val & 0xffff;
- CPUState *cs = qemu_get_cpu(cpuid);
- LoongArchCPU *cpu = LOONGARCH_CPU(cs);
- env = &cpu->env;
- send_ipi_data(env, val, addr);
+ cs = qemu_get_cpu(cpuid);
+ if (cs) {
+ cpu = LOONGARCH_CPU(cs);
+ env = &cpu->env;
+ send_ipi_data(env, val, addr);
+ }
}
static void loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
--
2.31.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 3/3] hw/loongarch/virt: Set max 256 cpus support on loongarch virt machine
2023-04-06 10:00 [PATCH 1/3] hw/loongarch/virt: Modify ipi as percpu device Song Gao
2023-04-06 10:00 ` [PATCH 2/3] hw/intc: Add NULL pointer check on LoongArch ipi device Song Gao
@ 2023-04-06 10:00 ` Song Gao
2023-04-26 1:37 ` Song Gao
2023-05-11 19:07 ` Philippe Mathieu-Daudé
2023-04-26 1:38 ` [PATCH 1/3] hw/loongarch/virt: Modify ipi as percpu device Song Gao
2023-05-11 19:11 ` Philippe Mathieu-Daudé
3 siblings, 2 replies; 15+ messages in thread
From: Song Gao @ 2023-04-06 10:00 UTC (permalink / raw)
To: qemu-devel; +Cc: richard.henderson, philmd, maobibo, yangxiaojuan
Add separate macro EXTIOI_CPUS for extioi interrupt controller, extioi
only supports 4 cpu. And set macro LOONGARCH_MAX_CPUS as 256 so that
loongarch virt machine supports more cpus.
Interrupts from external devices can only be routed cpu 0-3 because
of extioi limits, cpu internal interrupt such as timer/ipi can be
triggered on all cpus.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
hw/intc/loongarch_extioi.c | 4 ++--
hw/loongarch/virt.c | 21 ++++++++++++++-------
include/hw/intc/loongarch_extioi.h | 10 ++++++----
include/hw/loongarch/virt.h | 2 +-
4 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
index 4b8ec3f28a..0e7a3e32f3 100644
--- a/hw/intc/loongarch_extioi.c
+++ b/hw/intc/loongarch_extioi.c
@@ -254,7 +254,7 @@ static const VMStateDescription vmstate_loongarch_extioi = {
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(bounce, LoongArchExtIOI, EXTIOI_IRQS_GROUP_COUNT),
- VMSTATE_UINT32_2DARRAY(coreisr, LoongArchExtIOI, LOONGARCH_MAX_VCPUS,
+ VMSTATE_UINT32_2DARRAY(coreisr, LoongArchExtIOI, EXTIOI_CPUS,
EXTIOI_IRQS_GROUP_COUNT),
VMSTATE_UINT32_ARRAY(nodetype, LoongArchExtIOI,
EXTIOI_IRQS_NODETYPE_COUNT / 2),
@@ -281,7 +281,7 @@ static void loongarch_extioi_instance_init(Object *obj)
qdev_init_gpio_in(DEVICE(obj), extioi_setirq, EXTIOI_IRQS);
- for (cpu = 0; cpu < LOONGARCH_MAX_VCPUS; cpu++) {
+ for (cpu = 0; cpu < EXTIOI_CPUS; cpu++) {
memory_region_init_io(&s->extioi_iocsr_mem[cpu], OBJECT(s), &extioi_ops,
s, "extioi_iocsr", 0x900);
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->extioi_iocsr_mem[cpu]);
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index c8a01b1fb6..28bb35d614 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -607,8 +607,13 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
memory_region_add_subregion(&env->system_iocsr, MAIL_SEND_ADDR,
sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
1));
- /* extioi iocsr memory region */
- memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
+ /*
+ * extioi iocsr memory region
+ * only one extioi is added on loongarch virt machine
+ * external device interrupt can only be routed to cpu 0-3
+ */
+ if (cpu < EXTIOI_CPUS)
+ memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi),
cpu));
}
@@ -618,10 +623,12 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
* cpu_pin[9:2] <= intc_pin[7:0]
*/
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
- cpudev = DEVICE(qemu_get_cpu(cpu));
- for (pin = 0; pin < LS3A_INTC_IP; pin++) {
- qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
- qdev_get_gpio_in(cpudev, pin + 2));
+ if (cpu < EXTIOI_CPUS) {
+ cpudev = DEVICE(qemu_get_cpu(cpu));
+ for (pin = 0; pin < LS3A_INTC_IP; pin++) {
+ qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
+ qdev_get_gpio_in(cpudev, pin + 2));
+ }
}
}
@@ -1026,7 +1033,7 @@ static void loongarch_class_init(ObjectClass *oc, void *data)
mc->default_ram_size = 1 * GiB;
mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("la464");
mc->default_ram_id = "loongarch.ram";
- mc->max_cpus = LOONGARCH_MAX_VCPUS;
+ mc->max_cpus = LOONGARCH_MAX_CPUS;
mc->is_default = 1;
mc->default_kernel_irqchip_split = false;
mc->block_default_type = IF_VIRTIO;
diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h
index 15b8c999f6..fbdef9a7b3 100644
--- a/include/hw/intc/loongarch_extioi.h
+++ b/include/hw/intc/loongarch_extioi.h
@@ -14,6 +14,8 @@
#define LS3A_INTC_IP 8
#define EXTIOI_IRQS (256)
#define EXTIOI_IRQS_BITMAP_SIZE (256 / 8)
+/* irq from EXTIOI is routed to no more than 4 cpus */
+#define EXTIOI_CPUS (4)
/* map to ipnum per 32 irqs */
#define EXTIOI_IRQS_IPMAP_SIZE (256 / 32)
#define EXTIOI_IRQS_COREMAP_SIZE 256
@@ -46,17 +48,17 @@ struct LoongArchExtIOI {
uint32_t nodetype[EXTIOI_IRQS_NODETYPE_COUNT / 2];
uint32_t bounce[EXTIOI_IRQS_GROUP_COUNT];
uint32_t isr[EXTIOI_IRQS / 32];
- uint32_t coreisr[LOONGARCH_MAX_VCPUS][EXTIOI_IRQS_GROUP_COUNT];
+ uint32_t coreisr[EXTIOI_CPUS][EXTIOI_IRQS_GROUP_COUNT];
uint32_t enable[EXTIOI_IRQS / 32];
uint32_t ipmap[EXTIOI_IRQS_IPMAP_SIZE / 4];
uint32_t coremap[EXTIOI_IRQS / 4];
uint32_t sw_pending[EXTIOI_IRQS / 32];
- DECLARE_BITMAP(sw_isr[LOONGARCH_MAX_VCPUS][LS3A_INTC_IP], EXTIOI_IRQS);
+ DECLARE_BITMAP(sw_isr[EXTIOI_CPUS][LS3A_INTC_IP], EXTIOI_IRQS);
uint8_t sw_ipmap[EXTIOI_IRQS_IPMAP_SIZE];
uint8_t sw_coremap[EXTIOI_IRQS];
- qemu_irq parent_irq[LOONGARCH_MAX_VCPUS][LS3A_INTC_IP];
+ qemu_irq parent_irq[EXTIOI_CPUS][LS3A_INTC_IP];
qemu_irq irq[EXTIOI_IRQS];
- MemoryRegion extioi_iocsr_mem[LOONGARCH_MAX_VCPUS];
+ MemoryRegion extioi_iocsr_mem[EXTIOI_CPUS];
MemoryRegion extioi_system_mem;
};
#endif /* LOONGARCH_EXTIOI_H */
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 54a9f595bb..f1659655c6 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -14,7 +14,7 @@
#include "hw/intc/loongarch_ipi.h"
#include "hw/block/flash.h"
-#define LOONGARCH_MAX_VCPUS 4
+#define LOONGARCH_MAX_CPUS 256
#define VIRT_ISA_IO_BASE 0x18000000UL
#define VIRT_ISA_IO_SIZE 0x0004000
--
2.31.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 3/3] hw/loongarch/virt: Set max 256 cpus support on loongarch virt machine
2023-04-06 10:00 ` [PATCH 3/3] hw/loongarch/virt: Set max 256 cpus support on loongarch virt machine Song Gao
@ 2023-04-26 1:37 ` Song Gao
2023-05-08 2:11 ` Song Gao
2023-05-10 10:12 ` Richard Henderson
2023-05-11 19:07 ` Philippe Mathieu-Daudé
1 sibling, 2 replies; 15+ messages in thread
From: Song Gao @ 2023-04-26 1:37 UTC (permalink / raw)
To: qemu-devel; +Cc: richard.henderson, philmd, maobibo, yangxiaojuan
ping~
在 2023/4/6 下午6:00, Song Gao 写道:
> Add separate macro EXTIOI_CPUS for extioi interrupt controller, extioi
> only supports 4 cpu. And set macro LOONGARCH_MAX_CPUS as 256 so that
> loongarch virt machine supports more cpus.
>
> Interrupts from external devices can only be routed cpu 0-3 because
> of extioi limits, cpu internal interrupt such as timer/ipi can be
> triggered on all cpus.
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
> hw/intc/loongarch_extioi.c | 4 ++--
> hw/loongarch/virt.c | 21 ++++++++++++++-------
> include/hw/intc/loongarch_extioi.h | 10 ++++++----
> include/hw/loongarch/virt.h | 2 +-
> 4 files changed, 23 insertions(+), 14 deletions(-)
>
> diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
> index 4b8ec3f28a..0e7a3e32f3 100644
> --- a/hw/intc/loongarch_extioi.c
> +++ b/hw/intc/loongarch_extioi.c
> @@ -254,7 +254,7 @@ static const VMStateDescription vmstate_loongarch_extioi = {
> .minimum_version_id = 1,
> .fields = (VMStateField[]) {
> VMSTATE_UINT32_ARRAY(bounce, LoongArchExtIOI, EXTIOI_IRQS_GROUP_COUNT),
> - VMSTATE_UINT32_2DARRAY(coreisr, LoongArchExtIOI, LOONGARCH_MAX_VCPUS,
> + VMSTATE_UINT32_2DARRAY(coreisr, LoongArchExtIOI, EXTIOI_CPUS,
> EXTIOI_IRQS_GROUP_COUNT),
> VMSTATE_UINT32_ARRAY(nodetype, LoongArchExtIOI,
> EXTIOI_IRQS_NODETYPE_COUNT / 2),
> @@ -281,7 +281,7 @@ static void loongarch_extioi_instance_init(Object *obj)
>
> qdev_init_gpio_in(DEVICE(obj), extioi_setirq, EXTIOI_IRQS);
>
> - for (cpu = 0; cpu < LOONGARCH_MAX_VCPUS; cpu++) {
> + for (cpu = 0; cpu < EXTIOI_CPUS; cpu++) {
> memory_region_init_io(&s->extioi_iocsr_mem[cpu], OBJECT(s), &extioi_ops,
> s, "extioi_iocsr", 0x900);
> sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->extioi_iocsr_mem[cpu]);
> diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
> index c8a01b1fb6..28bb35d614 100644
> --- a/hw/loongarch/virt.c
> +++ b/hw/loongarch/virt.c
> @@ -607,8 +607,13 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
> memory_region_add_subregion(&env->system_iocsr, MAIL_SEND_ADDR,
> sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
> 1));
> - /* extioi iocsr memory region */
> - memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
> + /*
> + * extioi iocsr memory region
> + * only one extioi is added on loongarch virt machine
> + * external device interrupt can only be routed to cpu 0-3
> + */
> + if (cpu < EXTIOI_CPUS)
> + memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
> sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi),
> cpu));
> }
> @@ -618,10 +623,12 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
> * cpu_pin[9:2] <= intc_pin[7:0]
> */
> for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
> - cpudev = DEVICE(qemu_get_cpu(cpu));
> - for (pin = 0; pin < LS3A_INTC_IP; pin++) {
> - qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
> - qdev_get_gpio_in(cpudev, pin + 2));
> + if (cpu < EXTIOI_CPUS) {
> + cpudev = DEVICE(qemu_get_cpu(cpu));
> + for (pin = 0; pin < LS3A_INTC_IP; pin++) {
> + qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
> + qdev_get_gpio_in(cpudev, pin + 2));
> + }
> }
> }
>
> @@ -1026,7 +1033,7 @@ static void loongarch_class_init(ObjectClass *oc, void *data)
> mc->default_ram_size = 1 * GiB;
> mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("la464");
> mc->default_ram_id = "loongarch.ram";
> - mc->max_cpus = LOONGARCH_MAX_VCPUS;
> + mc->max_cpus = LOONGARCH_MAX_CPUS;
> mc->is_default = 1;
> mc->default_kernel_irqchip_split = false;
> mc->block_default_type = IF_VIRTIO;
> diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h
> index 15b8c999f6..fbdef9a7b3 100644
> --- a/include/hw/intc/loongarch_extioi.h
> +++ b/include/hw/intc/loongarch_extioi.h
> @@ -14,6 +14,8 @@
> #define LS3A_INTC_IP 8
> #define EXTIOI_IRQS (256)
> #define EXTIOI_IRQS_BITMAP_SIZE (256 / 8)
> +/* irq from EXTIOI is routed to no more than 4 cpus */
> +#define EXTIOI_CPUS (4)
> /* map to ipnum per 32 irqs */
> #define EXTIOI_IRQS_IPMAP_SIZE (256 / 32)
> #define EXTIOI_IRQS_COREMAP_SIZE 256
> @@ -46,17 +48,17 @@ struct LoongArchExtIOI {
> uint32_t nodetype[EXTIOI_IRQS_NODETYPE_COUNT / 2];
> uint32_t bounce[EXTIOI_IRQS_GROUP_COUNT];
> uint32_t isr[EXTIOI_IRQS / 32];
> - uint32_t coreisr[LOONGARCH_MAX_VCPUS][EXTIOI_IRQS_GROUP_COUNT];
> + uint32_t coreisr[EXTIOI_CPUS][EXTIOI_IRQS_GROUP_COUNT];
> uint32_t enable[EXTIOI_IRQS / 32];
> uint32_t ipmap[EXTIOI_IRQS_IPMAP_SIZE / 4];
> uint32_t coremap[EXTIOI_IRQS / 4];
> uint32_t sw_pending[EXTIOI_IRQS / 32];
> - DECLARE_BITMAP(sw_isr[LOONGARCH_MAX_VCPUS][LS3A_INTC_IP], EXTIOI_IRQS);
> + DECLARE_BITMAP(sw_isr[EXTIOI_CPUS][LS3A_INTC_IP], EXTIOI_IRQS);
> uint8_t sw_ipmap[EXTIOI_IRQS_IPMAP_SIZE];
> uint8_t sw_coremap[EXTIOI_IRQS];
> - qemu_irq parent_irq[LOONGARCH_MAX_VCPUS][LS3A_INTC_IP];
> + qemu_irq parent_irq[EXTIOI_CPUS][LS3A_INTC_IP];
> qemu_irq irq[EXTIOI_IRQS];
> - MemoryRegion extioi_iocsr_mem[LOONGARCH_MAX_VCPUS];
> + MemoryRegion extioi_iocsr_mem[EXTIOI_CPUS];
> MemoryRegion extioi_system_mem;
> };
> #endif /* LOONGARCH_EXTIOI_H */
> diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
> index 54a9f595bb..f1659655c6 100644
> --- a/include/hw/loongarch/virt.h
> +++ b/include/hw/loongarch/virt.h
> @@ -14,7 +14,7 @@
> #include "hw/intc/loongarch_ipi.h"
> #include "hw/block/flash.h"
>
> -#define LOONGARCH_MAX_VCPUS 4
> +#define LOONGARCH_MAX_CPUS 256
>
> #define VIRT_ISA_IO_BASE 0x18000000UL
> #define VIRT_ISA_IO_SIZE 0x0004000
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/3] hw/intc: Add NULL pointer check on LoongArch ipi device
2023-04-06 10:00 ` [PATCH 2/3] hw/intc: Add NULL pointer check on LoongArch ipi device Song Gao
@ 2023-04-26 1:37 ` Song Gao
2023-05-11 19:03 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 15+ messages in thread
From: Song Gao @ 2023-04-26 1:37 UTC (permalink / raw)
To: qemu-devel; +Cc: richard.henderson, philmd, maobibo, yangxiaojuan
ping ~
在 2023/4/6 下午6:00, Song Gao 写道:
> When ipi mailbox is used, cpu index is decoded from iocsr register.
> cpu maybe does not exist. This patch adss NULL pointer check on
> ipi device.
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
> hw/intc/loongarch_ipi.c | 31 +++++++++++++++++++------------
> 1 file changed, 19 insertions(+), 12 deletions(-)
>
> diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
> index 0563d83a35..39e899df46 100644
> --- a/hw/intc/loongarch_ipi.c
> +++ b/hw/intc/loongarch_ipi.c
> @@ -86,11 +86,12 @@ static void ipi_send(uint64_t val)
> /* IPI status vector */
> data = 1 << (val & 0x1f);
> cs = qemu_get_cpu(cpuid);
> - cpu = LOONGARCH_CPU(cs);
> - env = &cpu->env;
> - address_space_stl(&env->address_space_iocsr, 0x1008,
> - data, MEMTXATTRS_UNSPECIFIED, NULL);
> -
> + if (cs) {
> + cpu = LOONGARCH_CPU(cs);
> + env = &cpu->env;
> + address_space_stl(&env->address_space_iocsr, 0x1008,
> + data, MEMTXATTRS_UNSPECIFIED, NULL);
> + }
> }
>
> static void mail_send(uint64_t val)
> @@ -104,9 +105,11 @@ static void mail_send(uint64_t val)
> cpuid = (val >> 16) & 0x3ff;
> addr = 0x1020 + (val & 0x1c);
> cs = qemu_get_cpu(cpuid);
> - cpu = LOONGARCH_CPU(cs);
> - env = &cpu->env;
> - send_ipi_data(env, val, addr);
> + if (cs) {
> + cpu = LOONGARCH_CPU(cs);
> + env = &cpu->env;
> + send_ipi_data(env, val, addr);
> + }
> }
>
> static void any_send(uint64_t val)
> @@ -114,13 +117,17 @@ static void any_send(uint64_t val)
> int cpuid;
> hwaddr addr;
> CPULoongArchState *env;
> + CPUState *cs;
> + LoongArchCPU *cpu;
>
> cpuid = (val >> 16) & 0x3ff;
> addr = val & 0xffff;
> - CPUState *cs = qemu_get_cpu(cpuid);
> - LoongArchCPU *cpu = LOONGARCH_CPU(cs);
> - env = &cpu->env;
> - send_ipi_data(env, val, addr);
> + cs = qemu_get_cpu(cpuid);
> + if (cs) {
> + cpu = LOONGARCH_CPU(cs);
> + env = &cpu->env;
> + send_ipi_data(env, val, addr);
> + }
> }
>
> static void loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 1/3] hw/loongarch/virt: Modify ipi as percpu device
2023-04-06 10:00 [PATCH 1/3] hw/loongarch/virt: Modify ipi as percpu device Song Gao
2023-04-06 10:00 ` [PATCH 2/3] hw/intc: Add NULL pointer check on LoongArch ipi device Song Gao
2023-04-06 10:00 ` [PATCH 3/3] hw/loongarch/virt: Set max 256 cpus support on loongarch virt machine Song Gao
@ 2023-04-26 1:38 ` Song Gao
2023-05-11 19:11 ` Philippe Mathieu-Daudé
3 siblings, 0 replies; 15+ messages in thread
From: Song Gao @ 2023-04-26 1:38 UTC (permalink / raw)
To: qemu-devel; +Cc: richard.henderson, philmd, maobibo, yangxiaojuan
ping ~
在 2023/4/6 下午6:00, Song Gao 写道:
> ipi is used to communicate between cpus, this patch modified
> loongarch ipi device as percpu deivce, so that there are
> 2 MemoryRegions with ipi device, rather than 2*cpus
> MemoryRegions, which may be large than QDEV_MAX_MMIO if
> more cpus are added on loongarch virt machine.
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
> hw/intc/loongarch_ipi.c | 32 ++++++++++----------------------
> hw/loongarch/virt.c | 12 ++++++------
> include/hw/intc/loongarch_ipi.h | 10 ++++------
> include/hw/loongarch/virt.h | 1 -
> 4 files changed, 20 insertions(+), 35 deletions(-)
>
> diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
> index aa4bf9eb74..0563d83a35 100644
> --- a/hw/intc/loongarch_ipi.c
> +++ b/hw/intc/loongarch_ipi.c
> @@ -201,27 +201,17 @@ static const MemoryRegionOps loongarch_ipi64_ops = {
>
> static void loongarch_ipi_init(Object *obj)
> {
> - int cpu;
> - LoongArchMachineState *lams;
> LoongArchIPI *s = LOONGARCH_IPI(obj);
> SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
> - Object *machine = qdev_get_machine();
> - ObjectClass *mc = object_get_class(machine);
> - /* 'lams' should be initialized */
> - if (!strcmp(MACHINE_CLASS(mc)->name, "none")) {
> - return;
> - }
> - lams = LOONGARCH_MACHINE(machine);
> - for (cpu = 0; cpu < MAX_IPI_CORE_NUM; cpu++) {
> - memory_region_init_io(&s->ipi_iocsr_mem[cpu], obj, &loongarch_ipi_ops,
> - &lams->ipi_core[cpu], "loongarch_ipi_iocsr", 0x48);
> - sysbus_init_mmio(sbd, &s->ipi_iocsr_mem[cpu]);
>
> - memory_region_init_io(&s->ipi64_iocsr_mem[cpu], obj, &loongarch_ipi64_ops,
> - &lams->ipi_core[cpu], "loongarch_ipi64_iocsr", 0x118);
> - sysbus_init_mmio(sbd, &s->ipi64_iocsr_mem[cpu]);
> - qdev_init_gpio_out(DEVICE(obj), &lams->ipi_core[cpu].irq, 1);
> - }
> + memory_region_init_io(&s->ipi_iocsr_mem, obj, &loongarch_ipi_ops,
> + &s->ipi_core, "loongarch_ipi_iocsr", 0x48);
> + sysbus_init_mmio(sbd, &s->ipi_iocsr_mem);
> +
> + memory_region_init_io(&s->ipi64_iocsr_mem, obj, &loongarch_ipi64_ops,
> + &s->ipi_core, "loongarch_ipi64_iocsr", 0x118);
> + sysbus_init_mmio(sbd, &s->ipi64_iocsr_mem);
> + qdev_init_gpio_out(DEVICE(obj), &s->ipi_core.irq, 1);
> }
>
> static const VMStateDescription vmstate_ipi_core = {
> @@ -233,7 +223,7 @@ static const VMStateDescription vmstate_ipi_core = {
> VMSTATE_UINT32(en, IPICore),
> VMSTATE_UINT32(set, IPICore),
> VMSTATE_UINT32(clear, IPICore),
> - VMSTATE_UINT32_ARRAY(buf, IPICore, MAX_IPI_MBX_NUM * 2),
> + VMSTATE_UINT32_ARRAY(buf, IPICore, 2),
> VMSTATE_END_OF_LIST()
> }
> };
> @@ -243,9 +233,7 @@ static const VMStateDescription vmstate_loongarch_ipi = {
> .version_id = 0,
> .minimum_version_id = 0,
> .fields = (VMStateField[]) {
> - VMSTATE_STRUCT_ARRAY(ipi_core, LoongArchMachineState,
> - MAX_IPI_CORE_NUM, 0,
> - vmstate_ipi_core, IPICore),
> + VMSTATE_STRUCT(ipi_core, LoongArchIPI, 0, vmstate_ipi_core, IPICore),
> VMSTATE_END_OF_LIST()
> }
> };
> diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
> index f4bf14c1c8..c8a01b1fb6 100644
> --- a/hw/loongarch/virt.c
> +++ b/hw/loongarch/virt.c
> @@ -565,9 +565,6 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
> CPUState *cpu_state;
> int cpu, pin, i, start, num;
>
> - ipi = qdev_new(TYPE_LOONGARCH_IPI);
> - sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
> -
> extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
> sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
>
> @@ -598,15 +595,18 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
> lacpu = LOONGARCH_CPU(cpu_state);
> env = &(lacpu->env);
>
> + ipi = qdev_new(TYPE_LOONGARCH_IPI);
> + sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
> +
> /* connect ipi irq to cpu irq */
> - qdev_connect_gpio_out(ipi, cpu, qdev_get_gpio_in(cpudev, IRQ_IPI));
> + qdev_connect_gpio_out(ipi, 0, qdev_get_gpio_in(cpudev, IRQ_IPI));
> /* IPI iocsr memory region */
> memory_region_add_subregion(&env->system_iocsr, SMP_IPI_MAILBOX,
> sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
> - cpu * 2));
> + 0));
> memory_region_add_subregion(&env->system_iocsr, MAIL_SEND_ADDR,
> sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
> - cpu * 2 + 1));
> + 1));
> /* extioi iocsr memory region */
> memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
> sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi),
> diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h
> index 0ee48fca55..664e050b92 100644
> --- a/include/hw/intc/loongarch_ipi.h
> +++ b/include/hw/intc/loongarch_ipi.h
> @@ -28,9 +28,6 @@
> #define MAIL_SEND_OFFSET 0
> #define ANY_SEND_OFFSET (IOCSR_ANY_SEND - IOCSR_MAIL_SEND)
>
> -#define MAX_IPI_CORE_NUM 4
> -#define MAX_IPI_MBX_NUM 4
> -
> #define TYPE_LOONGARCH_IPI "loongarch_ipi"
> OBJECT_DECLARE_SIMPLE_TYPE(LoongArchIPI, LOONGARCH_IPI)
>
> @@ -40,14 +37,15 @@ typedef struct IPICore {
> uint32_t set;
> uint32_t clear;
> /* 64bit buf divide into 2 32bit buf */
> - uint32_t buf[MAX_IPI_MBX_NUM * 2];
> + uint32_t buf[2];
> qemu_irq irq;
> } IPICore;
>
> struct LoongArchIPI {
> SysBusDevice parent_obj;
> - MemoryRegion ipi_iocsr_mem[MAX_IPI_CORE_NUM];
> - MemoryRegion ipi64_iocsr_mem[MAX_IPI_CORE_NUM];
> + MemoryRegion ipi_iocsr_mem;
> + MemoryRegion ipi64_iocsr_mem;
> + IPICore ipi_core;
> };
>
> #endif
> diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
> index 7ae8a91229..54a9f595bb 100644
> --- a/include/hw/loongarch/virt.h
> +++ b/include/hw/loongarch/virt.h
> @@ -36,7 +36,6 @@ struct LoongArchMachineState {
> /*< private >*/
> MachineState parent_obj;
>
> - IPICore ipi_core[MAX_IPI_CORE_NUM];
> MemoryRegion lowmem;
> MemoryRegion highmem;
> MemoryRegion isa_io;
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 3/3] hw/loongarch/virt: Set max 256 cpus support on loongarch virt machine
2023-04-26 1:37 ` Song Gao
@ 2023-05-08 2:11 ` Song Gao
2023-05-10 10:12 ` Richard Henderson
1 sibling, 0 replies; 15+ messages in thread
From: Song Gao @ 2023-05-08 2:11 UTC (permalink / raw)
To: qemu-devel; +Cc: richard.henderson, philmd, maobibo, yangxiaojuan
ping~~
在 2023/4/26 上午9:37, Song Gao 写道:
> ping~
>
> 在 2023/4/6 下午6:00, Song Gao 写道:
>> Add separate macro EXTIOI_CPUS for extioi interrupt controller, extioi
>> only supports 4 cpu. And set macro LOONGARCH_MAX_CPUS as 256 so that
>> loongarch virt machine supports more cpus.
>>
>> Interrupts from external devices can only be routed cpu 0-3 because
>> of extioi limits, cpu internal interrupt such as timer/ipi can be
>> triggered on all cpus.
>>
>> Signed-off-by: Song Gao <gaosong@loongson.cn>
>> ---
>> hw/intc/loongarch_extioi.c | 4 ++--
>> hw/loongarch/virt.c | 21 ++++++++++++++-------
>> include/hw/intc/loongarch_extioi.h | 10 ++++++----
>> include/hw/loongarch/virt.h | 2 +-
>> 4 files changed, 23 insertions(+), 14 deletions(-)
>>
>> diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
>> index 4b8ec3f28a..0e7a3e32f3 100644
>> --- a/hw/intc/loongarch_extioi.c
>> +++ b/hw/intc/loongarch_extioi.c
>> @@ -254,7 +254,7 @@ static const VMStateDescription
>> vmstate_loongarch_extioi = {
>> .minimum_version_id = 1,
>> .fields = (VMStateField[]) {
>> VMSTATE_UINT32_ARRAY(bounce, LoongArchExtIOI,
>> EXTIOI_IRQS_GROUP_COUNT),
>> - VMSTATE_UINT32_2DARRAY(coreisr, LoongArchExtIOI,
>> LOONGARCH_MAX_VCPUS,
>> + VMSTATE_UINT32_2DARRAY(coreisr, LoongArchExtIOI, EXTIOI_CPUS,
>> EXTIOI_IRQS_GROUP_COUNT),
>> VMSTATE_UINT32_ARRAY(nodetype, LoongArchExtIOI,
>> EXTIOI_IRQS_NODETYPE_COUNT / 2),
>> @@ -281,7 +281,7 @@ static void loongarch_extioi_instance_init(Object
>> *obj)
>> qdev_init_gpio_in(DEVICE(obj), extioi_setirq, EXTIOI_IRQS);
>> - for (cpu = 0; cpu < LOONGARCH_MAX_VCPUS; cpu++) {
>> + for (cpu = 0; cpu < EXTIOI_CPUS; cpu++) {
>> memory_region_init_io(&s->extioi_iocsr_mem[cpu], OBJECT(s), &extioi_ops,
>> s, "extioi_iocsr", 0x900);
>> sysbus_init_mmio(SYS_BUS_DEVICE(dev),
>> &s->extioi_iocsr_mem[cpu]);
>> diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
>> index c8a01b1fb6..28bb35d614 100644
>> --- a/hw/loongarch/virt.c
>> +++ b/hw/loongarch/virt.c
>> @@ -607,8 +607,13 @@ static void
>> loongarch_irq_init(LoongArchMachineState *lams)
>> memory_region_add_subregion(&env->system_iocsr,
>> MAIL_SEND_ADDR,
>> sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
>> 1));
>> - /* extioi iocsr memory region */
>> - memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
>> + /*
>> + * extioi iocsr memory region
>> + * only one extioi is added on loongarch virt machine
>> + * external device interrupt can only be routed to cpu 0-3
>> + */
>> + if (cpu < EXTIOI_CPUS)
>> + memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
>> sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi),
>> cpu));
>> }
>> @@ -618,10 +623,12 @@ static void
>> loongarch_irq_init(LoongArchMachineState *lams)
>> * cpu_pin[9:2] <= intc_pin[7:0]
>> */
>> for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
>> - cpudev = DEVICE(qemu_get_cpu(cpu));
>> - for (pin = 0; pin < LS3A_INTC_IP; pin++) {
>> - qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
>> - qdev_get_gpio_in(cpudev, pin + 2));
>> + if (cpu < EXTIOI_CPUS) {
>> + cpudev = DEVICE(qemu_get_cpu(cpu));
>> + for (pin = 0; pin < LS3A_INTC_IP; pin++) {
>> + qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
>> + qdev_get_gpio_in(cpudev, pin +
>> 2));
>> + }
>> }
>> }
>> @@ -1026,7 +1033,7 @@ static void loongarch_class_init(ObjectClass
>> *oc, void *data)
>> mc->default_ram_size = 1 * GiB;
>> mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("la464");
>> mc->default_ram_id = "loongarch.ram";
>> - mc->max_cpus = LOONGARCH_MAX_VCPUS;
>> + mc->max_cpus = LOONGARCH_MAX_CPUS;
>> mc->is_default = 1;
>> mc->default_kernel_irqchip_split = false;
>> mc->block_default_type = IF_VIRTIO;
>> diff --git a/include/hw/intc/loongarch_extioi.h
>> b/include/hw/intc/loongarch_extioi.h
>> index 15b8c999f6..fbdef9a7b3 100644
>> --- a/include/hw/intc/loongarch_extioi.h
>> +++ b/include/hw/intc/loongarch_extioi.h
>> @@ -14,6 +14,8 @@
>> #define LS3A_INTC_IP 8
>> #define EXTIOI_IRQS (256)
>> #define EXTIOI_IRQS_BITMAP_SIZE (256 / 8)
>> +/* irq from EXTIOI is routed to no more than 4 cpus */
>> +#define EXTIOI_CPUS (4)
>> /* map to ipnum per 32 irqs */
>> #define EXTIOI_IRQS_IPMAP_SIZE (256 / 32)
>> #define EXTIOI_IRQS_COREMAP_SIZE 256
>> @@ -46,17 +48,17 @@ struct LoongArchExtIOI {
>> uint32_t nodetype[EXTIOI_IRQS_NODETYPE_COUNT / 2];
>> uint32_t bounce[EXTIOI_IRQS_GROUP_COUNT];
>> uint32_t isr[EXTIOI_IRQS / 32];
>> - uint32_t coreisr[LOONGARCH_MAX_VCPUS][EXTIOI_IRQS_GROUP_COUNT];
>> + uint32_t coreisr[EXTIOI_CPUS][EXTIOI_IRQS_GROUP_COUNT];
>> uint32_t enable[EXTIOI_IRQS / 32];
>> uint32_t ipmap[EXTIOI_IRQS_IPMAP_SIZE / 4];
>> uint32_t coremap[EXTIOI_IRQS / 4];
>> uint32_t sw_pending[EXTIOI_IRQS / 32];
>> - DECLARE_BITMAP(sw_isr[LOONGARCH_MAX_VCPUS][LS3A_INTC_IP],
>> EXTIOI_IRQS);
>> + DECLARE_BITMAP(sw_isr[EXTIOI_CPUS][LS3A_INTC_IP], EXTIOI_IRQS);
>> uint8_t sw_ipmap[EXTIOI_IRQS_IPMAP_SIZE];
>> uint8_t sw_coremap[EXTIOI_IRQS];
>> - qemu_irq parent_irq[LOONGARCH_MAX_VCPUS][LS3A_INTC_IP];
>> + qemu_irq parent_irq[EXTIOI_CPUS][LS3A_INTC_IP];
>> qemu_irq irq[EXTIOI_IRQS];
>> - MemoryRegion extioi_iocsr_mem[LOONGARCH_MAX_VCPUS];
>> + MemoryRegion extioi_iocsr_mem[EXTIOI_CPUS];
>> MemoryRegion extioi_system_mem;
>> };
>> #endif /* LOONGARCH_EXTIOI_H */
>> diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
>> index 54a9f595bb..f1659655c6 100644
>> --- a/include/hw/loongarch/virt.h
>> +++ b/include/hw/loongarch/virt.h
>> @@ -14,7 +14,7 @@
>> #include "hw/intc/loongarch_ipi.h"
>> #include "hw/block/flash.h"
>> -#define LOONGARCH_MAX_VCPUS 4
>> +#define LOONGARCH_MAX_CPUS 256
>> #define VIRT_ISA_IO_BASE 0x18000000UL
>> #define VIRT_ISA_IO_SIZE 0x0004000
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 3/3] hw/loongarch/virt: Set max 256 cpus support on loongarch virt machine
2023-04-26 1:37 ` Song Gao
2023-05-08 2:11 ` Song Gao
@ 2023-05-10 10:12 ` Richard Henderson
2023-05-11 12:22 ` Song Gao
1 sibling, 1 reply; 15+ messages in thread
From: Richard Henderson @ 2023-05-10 10:12 UTC (permalink / raw)
To: Song Gao, qemu-devel; +Cc: philmd, maobibo, yangxiaojuan
On 4/26/23 02:37, Song Gao wrote:
> ping~
>
> 在 2023/4/6 下午6:00, Song Gao 写道:
>> Add separate macro EXTIOI_CPUS for extioi interrupt controller, extioi
>> only supports 4 cpu. And set macro LOONGARCH_MAX_CPUS as 256 so that
>> loongarch virt machine supports more cpus.
>>
>> Interrupts from external devices can only be routed cpu 0-3 because
>> of extioi limits, cpu internal interrupt such as timer/ipi can be
>> triggered on all cpus.
>>
>> Signed-off-by: Song Gao <gaosong@loongson.cn>
>> ---
>> hw/intc/loongarch_extioi.c | 4 ++--
>> hw/loongarch/virt.c | 21 ++++++++++++++-------
>> include/hw/intc/loongarch_extioi.h | 10 ++++++----
>> include/hw/loongarch/virt.h | 2 +-
>> 4 files changed, 23 insertions(+), 14 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
>>
>> diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
>> index 4b8ec3f28a..0e7a3e32f3 100644
>> --- a/hw/intc/loongarch_extioi.c
>> +++ b/hw/intc/loongarch_extioi.c
>> @@ -254,7 +254,7 @@ static const VMStateDescription vmstate_loongarch_extioi = {
>> .minimum_version_id = 1,
>> .fields = (VMStateField[]) {
>> VMSTATE_UINT32_ARRAY(bounce, LoongArchExtIOI, EXTIOI_IRQS_GROUP_COUNT),
>> - VMSTATE_UINT32_2DARRAY(coreisr, LoongArchExtIOI, LOONGARCH_MAX_VCPUS,
>> + VMSTATE_UINT32_2DARRAY(coreisr, LoongArchExtIOI, EXTIOI_CPUS,
>> EXTIOI_IRQS_GROUP_COUNT),
>> VMSTATE_UINT32_ARRAY(nodetype, LoongArchExtIOI,
>> EXTIOI_IRQS_NODETYPE_COUNT / 2),
>> @@ -281,7 +281,7 @@ static void loongarch_extioi_instance_init(Object *obj)
>> qdev_init_gpio_in(DEVICE(obj), extioi_setirq, EXTIOI_IRQS);
>> - for (cpu = 0; cpu < LOONGARCH_MAX_VCPUS; cpu++) {
>> + for (cpu = 0; cpu < EXTIOI_CPUS; cpu++) {
>> memory_region_init_io(&s->extioi_iocsr_mem[cpu], OBJECT(s), &extioi_ops,
>> s, "extioi_iocsr", 0x900);
>> sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->extioi_iocsr_mem[cpu]);
>> diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
>> index c8a01b1fb6..28bb35d614 100644
>> --- a/hw/loongarch/virt.c
>> +++ b/hw/loongarch/virt.c
>> @@ -607,8 +607,13 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
>> memory_region_add_subregion(&env->system_iocsr, MAIL_SEND_ADDR,
>> sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
>> 1));
>> - /* extioi iocsr memory region */
>> - memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
>> + /*
>> + * extioi iocsr memory region
>> + * only one extioi is added on loongarch virt machine
>> + * external device interrupt can only be routed to cpu 0-3
>> + */
>> + if (cpu < EXTIOI_CPUS)
>> + memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
>> sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi),
>> cpu));
>> }
>> @@ -618,10 +623,12 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
>> * cpu_pin[9:2] <= intc_pin[7:0]
>> */
>> for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
>> - cpudev = DEVICE(qemu_get_cpu(cpu));
>> - for (pin = 0; pin < LS3A_INTC_IP; pin++) {
>> - qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
>> - qdev_get_gpio_in(cpudev, pin + 2));
>> + if (cpu < EXTIOI_CPUS) {
>> + cpudev = DEVICE(qemu_get_cpu(cpu));
>> + for (pin = 0; pin < LS3A_INTC_IP; pin++) {
>> + qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
>> + qdev_get_gpio_in(cpudev, pin + 2));
>> + }
>> }
>> }
>> @@ -1026,7 +1033,7 @@ static void loongarch_class_init(ObjectClass *oc, void *data)
>> mc->default_ram_size = 1 * GiB;
>> mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("la464");
>> mc->default_ram_id = "loongarch.ram";
>> - mc->max_cpus = LOONGARCH_MAX_VCPUS;
>> + mc->max_cpus = LOONGARCH_MAX_CPUS;
>> mc->is_default = 1;
>> mc->default_kernel_irqchip_split = false;
>> mc->block_default_type = IF_VIRTIO;
>> diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h
>> index 15b8c999f6..fbdef9a7b3 100644
>> --- a/include/hw/intc/loongarch_extioi.h
>> +++ b/include/hw/intc/loongarch_extioi.h
>> @@ -14,6 +14,8 @@
>> #define LS3A_INTC_IP 8
>> #define EXTIOI_IRQS (256)
>> #define EXTIOI_IRQS_BITMAP_SIZE (256 / 8)
>> +/* irq from EXTIOI is routed to no more than 4 cpus */
>> +#define EXTIOI_CPUS (4)
>> /* map to ipnum per 32 irqs */
>> #define EXTIOI_IRQS_IPMAP_SIZE (256 / 32)
>> #define EXTIOI_IRQS_COREMAP_SIZE 256
>> @@ -46,17 +48,17 @@ struct LoongArchExtIOI {
>> uint32_t nodetype[EXTIOI_IRQS_NODETYPE_COUNT / 2];
>> uint32_t bounce[EXTIOI_IRQS_GROUP_COUNT];
>> uint32_t isr[EXTIOI_IRQS / 32];
>> - uint32_t coreisr[LOONGARCH_MAX_VCPUS][EXTIOI_IRQS_GROUP_COUNT];
>> + uint32_t coreisr[EXTIOI_CPUS][EXTIOI_IRQS_GROUP_COUNT];
>> uint32_t enable[EXTIOI_IRQS / 32];
>> uint32_t ipmap[EXTIOI_IRQS_IPMAP_SIZE / 4];
>> uint32_t coremap[EXTIOI_IRQS / 4];
>> uint32_t sw_pending[EXTIOI_IRQS / 32];
>> - DECLARE_BITMAP(sw_isr[LOONGARCH_MAX_VCPUS][LS3A_INTC_IP], EXTIOI_IRQS);
>> + DECLARE_BITMAP(sw_isr[EXTIOI_CPUS][LS3A_INTC_IP], EXTIOI_IRQS);
>> uint8_t sw_ipmap[EXTIOI_IRQS_IPMAP_SIZE];
>> uint8_t sw_coremap[EXTIOI_IRQS];
>> - qemu_irq parent_irq[LOONGARCH_MAX_VCPUS][LS3A_INTC_IP];
>> + qemu_irq parent_irq[EXTIOI_CPUS][LS3A_INTC_IP];
>> qemu_irq irq[EXTIOI_IRQS];
>> - MemoryRegion extioi_iocsr_mem[LOONGARCH_MAX_VCPUS];
>> + MemoryRegion extioi_iocsr_mem[EXTIOI_CPUS];
>> MemoryRegion extioi_system_mem;
>> };
>> #endif /* LOONGARCH_EXTIOI_H */
>> diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
>> index 54a9f595bb..f1659655c6 100644
>> --- a/include/hw/loongarch/virt.h
>> +++ b/include/hw/loongarch/virt.h
>> @@ -14,7 +14,7 @@
>> #include "hw/intc/loongarch_ipi.h"
>> #include "hw/block/flash.h"
>> -#define LOONGARCH_MAX_VCPUS 4
>> +#define LOONGARCH_MAX_CPUS 256
>> #define VIRT_ISA_IO_BASE 0x18000000UL
>> #define VIRT_ISA_IO_SIZE 0x0004000
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 3/3] hw/loongarch/virt: Set max 256 cpus support on loongarch virt machine
2023-05-10 10:12 ` Richard Henderson
@ 2023-05-11 12:22 ` Song Gao
0 siblings, 0 replies; 15+ messages in thread
From: Song Gao @ 2023-05-11 12:22 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: philmd, maobibo, yangxiaojuan
Hi, Richard
在 2023/5/10 下午6:12, Richard Henderson 写道:
> On 4/26/23 02:37, Song Gao wrote:
>> ping~
>>
>> 在 2023/4/6 下午6:00, Song Gao 写道:
>>> Add separate macro EXTIOI_CPUS for extioi interrupt controller, extioi
>>> only supports 4 cpu. And set macro LOONGARCH_MAX_CPUS as 256 so that
>>> loongarch virt machine supports more cpus.
>>>
>>> Interrupts from external devices can only be routed cpu 0-3 because
>>> of extioi limits, cpu internal interrupt such as timer/ipi can be
>>> triggered on all cpus.
>>>
>>> Signed-off-by: Song Gao <gaosong@loongson.cn>
>>> ---
>>> hw/intc/loongarch_extioi.c | 4 ++--
>>> hw/loongarch/virt.c | 21 ++++++++++++++-------
>>> include/hw/intc/loongarch_extioi.h | 10 ++++++----
>>> include/hw/loongarch/virt.h | 2 +-
>>> 4 files changed, 23 insertions(+), 14 deletions(-)
>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>
>
Thanks for you review.
Could you also review the other 2 patches?
Thanks.
Song Gao
> r~
>
>>>
>>> diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
>>> index 4b8ec3f28a..0e7a3e32f3 100644
>>> --- a/hw/intc/loongarch_extioi.c
>>> +++ b/hw/intc/loongarch_extioi.c
>>> @@ -254,7 +254,7 @@ static const VMStateDescription
>>> vmstate_loongarch_extioi = {
>>> .minimum_version_id = 1,
>>> .fields = (VMStateField[]) {
>>> VMSTATE_UINT32_ARRAY(bounce, LoongArchExtIOI,
>>> EXTIOI_IRQS_GROUP_COUNT),
>>> - VMSTATE_UINT32_2DARRAY(coreisr, LoongArchExtIOI,
>>> LOONGARCH_MAX_VCPUS,
>>> + VMSTATE_UINT32_2DARRAY(coreisr, LoongArchExtIOI, EXTIOI_CPUS,
>>> EXTIOI_IRQS_GROUP_COUNT),
>>> VMSTATE_UINT32_ARRAY(nodetype, LoongArchExtIOI,
>>> EXTIOI_IRQS_NODETYPE_COUNT / 2),
>>> @@ -281,7 +281,7 @@ static void
>>> loongarch_extioi_instance_init(Object *obj)
>>> qdev_init_gpio_in(DEVICE(obj), extioi_setirq, EXTIOI_IRQS);
>>> - for (cpu = 0; cpu < LOONGARCH_MAX_VCPUS; cpu++) {
>>> + for (cpu = 0; cpu < EXTIOI_CPUS; cpu++) {
>>> memory_region_init_io(&s->extioi_iocsr_mem[cpu], OBJECT(s),
>>> &extioi_ops,
>>> s, "extioi_iocsr", 0x900);
>>> sysbus_init_mmio(SYS_BUS_DEVICE(dev),
>>> &s->extioi_iocsr_mem[cpu]);
>>> diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
>>> index c8a01b1fb6..28bb35d614 100644
>>> --- a/hw/loongarch/virt.c
>>> +++ b/hw/loongarch/virt.c
>>> @@ -607,8 +607,13 @@ static void
>>> loongarch_irq_init(LoongArchMachineState *lams)
>>> memory_region_add_subregion(&env->system_iocsr, MAIL_SEND_ADDR,
>>> sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
>>> 1));
>>> - /* extioi iocsr memory region */
>>> - memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
>>> + /*
>>> + * extioi iocsr memory region
>>> + * only one extioi is added on loongarch virt machine
>>> + * external device interrupt can only be routed to cpu 0-3
>>> + */
>>> + if (cpu < EXTIOI_CPUS)
>>> + memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
>>> sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi),
>>> cpu));
>>> }
>>> @@ -618,10 +623,12 @@ static void
>>> loongarch_irq_init(LoongArchMachineState *lams)
>>> * cpu_pin[9:2] <= intc_pin[7:0]
>>> */
>>> for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
>>> - cpudev = DEVICE(qemu_get_cpu(cpu));
>>> - for (pin = 0; pin < LS3A_INTC_IP; pin++) {
>>> - qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
>>> - qdev_get_gpio_in(cpudev, pin + 2));
>>> + if (cpu < EXTIOI_CPUS) {
>>> + cpudev = DEVICE(qemu_get_cpu(cpu));
>>> + for (pin = 0; pin < LS3A_INTC_IP; pin++) {
>>> + qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
>>> + qdev_get_gpio_in(cpudev, pin + 2));
>>> + }
>>> }
>>> }
>>> @@ -1026,7 +1033,7 @@ static void loongarch_class_init(ObjectClass
>>> *oc, void *data)
>>> mc->default_ram_size = 1 * GiB;
>>> mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("la464");
>>> mc->default_ram_id = "loongarch.ram";
>>> - mc->max_cpus = LOONGARCH_MAX_VCPUS;
>>> + mc->max_cpus = LOONGARCH_MAX_CPUS;
>>> mc->is_default = 1;
>>> mc->default_kernel_irqchip_split = false;
>>> mc->block_default_type = IF_VIRTIO;
>>> diff --git a/include/hw/intc/loongarch_extioi.h
>>> b/include/hw/intc/loongarch_extioi.h
>>> index 15b8c999f6..fbdef9a7b3 100644
>>> --- a/include/hw/intc/loongarch_extioi.h
>>> +++ b/include/hw/intc/loongarch_extioi.h
>>> @@ -14,6 +14,8 @@
>>> #define LS3A_INTC_IP 8
>>> #define EXTIOI_IRQS (256)
>>> #define EXTIOI_IRQS_BITMAP_SIZE (256 / 8)
>>> +/* irq from EXTIOI is routed to no more than 4 cpus */
>>> +#define EXTIOI_CPUS (4)
>>> /* map to ipnum per 32 irqs */
>>> #define EXTIOI_IRQS_IPMAP_SIZE (256 / 32)
>>> #define EXTIOI_IRQS_COREMAP_SIZE 256
>>> @@ -46,17 +48,17 @@ struct LoongArchExtIOI {
>>> uint32_t nodetype[EXTIOI_IRQS_NODETYPE_COUNT / 2];
>>> uint32_t bounce[EXTIOI_IRQS_GROUP_COUNT];
>>> uint32_t isr[EXTIOI_IRQS / 32];
>>> - uint32_t coreisr[LOONGARCH_MAX_VCPUS][EXTIOI_IRQS_GROUP_COUNT];
>>> + uint32_t coreisr[EXTIOI_CPUS][EXTIOI_IRQS_GROUP_COUNT];
>>> uint32_t enable[EXTIOI_IRQS / 32];
>>> uint32_t ipmap[EXTIOI_IRQS_IPMAP_SIZE / 4];
>>> uint32_t coremap[EXTIOI_IRQS / 4];
>>> uint32_t sw_pending[EXTIOI_IRQS / 32];
>>> - DECLARE_BITMAP(sw_isr[LOONGARCH_MAX_VCPUS][LS3A_INTC_IP],
>>> EXTIOI_IRQS);
>>> + DECLARE_BITMAP(sw_isr[EXTIOI_CPUS][LS3A_INTC_IP], EXTIOI_IRQS);
>>> uint8_t sw_ipmap[EXTIOI_IRQS_IPMAP_SIZE];
>>> uint8_t sw_coremap[EXTIOI_IRQS];
>>> - qemu_irq parent_irq[LOONGARCH_MAX_VCPUS][LS3A_INTC_IP];
>>> + qemu_irq parent_irq[EXTIOI_CPUS][LS3A_INTC_IP];
>>> qemu_irq irq[EXTIOI_IRQS];
>>> - MemoryRegion extioi_iocsr_mem[LOONGARCH_MAX_VCPUS];
>>> + MemoryRegion extioi_iocsr_mem[EXTIOI_CPUS];
>>> MemoryRegion extioi_system_mem;
>>> };
>>> #endif /* LOONGARCH_EXTIOI_H */
>>> diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
>>> index 54a9f595bb..f1659655c6 100644
>>> --- a/include/hw/loongarch/virt.h
>>> +++ b/include/hw/loongarch/virt.h
>>> @@ -14,7 +14,7 @@
>>> #include "hw/intc/loongarch_ipi.h"
>>> #include "hw/block/flash.h"
>>> -#define LOONGARCH_MAX_VCPUS 4
>>> +#define LOONGARCH_MAX_CPUS 256
>>> #define VIRT_ISA_IO_BASE 0x18000000UL
>>> #define VIRT_ISA_IO_SIZE 0x0004000
>>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/3] hw/intc: Add NULL pointer check on LoongArch ipi device
2023-04-06 10:00 ` [PATCH 2/3] hw/intc: Add NULL pointer check on LoongArch ipi device Song Gao
2023-04-26 1:37 ` Song Gao
@ 2023-05-11 19:03 ` Philippe Mathieu-Daudé
2023-05-12 3:01 ` Song Gao
1 sibling, 1 reply; 15+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-05-11 19:03 UTC (permalink / raw)
To: Song Gao, qemu-devel; +Cc: richard.henderson, maobibo, yangxiaojuan
On 6/4/23 12:00, Song Gao wrote:
> When ipi mailbox is used, cpu index is decoded from iocsr register.
> cpu maybe does not exist. This patch adss NULL pointer check on
> ipi device.
How can that happens from a guest vcpu context?
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
> hw/intc/loongarch_ipi.c | 31 +++++++++++++++++++------------
> 1 file changed, 19 insertions(+), 12 deletions(-)
>
> diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
> index 0563d83a35..39e899df46 100644
> --- a/hw/intc/loongarch_ipi.c
> +++ b/hw/intc/loongarch_ipi.c
> @@ -86,11 +86,12 @@ static void ipi_send(uint64_t val)
> /* IPI status vector */
> data = 1 << (val & 0x1f);
> cs = qemu_get_cpu(cpuid);
> - cpu = LOONGARCH_CPU(cs);
> - env = &cpu->env;
> - address_space_stl(&env->address_space_iocsr, 0x1008,
> - data, MEMTXATTRS_UNSPECIFIED, NULL);
> -
> + if (cs) {
> + cpu = LOONGARCH_CPU(cs);
> + env = &cpu->env;
> + address_space_stl(&env->address_space_iocsr, 0x1008,
> + data, MEMTXATTRS_UNSPECIFIED, NULL);
> + }
Is that the hardware behavior?
Could logging the invalid cpuid request be useful?
else {
//log or trace event here
}
> }
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 3/3] hw/loongarch/virt: Set max 256 cpus support on loongarch virt machine
2023-04-06 10:00 ` [PATCH 3/3] hw/loongarch/virt: Set max 256 cpus support on loongarch virt machine Song Gao
2023-04-26 1:37 ` Song Gao
@ 2023-05-11 19:07 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 15+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-05-11 19:07 UTC (permalink / raw)
To: Song Gao, qemu-devel; +Cc: richard.henderson, maobibo, yangxiaojuan
On 6/4/23 12:00, Song Gao wrote:
> Add separate macro EXTIOI_CPUS for extioi interrupt controller, extioi
> only supports 4 cpu. And set macro LOONGARCH_MAX_CPUS as 256 so that
> loongarch virt machine supports more cpus.
>
> Interrupts from external devices can only be routed cpu 0-3 because
> of extioi limits, cpu internal interrupt such as timer/ipi can be
> triggered on all cpus.
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
> hw/intc/loongarch_extioi.c | 4 ++--
> hw/loongarch/virt.c | 21 ++++++++++++++-------
> include/hw/intc/loongarch_extioi.h | 10 ++++++----
> include/hw/loongarch/virt.h | 2 +-
> 4 files changed, 23 insertions(+), 14 deletions(-)
> @@ -618,10 +623,12 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
> * cpu_pin[9:2] <= intc_pin[7:0]
> */
> for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
> - cpudev = DEVICE(qemu_get_cpu(cpu));
> - for (pin = 0; pin < LS3A_INTC_IP; pin++) {
> - qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
> - qdev_get_gpio_in(cpudev, pin + 2));
> + if (cpu < EXTIOI_CPUS) {
Alternatively:
for (cpu = 0; cpu < MIN(ms->smp.cpus, EXTIOI_CPUS); cpu++) {
> + cpudev = DEVICE(qemu_get_cpu(cpu));
> + for (pin = 0; pin < LS3A_INTC_IP; pin++) {
> + qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
> + qdev_get_gpio_in(cpudev, pin + 2));
> + }
> }
> }
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 1/3] hw/loongarch/virt: Modify ipi as percpu device
2023-04-06 10:00 [PATCH 1/3] hw/loongarch/virt: Modify ipi as percpu device Song Gao
` (2 preceding siblings ...)
2023-04-26 1:38 ` [PATCH 1/3] hw/loongarch/virt: Modify ipi as percpu device Song Gao
@ 2023-05-11 19:11 ` Philippe Mathieu-Daudé
3 siblings, 0 replies; 15+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-05-11 19:11 UTC (permalink / raw)
To: Song Gao, qemu-devel; +Cc: richard.henderson, maobibo, yangxiaojuan
On 6/4/23 12:00, Song Gao wrote:
> ipi is used to communicate between cpus, this patch modified
> loongarch ipi device as percpu deivce, so that there are
> 2 MemoryRegions with ipi device, rather than 2*cpus
> MemoryRegions, which may be large than QDEV_MAX_MMIO if
> more cpus are added on loongarch virt machine.
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
> hw/intc/loongarch_ipi.c | 32 ++++++++++----------------------
> hw/loongarch/virt.c | 12 ++++++------
> include/hw/intc/loongarch_ipi.h | 10 ++++------
> include/hw/loongarch/virt.h | 1 -
> 4 files changed, 20 insertions(+), 35 deletions(-)
> static const VMStateDescription vmstate_ipi_core = {
> @@ -233,7 +223,7 @@ static const VMStateDescription vmstate_ipi_core = {
> VMSTATE_UINT32(en, IPICore),
> VMSTATE_UINT32(set, IPICore),
> VMSTATE_UINT32(clear, IPICore),
> - VMSTATE_UINT32_ARRAY(buf, IPICore, MAX_IPI_MBX_NUM * 2),
> + VMSTATE_UINT32_ARRAY(buf, IPICore, 2),
Since this break the migration stream, you should update the version_id.
> VMSTATE_END_OF_LIST()
> }
> };
> @@ -243,9 +233,7 @@ static const VMStateDescription vmstate_loongarch_ipi = {
> .version_id = 0,
Ditto.
> .minimum_version_id = 0,
> .fields = (VMStateField[]) {
> - VMSTATE_STRUCT_ARRAY(ipi_core, LoongArchMachineState,
> - MAX_IPI_CORE_NUM, 0,
> - vmstate_ipi_core, IPICore),
> + VMSTATE_STRUCT(ipi_core, LoongArchIPI, 0, vmstate_ipi_core, IPICore),
> VMSTATE_END_OF_LIST()
> }
> };
The rest LGTM.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/3] hw/intc: Add NULL pointer check on LoongArch ipi device
2023-05-11 19:03 ` Philippe Mathieu-Daudé
@ 2023-05-12 3:01 ` Song Gao
2023-05-12 3:45 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 15+ messages in thread
From: Song Gao @ 2023-05-12 3:01 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: richard.henderson, maobibo, yangxiaojuan
Hi, Philippe
在 2023/5/12 上午3:03, Philippe Mathieu-Daudé 写道:
> On 6/4/23 12:00, Song Gao wrote:
>> When ipi mailbox is used, cpu index is decoded from iocsr register.
>> cpu maybe does not exist. This patch adss NULL pointer check on
>> ipi device.
>
> How can that happens from a guest vcpu context?
>
cpuid(cs->cpu_index) is decoded from iocsr register.
cpuid = (val >> 16) & 0x3ff; // ipi_sned [25:16]
The value maybe invalid. qemu only support 4 vcpu.
you can find more about ipi_send registers at:
https://github.com/loongson/LoongArch-Documentation/releases/download/2023.04.20/Loongson-3A5000-usermanual-v1.03-EN.pdf
Table 63. Processor core inter-processor communication registers
>> Signed-off-by: Song Gao <gaosong@loongson.cn>
>> ---
>> hw/intc/loongarch_ipi.c | 31 +++++++++++++++++++------------
>> 1 file changed, 19 insertions(+), 12 deletions(-)
>>
>> diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
>> index 0563d83a35..39e899df46 100644
>> --- a/hw/intc/loongarch_ipi.c
>> +++ b/hw/intc/loongarch_ipi.c
>> @@ -86,11 +86,12 @@ static void ipi_send(uint64_t val)
>> /* IPI status vector */
>> data = 1 << (val & 0x1f);
>> cs = qemu_get_cpu(cpuid);
>> - cpu = LOONGARCH_CPU(cs);
>> - env = &cpu->env;
>> - address_space_stl(&env->address_space_iocsr, 0x1008,
>> - data, MEMTXATTRS_UNSPECIFIED, NULL);
>> -
>> + if (cs) {
>> + cpu = LOONGARCH_CPU(cs);
>> + env = &cpu->env;
>> + address_space_stl(&env->address_space_iocsr, 0x1008,
>> + data, MEMTXATTRS_UNSPECIFIED, NULL);
>> + }
>
> Is that the hardware behavior?
>
Yes.
> Could logging the invalid cpuid request be useful?
>
Sure.
Thanks.
Song Gao
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/3] hw/intc: Add NULL pointer check on LoongArch ipi device
2023-05-12 3:01 ` Song Gao
@ 2023-05-12 3:45 ` Philippe Mathieu-Daudé
2023-05-12 6:29 ` Song Gao
0 siblings, 1 reply; 15+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-05-12 3:45 UTC (permalink / raw)
To: Song Gao, qemu-devel; +Cc: richard.henderson, maobibo, yangxiaojuan
On 12/5/23 05:01, Song Gao wrote:
> Hi, Philippe
>
> 在 2023/5/12 上午3:03, Philippe Mathieu-Daudé 写道:
>> On 6/4/23 12:00, Song Gao wrote:
>>> When ipi mailbox is used, cpu index is decoded from iocsr register.
>>> cpu maybe does not exist. This patch adss NULL pointer check on
>>> ipi device.
>>
>> How can that happens from a guest vcpu context?
>>
> cpuid(cs->cpu_index) is decoded from iocsr register.
>
> cpuid = (val >> 16) & 0x3ff; // ipi_sned [25:16]
>
> The value maybe invalid. qemu only support 4 vcpu.
What about something like this?
-- >8 --
-static void ipi_send(uint64_t val)
+static void ipi_send(uint32_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 >= MAX_IPI_CORE_NUM) {
+ 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);
}
---
> you can find more about ipi_send registers at:
> https://github.com/loongson/LoongArch-Documentation/releases/download/2023.04.20/Loongson-3A5000-usermanual-v1.03-EN.pdf
> Table 63. Processor core inter-processor communication registers
>
>>> Signed-off-by: Song Gao <gaosong@loongson.cn>
>>> ---
>>> hw/intc/loongarch_ipi.c | 31 +++++++++++++++++++------------
>>> 1 file changed, 19 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
>>> index 0563d83a35..39e899df46 100644
>>> --- a/hw/intc/loongarch_ipi.c
>>> +++ b/hw/intc/loongarch_ipi.c
>>> @@ -86,11 +86,12 @@ static void ipi_send(uint64_t val)
>>> /* IPI status vector */
>>> data = 1 << (val & 0x1f);
>>> cs = qemu_get_cpu(cpuid);
>>> - cpu = LOONGARCH_CPU(cs);
>>> - env = &cpu->env;
>>> - address_space_stl(&env->address_space_iocsr, 0x1008,
>>> - data, MEMTXATTRS_UNSPECIFIED, NULL);
>>> -
>>> + if (cs) {
>>> + cpu = LOONGARCH_CPU(cs);
>>> + env = &cpu->env;
>>> + address_space_stl(&env->address_space_iocsr, 0x1008,
>>> + data, MEMTXATTRS_UNSPECIFIED, NULL);
>>> + }
>>
>> Is that the hardware behavior?
>>
> Yes.
>> Could logging the invalid cpuid request be useful?
>>
> Sure.
>
> Thanks.
> Song Gao
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/3] hw/intc: Add NULL pointer check on LoongArch ipi device
2023-05-12 3:45 ` Philippe Mathieu-Daudé
@ 2023-05-12 6:29 ` Song Gao
0 siblings, 0 replies; 15+ messages in thread
From: Song Gao @ 2023-05-12 6:29 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: richard.henderson, maobibo, yangxiaojuan
在 2023/5/12 上午11:45, Philippe Mathieu-Daudé 写道:
> On 12/5/23 05:01, Song Gao wrote:
>> Hi, Philippe
>>
>> 在 2023/5/12 上午3:03, Philippe Mathieu-Daudé 写道:
>>> On 6/4/23 12:00, Song Gao wrote:
>>>> When ipi mailbox is used, cpu index is decoded from iocsr register.
>>>> cpu maybe does not exist. This patch adss NULL pointer check on
>>>> ipi device.
>>>
>>> How can that happens from a guest vcpu context?
>>>
>> cpuid(cs->cpu_index) is decoded from iocsr register.
>>
>> cpuid = (val >> 16) & 0x3ff; // ipi_sned [25:16]
>>
>> The value maybe invalid. qemu only support 4 vcpu.
>
> What about something like this?
>
Nice, thanks for you suggestion.
Thanks
Song Gao.
> -- >8 --
> -static void ipi_send(uint64_t val)
> +static void ipi_send(uint32_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 >= MAX_IPI_CORE_NUM) {
> + 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);
>
> }
> ---
>
>> you can find more about ipi_send registers at:
>> https://github.com/loongson/LoongArch-Documentation/releases/download/2023.04.20/Loongson-3A5000-usermanual-v1.03-EN.pdf
>>
>> Table 63. Processor core inter-processor communication registers
>>
>>>> Signed-off-by: Song Gao <gaosong@loongson.cn>
>>>> ---
>>>> hw/intc/loongarch_ipi.c | 31 +++++++++++++++++++------------
>>>> 1 file changed, 19 insertions(+), 12 deletions(-)
>>>>
>>>> diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
>>>> index 0563d83a35..39e899df46 100644
>>>> --- a/hw/intc/loongarch_ipi.c
>>>> +++ b/hw/intc/loongarch_ipi.c
>>>> @@ -86,11 +86,12 @@ static void ipi_send(uint64_t val)
>>>> /* IPI status vector */
>>>> data = 1 << (val & 0x1f);
>>>> cs = qemu_get_cpu(cpuid);
>>>> - cpu = LOONGARCH_CPU(cs);
>>>> - env = &cpu->env;
>>>> - address_space_stl(&env->address_space_iocsr, 0x1008,
>>>> - data, MEMTXATTRS_UNSPECIFIED, NULL);
>>>> -
>>>> + if (cs) {
>>>> + cpu = LOONGARCH_CPU(cs);
>>>> + env = &cpu->env;
>>>> + address_space_stl(&env->address_space_iocsr, 0x1008,
>>>> + data, MEMTXATTRS_UNSPECIFIED, NULL);
>>>> + }
>>>
>>> Is that the hardware behavior?
>>>
>> Yes.
>>> Could logging the invalid cpuid request be useful?
>>>
>> Sure.
>>
>> Thanks.
>> Song Gao
>>
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2023-05-12 6:31 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-06 10:00 [PATCH 1/3] hw/loongarch/virt: Modify ipi as percpu device Song Gao
2023-04-06 10:00 ` [PATCH 2/3] hw/intc: Add NULL pointer check on LoongArch ipi device Song Gao
2023-04-26 1:37 ` Song Gao
2023-05-11 19:03 ` Philippe Mathieu-Daudé
2023-05-12 3:01 ` Song Gao
2023-05-12 3:45 ` Philippe Mathieu-Daudé
2023-05-12 6:29 ` Song Gao
2023-04-06 10:00 ` [PATCH 3/3] hw/loongarch/virt: Set max 256 cpus support on loongarch virt machine Song Gao
2023-04-26 1:37 ` Song Gao
2023-05-08 2:11 ` Song Gao
2023-05-10 10:12 ` Richard Henderson
2023-05-11 12:22 ` Song Gao
2023-05-11 19:07 ` Philippe Mathieu-Daudé
2023-04-26 1:38 ` [PATCH 1/3] hw/loongarch/virt: Modify ipi as percpu device Song Gao
2023-05-11 19:11 ` Philippe Mathieu-Daudé
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.