* Re: [PATCH v3 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly
2025-04-16 5:17 ` [PATCH v3 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly Chao Liu
@ 2025-05-22 1:27 ` Alistair Francis
2025-05-22 1:29 ` Alistair Francis
1 sibling, 0 replies; 4+ messages in thread
From: Alistair Francis @ 2025-05-22 1:27 UTC (permalink / raw)
To: Chao Liu
Cc: palmer, zhiwei_liu, alistair.francis, dbarboza, liwei1518,
zhangtj, zqz00548, qemu-devel, qemu-riscv
On Wed, Apr 16, 2025 at 3:20 PM Chao Liu <lc00631@tecorigin.com> 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: Qingze Zhao <zqz00548@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 | 5 +++--
> hw/riscv/virt.c | 2 +-
> include/hw/riscv/boot.h | 2 +-
> 6 files changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
> index a5b0f6ef1b..d2aedfce78 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 765b9e2b1a..4cd29221c2 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 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/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 [flat|nested] 4+ messages in thread* Re: [PATCH v3 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly
2025-04-16 5:17 ` [PATCH v3 1/1] hw/riscv: fix PLIC hart topology configuration string when not getting CPUState correctly Chao Liu
2025-05-22 1:27 ` Alistair Francis
@ 2025-05-22 1:29 ` Alistair Francis
1 sibling, 0 replies; 4+ messages in thread
From: Alistair Francis @ 2025-05-22 1:29 UTC (permalink / raw)
To: Chao Liu
Cc: palmer, zhiwei_liu, alistair.francis, dbarboza, liwei1518,
zhangtj, zqz00548, qemu-devel, qemu-riscv
On Wed, Apr 16, 2025 at 3:20 PM Chao Liu <lc00631@tecorigin.com> 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: Qingze Zhao <zqz00548@tecorigin.com>
> Reviewed-by: Tingjian Zhang <zhangtj@tecorigin.com>
Do you mind rebasing this on
https://github.com/alistair23/qemu/tree/riscv-to-apply.next
Alistair
> ---
> hw/intc/sifive_plic.c | 4 ++--
> hw/riscv/boot.c | 4 ++--
> hw/riscv/microchip_pfsoc.c | 2 +-
> hw/riscv/sifive_u.c | 5 +++--
> hw/riscv/virt.c | 2 +-
> include/hw/riscv/boot.h | 2 +-
> 6 files changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
> index a5b0f6ef1b..d2aedfce78 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 765b9e2b1a..4cd29221c2 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 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/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 [flat|nested] 4+ messages in thread