hw/acpi/aml-build.c | 31 +- hw/arm/Kconfig | 4 + hw/arm/meson.build | 3 + hw/arm/mpam-qapi-stubs.c | 14 + hw/arm/mpam-qapi.c | 62 ++ hw/arm/mpam.c | 1620 +++++++++++++++++++++++++++++++++++ hw/arm/virt-acpi-build.c | 231 +++++ hw/arm/virt.c | 239 ++++++ include/hw/acpi/aml-build.h | 8 + include/hw/arm/mpam.h | 23 + include/hw/arm/virt.h | 3 + qapi/meson.build | 1 + qapi/mpam.json | 120 +++ qapi/qapi-schema.json | 1 + target/arm/cpu-features.h | 11 + target/arm/cpu.c | 10 +- target/arm/cpu.h | 6 + target/arm/helper.c | 33 + 18 files changed, 2410 insertions(+), 10 deletions(-) create mode 100644 hw/arm/mpam-qapi-stubs.c create mode 100644 hw/arm/mpam-qapi.c create mode 100644 hw/arm/mpam.c create mode 100644 include/hw/arm/mpam.h create mode 100644 qapi/mpam.json
From: Jinjie Ruan <ruanjinjie@huawei.com>
MPAM (Memory System Resource Partitioning and Monitoring) is Arm's
architecture for partitioning and monitoring system memory resources
- Cache portions
- Capacity limits
- Memory bandwidth and priority
And MPAM is the Arm counterpart of x86 RDT, which Linux exposes to user
space via resctrl.
QEMU so far has no MPAM support at all: the CPU-side system registers
are missing (a guest kernel that probes FEAT_MPAM takes an UNDEFINED
exception), and there are no Memory System Components (MSCs), so a virt
guest cannot exercise resctrl on Arm.
This series adds MPAM 1.1 emulation for the virt machine,
and the structure is as below:
* target/arm (patches 1-3): the CPU registers:
- MPAMIDR_EL1 and MPAM0_EL1/MPAM1_EL1
- MPAM2_EL2/MPAMHCR_EL2
- MPAMSM_EL1 for FEAT_MPAM_SMS
* hw/acpi (patch 4): PPTT revision 3 with Cache IDs, which the kernel
needs to resolve the MPAM table's cache references to PPTT cache
nodes.
* hw/arm/mpam device model (patches 5-15): built up layer by layer
- The register map as pure registerfields declarations
- The base MSC device with MMIO access
- The mpam-msc-mem and mpam-msc-cache subtypes
- MPAMCFG_PART_SEL selection
- Per-RIS partition config storage
- The partitioning features one at a time (CPOR cache portions, MBW
bandwidth, PRI priority, CCAP capacity)
- The ECR/ESR register surface
* hw/arm/mpam (patch 16): PARTID narrowing via MPAMCFG_INTPARTID with
the identity-wrap default map
- The linux mainline driver exercises it by default and resctrl
reports num_closids=32.
* hw/arm/virt + hw/acpi (patches 17-23): the board wiring, one concern
per patch
- Machine properties
- The MMIO window reservation
- Device locator/irq properties
- Memory-side MSC creation
- Cache MSC creation derived from the smp cache topology
- The ACPI MPAM table, split into the DEN0065 MSC node builders
and the table assembly
* Monitoring (patches 24-29):
- The MSMON selection/window infrastructure
- The MBWU bandwidth monitor whose counters track the configured
bandwidth control (MBW_MAX or MBW_PBM, whichever the guest drives)
- CMIN/CASSOC storage
- PRI advertised on the memory side (backing the driver's MBPRI
pseudo-resource)
- The CSU occupancy monitor (a snapshot of the capacity scaled by
the CPBM fraction)
- The board sizing of that capacity per cache level
*Error reporting (patches 30-33):
- ECR/ESR as MSC-global registers (IHI 0099 4.3)
- Device reset with power-on state initialisation
- The two level-held interrupt outputs (8.2/8.3)
- Table 7-1 error recording injected on the invalid-configuration
write paths.
* patch 34: the board wiring of the MSC interrupts to free SPIs on the
GIC, with the assigned GSIVs reported in the ACPI MPAM table.
* patch 35: defaulting to a single node when none is specified.
* patches 36-37: the query-mpam-cache QMP introspection, split into
schema+stub and implementation.
With this, a Linux guest booted with -M virt,mpam=on (plus NUMA nodes)
mounts resctrl with the full schemata set (L2/L3 CAT, capacity, MBA,
priority), and MBM bandwidth and L2/L3 occupancy counters track the
configured controls.
Verified with a Linux 7.3-rc6 guest on gic-v3: the arm_mpam driver probes
cleanly, the resctrl regression suite passes and no MPAM error interrupt
fires during normal boot.
Patches 1, 5-8 and 36-37 carry Jonathan Cameron's authorship, being
derived from his RFC series and its QMP face. Compared to that RFC [1],
this series completes most of its TODO list and tracks what the
mainline arm_mpam driver now requires:
- Monitoring
- The MSC interrupts
- Error reporting on invalid parameters
- PARTID narrowing
- The missing CPU registers
- PPTT rev 3 with Cache IDs
- CMIN/CASSOC
- Memory-side
- CSU monitoring
Still open from the RFC's TODO list: ACPI table unit tests. Like the
RFC, this is ACPI-only; the DT binding remains unimplemented.
[1] https://patchew.org/QEMU/20230808115713.2613-1-Jonathan.Cameron@huawei.com/
Jinjie Ruan (30):
target/arm: Add MPAM2_EL2 and MPAMHCR_EL2 registers
target/arm: Add MPAMSM_EL1 register
hw/acpi: Build PPTT rev 3 with cache IDs for MPAM cross-references
hw/arm/mpam: Handle MPAMCFG_PART_SEL selection
hw/arm/mpam: Add per-RIS partition config storage
hw/arm/mpam: Implement CPOR cache portion partitioning
hw/arm/mpam: Implement MBW bandwidth partitioning
hw/arm/mpam: Implement PRI priority partitioning
hw/arm/mpam: Implement CCAP capacity partitioning
hw/arm/mpam: Add ECR/ESR and error MSI register storage
hw/arm/mpam: Implement PARTID narrowing
hw/arm/virt: Add mpam and mpam-min-msc machine properties
hw/arm/virt: Reserve the MPAM MSC MMIO window
hw/arm/mpam: Add node and interrupt GSIV properties
hw/arm/virt: Create memory-side MPAM MSCs
hw/arm/virt: Create L2/L3 cache MPAM MSCs
hw/acpi: Add MPAM table MSC node builders
hw/acpi: Build the MPAM ACPI table
hw/arm/mpam: Add MSMON monitor selection and window configuration
hw/arm/mpam: Emulate MBWU bandwidth monitoring
hw/arm/mpam: Implement CMIN/CASSOC storage
hw/arm/mpam: Advertise PRI on memory-side MSCs
hw/arm/mpam: Emulate CSU cache-usage monitoring
hw/arm/virt: Size the cache MSC occupancy model by level
hw/arm/mpam: Handle ECR/ESR as MSC-global registers
hw/arm/mpam: Add device reset and power-on state initialisation
hw/arm/mpam: Add error and overflow interrupt outputs
hw/arm/mpam: Record errors and reject invalid configuration writes
hw/arm/virt: Wire MSC error and overflow interrupts to the GIC
hw/arm/virt: Default to implicit node 0 for MPAM without -numa
Jonathan Cameron (7):
target/arm: Add support for MPAM CPU registers
hw/arm/mpam: Add MPAM MSC register map
hw/arm/mpam: Add MPAM MSC base device
hw/arm/mpam: Add mpam-msc-mem memory-side MSC subtype
hw/arm/mpam: Add mpam-msc-cache MSC subtype
qapi: Add MPAM cache introspection schema and stub
hw/arm/mpam: Implement query-mpam-cache
hw/acpi/aml-build.c | 31 +-
hw/arm/Kconfig | 4 +
hw/arm/meson.build | 3 +
hw/arm/mpam-qapi-stubs.c | 14 +
hw/arm/mpam-qapi.c | 62 ++
hw/arm/mpam.c | 1620 +++++++++++++++++++++++++++++++++++
hw/arm/virt-acpi-build.c | 231 +++++
hw/arm/virt.c | 239 ++++++
include/hw/acpi/aml-build.h | 8 +
include/hw/arm/mpam.h | 23 +
include/hw/arm/virt.h | 3 +
qapi/meson.build | 1 +
qapi/mpam.json | 120 +++
qapi/qapi-schema.json | 1 +
target/arm/cpu-features.h | 11 +
target/arm/cpu.c | 10 +-
target/arm/cpu.h | 6 +
target/arm/helper.c | 33 +
18 files changed, 2410 insertions(+), 10 deletions(-)
create mode 100644 hw/arm/mpam-qapi-stubs.c
create mode 100644 hw/arm/mpam-qapi.c
create mode 100644 hw/arm/mpam.c
create mode 100644 include/hw/arm/mpam.h
create mode 100644 qapi/mpam.json
--
2.43.0
On Fri, Oct 16, 2026 at 05:46:54PM +0800, Jinjie Ruan wrote: > From: Jinjie Ruan <ruanjinjie@huawei.com> > > MPAM (Memory System Resource Partitioning and Monitoring) is Arm's > architecture for partitioning and monitoring system memory resources > - Cache portions > - Capacity limits > - Memory bandwidth and priority > > And MPAM is the Arm counterpart of x86 RDT, which Linux exposes to user > space via resctrl. > > QEMU so far has no MPAM support at all: the CPU-side system registers > are missing (a guest kernel that probes FEAT_MPAM takes an UNDEFINED > exception), and there are no Memory System Components (MSCs), so a virt > guest cannot exercise resctrl on Arm. > > This series adds MPAM 1.1 emulation for the virt machine, > and the structure is as below: > > * target/arm (patches 1-3): the CPU registers: > - MPAMIDR_EL1 and MPAM0_EL1/MPAM1_EL1 > - MPAM2_EL2/MPAMHCR_EL2 > - MPAMSM_EL1 for FEAT_MPAM_SMS > > * hw/acpi (patch 4): PPTT revision 3 with Cache IDs, which the kernel > needs to resolve the MPAM table's cache references to PPTT cache > node. On Fri, Oct 16, 2026 at 05:46:54PM +0800, Jinjie Ruan wrote: > From: Jinjie Ruan <ruanjinjie@huawei.com> > > MPAM (Memory System Resource Partitioning and Monitoring) is Arm's > architecture for partitioning and monitoring system memory resources > - Cache portions > - Capacity limits > - Memory bandwidth and priority > > And MPAM is the Arm counterpart of x86 RDT, which Linux exposes to user > space via resctrl. > > QEMU so far has no MPAM support at all: the CPU-side system registers > are missing (a guest kernel that probes FEAT_MPAM takes an UNDEFINED > exception), and there are no Memory System Components (MSCs), so a virt > guest cannot exercise resctrl on Arm. > > This series adds MPAM 1.1 emulation for the virt machine, > and the structure is as below: > > * target/arm (patches 1-3): the CPU registers: > - MPAMIDR_EL1 and MPAM0_EL1/MPAM1_EL1 > - MPAM2_EL2/MPAMHCR_EL2 > - MPAMSM_EL1 for FEAT_MPAM_SMS > > * hw/acpi (patch 4): PPTT revision 3 with Cache IDs, which the kernel > needs to resolve the MPAM table's cache references to PPTT cache > node. Thanks for posting as this patch would also be useful for RISC-V. The QoS equivalent to MPAM is CBQRI [1], and I've been working on the Qemu implementation and Linux resctrl integration. The ACPI RQSC table [2] needs to reference PPTT cache IDs, too. Sunil recently posted a PPTT series [3] but this patch 04/37 would also be needed. Thanks, Drew [1] https://lore.kernel.org/qemu-devel/20260201-riscv-ssqosid-cbqri-v5-0-273ea4a21703@kernel.org/ [2] https://lore.kernel.org/qemu-devel/20260202-riscv-rqsc-v1-0-dcf448a3ed73@kernel.org/ [3] https://lore.kernel.org/qemu-devel/20261015064957.4076464-1-sunilvl@oss.qualcomm.com/
Hi all, Sorry, due to SMTP rate limiting, this series has been split into multiple threads. The complete 37 patches are as follows: - patch 1 ~ 16: https://lore.kernel.org/all/tencent_0D8D61C20611EC56598A6F86E7B869052E05@qq.com/ - patch 17 ~ 37: https://lore.kernel.org/all/tencent_88B063FC15FDB4BD89164484DB67A9B61907@qq.com/#t 在 2026/10/16 17:46, Jinjie Ruan 写道: > From: Jinjie Ruan <ruanjinjie@huawei.com> > > MPAM (Memory System Resource Partitioning and Monitoring) is Arm's > architecture for partitioning and monitoring system memory resources > - Cache portions > - Capacity limits > - Memory bandwidth and priority > > And MPAM is the Arm counterpart of x86 RDT, which Linux exposes to user > space via resctrl. > > QEMU so far has no MPAM support at all: the CPU-side system registers > are missing (a guest kernel that probes FEAT_MPAM takes an UNDEFINED > exception), and there are no Memory System Components (MSCs), so a virt > guest cannot exercise resctrl on Arm. > > This series adds MPAM 1.1 emulation for the virt machine, > and the structure is as below: > > * target/arm (patches 1-3): the CPU registers: > - MPAMIDR_EL1 and MPAM0_EL1/MPAM1_EL1 > - MPAM2_EL2/MPAMHCR_EL2 > - MPAMSM_EL1 for FEAT_MPAM_SMS > > * hw/acpi (patch 4): PPTT revision 3 with Cache IDs, which the kernel > needs to resolve the MPAM table's cache references to PPTT cache > nodes. > > * hw/arm/mpam device model (patches 5-15): built up layer by layer > - The register map as pure registerfields declarations > - The base MSC device with MMIO access > - The mpam-msc-mem and mpam-msc-cache subtypes > - MPAMCFG_PART_SEL selection > - Per-RIS partition config storage > - The partitioning features one at a time (CPOR cache portions, MBW > bandwidth, PRI priority, CCAP capacity) > - The ECR/ESR register surface > > * hw/arm/mpam (patch 16): PARTID narrowing via MPAMCFG_INTPARTID with > the identity-wrap default map > - The linux mainline driver exercises it by default and resctrl > reports num_closids=32. > > * hw/arm/virt + hw/acpi (patches 17-23): the board wiring, one concern > per patch > - Machine properties > - The MMIO window reservation > - Device locator/irq properties > - Memory-side MSC creation > - Cache MSC creation derived from the smp cache topology > - The ACPI MPAM table, split into the DEN0065 MSC node builders > and the table assembly > > * Monitoring (patches 24-29): > - The MSMON selection/window infrastructure > - The MBWU bandwidth monitor whose counters track the configured > bandwidth control (MBW_MAX or MBW_PBM, whichever the guest drives) > - CMIN/CASSOC storage > - PRI advertised on the memory side (backing the driver's MBPRI > pseudo-resource) > - The CSU occupancy monitor (a snapshot of the capacity scaled by > the CPBM fraction) > - The board sizing of that capacity per cache level > > *Error reporting (patches 30-33): > - ECR/ESR as MSC-global registers (IHI 0099 4.3) > - Device reset with power-on state initialisation > - The two level-held interrupt outputs (8.2/8.3) > - Table 7-1 error recording injected on the invalid-configuration > write paths. > > * patch 34: the board wiring of the MSC interrupts to free SPIs on the > GIC, with the assigned GSIVs reported in the ACPI MPAM table. > > * patch 35: defaulting to a single node when none is specified. > > * patches 36-37: the query-mpam-cache QMP introspection, split into > schema+stub and implementation. > > With this, a Linux guest booted with -M virt,mpam=on (plus NUMA nodes) > mounts resctrl with the full schemata set (L2/L3 CAT, capacity, MBA, > priority), and MBM bandwidth and L2/L3 occupancy counters track the > configured controls. > > Verified with a Linux 7.3-rc6 guest on gic-v3: the arm_mpam driver probes > cleanly, the resctrl regression suite passes and no MPAM error interrupt > fires during normal boot. > > Patches 1, 5-8 and 36-37 carry Jonathan Cameron's authorship, being > derived from his RFC series and its QMP face. Compared to that RFC [1], > this series completes most of its TODO list and tracks what the > mainline arm_mpam driver now requires: > - Monitoring > - The MSC interrupts > - Error reporting on invalid parameters > - PARTID narrowing > - The missing CPU registers > - PPTT rev 3 with Cache IDs > - CMIN/CASSOC > - Memory-side > - CSU monitoring > > Still open from the RFC's TODO list: ACPI table unit tests. Like the > RFC, this is ACPI-only; the DT binding remains unimplemented. > > [1] https://patchew.org/QEMU/20230808115713.2613-1-Jonathan.Cameron@huawei.com/ > > Jinjie Ruan (30): > target/arm: Add MPAM2_EL2 and MPAMHCR_EL2 registers > target/arm: Add MPAMSM_EL1 register > hw/acpi: Build PPTT rev 3 with cache IDs for MPAM cross-references > hw/arm/mpam: Handle MPAMCFG_PART_SEL selection > hw/arm/mpam: Add per-RIS partition config storage > hw/arm/mpam: Implement CPOR cache portion partitioning > hw/arm/mpam: Implement MBW bandwidth partitioning > hw/arm/mpam: Implement PRI priority partitioning > hw/arm/mpam: Implement CCAP capacity partitioning > hw/arm/mpam: Add ECR/ESR and error MSI register storage > hw/arm/mpam: Implement PARTID narrowing > hw/arm/virt: Add mpam and mpam-min-msc machine properties > hw/arm/virt: Reserve the MPAM MSC MMIO window > hw/arm/mpam: Add node and interrupt GSIV properties > hw/arm/virt: Create memory-side MPAM MSCs > hw/arm/virt: Create L2/L3 cache MPAM MSCs > hw/acpi: Add MPAM table MSC node builders > hw/acpi: Build the MPAM ACPI table > hw/arm/mpam: Add MSMON monitor selection and window configuration > hw/arm/mpam: Emulate MBWU bandwidth monitoring > hw/arm/mpam: Implement CMIN/CASSOC storage > hw/arm/mpam: Advertise PRI on memory-side MSCs > hw/arm/mpam: Emulate CSU cache-usage monitoring > hw/arm/virt: Size the cache MSC occupancy model by level > hw/arm/mpam: Handle ECR/ESR as MSC-global registers > hw/arm/mpam: Add device reset and power-on state initialisation > hw/arm/mpam: Add error and overflow interrupt outputs > hw/arm/mpam: Record errors and reject invalid configuration writes > hw/arm/virt: Wire MSC error and overflow interrupts to the GIC > hw/arm/virt: Default to implicit node 0 for MPAM without -numa > > Jonathan Cameron (7): > target/arm: Add support for MPAM CPU registers > hw/arm/mpam: Add MPAM MSC register map > hw/arm/mpam: Add MPAM MSC base device > hw/arm/mpam: Add mpam-msc-mem memory-side MSC subtype > hw/arm/mpam: Add mpam-msc-cache MSC subtype > qapi: Add MPAM cache introspection schema and stub > hw/arm/mpam: Implement query-mpam-cache > > hw/acpi/aml-build.c | 31 +- > hw/arm/Kconfig | 4 + > hw/arm/meson.build | 3 + > hw/arm/mpam-qapi-stubs.c | 14 + > hw/arm/mpam-qapi.c | 62 ++ > hw/arm/mpam.c | 1620 +++++++++++++++++++++++++++++++++++ > hw/arm/virt-acpi-build.c | 231 +++++ > hw/arm/virt.c | 239 ++++++ > include/hw/acpi/aml-build.h | 8 + > include/hw/arm/mpam.h | 23 + > include/hw/arm/virt.h | 3 + > qapi/meson.build | 1 + > qapi/mpam.json | 120 +++ > qapi/qapi-schema.json | 1 + > target/arm/cpu-features.h | 11 + > target/arm/cpu.c | 10 +- > target/arm/cpu.h | 6 + > target/arm/helper.c | 33 + > 18 files changed, 2410 insertions(+), 10 deletions(-) > create mode 100644 hw/arm/mpam-qapi-stubs.c > create mode 100644 hw/arm/mpam-qapi.c > create mode 100644 hw/arm/mpam.c > create mode 100644 include/hw/arm/mpam.h > create mode 100644 qapi/mpam.json > -- Best regards, Jinjie
On Fri, 16 Oct 2026 at 10:47, Jinjie Ruan <2118537295@qq.com> wrote: > > From: Jinjie Ruan <ruanjinjie@huawei.com> > > MPAM (Memory System Resource Partitioning and Monitoring) is Arm's > architecture for partitioning and monitoring system memory resources > - Cache portions > - Capacity limits > - Memory bandwidth and priority > > And MPAM is the Arm counterpart of x86 RDT, which Linux exposes to user > space via resctrl. > > QEMU so far has no MPAM support at all: the CPU-side system registers > are missing (a guest kernel that probes FEAT_MPAM takes an UNDEFINED > exception), and there are no Memory System Components (MSCs), so a virt > guest cannot exercise resctrl on Arm. > > This series adds MPAM 1.1 emulation for the virt machine, > and the structure is as below: > With this, a Linux guest booted with -M virt,mpam=on (plus NUMA nodes) > mounts resctrl with the full schemata set (L2/L3 CAT, capacity, MBA, > priority), and MBM bandwidth and L2/L3 occupancy counters track the > configured controls. I guess my question here is "how much is this actually doing, and how much is it 'we provide enough software-facing interface to keep the guest happy'" ? My (rather shallow) understanding of MPAM is that it's essentially adding tags to memory transactions and then accounting how much bandwidth each tag is using. That seems obviously infeasible for emulation, but on the other hand this looks like it's rather larger than a minimal "we provide the register interface but it does nothing", so what are we doing? thanks -- PMM
在 2026/10/16 18:20, Peter Maydell 写道: > On Fri, 16 Oct 2026 at 10:47, Jinjie Ruan <2118537295@qq.com> wrote: >> >> From: Jinjie Ruan <ruanjinjie@huawei.com> >> >> MPAM (Memory System Resource Partitioning and Monitoring) is Arm's >> architecture for partitioning and monitoring system memory resources >> - Cache portions >> - Capacity limits >> - Memory bandwidth and priority >> >> And MPAM is the Arm counterpart of x86 RDT, which Linux exposes to user >> space via resctrl. >> >> QEMU so far has no MPAM support at all: the CPU-side system registers >> are missing (a guest kernel that probes FEAT_MPAM takes an UNDEFINED >> exception), and there are no Memory System Components (MSCs), so a virt >> guest cannot exercise resctrl on Arm. >> >> This series adds MPAM 1.1 emulation for the virt machine, >> and the structure is as below: > >> With this, a Linux guest booted with -M virt,mpam=on (plus NUMA nodes) >> mounts resctrl with the full schemata set (L2/L3 CAT, capacity, MBA, >> priority), and MBM bandwidth and L2/L3 occupancy counters track the >> configured controls. > > I guess my question here is "how much is this actually doing, > and how much is it 'we provide enough software-facing interface > to keep the guest happy'" ? My (rather shallow) understanding of > MPAM is that it's essentially adding tags to memory transactions > and then accounting how much bandwidth each tag is using. That > seems obviously infeasible for emulation, but on the other hand Hi Peter, Yes, I agree with you. Implementing MPAM bandwidth control and partitioning at the performance-effect level in QEMU is neither feasible nor necessary, and it is not in line with QEMU’s original purpose as a fast functional emulator. We only need to implement the functionality-related parts (i.e., the register interfaces and control flow) to ensure that the software stack can correctly recognize and configure MPAM, without simulating the real performance impact produced by those configurations. > this looks like it's rather larger than a minimal "we provide > the register interface but it does nothing", so what are we doing? By implementing MPAM-related register interfaces and control flow, as well as the MSC hardware topology in QEMU, we can understand the resctrl framework and interfaces in Linux, along with the related hardware topology discovery process. This facilitates kernel debugging and pre-silicon testing, and also allows us to debug and test test cases, avoiding the complexity and slowness of testing on FPGA. Through this series of QEMU implementations, I discovered many kernel issues and test-case issues in advance before FPGA testing, accelerating the development and testing of new kernel features (such as narrow PARTID). Moreover, as far as I understand, many hardware vendors have not yet implemented MPAM. Implementing it in QEMU helps enable MPAM on Linux, and then understand, learn, test, and even develop some MPAM-related features. Link: https://lore.kernel.org/all/20261012082337.822258-1-ruanjinjie@huawei.com/ > > thanks > -- PMM -- Best regards, Jinjie
On Mon, 19 Oct 2026 at 02:57, Jinjie Ruan <ruanjinjie@huawei.com> wrote: > 在 2026/10/16 18:20, Peter Maydell 写道: > > I guess my question here is "how much is this actually doing, > > and how much is it 'we provide enough software-facing interface > > to keep the guest happy'" ? My (rather shallow) understanding of > > MPAM is that it's essentially adding tags to memory transactions > > and then accounting how much bandwidth each tag is using. That > > seems obviously infeasible for emulation, but on the other hand > > Hi Peter, > > Yes, I agree with you. > > Implementing MPAM bandwidth control and partitioning at the > performance-effect level in QEMU is neither feasible nor necessary, and > it is not in line with QEMU’s original purpose as a fast functional > emulator. > > We only need to implement the functionality-related parts (i.e., the > register interfaces and control flow) to ensure that the software stack > can correctly recognize and configure MPAM, without simulating the real > performance impact produced by those configurations. > > > this looks like it's rather larger than a minimal "we provide > > the register interface but it does nothing", so what are we doing? > > By implementing MPAM-related register interfaces and control flow, as > well as the MSC hardware topology in QEMU, we can understand the resctrl > framework and interfaces in Linux, along with the related hardware > topology discovery process. This facilitates kernel debugging and > pre-silicon testing, and also allows us to debug and test test cases, > avoiding the complexity and slowness of testing on FPGA. Yes, but what is your implementation actually *doing* ? If software reads some MPAM resource monitor, does it read zeroes, or something else, or do we implement no monitors at all? 2400 lines is a lot of code for "nothing actually happens". -- PMM
在 2026/10/19 17:24, Peter Maydell 写道:
> On Mon, 19 Oct 2026 at 02:57, Jinjie Ruan <ruanjinjie@huawei.com> wrote:
>> 在 2026/10/16 18:20, Peter Maydell 写道:
>>> I guess my question here is "how much is this actually doing,
>>> and how much is it 'we provide enough software-facing interface
>>> to keep the guest happy'" ? My (rather shallow) understanding of
>>> MPAM is that it's essentially adding tags to memory transactions
>>> and then accounting how much bandwidth each tag is using. That
>>> seems obviously infeasible for emulation, but on the other hand
>> Hi Peter,
>>
>> Yes, I agree with you.
>>
>> Implementing MPAM bandwidth control and partitioning at the
>> performance-effect level in QEMU is neither feasible nor necessary, and
>> it is not in line with QEMU’s original purpose as a fast functional
>> emulator.
>>
>> We only need to implement the functionality-related parts (i.e., the
>> register interfaces and control flow) to ensure that the software stack
>> can correctly recognize and configure MPAM, without simulating the real
>> performance impact produced by those configurations.
>>
>>> this looks like it's rather larger than a minimal "we provide
>>> the register interface but it does nothing", so what are we doing?
>> By implementing MPAM-related register interfaces and control flow, as
>> well as the MSC hardware topology in QEMU, we can understand the resctrl
>> framework and interfaces in Linux, along with the related hardware
>> topology discovery process. This facilitates kernel debugging and
>> pre-silicon testing, and also allows us to debug and test test cases,
>> avoiding the complexity and slowness of testing on FPGA.
> Yes, but what is your implementation actually *doing* ? If
> software reads some MPAM resource monitor, does it read zeroes,
> or something else, or do we implement no monitors at all?
> 2400 lines is a lot of code for "nothing actually happens".
Monitors are implemented and do not return inert zeroes — both CSU and
MBWU read back values thattrack the partition configuration software has
programmed.
CSU (MPAMF_MSMON_CSU) — mpam_csu_value(), hw/arm/mpam.c:615, as the
"hw/arm/mpam: Emulate CSU cache-usage monitoring" patch done:
- Monitor disabled → returns 0.
- Monitor enabled with MATCH_PARTID → returns csu_capacity ×
popcount(CPBM)/32, i.e. the fraction of cache capacity the filtered
PARTID is currently allowed to occupy. Granting/revoking cache ways in
CPBM changes the readback.
static uint32_t mpam_csu_value(MPAMMSCState *s, Mpamf *mf, MpamCsuMon *m)
{
if (FIELD_EX32(m->ctl, MSMON_CFG_CSU_CTL, EN) &&
FIELD_EX32(m->ctl, MSMON_CFG_CSU_CTL, MATCH_PARTID)) {
uint32_t partid = FIELD_EX32(m->flt, MSMON_CFG_CSU_FLT, PARTID);
uint32_t nrw = mpam_nrw_id_for(s, mf, partid);
uint32_t cpbm = mf->per_nrw_id[nrw].cfg_cpbm[0];
return muldiv64(s->csu_capacity, ctpop32(cpbm), MPAM_CACHE_PART);
}
return 0;
}
The cfg_cpbm[0] was set by software by partid in patch "hw/arm/mpam:
Implement CPOR cache portion partitioning"
+ case A_MPAMF_MPAMCFG_CPBM0...
+ (A_MPAMF_MPAMCFG_CPBM0 + ((MPAM_CACHE_PART + 31) / 32 - 1) * 4):
+ {
+ uint32_t array_offset;
......
+ array_offset = (offset - A_MPAMF_MPAMCFG_CPBM0) / sizeof(uint32_t);
+ mpamf->per_nrw_id[nrw_part_sel].cfg_cpbm[array_offset] = value;
MBWU (MSMON_MBWU / MSMON_MBWU_L) — mpam_mbwu_value(), hw/arm/mpam.c:542:
- Lazily accumulated: value = base + rate × (now − t0), rate =
bw_nominal × MBW_MAX fraction (or MBW_PBM popcount ratio, if set).
- Disabled → rate = 0, readback stays at base (0 at reset).
- Enabled → counts up over time, wraps at 48 bits, latches OFLOW_STATUS,
raises the overflow IRQ. The rate depends on the MBW_MAX/PBM programmed
for the filtered PARTID, so raising a PARTID's bandwidth quota is
visible in that monitor's readback.
if (cfg->cfg_mbw_pbm[0]) {
frac_num = __builtin_popcount(cfg->cfg_mbw_pbm[0] &
((1u << MPAM_MBW_PART) - 1));
frac_den = MPAM_MBWetPART;
} else {
/* MBW_MAX is a 16-bit fraction; 0xffff = full
bandwidth. */
frac_num = cfg->cfg_mbw_max & 0xffff;
frac_den = 0xffff;
}
rate_mbs = muldiv64(rate_mbs, frac_num, frac_den);
The MBW_MAX was set by software as below in patch "hw/arm/mpam:
Implement MBW bandwidth partitioning"
case A_MPAMF_MPAMCFG_MBW_MAX:
......
mpamf->per_nrw_id[nrw_part_sel].cfg_mbw_max = value;
So the two monitors are closed-loop with the control plane: write
CPBM/MBW_MAX → the matching PARTID's CSU/MBWU readback moves. Not no-ops.
The 2400 lines break down as:
- MPAM2/MPAMHCR/MPAMSM_EL1 + PPTT rev3 cache IDs (guest visibility)
- MSC (Memory System Component) register map, mem/cache MSC subtypes,
partition control (CPOR/MBW/PRI/CCAP) + PARTID narrowing (*extended
feature*), the CSU/MBWU monitors above, error/overflow IRQ + ECR/ESR,
reset/power-on state
- MSC creation/sizing, MMIO window, IRQ-to-GIC wiring, ACPI MPAM table
- qapi/mpam.json + query-mpam-cache: introspection
- qemu boot parameters for mpam.
The bulk sits in hw/arm/mpam.c (1620 lines, two-thirds of the total),
and most of that is IHI 0099 register field definitions plus the MMIO
read/write dispatch — fixed overhead from the spec's many registers, not
logic bloat.
One honest caveat: monitors reflect configuration, not measured traffic
— rate is derived from the programmed MBW_MAX/PBM fraction, not from
real memory transactions. That is intentional for a
functional/configuration model.
Thanks,
Jinjie
>
> -- PMM
On Mon, 19 Oct 2026 at 12:46, Jinjie Ruan <2118537295@qq.com> wrote: > One honest caveat Please don't send LLM output to qemu-devel. thanks -- PMM
在 2026/10/19 20:01, Peter Maydell 写道:
> On Mon, 19 Oct 2026 at 12:46, Jinjie Ruan <2118537295@qq.com> wrote:
>> One honest caveat
>
> Please don't send LLM output to qemu-devel.
Sorry. Here is my understanding:
As mpam_csu_value() and mpam_mbwu_value() below done, the monitor code
scales the base value based on the software-configured PBM
(Partition-Based Monitoring) or MB MAX values, rather than just
returning zeroes.
And most of the code are to expose the many MPAM registers, constructing
the ACPI tables, and building the hardware topology of the memory
controllers and caches to correctly expose the MSC (Memory System
Controller) components.
static uint32_t mpam_csu_value(MPAMMSCState *s, Mpamf *mf, MpamCsuMon *m)
{
if (FIELD_EX32(m->ctl, MSMON_CFG_CSU_CTL, EN) &&
FIELD_EX32(m->ctl, MSMON_CFG_CSU_CTL, MATCH_PARTID)) {
uint32_t partid = FIELD_EX32(m->flt, MSMON_CFG_CSU_FLT, PARTID);
uint32_t nrw = mpam_nrw_id_for(s, mf, partid);
uint32_t cpbm = mf->per_nrw_id[nrw].cfg_cpbm[0];
return muldiv64(s->csu_capacity, ctpop32(cpbm),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
MPAM_CACHE_PART);
^^^^^^^^^^^^^^^^^^
}
return 0;
}
static uint64_t mpam_mbwu_value(...)
{
......
if (cfg->cfg_mbw_pbm[0]) {
frac_num = __builtin_popcount(cfg->cfg_mbw_pbm[0] &
((1u << MPAM_MBW_PART) - 1));
frac_den = MPAM_MBW_PART;
} else {
/* MBW_MAX is a 16-bit fraction; 0xffff = full bandwidth. */
frac_num = cfg->cfg_mbw_max & 0xffff;
frac_den = 0xffff;
}
rate_mbs = muldiv64(rate_mbs, frac_num, frac_den);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......
}
>
> thanks
> -- PMM
--
Best regards,
Jinjie
On Mon, 19 Oct 2026 at 13:19, Jinjie Ruan <ruanjinjie@huawei.com> wrote: > > > > 在 2026/10/19 20:01, Peter Maydell 写道: > > On Mon, 19 Oct 2026 at 12:46, Jinjie Ruan <2118537295@qq.com> wrote: > >> One honest caveat > > > > Please don't send LLM output to qemu-devel. > > Sorry. Here is my understanding: > > As mpam_csu_value() and mpam_mbwu_value() below done, the monitor code > scales the base value based on the software-configured PBM > (Partition-Based Monitoring) or MB MAX values, rather than just > returning zeroes. Thanks. So we report "you're using the full amount the system is configured to let you use". That seems reasonable. > And most of the code are to expose the many MPAM registers, constructing > the ACPI tables, and building the hardware topology of the memory > controllers and caches to correctly expose the MSC (Memory System > Controller) components. OK, that makes sense too -- I guess there's just a lot of pieces of hardware in there. thanks -- PMM
On Mon, 19 Oct 2026 13:28:03 +0100
Peter Maydell <peter.maydell@linaro.org> wrote:
> On Mon, 19 Oct 2026 at 13:19, Jinjie Ruan <ruanjinjie@huawei.com> wrote:
> >
> >
> >
> > 在 2026/10/19 20:01, Peter Maydell 写道:
> > > On Mon, 19 Oct 2026 at 12:46, Jinjie Ruan <2118537295@qq.com> wrote:
> > >> One honest caveat
> > >
> > > Please don't send LLM output to qemu-devel.
> >
> > Sorry. Here is my understanding:
> >
> > As mpam_csu_value() and mpam_mbwu_value() below done, the monitor code
> > scales the base value based on the software-configured PBM
> > (Partition-Based Monitoring) or MB MAX values, rather than just
> > returning zeroes.
>
> Thanks. So we report "you're using the full amount the system
> is configured to let you use". That seems reasonable.
>
> > And most of the code are to expose the many MPAM registers, constructing
> > the ACPI tables, and building the hardware topology of the memory
> > controllers and caches to correctly expose the MSC (Memory System
> > Controller) components.
>
> OK, that makes sense too -- I guess there's just a lot of pieces
> of hardware in there.
>
> thanks
> -- PMM
>
Hi Peter, ruanjinjie,
FWIW the much more minimal emulation that I posted years ago and
which I few crumbs of in here came up at plumbers this year with
an engineer from yet another company asking if I could look at
rebasing and upstreaming because they also found it very useful.
I was trying to work out if I could fit that into my todo list
or whether to ask a colleague to do it.
As such I'm very pleased to see this surface a few days later!
Even what I had was very useful for testing so I'm with this
much extended feature set I'm not surprised to hear even more
issues have shaken out.
It might take me a little while to get time to look at this series
but I definitely plan on doing so!
Jonathan
p.s. On off chance that (carefully unnamed) engineer sees this I
had no idea ruanjinjie was working on this.
Must have been something in the air :)
© 2016 - 2026 Red Hat, Inc.