@samitouri / QOSamiQemu / commits / abc2eb40ad

hw/arm/virt: Remember CPU phandles rather than looking them up by name

In fdt_add_cpu_nodes(), we currently add phandles for each CPU node if we are going to add a topology description, and when we do, we re-look-up the phandle by node name when creating the topology description. For GICv5 we will also want to refer to the CPU phandles; so always add a phandle, and keep track of those phandles in the VirtMachineState so we don't have to look them up by name in the dtb every time. The phandle property is extra data in the final DTB, but only a tiny amount, so it's not worth trying to carefully track the conditions when we're going to need them so we only emit them when required. (We need to change the smp_cpus variable to unsigned because otherwise gcc thinks that we might be passing a negative number to g_new0() and produces an error: /usr/include/glib-2.0/glib/gmem.h:270:19: error: argument 1 range [18446744071562067968, 18446744073709551615] exceeds maximum object size 9223372036854775807 [-Werror=alloc-size-larger-than=] 270 | __p = g_##func##_n (__n, __s); \ | ^~~~~~~~~~~~~~~~~~~~~~~ /usr/include/glib-2.0/glib/gmem.h:332:57: note: in expansion of macro ‘_G_NEW’ 332 | #define g_new0(struct_type, n_structs) _G_NEW (struct_type, n_structs, malloc0) | ^~~~~~ ../../hw/arm/virt.c:469:25: note: in expansion of macro ‘g_new0’ 469 | vms->cpu_phandles = g_new0(uint32_t, smp_cpus); | ^~~~~~ ) Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Message-id: 20260327111700.795099-57-peter.maydell@linaro.org

Peter Maydell committed Mar 27, 2026 at 11:16 UTC abc2eb40ada3fde9bf9ae26d5e19533b0c996c20
2 files changed +11 -9
hw/arm/virt.c
+10 -9
@@ -595,14 +595,14 @@ static bool partial_cache_description(const MachineState *ms, int num_caches)
595 return false;
596 }
597
598 -static void fdt_add_cpu_nodes(const VirtMachineState *vms)
598 +static void fdt_add_cpu_nodes(VirtMachineState *vms)
599 {
600 int cpu;
601 int addr_cells = 1;
602 const MachineState *ms = MACHINE(vms);
603 const MachineClass *mc = MACHINE_GET_CLASS(ms);
604 const VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
605 - int smp_cpus = ms->smp.cpus;
605 + unsigned int smp_cpus = ms->smp.cpus;
606 int socket_id, cluster_id, core_id;
607 uint32_t next_level = 0;
608 uint32_t socket_offset = 0;
@@ -656,6 +656,8 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
656 qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", addr_cells);
657 qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
658
659 + vms->cpu_phandles = g_new0(uint32_t, smp_cpus);
660 +
661 for (cpu = smp_cpus - 1; cpu >= 0; cpu--) {
662 socket_id = cpu / (ms->smp.clusters * ms->smp.cores * ms->smp.threads);
663 cluster_id = cpu / (ms->smp.cores * ms->smp.threads) % ms->smp.clusters;
@@ -665,6 +667,7 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
667 ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
668 CPUState *cs = CPU(armcpu);
669 const char *prefix = NULL;
670 + uint32_t phandle;
671
672 qemu_fdt_add_subnode(ms->fdt, nodename);
673 qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "cpu");
@@ -689,10 +692,9 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
692 ms->possible_cpus->cpus[cs->cpu_index].props.node_id);
693 }
694
692 - if (!vmc->no_cpu_topology) {
693 - qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
694 - qemu_fdt_alloc_phandle(ms->fdt));
695 - }
695 + phandle = qemu_fdt_alloc_phandle(ms->fdt);
696 + qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", phandle);
697 + vms->cpu_phandles[cpu] = phandle;
698
699 if (!vmc->no_cpu_topology && num_cache) {
700 for (uint8_t i = 0; i < num_cache; i++) {
@@ -847,7 +849,6 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
849 qemu_fdt_add_subnode(ms->fdt, "/cpus/cpu-map");
850
851 for (cpu = smp_cpus - 1; cpu >= 0; cpu--) {
850 - char *cpu_path = g_strdup_printf("/cpus/cpu@%d", cpu);
852 char *map_path;
853
854 if (ms->smp.threads > 1) {
@@ -865,10 +866,10 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
866 cpu % ms->smp.cores);
867 }
868 qemu_fdt_add_path(ms->fdt, map_path);
868 - qemu_fdt_setprop_phandle(ms->fdt, map_path, "cpu", cpu_path);
869 + qemu_fdt_setprop_cell(ms->fdt, map_path, "cpu",
870 + vms->cpu_phandles[cpu]);
871
872 g_free(map_path);
871 - g_free(cpu_path);
873 }
874 }
875 }
include/hw/arm/virt.h
+1
@@ -176,6 +176,7 @@ struct VirtMachineState {
176 uint32_t gic_phandle;
177 uint32_t msi_phandle;
178 uint32_t iommu_phandle;
179 + uint32_t *cpu_phandles;
180 int psci_conduit;
181 uint8_t virtio_transports;
182 hwaddr highest_gpa;