* [PATCH v5 0/1] fix the way riscv_plic_hart_config_string() gets the CPUState
@ 2025-06-07 2:11 Chao Liu
2025-06-07 2:11 ` [PATCH v5 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly Chao Liu
2025-06-09 4:20 ` [PATCH v5 0/1] fix the way riscv_plic_hart_config_string() gets the CPUState Alistair Francis
0 siblings, 2 replies; 4+ messages in thread
From: Chao Liu @ 2025-06-07 2:11 UTC (permalink / raw)
To: dbarboza, palmer, alistair23
Cc: zhiwei_liu, alistair.francis, liwei1518, zhangtj, qemu-devel,
qemu-riscv, Chao Liu
Hi,
Thanks to Daniel's testing, I have fixed this bug.
PATCHv5:
The differences are as follows:
```
@@ -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", hartid_base);
+ qdev_prop_set_uint32(DEVICE(&s->u_cpus), "hartid-base", 1);
...
@@ -829,7 +829,7 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
- plic_hart_config = riscv_plic_hart_config_string(hartid_base, ms->smp.cpus);
+ plic_hart_config = riscv_plic_hart_config_string(0, ms->smp.cpus);
```
s->u_cpus use (ms->smp.cpus - 1), but plic_hart_config use ms->smp.cpus,
so the same hartid-base should not be used.
Therefore, we should keep the original implementation here.
PS:
During my testing, I encountered a small issue, although riscv64_tuxrun passed
the test, it still displayed a timeout. When I removed my patch,
the result was still the same.
PATCH v4:
Rebasing this on
https://github.com/alistair23/qemu/tree/riscv-to-apply.next
PATCH v3:
Use cpu_by_arch_id() instead of qemu_get_cpu(), when registering gpio in
sifive_plic_create().
PATCH v2:
During plic initialization, CPUSate is obtained by traversing qemu_get_cpu(),
which was an early design flaw (see PATCH v1 reviewed).
A better approach is to use riscv's hartid for indexing via the cpu_by_arch_id()
interface.
PATCH v1 (Reviewed):
https://lore.kernel.org/qemu-riscv/416e68f4-bf12-4218-ae2d-0246cc8ea8ec@linaro.org/T/#u
--
Regards,
Chao
Chao Liu (1):
hw/riscv: fix PLIC hart topology configuration string when not getting
CPUState correctly
hw/intc/sifive_plic.c | 4 ++--
hw/riscv/boot.c | 4 ++--
hw/riscv/microchip_pfsoc.c | 2 +-
hw/riscv/sifive_u.c | 2 +-
hw/riscv/virt.c | 2 +-
include/hw/riscv/boot.h | 2 +-
6 files changed, 8 insertions(+), 8 deletions(-)
--
2.49.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v5 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly
2025-06-07 2:11 [PATCH v5 0/1] fix the way riscv_plic_hart_config_string() gets the CPUState Chao Liu
@ 2025-06-07 2:11 ` Chao Liu
2025-06-09 4:10 ` Alistair Francis
2025-06-09 4:20 ` [PATCH v5 0/1] fix the way riscv_plic_hart_config_string() gets the CPUState Alistair Francis
1 sibling, 1 reply; 4+ messages in thread
From: Chao Liu @ 2025-06-07 2:11 UTC (permalink / raw)
To: dbarboza, palmer, alistair23
Cc: zhiwei_liu, alistair.francis, liwei1518, zhangtj, qemu-devel,
qemu-riscv, Chao Liu, Chao Liu
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.
A better approach is to use cpu_by_arch_id() instead of qemu_get_cpu(),
in riscv cpu_by_arch_id() uses the mhartid.
For non-numa or single-cluster machines, hartid_base should be 0.
Signed-off-by: Chao Liu <lc00631@tecorigin.com>
Reviewed-by: Tingjian Zhang <zhangtj@tecorigin.com>
---
hw/intc/sifive_plic.c | 4 ++--
hw/riscv/boot.c | 4 ++--
hw/riscv/microchip_pfsoc.c | 2 +-
hw/riscv/sifive_u.c | 2 +-
hw/riscv/virt.c | 2 +-
include/hw/riscv/boot.h | 2 +-
6 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index 3160b216fd..8e7ebc0655 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -399,7 +399,7 @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
* hardware controlled when a PLIC is attached.
*/
for (i = 0; i < s->num_harts; i++) {
- RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i));
+ RISCVCPU *cpu = RISCV_CPU(cpu_by_arch_id(s->hartid_base + i));
if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
error_setg(errp, "SEIP already claimed");
return;
@@ -505,7 +505,7 @@ DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
for (i = 0; i < plic->num_addrs; i++) {
int cpu_num = plic->addr_config[i].hartid;
- CPUState *cpu = qemu_get_cpu(cpu_num);
+ CPUState *cpu = cpu_by_arch_id(cpu_num);
if (plic->addr_config[i].mode == PLICMode_M) {
qdev_connect_gpio_out(dev, cpu_num - hartid_base + num_harts,
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 828a867be3..aa775e846c 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 = cpu_by_arch_id(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 2e74783fce..6c0e3b22af 100644
--- a/hw/riscv/microchip_pfsoc.c
+++ b/hw/riscv/microchip_pfsoc.c
@@ -274,7 +274,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/sifive_u.c b/hw/riscv/sifive_u.c
index d69f942cfb..c89dac0f21 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -829,7 +829,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(0, 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 cf280a92e5..d094bd186b 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1289,7 +1289,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 */
return 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.49.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v5 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly
2025-06-07 2:11 ` [PATCH v5 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly Chao Liu
@ 2025-06-09 4:10 ` Alistair Francis
0 siblings, 0 replies; 4+ messages in thread
From: Alistair Francis @ 2025-06-09 4:10 UTC (permalink / raw)
To: Chao Liu
Cc: dbarboza, palmer, zhiwei_liu, alistair.francis, liwei1518,
zhangtj, qemu-devel, qemu-riscv, Chao Liu
On Sat, Jun 7, 2025 at 12:13 PM Chao Liu <chao.liu@yeah.net> 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.
>
> A better approach is to use cpu_by_arch_id() instead of qemu_get_cpu(),
> in riscv cpu_by_arch_id() uses the mhartid.
>
> For non-numa or single-cluster machines, hartid_base should be 0.
>
> Signed-off-by: Chao Liu <lc00631@tecorigin.com>
> Reviewed-by: Tingjian Zhang <zhangtj@tecorigin.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> hw/intc/sifive_plic.c | 4 ++--
> hw/riscv/boot.c | 4 ++--
> hw/riscv/microchip_pfsoc.c | 2 +-
> hw/riscv/sifive_u.c | 2 +-
> hw/riscv/virt.c | 2 +-
> include/hw/riscv/boot.h | 2 +-
> 6 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
> index 3160b216fd..8e7ebc0655 100644
> --- a/hw/intc/sifive_plic.c
> +++ b/hw/intc/sifive_plic.c
> @@ -399,7 +399,7 @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
> * hardware controlled when a PLIC is attached.
> */
> for (i = 0; i < s->num_harts; i++) {
> - RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i));
> + RISCVCPU *cpu = RISCV_CPU(cpu_by_arch_id(s->hartid_base + i));
> if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
> error_setg(errp, "SEIP already claimed");
> return;
> @@ -505,7 +505,7 @@ DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
>
> for (i = 0; i < plic->num_addrs; i++) {
> int cpu_num = plic->addr_config[i].hartid;
> - CPUState *cpu = qemu_get_cpu(cpu_num);
> + CPUState *cpu = cpu_by_arch_id(cpu_num);
>
> if (plic->addr_config[i].mode == PLICMode_M) {
> qdev_connect_gpio_out(dev, cpu_num - hartid_base + num_harts,
> diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
> index 828a867be3..aa775e846c 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 = cpu_by_arch_id(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 2e74783fce..6c0e3b22af 100644
> --- a/hw/riscv/microchip_pfsoc.c
> +++ b/hw/riscv/microchip_pfsoc.c
> @@ -274,7 +274,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/sifive_u.c b/hw/riscv/sifive_u.c
> index d69f942cfb..c89dac0f21 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -829,7 +829,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(0, 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 cf280a92e5..d094bd186b 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -1289,7 +1289,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 */
> return 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.49.0
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v5 0/1] fix the way riscv_plic_hart_config_string() gets the CPUState
2025-06-07 2:11 [PATCH v5 0/1] fix the way riscv_plic_hart_config_string() gets the CPUState Chao Liu
2025-06-07 2:11 ` [PATCH v5 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly Chao Liu
@ 2025-06-09 4:20 ` Alistair Francis
1 sibling, 0 replies; 4+ messages in thread
From: Alistair Francis @ 2025-06-09 4:20 UTC (permalink / raw)
To: Chao Liu
Cc: dbarboza, palmer, zhiwei_liu, alistair.francis, liwei1518,
zhangtj, qemu-devel, qemu-riscv
On Sat, Jun 7, 2025 at 12:12 PM Chao Liu <chao.liu@yeah.net> wrote:
>
> Hi,
>
> Thanks to Daniel's testing, I have fixed this bug.
>
> PATCHv5:
>
> The differences are as follows:
>
> ```
> @@ -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", hartid_base);
> + qdev_prop_set_uint32(DEVICE(&s->u_cpus), "hartid-base", 1);
>
> ...
> @@ -829,7 +829,7 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
>
> - plic_hart_config = riscv_plic_hart_config_string(hartid_base, ms->smp.cpus);
> + plic_hart_config = riscv_plic_hart_config_string(0, ms->smp.cpus);
> ```
>
> s->u_cpus use (ms->smp.cpus - 1), but plic_hart_config use ms->smp.cpus,
> so the same hartid-base should not be used.
>
> Therefore, we should keep the original implementation here.
>
> PS:
>
> During my testing, I encountered a small issue, although riscv64_tuxrun passed
> the test, it still displayed a timeout. When I removed my patch,
> the result was still the same.
>
> PATCH v4:
>
> Rebasing this on
> https://github.com/alistair23/qemu/tree/riscv-to-apply.next
>
> PATCH v3:
>
> Use cpu_by_arch_id() instead of qemu_get_cpu(), when registering gpio in
> sifive_plic_create().
>
> PATCH v2:
>
> During plic initialization, CPUSate is obtained by traversing qemu_get_cpu(),
> which was an early design flaw (see PATCH v1 reviewed).
>
> A better approach is to use riscv's hartid for indexing via the cpu_by_arch_id()
> interface.
>
> PATCH v1 (Reviewed):
> https://lore.kernel.org/qemu-riscv/416e68f4-bf12-4218-ae2d-0246cc8ea8ec@linaro.org/T/#u
>
> --
> Regards,
> Chao
>
> Chao Liu (1):
> hw/riscv: fix PLIC hart topology configuration string when not getting
> CPUState correctly
>
> hw/intc/sifive_plic.c | 4 ++--
> hw/riscv/boot.c | 4 ++--
> hw/riscv/microchip_pfsoc.c | 2 +-
> hw/riscv/sifive_u.c | 2 +-
> hw/riscv/virt.c | 2 +-
> include/hw/riscv/boot.h | 2 +-
> 6 files changed, 8 insertions(+), 8 deletions(-)
Thanks!
Applied to riscv-to-apply.next
Alistair
>
> --
> 2.49.0
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-06-09 4:27 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-07 2:11 [PATCH v5 0/1] fix the way riscv_plic_hart_config_string() gets the CPUState Chao Liu
2025-06-07 2:11 ` [PATCH v5 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly Chao Liu
2025-06-09 4:10 ` Alistair Francis
2025-06-09 4:20 ` [PATCH v5 0/1] fix the way riscv_plic_hart_config_string() gets the CPUState Alistair Francis
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.