qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v0 0/1] fix the way riscv_plic_hart_config_string()
@ 2025-04-15  9:53 Chao Liu
  2025-04-15  9:53 ` [PATCH v0 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly Chao Liu
  2025-04-15 10:05 ` [PATCH v1 0/1] fix the way riscv_plic_hart_config_string() gets the CPUState Chao Liu
  0 siblings, 2 replies; 7+ messages in thread
From: Chao Liu @ 2025-04-15  9:53 UTC (permalink / raw)
  To: alistair23, palmer
  Cc: zhiwei_liu, alistair.francis, dbarboza, liwei1518, lc00631,
	zqz00548, qemu-devel, qemu-riscv

Hi, all:

When I was configuring multiple sockets using riscv virt Machine, I found that
I could not set the PLIC correctly.

By checking the code, I found that it was due to not traversing the CPUState
correctly in the riscv_plic_hart_config_string() function.

So I tried to fix this.

--
Regards,
Chao

Chao Liu (1):
  hw/riscv: fix PLIC hart topology configuration string when not getting
    CPUState correctly

 hw/riscv/boot.c            | 4 ++--
 hw/riscv/microchip_pfsoc.c | 2 +-
 hw/riscv/riscv_hart.c      | 1 +
 hw/riscv/sifive_u.c        | 5 +++--
 hw/riscv/virt.c            | 2 +-
 include/hw/riscv/boot.h    | 2 +-
 6 files changed, 9 insertions(+), 7 deletions(-)

-- 
2.48.1



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v0 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly
  2025-04-15  9:53 [PATCH v0 0/1] fix the way riscv_plic_hart_config_string() Chao Liu
