[PATCH 00/37] Add Arm MPAM emulation

Jinjie Ruan posted 37 patches 1 week, 1 day ago
Only 0 patches received!
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
[PATCH 00/37] Add Arm MPAM emulation
Posted by Jinjie Ruan 1 week, 1 day ago
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
Re: [PATCH 00/37] Add Arm MPAM emulation
Posted by Drew Fustini 3 days, 16 hours ago
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/
Re: [PATCH 00/37] Add Arm MPAM emulation
Posted by Jinjie Ruan 5 days, 5 hours ago
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


Re: [PATCH 00/37] Add Arm MPAM emulation
Posted by Peter Maydell 1 week, 1 day ago
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
Re: [PATCH 00/37] Add Arm MPAM emulation
Posted by Jinjie Ruan 5 days, 13 hours ago

在 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


Re: [PATCH 00/37] Add Arm MPAM emulation
Posted by Peter Maydell 5 days, 5 hours ago
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
Re: [PATCH 00/37] Add Arm MPAM emulation
Posted by Jinjie Ruan 5 days, 3 hours ago
在 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


Re: [PATCH 00/37] Add Arm MPAM emulation
Posted by Peter Maydell 5 days, 2 hours ago
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
Re: [PATCH 00/37] Add Arm MPAM emulation
Posted by Jinjie Ruan 5 days, 2 hours ago

在 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


Re: [PATCH 00/37] Add Arm MPAM emulation
Posted by Peter Maydell 5 days, 2 hours ago
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
Re: [PATCH 00/37] Add Arm MPAM emulation
Posted by Jonathan Cameron 4 days, 14 hours ago
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 :)