On 10/21/2026 5:29 PM, Ralf Ramsauer wrote:
On 10/21/26 20:50, Daniel Henrique Barboza wrote:


On 10/21/2026 8:08 AM, Ralf Ramsauer wrote:
From: Ralf Ramsauer <[email protected]>

virt and sifive_u now describe a hart's PLIC contexts with the same rule:
a machine context unless the hart runs under KVM, where there is no
M-mode, and a supervisor context if the hart has supervisor mode.
Writing that rule down twice is what let the virt device tree drift away
from riscv_plic_hart_config_string().

This makes the sifive_u device tree ask whether KVM is in use, which it
did not do before.  Its PLIC device already does, so the two now agree.

Signed-off-by: Ralf Ramsauer <[email protected]>
---
Cleanup, not a fix.  Can be dropped, the rest does not depend on it.

   hw/riscv/fdt-common.c         | 20 ++++++++++++++++++++
   hw/riscv/sifive_u.c           | 10 ++--------
   hw/riscv/virt.c               | 12 +++---------
   include/hw/riscv/fdt-common.h |  3 +++
   4 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/hw/riscv/fdt-common.c b/hw/riscv/fdt-common.c
index ce2dcb43b4..70f96734b4 100644
--- a/hw/riscv/fdt-common.c
+++ b/hw/riscv/fdt-common.c
@@ -10,6 +10,7 @@
   #include "qemu/error-report.h"
   #include "system/device_tree.h"
+#include "system/kvm.h"
   #include "hw/core/boards.h"
   #include "hw/core/sysbus-fdt.h"
   #include "hw/riscv/fdt-common.h"
@@ -212,6 +213,25 @@ riscv_create_fdt_socket_cpu_sifive(void *fdt,
char *clust_name,
                                      phandle, intc_phandles, false,
false);
   }
+uint32_t riscv_plic_hart_fdt_cells(uint32_t *cells, RISCVCPU *hart,
+                                   uint32_t intc_phandle)
+{
+    uint32_t len = 0;
+
+    /* harts running under KVM have no M-mode */
+    if (!kvm_enabled()) {

In this file we're trying to keep it as bland as possible w.r.t
accelerator logic.
The idea is that the boards will do accelerator considerations and just
point
the fdt functions what to write in the fdt.  This will make it less
annoying to deal
with accel differences across multiple files ... ideally.

For example in virt.c we have:

      riscv_fdt_create_cpu_socket_subnode(ms->fdt,
          kvm_enabled() ? kvm_riscv_get_timebase_frequency(&s->soc-
  >harts[0]) :
                          RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ);

The above calls this fdt helper:

void riscv_fdt_create_cpu_socket_subnode(void *fdt,
                                           uint64_t timebase_frequency)

I.e. the fdt helper only cares about timebase_frequency to blindly put
it in the
fdt.  It doesn't care if it's kvm or not.

So for this helper I suggest something like:

uint32_t riscv_plic_hart_fdt_cells(uint32_t *cells, RISCVCPU *hart,
                                     uint32_t intc_phandle, bool has_m_mode)

{
      uint32_t len = 0;

      if (has_m_mode) {
          ...
      }
      ...
}

And then virt.c and sifive_u.c makes accellerator considerations if needed.
E.g.:


riscv_plic_hart_fdt_cells(&cells[cells_length], hart,
                            intc_phandles[cpu], !kvm_enabled());

Understand, makes sense and that's no big deal. Will send a v3-fix for
just this one, to not annoy again with a full series, unless there's
anything bigger left.

In fact it's preferrable if you could re-send everything as v3 adding my
r-bs in patches 1-3 and updating patch 4.  It's easier for the maintainer to
pick up the patches later.


Thanks,
Daniel


Thanks,
    Ralf



Thanks,
Daniel

+        cells[len++] = cpu_to_be32(intc_phandle);
+        cells[len++] = cpu_to_be32(IRQ_M_EXT);
+    }
+
+    if (riscv_cpu_has_supervisor_mode(hart)) {
+        cells[len++] = cpu_to_be32(intc_phandle);
+        cells[len++] = cpu_to_be32(IRQ_S_EXT);
+    }
+
+    return len;
+}
+
   void riscv_create_fdt_plic(void *fdt, hwaddr addr, uint64_t size,
                              uint32_t plic_phandle, uint32_t int_cells,
                              uint32_t addr_cells, uint32_t *plic_cells,
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 8f50c67a14..456b6da3e6 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -201,14 +201,8 @@ static void create_fdt(SiFiveUState *s, const
MemMapEntry *memmap,
       for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
           /* cpu 0 is the management hart that does not have S-mode */
           hart = cpu ? &s->soc.u_cpus.harts[cpu - 1] : &s-
soc.e_cpus.harts[0];
-
-        cells[cells_length++] = cpu_to_be32(intc_phandles[cpu]);
-        cells[cells_length++] = cpu_to_be32(IRQ_M_EXT);
-
-        if (riscv_cpu_has_supervisor_mode(hart)) {
-            cells[cells_length++] = cpu_to_be32(intc_phandles[cpu]);
-            cells[cells_length++] = cpu_to_be32(IRQ_S_EXT);
-        }
+        cells_length +=
riscv_plic_hart_fdt_cells(&cells[cells_length], hart,
+                                                  intc_phandles[cpu]);
       }
       riscv_create_fdt_plic(fdt, memmap[SIFIVE_U_DEV_PLIC].base,
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index a2851b506d..a325891dca 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -161,15 +161,9 @@ static void create_fdt_socket_plic(RISCVVirtState
*s,
       cells_length = 0;
       for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
-        if (!kvm_enabled()) {
-            plic_cells[cells_length++] =
cpu_to_be32(intc_phandles[cpu]);
-            plic_cells[cells_length++] = cpu_to_be32(IRQ_M_EXT);
-        }
-
-        if (riscv_cpu_has_supervisor_mode(&s->soc[socket].harts[cpu])) {
-            plic_cells[cells_length++] =
cpu_to_be32(intc_phandles[cpu]);
-            plic_cells[cells_length++] = cpu_to_be32(IRQ_S_EXT);
-        }
+        cells_length +=
riscv_plic_hart_fdt_cells(&plic_cells[cells_length],
+                                                  &s-
soc[socket].harts[cpu],
+                                                  intc_phandles[cpu]);
       }
       plic_phandles[socket] = (*phandle)++;
diff --git a/include/hw/riscv/fdt-common.h b/include/hw/riscv/fdt-
common.h
index eb9db8278d..14116a95cf 100644
--- a/include/hw/riscv/fdt-common.h
+++ b/include/hw/riscv/fdt-common.h
@@ -93,6 +93,9 @@ void riscv_create_fdt_socket_cpu_sifive(void *fdt,
char *clust_name,
                                           int socket_hartid_base,
                                           uint32_t *phandle,
                                           uint32_t *intc_phandles);
+/* Describe one hart's PLIC contexts, returns the number of cells
written */
+uint32_t riscv_plic_hart_fdt_cells(uint32_t *cells, RISCVCPU *hart,
+                                   uint32_t intc_phandle);
   void riscv_create_fdt_plic(void *fdt, hwaddr addr, uint64_t size,
                              uint32_t plic_phandle, uint32_t int_cells,
                              uint32_t addr_cells, uint32_t *plic_cells,




Reply via email to