All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.