@ 2025-04-15  9:53 ` Chao Liu
  2025-04-15 10:05   ` [PATCH v1 " Chao Liu
                     ` (2 more replies)
  2025-04-15 10:05 ` [PATCH v1 0/1] fix the way riscv_plic_hart_config_string() gets the CPUState Chao Liu
  1 sibling, 3 replies; 7+ messages in thread
From: Chao Liu @ 2025-04-15  9:53 UTC (permalink / raw)
  To: alistair23, palmer
  Cc: zhiwei_liu, alistair.francis, dbarboza, liwei1518, lc00631,
	zqz00548, qemu-devel, qemu-riscv

riscv_plic_hart_config_string() when getting CPUState via qemu_get_cpu()
should be consistent with keeping sifive_plic_realize() by
hartid_base + cpu_index.

For non-numa or multi-cluster machines, hartid_base should be 0.

Also, to ensure that CPUState->cpu_index is set correctly, we need to
update it with the value of mhartid during riscv_hart_realize().

Signed-off-by: Chao Liu <lc00631@tecorigin.com>
Reviewed-by: zhaoqingze <zqz00548@tecorigin.com>
---
 hw/riscv/boot.c            | 4 ++--
 hw/riscv/microchip_pfsoc.c | 2 +-
 hw/riscv/riscv_hart.c      | 1 +
 hw/riscv/sifive_u.c        | 5 +++--
 hw/riscv/virt.c            | 2 +-
 include/hw/riscv/boot.h    | 2 +-
 6 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 765b9e2b1a..d4c06e7530 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -44,13 +44,13 @@ bool riscv_is_32bit(RISCVHartArrayState *harts)
  * Return the per-socket PLIC hart topology configuration string
  * (caller must free with g_free())
  */
-char *riscv_plic_hart_config_string(int hart_count)
+char *riscv_plic_hart_config_string(int hart_base, int hart_count)
 {
     g_autofree const char **vals = g_new(const char *, hart_count + 1);
     int i;
 
     for (i = 0; i < hart_count; i++) {
-        CPUState *cs = qemu_get_cpu(i);
+        CPUState *cs = qemu_get_cpu(hart_base + i);
         CPURISCVState *env = &RISCV_CPU(cs)->env;
 
         if (kvm_enabled()) {
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
index 9c846f9b5b..5269336346 100644
--- a/hw/riscv/microchip_pfsoc.c
+++ b/hw/riscv/microchip_pfsoc.c
@@ -275,7 +275,7 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
                                 l2lim_mem);
 
     /* create PLIC hart topology configuration string */
-    plic_hart_config = riscv_plic_hart_config_string(ms->smp.cpus);
+    plic_hart_config = riscv_plic_hart_config_string(0, ms->smp.cpus);
 
     /* PLIC */
     s->plic = sifive_plic_create(memmap[MICROCHIP_PFSOC_PLIC].base,
diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
index a55d156668..522e795033 100644
--- a/hw/riscv/riscv_hart.c
+++ b/hw/riscv/riscv_hart.c
@@ -138,6 +138,7 @@ static bool riscv_hart_realize(RISCVHartArrayState *s, int idx,
     }
 
     s->harts[idx].env.mhartid = s->hartid_base + idx;
+    CPU(&s->harts[idx])->cpu_index = s->harts[idx].env.mhartid;
     qemu_register_reset(riscv_harts_cpu_reset, &s->harts[idx]);
     return qdev_realize(DEVICE(&s->harts[idx]), NULL, errp);
 }
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 679f2024bc..516912c4f4 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -790,10 +790,11 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
     MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
     MemoryRegion *l2lim_mem = g_new(MemoryRegion, 1);
     char *plic_hart_config;
+    int hartid_base = 1;
     int i, j;
 
     qdev_prop_set_uint32(DEVICE(&s->u_cpus), "num-harts", ms->smp.cpus - 1);
-    qdev_prop_set_uint32(DEVICE(&s->u_cpus), "hartid-base", 1);
+    qdev_prop_set_uint32(DEVICE(&s->u_cpus), "hartid-base", hartid_base);
     qdev_prop_set_string(DEVICE(&s->u_cpus), "cpu-type", s->cpu_type);
     qdev_prop_set_uint64(DEVICE(&s->u_cpus), "resetvec", 0x1004);
 
@@ -829,7 +830,7 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
                                 l2lim_mem);
 
     /* create PLIC hart topology configuration string */
-    plic_hart_config = riscv_plic_hart_config_string(ms->smp.cpus);
+    plic_hart_config = riscv_plic_hart_config_string(hartid_base, ms->smp.cpus);
 
     /* MMIO */
     s->plic = sifive_plic_create(memmap[SIFIVE_U_DEV_PLIC].base,
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index e517002fdf..41fdfd2bc8 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1280,7 +1280,7 @@ static DeviceState *virt_create_plic(const MemMapEntry *memmap, int socket,
     g_autofree char *plic_hart_config = NULL;
 
     /* Per-socket PLIC hart topology configuration string */
-    plic_hart_config = riscv_plic_hart_config_string(hart_count);
+    plic_hart_config = riscv_plic_hart_config_string(base_hartid, hart_count);
 
     /* Per-socket PLIC */
     ret = sifive_plic_create(
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
index 7d59b2e6c6..5937298646 100644
--- a/include/hw/riscv/boot.h
+++ b/include/hw/riscv/boot.h
@@ -40,7 +40,7 @@ typedef struct RISCVBootInfo {
 
 bool riscv_is_32bit(RISCVHartArrayState *harts);
 
-char *riscv_plic_hart_config_string(int hart_count);
+char *riscv_plic_hart_config_string(int hart_base, int hart_count);
 
 void riscv_boot_info_init(RISCVBootInfo *info, RISCVHartArrayState *harts);
 target_ulong riscv_calc_kernel_start_addr(RISCVBootInfo *info,
-- 
2.48.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v1 0/1] fix the way riscv_plic_hart_config_string() gets the CPUState
  2025-04-15  9:53 [PATCH v0 0/1] fix the way riscv_plic_hart_config_string() Chao Liu
  2025-04-15  9:53 ` [PATCH v0 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly Chao Liu
@ 2025-04-15 10:05 ` Chao Liu
  1 sibling, 0 replies; 7+ messages in thread
From: Chao Liu @ 2025-04-15 10:05 UTC (permalink / raw)
  To: alistair23, palmer
  Cc: zhiwei_liu, alistair.francis, dbarboza, liwei1518, lc00631,
	zqz00548, qemu-devel, qemu-riscv

Hi, all:

When I was configuring multiple sockets using riscv virt Machine, I found that
I could not set the PLIC correctly.

By checking the code, I found that it was due to not traversing the CPUState
correctly in the riscv_plic_hart_config_string() function.

So I tried to fix this.

PATCH v1 update commit message:
"For non-numa or single-cluster machines, hartid_base should be 0."

--
Regards,
Chao

Chao Liu (1):
  hw/riscv: fix PLIC hart topology configuration string when not getting
    CPUState correctly

 hw/riscv/boot.c            | 4 ++--
 hw/riscv/microchip_pfsoc.c | 2 +-
 hw/riscv/riscv_hart.c      | 1 +
 hw/riscv/sifive_u.c        | 5 +++--
 hw/riscv/virt.c            | 2 +-
 include/hw/riscv/boot.h    | 2 +-
 6 files changed, 9 insertions(+), 7 deletions(-)

-- 
2.48.1



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v1 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly
  2025-04-15  9:53 ` [PATCH v0 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly Chao Liu
@ 2025-04-15 10:05   ` Chao Liu
  2025-04-15 10:48   ` Philippe Mathieu-Daudé
  2025-04-15 11:14   ` Chao Liu
  2 siblings, 0 replies; 7+ messages in thread
From: Chao Liu @ 2025-04-15 10:05 UTC (permalink / raw)
  To: alistair23, palmer
  Cc: zhiwei_liu, alistair.francis, dbarboza, liwei1518, lc00631,
	zqz00548, qemu-devel, qemu-riscv

riscv_plic_hart_config_string() when getting CPUState via qemu_get_cpu()
should be consistent with keeping sifive_plic_realize() by
hartid_base + cpu_index.

For non-numa or single-cluster machines, hartid_base should be 0.

Also, to ensure that CPUState->cpu_index is set correctly, we need to
update it with the value of mhartid during riscv_hart_realize().

Signed-off-by: Chao Liu <lc00631@tecorigin.com>
Reviewed-by: zhaoqingze <zqz00548@tecorigin.com>
---
 hw/riscv/boot.c            | 4 ++--
 hw/riscv/microchip_pfsoc.c | 2 +-
 hw/riscv/riscv_hart.c      | 1 +
 hw/riscv/sifive_u.c        | 5 +++--
 hw/riscv/virt.c            | 2 +-
 include/hw/riscv/boot.h    | 2 +-
 6 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 765b9e2b1a..d4c06e7530 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -44,13 +44,13 @@ bool riscv_is_32bit(RISCVHartArrayState *harts)
  * Return the per-socket PLIC hart topology configuration string
  * (caller must free with g_free())
  */
-char *riscv_plic_hart_config_string(int hart_count)
+char *riscv_plic_hart_config_string(int hart_base, int hart_count)
 {
     g_autofree const char **vals = g_new(const char *, hart_count + 1);
     int i;
 
     for (i = 0; i < hart_count; i++) {
-        CPUState *cs = qemu_get_cpu(i);
+        CPUState *cs = qemu_get_cpu(hart_base + i);
         CPURISCVState *env = &RISCV_CPU(cs)->env;
 
         if (kvm_enabled()) {
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
index 9c846f9b5b..5269336346 100644
--- a/hw/riscv/microchip_pfsoc.c
+++ b/hw/riscv/microchip_pfsoc.c
@@ -275,7 +275,7 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
                                 l2lim_mem);
 
     /* create PLIC hart topology configuration string */
-    plic_hart_config = riscv_plic_hart_config_string(ms->smp.cpus);
+    plic_hart_config = riscv_plic_hart_config_string(0, ms->smp.cpus);
 
     /* PLIC */
     s->plic = sifive_plic_create(memmap[MICROCHIP_PFSOC_PLIC].base,
diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
index a55d156668..522e795033 100644
--- a/hw/riscv/riscv_hart.c
+++ b/hw/riscv/riscv_hart.c
@@ -138,6 +138,7 @@ static bool riscv_hart_realize(RISCVHartArrayState *s, int idx,
     }
 
     s->harts[idx].env.mhartid = s->hartid_base + idx;
+    CPU(&s->harts[idx])->cpu_index = s->harts[idx].env.mhartid;
     qemu_register_reset(riscv_harts_cpu_reset, &s->harts[idx]);
     return qdev_realize(DEVICE(&s->harts[idx]), NULL, errp);
 }
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 679f2024bc..516912c4f4 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -790,10 +790,11 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
     MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
     MemoryRegion *l2lim_mem = g_new(MemoryRegion, 1);
     char *plic_hart_config;
+    int hartid_base = 1;
     int i, j;
 
     qdev_prop_set_uint32(DEVICE(&s->u_cpus), "num-harts", ms->smp.cpus - 1);
-    qdev_prop_set_uint32(DEVICE(&s->u_cpus), "hartid-base", 1);
+    qdev_prop_set_uint32(DEVICE(&s->u_cpus), "hartid-base", hartid_base);
     qdev_prop_set_string(DEVICE(&s->u_cpus), "cpu-type", s->cpu_type);
     qdev_prop_set_uint64(DEVICE(&s->u_cpus), "resetvec", 0x1004);
 
@@ -829,7 +830,7 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
                                 l2lim_mem);
 
     /* create PLIC hart topology configuration string */
-    plic_hart_config = riscv_plic_hart_config_string(ms->smp.cpus);
+    plic_hart_config = riscv_plic_hart_config_string(hartid_base, ms->smp.cpus);
 
     /* MMIO */
     s->plic = sifive_plic_create(memmap[SIFIVE_U_DEV_PLIC].base,
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index e517002fdf..41fdfd2bc8 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1280,7 +1280,7 @@ static DeviceState *virt_create_plic(const MemMapEntry *memmap, int socket,
     g_autofree char *plic_hart_config = NULL;
 
     /* Per-socket PLIC hart topology configuration string */
-    plic_hart_config = riscv_plic_hart_config_string(hart_count);
+    plic_hart_config = riscv_plic_hart_config_string(base_hartid, hart_count);
 
     /* Per-socket PLIC */
     ret = sifive_plic_create(
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
index 7d59b2e6c6..5937298646 100644
--- a/include/hw/riscv/boot.h
+++ b/include/hw/riscv/boot.h
@@ -40,7 +40,7 @@ typedef struct RISCVBootInfo {
 
 bool riscv_is_32bit(RISCVHartArrayState *harts);
 
-char *riscv_plic_hart_config_string(int hart_count);
+char *riscv_plic_hart_config_string(int hart_base, int hart_count);
 
 void riscv_boot_info_init(RISCVBootInfo *info, RISCVHartArrayState *harts);
 target_ulong riscv_calc_kernel_start_addr(RISCVBootInfo *info,
-- 
2.48.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v1 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly
  2025-04-15  9:53 ` [PATCH v0 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly Chao Liu
  2025-04-15 10:05   ` [PATCH v1 " Chao Liu
@ 2025-04-15 10:48   ` Philippe Mathieu-Daudé
  2025-04-15 11:14   ` Chao Liu
  2 siblings, 0 replies; 7+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-04-15 10:48 UTC (permalink / raw)
  To: Chao Liu, alistair23, palmer
  Cc: zhiwei_liu, alistair.francis, dbarboza, liwei1518, zqz00548,
	qemu-devel, qemu-riscv

Hi,

On 15/4/25 12:05, Chao Liu wrote:
> riscv_plic_hart_config_string() when getting CPUState via qemu_get_cpu()
> should be consistent with keeping sifive_plic_realize() by
> hartid_base + cpu_index.
> 
> For non-numa or single-cluster machines, hartid_base should be 0.
> 
> Also, to ensure that CPUState->cpu_index is set correctly, we need to
> update it with the value of mhartid during riscv_hart_realize().
> 
> Signed-off-by: Chao Liu <lc00631@tecorigin.com>
> Reviewed-by: zhaoqingze <zqz00548@tecorigin.com>
> ---
>   hw/riscv/boot.c            | 4 ++--
>   hw/riscv/microchip_pfsoc.c | 2 +-
>   hw/riscv/riscv_hart.c      | 1 +
>   hw/riscv/sifive_u.c        | 5 +++--
>   hw/riscv/virt.c            | 2 +-
>   include/hw/riscv/boot.h    | 2 +-
>   6 files changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
> index 765b9e2b1a..d4c06e7530 100644
> --- a/hw/riscv/boot.c
> +++ b/hw/riscv/boot.c
> @@ -44,13 +44,13 @@ bool riscv_is_32bit(RISCVHartArrayState *harts)
>    * Return the per-socket PLIC hart topology configuration string
>    * (caller must free with g_free())
>    */
> -char *riscv_plic_hart_config_string(int hart_count)
> +char *riscv_plic_hart_config_string(int hart_base, int hart_count)
>   {
>       g_autofree const char **vals = g_new(const char *, hart_count + 1);
>       int i;
>   
>       for (i = 0; i < hart_count; i++) {
> -        CPUState *cs = qemu_get_cpu(i);
> +        CPUState *cs = qemu_get_cpu(hart_base + i);
>           CPURISCVState *env = &RISCV_CPU(cs)->env;
>   
>           if (kvm_enabled()) {
> diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
> index 9c846f9b5b..5269336346 100644
> --- a/hw/riscv/microchip_pfsoc.c
> +++ b/hw/riscv/microchip_pfsoc.c
> @@ -275,7 +275,7 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
>                                   l2lim_mem);
>   
>       /* create PLIC hart topology configuration string */
> -    plic_hart_config = riscv_plic_hart_config_string(ms->smp.cpus);
> +    plic_hart_config = riscv_plic_hart_config_string(0, ms->smp.cpus);
>   
>       /* PLIC */
>       s->plic = sifive_plic_create(memmap[MICROCHIP_PFSOC_PLIC].base,
> diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
> index a55d156668..522e795033 100644
> --- a/hw/riscv/riscv_hart.c
> +++ b/hw/riscv/riscv_hart.c
> @@ -138,6 +138,7 @@ static bool riscv_hart_realize(RISCVHartArrayState *s, int idx,
>       }
>   
>       s->harts[idx].env.mhartid = s->hartid_base + idx;
> +    CPU(&s->harts[idx])->cpu_index = s->harts[idx].env.mhartid;

Why do we need this particular change? CPUState::cpu_index isn't related
to RISC-V HART index, it is meant for the accelerators (KVM, TCG, ...),
and shouldn't be used by hw/ code.

Otherwise the rest LGTM.

Regards,

Phil.

>       qemu_register_reset(riscv_harts_cpu_reset, &s->harts[idx]);
>       return qdev_realize(DEVICE(&s->harts[idx]), NULL, errp);
>   }
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 679f2024bc..516912c4f4 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -790,10 +790,11 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
>       MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
>       MemoryRegion *l2lim_mem = g_new(MemoryRegion, 1);
>       char *plic_hart_config;
> +    int hartid_base = 1;
>       int i, j;
>   
>       qdev_prop_set_uint32(DEVICE(&s->u_cpus), "num-harts", ms->smp.cpus - 1);
> -    qdev_prop_set_uint32(DEVICE(&s->u_cpus), "hartid-base", 1);
> +    qdev_prop_set_uint32(DEVICE(&s->u_cpus), "hartid-base", hartid_base);
>       qdev_prop_set_string(DEVICE(&s->u_cpus), "cpu-type", s->cpu_type);
>       qdev_prop_set_uint64(DEVICE(&s->u_cpus), "resetvec", 0x1004);
>   
> @@ -829,7 +830,7 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
>                                   l2lim_mem);
>   
>       /* create PLIC hart topology configuration string */
> -    plic_hart_config = riscv_plic_hart_config_string(ms->smp.cpus);
> +    plic_hart_config = riscv_plic_hart_config_string(hartid_base, ms->smp.cpus);
>   
>       /* MMIO */
>       s->plic = sifive_plic_create(memmap[SIFIVE_U_DEV_PLIC].base,
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index e517002fdf..41fdfd2bc8 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -1280,7 +1280,7 @@ static DeviceState *virt_create_plic(const MemMapEntry *memmap, int socket,
>       g_autofree char *plic_hart_config = NULL;
>   
>       /* Per-socket PLIC hart topology configuration string */
> -    plic_hart_config = riscv_plic_hart_config_string(hart_count);
> +    plic_hart_config = riscv_plic_hart_config_string(base_hartid, hart_count);
>   
>       /* Per-socket PLIC */
>       ret = sifive_plic_create(
> diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
> index 7d59b2e6c6..5937298646 100644
> --- a/include/hw/riscv/boot.h
> +++ b/include/hw/riscv/boot.h
> @@ -40,7 +40,7 @@ typedef struct RISCVBootInfo {
>   
>   bool riscv_is_32bit(RISCVHartArrayState *harts);
>   
> -char *riscv_plic_hart_config_string(int hart_count);
> +char *riscv_plic_hart_config_string(int hart_base, int hart_count);
>   
>   void riscv_boot_info_init(RISCVBootInfo *info, RISCVHartArrayState *harts);
>   target_ulong riscv_calc_kernel_start_addr(RISCVBootInfo *info,



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Re: [PATCH v1 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly
  2025-04-15  9:53 ` [PATCH v0 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly Chao Liu
  2025-04-15 10:05   ` [PATCH v1 " Chao Liu
  2025-04-15 10:48   ` Philippe Mathieu-Daudé
@ 2025-04-15 11:14   ` Chao Liu
  2025-04-15 11:40     ` Philippe Mathieu-Daudé
  2 siblings, 1 reply; 7+ messages in thread
From: Chao Liu @ 2025-04-15 11:14 UTC (permalink / raw)
  To: philmd, Chao Liu, alistair23, palmer
  Cc: alistair.francis, dbarboza, liwei1518, qemu-devel, qemu-riscv,
	zhiwei_liu, zqz00548

From: Philippe Mathieu-Daudé <philmd@linaro.org>

> Hi,
> 
> On 15/4/25 12:05, Chao Liu wrote:
> > riscv_plic_hart_config_string() when getting CPUState via qemu_get_cpu()
> > should be consistent with keeping sifive_plic_realize() by
> > hartid_base + cpu_index.
> > 
> > For non-numa or single-cluster machines, hartid_base should be 0.
> > 
> > Also, to ensure that CPUState->cpu_index is set correctly, we need to
> > update it with the value of mhartid during riscv_hart_realize().
> > 
> > Signed-off-by: Chao Liu <lc00631@tecorigin.com>
> > Reviewed-by: zhaoqingze <zqz00548@tecorigin.com>
> > ---
> >   hw/riscv/boot.c            | 4 ++--
> >   hw/riscv/microchip_pfsoc.c | 2 +-
> >   hw/riscv/riscv_hart.c      | 1 +
> >   hw/riscv/sifive_u.c        | 5 +++--
> >   hw/riscv/virt.c            | 2 +-
> >   include/hw/riscv/boot.h    | 2 +-
> >   6 files changed, 9 insertions(+), 7 deletions(-)
> > 
> > diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
> > index 765b9e2b1a..d4c06e7530 100644
> > --- a/hw/riscv/boot.c
> > +++ b/hw/riscv/boot.c
> > @@ -44,13 +44,13 @@ bool riscv_is_32bit(RISCVHartArrayState *harts)
> >    * Return the per-socket PLIC hart topology configuration string
> >    * (caller must free with g_free())
> >    */
> > -char *riscv_plic_hart_config_string(int hart_count)
> > +char *riscv_plic_hart_config_string(int hart_base, int hart_count)
> >   {
> >       g_autofree const char **vals = g_new(const char *, hart_count + 1);
> >       int i;
> >   
> >       for (i = 0; i < hart_count; i++) {
> > -        CPUState *cs = qemu_get_cpu(i);
> > +        CPUState *cs = qemu_get_cpu(hart_base + i);
> >           CPURISCVState *env = &RISCV_CPU(cs)->env;
> >   
> >           if (kvm_enabled()) {
> > diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
> > index 9c846f9b5b..5269336346 100644
> > --- a/hw/riscv/microchip_pfsoc.c
> > +++ b/hw/riscv/microchip_pfsoc.c
> > @@ -275,7 +275,7 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
> >                                   l2lim_mem);
> >   
> >       /* create PLIC hart topology configuration string */
> > -    plic_hart_config = riscv_plic_hart_config_string(ms->smp.cpus);
> > +    plic_hart_config = riscv_plic_hart_config_string(0, ms->smp.cpus);
> >   
> >       /* PLIC */
> >       s->plic = sifive_plic_create(memmap[MICROCHIP_PFSOC_PLIC].base,
> > diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
> > index a55d156668..522e795033 100644
> > --- a/hw/riscv/riscv_hart.c
> > +++ b/hw/riscv/riscv_hart.c
> > @@ -138,6 +138,7 @@ static bool riscv_hart_realize(RISCVHartArrayState *s, int idx,
> >       }
> >   
> >       s->harts[idx].env.mhartid = s->hartid_base + idx;
> > +    CPU(&s->harts[idx])->cpu_index = s->harts[idx].env.mhartid;
> 
> Why do we need this particular change? CPUState::cpu_index isn't related
> to RISC-V HART index, it is meant for the accelerators (KVM, TCG, ...),
> and shouldn't be used by hw/ code.
> 
> Otherwise the rest LGTM.
> 
> Regards,
> 
> Phil.

Thanks for the reply, here is an update to cpu_index, mainly for consistency
with the following:

static void sifive_plic_realize(DeviceState *dev, Error **errp)
{
    ...

    for (i = 0; i < s->num_harts; i++) {
        /* this get cpu with hartid_base + i */ 
        RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i));
        if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
            error_setg(errp, "SEIP already claimed");
            return;
        }
    }

    msi_nonbroken = true;
}

But when adding the cpu to the global chain table, the cpu_index starts at 0.

Maybe there is a better way to handle this here?

For example:

1. When updating the cpu_index in the upper level, we can set a base id, and by
setting this base id, we can update the cpu_index indirectly.

or

2. Modify sifive_plic_realize() to iterate over cpu's to avoid getting them
by id.

I haven't thought of a better way to handle this at the moment,
so we can discuss it further

--
Regards,
Chao


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v1 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly
  2025-04-15 11:14   ` Chao Liu
@ 2025-04-15 11:40     ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 7+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-04-15 11:40 UTC (permalink / raw)
  To: Chao Liu, alistair23, palmer
  Cc: alistair.francis, dbarboza, liwei1518, qemu-devel, qemu-riscv,
	zhiwei_liu, zqz00548

On 15/4/25 13:14, Chao Liu wrote:
> From: Philippe Mathieu-Daudé <philmd@linaro.org>
> 
>> Hi,
>>
>> On 15/4/25 12:05, Chao Liu wrote:
>> > riscv_plic_hart_config_string() when getting CPUState via 
>> qemu_get_cpu()
>> > should be consistent with keeping sifive_plic_realize() by
>> > hartid_base + cpu_index.
>> > > For non-numa or single-cluster machines, hartid_base should be 0.
>> > > Also, to ensure that CPUState->cpu_index is set correctly, we need to
>> > update it with the value of mhartid during riscv_hart_realize().
>> > > Signed-off-by: Chao Liu <lc00631@tecorigin.com>
>> > Reviewed-by: zhaoqingze <zqz00548@tecorigin.com>
>> > ---
>> >   hw/riscv/boot.c            | 4 ++--
>> >   hw/riscv/microchip_pfsoc.c | 2 +-
>> >   hw/riscv/riscv_hart.c      | 1 +
>> >   hw/riscv/sifive_u.c        | 5 +++--
>> >   hw/riscv/virt.c            | 2 +-
>> >   include/hw/riscv/boot.h    | 2 +-
>> >   6 files changed, 9 insertions(+), 7 deletions(-)
>> > > diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
>> > index 765b9e2b1a..d4c06e7530 100644
>> > --- a/hw/riscv/boot.c
>> > +++ b/hw/riscv/boot.c
>> > @@ -44,13 +44,13 @@ bool riscv_is_32bit(RISCVHartArrayState *harts)
>> >    * Return the per-socket PLIC hart topology configuration string
>> >    * (caller must free with g_free())
>> >    */
>> > -char *riscv_plic_hart_config_string(int hart_count)
>> > +char *riscv_plic_hart_config_string(int hart_base, int hart_count)
>> >   {
>> >       g_autofree const char **vals = g_new(const char *, hart_count 
>> + 1);
>> >       int i;
>> > >       for (i = 0; i < hart_count; i++) {
>> > -        CPUState *cs = qemu_get_cpu(i);
>> > +        CPUState *cs = qemu_get_cpu(hart_base + i);
>> >           CPURISCVState *env = &RISCV_CPU(cs)->env;
>> > >           if (kvm_enabled()) {
>> > diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
>> > index 9c846f9b5b..5269336346 100644
>> > --- a/hw/riscv/microchip_pfsoc.c
>> > +++ b/hw/riscv/microchip_pfsoc.c
>> > @@ -275,7 +275,7 @@ static void 
>> microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
>> >                                   l2lim_mem);
>> > >       /* create PLIC hart topology configuration string */
>> > -    plic_hart_config = riscv_plic_hart_config_string(ms->smp.cpus);
>> > +    plic_hart_config = riscv_plic_hart_config_string(0, ms->smp.cpus);
>> > >       /* PLIC */
>> >       s->plic = sifive_plic_create(memmap[MICROCHIP_PFSOC_PLIC].base,
>> > diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
>> > index a55d156668..522e795033 100644
>> > --- a/hw/riscv/riscv_hart.c
>> > +++ b/hw/riscv/riscv_hart.c
>> > @@ -138,6 +138,7 @@ static bool 
>> riscv_hart_realize(RISCVHartArrayState *s, int idx,
>> >       }
>> > >       s->harts[idx].env.mhartid = s->hartid_base + idx;
>> > +    CPU(&s->harts[idx])->cpu_index = s->harts[idx].env.mhartid;
>>
>> Why do we need this particular change? CPUState::cpu_index isn't related
>> to RISC-V HART index, it is meant for the accelerators (KVM, TCG, ...),
>> and shouldn't be used by hw/ code.
>>
>> Otherwise the rest LGTM.
>>
>> Regards,
>>
>> Phil.
> 
> Thanks for the reply, here is an update to cpu_index, mainly for 
> consistency
> with the following:
> 
> static void sifive_plic_realize(DeviceState *dev, Error **errp)
> {
>     ...
> 
>     for (i = 0; i < s->num_harts; i++) {
>         /* this get cpu with hartid_base + i */        RISCVCPU *cpu = 
> RISCV_CPU(qemu_get_cpu(s->hartid_base + i));

OK I see. Pre-existing design issue, qemu_get_cpu() shouldn't exist.
Not your fault. Normally indexed cores belong to some array / cluster.

I'd assume PLIC to be wired to a fixed set of CPUs, not to some
unrelated random index. I'd expect the PLIC model to take either
an CPUCluster as link property, or a set of HART link properties,
then iterates over these internal references. Not to fish it out
elsewhere.

Again, pre-existing and not related to what you try to achieve.


Please add a /* Set CPU index for i.e. sifive_plic_realize() */
before the assignment in riscv_hart_realize(). With that:

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>

Regards,

Phil.

>         if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
>             error_setg(errp, "SEIP already claimed");
>             return;
>         }
>     }
> 
>     msi_nonbroken = true;
> }
> 
> But when adding the cpu to the global chain table, the cpu_index starts 
> at 0.
> 
> Maybe there is a better way to handle this here?
> 
> For example:
> 
> 1. When updating the cpu_index in the upper level, we can set a base id, 
> and by
> setting this base id, we can update the cpu_index indirectly.
> 
> or
> 
> 2. Modify sifive_plic_realize() to iterate over cpu's to avoid getting them
> by id.
> 
> I haven't thought of a better way to handle this at the moment,
> so we can discuss it further
> 
> -- 
> Regards,
> Chao



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-04-15 11:42 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-15  9:53 [PATCH v0 0/1] fix the way riscv_plic_hart_config_string() Chao Liu
2025-04-15  9:53 ` [PATCH v0 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly Chao Liu
2025-04-15 10:05   ` [PATCH v1 " Chao Liu
2025-04-15 10:48   ` Philippe Mathieu-Daudé
2025-04-15 11:14   ` Chao Liu
2025-04-15 11:40     ` Philippe Mathieu-Daudé
2025-04-15 10:05 ` [PATCH v1 0/1] fix the way riscv_plic_hart_config_string() gets the CPUState Chao Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).