On Fri, 16 Oct 2026 18:10:43 +0800 Jinjie Ruan <[email protected]> wrote:
> From: Jinjie Ruan <[email protected]> > > Assemble the MPAM table when vms->mpam is set: walk the QOM tree > for the board-created MSCs and emit each as a memory-controller or > cache-controller node with its MMIO base, wired interrupt GSIVs > and per-RIS locators -- per-node instances scope their locator to > their own NUMA node, single-MSC instances span every memory node, > and cache nodes carry the PPTT-referencing cache id. > > Signed-off-by: Jinjie Ruan <[email protected]> One thing around IDs I don't follow. See below. > --- > hw/arm/virt-acpi-build.c | 101 +++++++++++++++++++++++++++++++++++++++ > 1 file changed, 101 insertions(+) > > diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c > index 871ee45..3b71af9 100644 > --- a/hw/arm/virt-acpi-build.c > +++ b/hw/arm/virt-acpi-build.c > @@ -985,6 +985,102 @@ static void build_msc_cache_controller(GArray > *table_data, int identifier, > } > } > > +struct mpam_stat { > + MachineState *ms; > + GArray *table_data; > + hwaddr base_addr; > + int count; > + int cpu_count; > + uint32_t mpam_id; /* Just needs to be unique */ > +}; > + > +static int mpam_add_msc(Object *obj, void *opaque) > +{ > + if (object_dynamic_cast(obj, TYPE_MPAM_MSC_MEM)) { > + struct mpam_stat *mpam_s = opaque; > + SysBusDevice *s = SYS_BUS_DEVICE(obj); > + int num_ris = object_property_get_uint(obj, "num-ris", &error_fatal); > + uint32_t oflow_gsiv = object_property_get_uint(obj, "oflow-gsiv", > + &error_fatal); > + uint32_t err_gsiv = object_property_get_uint(obj, "err-gsiv", > + &error_fatal); > + uint64_t *ids = g_new0(uint64_t, num_ris); > + int j = 0; > + int i; > + > + /* > + * Locator for each RIS. A per-node instance (node property set) > + * covers exactly its own NUMA node; a single-MSC instance spans > + * every memory-bearing node, one RIS each. > + */ > + if (object_property_get_uint(obj, "node", &error_fatal) != > UINT16_MAX) { > + ids[j++] = object_property_get_uint(obj, "node", &error_fatal); I'm confused. Why are we setting one id here and the rest below? What is this first id? > + } > + for (i = 0; i < mpam_s->ms->numa_state->num_nodes; i++) { for (int i = 0; to keep the scope clearly defined. > + if (j >= num_ris) { > + break; > + } > + if (mpam_s->ms->numa_state->nodes[i].node_mem) { > + ids[j++] = i; > + } > + } > + > + build_msc_memory_controller(mpam_s->table_data, mpam_s->count, > + s->mmio[0].addr, mpam_s->mpam_id++, > + num_ris, ids, oflow_gsiv, err_gsiv); > + mpam_s->count++; > + g_free(ids); > + } > + > + if (object_dynamic_cast(obj, TYPE_MPAM_MSC_CACHE)) { > + struct mpam_stat *mpam_s = opaque; > + SysBusDevice *s = SYS_BUS_DEVICE(obj); > + int num_ris = 1; > + uint64_t *ids = g_new0(uint64_t, num_ris); > + uint8_t cache_level = object_property_get_uint(obj, "cache-level", > + &error_fatal); > + uint8_t cache_type = object_property_get_uint(obj, "cache-type", > + &error_fatal); > + uint16_t cpu = object_property_get_uint(obj, "cpu", &error_fatal); > + uint32_t oflow_gsiv = object_property_get_uint(obj, "oflow-gsiv", > + &error_fatal); > + uint32_t err_gsiv = object_property_get_uint(obj, "err-gsiv", > + &error_fatal); > + > + ids[0] = PPTT_CACHE_ID(cache_type, cache_level, cpu); > + build_msc_cache_controller(mpam_s->table_data, mpam_s->count, > + s->mmio[0].addr, mpam_s->mpam_id++, > + num_ris, ids, oflow_gsiv, err_gsiv); > + mpam_s->count++; > + g_free(ids); > + } > + > + return 0; > +} > + > +static void > +build_mpam(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) > +{ > + AcpiTable table = { > + .sig = "MPAM", > + .rev = 1, Is there a reason not to go directly to a newer version? Doesn't seem like that much changed and it might save us some churn at somepoint such as when adding mpam_fb option. > + .oem_id = vms->oem_id, > + .oem_table_id = vms->oem_table_id, > + }; > + struct mpam_stat mpam_s = { > + .ms = MACHINE(vms), > + .count = 0, > + .base_addr = vms->memmap[VIRT_MPAM_MSC].base, > + .table_data = table_data, > + }; > + > + acpi_table_begin(&table, table_data); > + > + object_child_foreach_recursive(object_get_root(), mpam_add_msc, &mpam_s); > + > + acpi_table_end(linker, &table); > +}
