From: Jinjie Ruan <[email protected]> With mpam=on, create one mpam-msc-mem per NUMA node with memory (256 request PARTIDs narrowed to 32 internal PARTIDs), or with mpam-min-msc=on a single shared MSC with one RIS per memory node and extreme narrowing (2 internal PARTIDs). MSC creation requires NUMA nodes to be specified. Cache MSC creation arrives with the next patch.
Based on an RFC series by Jonathan Cameron, adapted to the current cache topology API (machine_get_cache_topo_level). Signed-off-by: Jinjie Ruan <[email protected]> --- hw/arm/virt.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 3ad7de8..77942e7 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -2144,6 +2144,63 @@ static void create_virtio_iommu_dt_bindings(VirtMachineState *vms) #define MPAM_VIRT_NUM_PARTID 256 #define MPAM_VIRT_NUM_INTPARTID 32 +static void create_mpam_msc(VirtMachineState *vms, Error **errp) +{ + MachineState *ms = MACHINE(vms); + DeviceState *dev; + int i, count = 0; + hwaddr base = vms->memmap[VIRT_MPAM_MSC].base; + + if (ms->numa_state->num_nodes == 0) { + error_setg(errp, + "MPAM support requires NUMA nodes to be specified"); + return; + } + if (!vms->mpam_min_msc) { + for (i = 0; i < ms->numa_state->num_nodes; i++) { + /* at most 16 mem MSCs (4-bit selector space, SPI budget) */ + if (ms->numa_state->nodes[i].node_mem > 0 && count < 16) { + dev = qdev_new(TYPE_MPAM_MSC_MEM); + + object_property_set_uint(OBJECT(dev), "node", i, + &error_fatal); + object_property_set_uint(OBJECT(dev), "num-ris", 1, + &error_fatal); + object_property_set_uint(OBJECT(dev), "num-partid", + MPAM_VIRT_NUM_PARTID, + &error_fatal); + object_property_set_uint(OBJECT(dev), "num-int-partid", + MPAM_VIRT_NUM_INTPARTID, + &error_fatal); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); + base += MPAM_SIZE; + count++; + } + } + } else { + int count_with_mem = 0; + + for (i = 0; i < ms->numa_state->num_nodes; i++) { + if (ms->numa_state->nodes[i].node_mem) { + count_with_mem++; + } + } + dev = qdev_new(TYPE_MPAM_MSC_MEM); + object_property_set_uint(OBJECT(dev), "num-ris", count_with_mem, + &error_fatal); + object_property_set_uint(OBJECT(dev), "num-partid", + MPAM_VIRT_NUM_PARTID, &error_fatal); + object_property_set_uint(OBJECT(dev), "num-int-partid", + 2, /* extreme narrowing */ + &error_fatal); + + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); + base += MPAM_SIZE; + } +} + static void create_pcie(VirtMachineState *vms) { hwaddr base_mmio = vms->memmap[VIRT_PCIE_MMIO].base; @@ -3216,6 +3273,10 @@ static void machvirt_init(MachineState *machine) create_pcie(vms); create_cxl_host_reg_region(vms); + if (vms->mpam) { + create_mpam_msc(vms, &error_fatal); + } + if (aarch64 && firmware_loaded && virt_is_acpi_enabled(vms)) { vms->acpi_dev = create_acpi_ged(vms); vms->generic_error_notifier.notify = virt_generic_error_req; -- 2.43.0
