Devicetree
 help / color / mirror / Atom feed
* [PATCH v5 0/7] arm-mpam: Add basic device tree support for resctrl
@ 2026-11-09 10:05 Yin Li
  2026-11-09 10:05 ` [PATCH v5 1/7] arm_mpam: Fix the RIS index range check in mpam_ris_create_locked Yin Li
                   ` (6 more replies)
  0 siblings, 7 replies; 15+ messages in thread
From: Yin Li @ 2026-11-09 10:05 UTC (permalink / raw)
  To: James Morse, Rob Herring, Shanker Donthineni, Ben Horgan,
	Krzysztof Kozlowski, Conor Dooley, Catalin Marinas,
	Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
	Reinette Chatre, Fenghua Yu, Jonathan Cameron, Bjorn Andersson,
	Konrad Dybcio, Gavin Shan
  Cc: Yin Li, Andre Przywara, Drew Fustini, Ilpo Järvinen,
	Shaopeng Tan, trilok.soni, aiqun.yu, ganapatrao.kulkarni,
	Srivathsa L Rao, Huang Yiwei, linux-arm-kernel, linux-arm-msm,
	linux-kernel, driver-core, devicetree, Ping Li, stable,
	kernel test robot, Jinjie Ruan

Arm Memory System Resource Partitioning and Monitoring (MPAM) with
resctrl requires device tree (DT) support before it can be enabled on
DT-based platforms. This series provides the foundational DT binding and
parsing support for MPAM.

The verification platform has been updated from Kaanapali to Nord.

The patches are based on earlier work by James Morse, Shanker Donthineni
and Rob Herring, with fixes and additions on top.

Standalone fixes to existing mainline code (placed first, independent
of the DT work):
- arm_mpam: fix the RIS index range check
- arm_mpam: fix the MSC MMIO window size (off-by-one)

Inherited (authorship preserved, with fixes noted in each patch):
- dt-bindings: MPAM MSC binding [1]
- cacheinfo: expose cache-id generation from a device_node [2]
- arm_mpam: device tree support for MSC probing [3]
- arm_mpam: memory controller MSC support on DT platforms [4]

[1] https://git.kernel.org/pub/scm/linux/kernel/git/morse/linux.git/commit/?h=mpam/snapshot+extras/v6.18-rc1&id=b38bed339681
[2] https://git.kernel.org/pub/scm/linux/kernel/git/morse/linux.git/commit/?h=mpam/snapshot+extras/v6.18-rc1&id=2af39084438c
[3] https://git.kernel.org/pub/scm/linux/kernel/git/morse/linux.git/commit/?h=mpam/snapshot+extras/v6.18-rc1&id=a6ab8b6c77cb
[4] https://git.kernel.org/pub/scm/linux/kernel/git/morse/linux.git/commit/?h=mpam/snapshot+extras/v6.18-rc1&id=c1be40782ace

The verification platform has been updated from Kaanapali to Nord. The
Nord DTS patch adds MSC nodes for the L2 caches as a local verification
example. The MSC register size is 0x2000, as the Nord platform implements
MPAM registers up to offset 0x1FFF (permitted when MPAMCFG_MBW_PBM is
not implemented).

Signed-off-by: Yin Li <yin.li@oss.qualcomm.com>
---
Changes in v5:
  - Restore memory controller MSC support: a concrete platform user
    (DDR egress MSC) has been confirmed and verified on hardware.
  - Update binding: restore 'arm,mpam-memory-controller-msc' compatible
    and add a top-level memory controller MSC example.
  - Switch platform DTS from Kaanapali to Nord.
  - Rebase onto next-20261014.
  - Link to v4: https://patch.msgid.link/20261028-mpam-resctrl-dt-knp-support-v4-0-bdda1e445cba@oss.qualcomm.com

Changes in v4:
  - Reduce binding to minimal set covering only properties in current
    use: remove RIS child node support, memory controller support,
    arm,mpam-device, cpus and interrupt-names.
  - Drop memory controller MSC patch (no concrete platform user).
  - Drop RIS accessibility patch (no concrete platform user).
  - Update DNM Kaanapali DTS: fix node names, compatible, ranges/reg
    format; use 0x2000 register size reflecting platform implementation.
  - Rebase onto next-20261014.
  - Link to v3: https://patch.msgid.link/20261008-mpam-resctrl-dt-knp-support-v3-0-35196c2b43bf@oss.qualcomm.com

Changes since RFC v2:
  - Fold the binding schema/example fixes into the binding patch.
  - Fold the foundling MSC fix into the DT support patch; remove the
    unnecessary parent cache availability check from
    mpam_dt_create_foundling_msc() to keep it consistent with
    mpam_dt_count_msc().
  - Remove the #ifdef CONFIG_OF guard around the cache_of_calculate_id()
    prototype in cacheinfo.h.
  - Remove the [Yin Li:] annotation from the cacheinfo patch.
  - Rebase onto next-20260918.

Changes since RFC v1:
  - Fold fixes to inherited patches into their respective patches with
    [Yin Li: ...] annotations, as requested by Ben and Andre.
  - Move the RIS index range-check and MSC MMIO window size fixes to the
    front as standalone fixes with Fixes: tags.
  - MSC MMIO window size: genuine off-by-one fix; the ">" bounds checks
    include the access width and are kept as-is.
  - ris_idx: validate range after of_property_read_reg() and keep u8
    downstream, instead of widening the call chain to u64.
  - cache-id sentinel: keep ~0U notation, leave cacheinfo.c unchanged,
    replace unsigned long with u32.
  - Convert mpam_get_cpumask_from_cache_id() and the cache/component-id
    variables from unsigned long to u32.
  - Fold the device_node refcount fix (of_node_get()), reviewed by Andre
    Przywara in RFC v1, into the DT support and memory-controller MSC
    patches.
  - Drop the "clear mask on error" patch.

Previous versions:
  v4: https://lore.kernel.org/all/20261028-mpam-resctrl-dt-knp-support-v4-0-bdda1e445cba@oss.qualcomm.com/
  v3: https://lore.kernel.org/all/20261008-mpam-resctrl-dt-knp-support-v3-0-35196c2b43bf@oss.qualcomm.com/
  RFC v2: https://lore.kernel.org/all/20260914-mpam-resctrl-dt-knp-support-v2-0-bf6645bb2f65@oss.qualcomm.com/
  RFC v1: https://lore.kernel.org/all/20260811-mpam-resctrl-dt-knp-support-v1-0-ea6397bead59@oss.qualcomm.com/

To: James Morse <james.morse@arm.com>
To: Rob Herring <robh@kernel.org>
To: Shanker Donthineni <sdonthineni@nvidia.com>
To: Ben Horgan <ben.horgan@arm.com>
To: Krzysztof Kozlowski <krzk+dt@kernel.org>
To: Conor Dooley <conor+dt@kernel.org>
To: Catalin Marinas <catalin.marinas@arm.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: "Rafael J. Wysocki" <rafael@kernel.org>
To: Danilo Krummrich <dakr@kernel.org>
To: Reinette Chatre <reinette.chatre@intel.com>
To: Fenghua Yu <fenghuay@nvidia.com>
To: Jonathan Cameron <jic23@kernel.org>
To: Bjorn Andersson <andersson@kernel.org>
To: Konrad Dybcio <konradybcio@kernel.org>
To: Gavin Shan <gshan@redhat.com>
Cc: Andre Przywara <andre.przywara@arm.com>
Cc: Drew Fustini <fustini@kernel.org>
Cc: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Cc: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Cc: trilok.soni@oss.qualcomm.com
Cc: aiqun.yu@oss.qualcomm.com
Cc: ganapatrao.kulkarni@oss.qualcomm.com
Cc: Srivathsa L Rao <srivathsa.rao@oss.qualcomm.com>
Cc: Huang Yiwei <huang.yiwei@oss.qualcomm.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-arm-msm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: driver-core@lists.linux.dev
Cc: devicetree@vger.kernel.org
Cc: Ping Li <leeonion.muyu@gmail.com>

---
James Morse (2):
      cacheinfo: Expose the code to generate a cache-id from a device_node
      arm_mpam: Add device tree support for MSC probing

Rob Herring (1):
      dt-bindings: arm: Add MPAM MSC binding

Shanker Donthineni (1):
      arm_mpam: Add support for memory controller MSC on DT platforms

Yin Li (3):
      arm_mpam: Fix the RIS index range check in mpam_ris_create_locked
      arm_mpam: Fix MSC MMIO window size off-by-one with resource_size()
      arm64: dts: qcom: nord: Add MPAM MSC nodes for the L2 caches

 .../devicetree/bindings/arm/arm,mpam-msc.yaml      |  62 +++++
 arch/arm64/boot/dts/qcom/nord.dtsi                 |  72 ++++--
 drivers/base/cacheinfo.c                           |  17 +-
 drivers/resctrl/mpam_devices.c                     | 278 +++++++++++++++++++--
 drivers/resctrl/mpam_internal.h                    |   2 +-
 include/linux/cacheinfo.h                          |   1 +
 6 files changed, 389 insertions(+), 43 deletions(-)
---
base-commit: ddfe51b0a0f5dc9e415cc2c8ad8db17532dd426b
change-id: 20260731-mpam-resctrl-dt-knp-support-c15dcc3a4a98

Best regards,
--  
Yin Li <yin.li@oss.qualcomm.com>


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v5 1/7] arm_mpam: Fix the RIS index range check in mpam_ris_create_locked
  2026-11-09 10:05 [PATCH v5 0/7] arm-mpam: Add basic device tree support for resctrl Yin Li
@ 2026-11-09 10:05 ` Yin Li
  2026-11-09 10:05 ` [PATCH v5 2/7] arm_mpam: Fix MSC MMIO window size off-by-one with resource_size() Yin Li
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Yin Li @ 2026-11-09 10:05 UTC (permalink / raw)
  To: James Morse, Rob Herring, Shanker Donthineni, Ben Horgan,
	Krzysztof Kozlowski, Conor Dooley, Catalin Marinas,
	Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
	Reinette Chatre, Fenghua Yu, Jonathan Cameron, Bjorn Andersson,
	Konrad Dybcio, Gavin Shan
  Cc: Yin Li, Andre Przywara, Drew Fustini, Ilpo Järvinen,
	Shaopeng Tan, trilok.soni, aiqun.yu, ganapatrao.kulkarni,
	Srivathsa L Rao, Huang Yiwei, linux-arm-kernel, linux-arm-msm,
	linux-kernel, driver-core, devicetree, Ping Li, stable

The RIS selector field is defined as MPAMCFG_PART_SEL_RIS (bits 27:24),
which is 4 bits wide and gives valid indices 0..15. MPAM_MSC_MAX_NUM_RIS
is defined as 16, so the check should use >= to reject index 16 and
above. The previous > check incorrectly accepted index 16 as valid.

Fixes: 01fb4b822472 ("arm_mpam: Add the class and component structures for firmware described ris")
Cc: stable@vger.kernel.org
Signed-off-by: Yin Li <yin.li@oss.qualcomm.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Ben Horgan <ben.horgan@arm.com>
Reviewed-by: Srivathsa L Rao <srivathsa.rao@oss.qualcomm.com>
---
 drivers/resctrl/mpam_devices.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/resctrl/mpam_devices.c b/drivers/resctrl/mpam_devices.c
index c067b6d57d71..05f785328dc2 100644
--- a/drivers/resctrl/mpam_devices.c
+++ b/drivers/resctrl/mpam_devices.c
@@ -700,7 +700,7 @@ static int mpam_ris_create_locked(struct mpam_msc *msc, u8 ris_idx,
 
 	lockdep_assert_held(&mpam_list_lock);
 
-	if (ris_idx > MPAM_MSC_MAX_NUM_RIS)
+	if (ris_idx >= MPAM_MSC_MAX_NUM_RIS)
 		return -EINVAL;
 
 	if (test_and_set_bit(ris_idx, &msc->ris_idxs))

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 2/7] arm_mpam: Fix MSC MMIO window size off-by-one with resource_size()
  2026-11-09 10:05 [PATCH v5 0/7] arm-mpam: Add basic device tree support for resctrl Yin Li
  2026-11-09 10:05 ` [PATCH v5 1/7] arm_mpam: Fix the RIS index range check in mpam_ris_create_locked Yin Li
@ 2026-11-09 10:05 ` Yin Li
  2026-11-09 10:05 ` [PATCH v5 3/7] dt-bindings: arm: Add MPAM MSC binding Yin Li
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Yin Li @ 2026-11-09 10:05 UTC (permalink / raw)
  To: James Morse, Rob Herring, Shanker Donthineni, Ben Horgan,
	Krzysztof Kozlowski, Conor Dooley, Catalin Marinas,
	Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
	Reinette Chatre, Fenghua Yu, Jonathan Cameron, Bjorn Andersson,
	Konrad Dybcio, Gavin Shan
  Cc: Yin Li, Andre Przywara, Drew Fustini, Ilpo Järvinen,
	Shaopeng Tan, trilok.soni, aiqun.yu, ganapatrao.kulkarni,
	Srivathsa L Rao, Huang Yiwei, linux-arm-kernel, linux-arm-msm,
	linux-kernel, driver-core, devicetree, Ping Li, stable,
	kernel test robot, Jinjie Ruan

struct resource uses an inclusive end address, so the window size is
end - start + 1. do_mpam_msc_drv_probe() computed it as end - start,
which is one byte too small.

mapped_hwpage_sz is used by the register access bounds checks, which
have the form "offset + width > mapped_hwpage_sz". With the size one
byte too small, an access to the last register in the window is
incorrectly flagged as out of bounds: for a 0x1000 window, a 4-byte
access at offset 0xFFC (bytes 0xFFC..0xFFF, legal) computes
0xFFC + 4 = 0x1000 > 0xFFF and falsely warns.

Use resource_size() so the size is correct. The ">" bounds checks are
correct as-is once the size is accurate and are left unchanged.

Fixes: f04046f2577a ("arm_mpam: Add probe/remove for mpam msc driver and kbuild boiler plate")
Cc: stable@vger.kernel.org
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202609030809.ObirDhR3-lkp@intel.com/
Signed-off-by: Yin Li <yin.li@oss.qualcomm.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Ben Horgan <ben.horgan@arm.com>
Reviewed-by: Jinjie Ruan <ruanjinjie@huawei.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Reviewed-by: Srivathsa L Rao <srivathsa.rao@oss.qualcomm.com>
---
 drivers/resctrl/mpam_devices.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/resctrl/mpam_devices.c b/drivers/resctrl/mpam_devices.c
index 05f785328dc2..bea231dac7e6 100644
--- a/drivers/resctrl/mpam_devices.c
+++ b/drivers/resctrl/mpam_devices.c
@@ -2506,7 +2506,7 @@ static struct mpam_msc *do_mpam_msc_drv_probe(struct platform_device *pdev)
 			dev_err_once(dev, "Failed to map MSC base address\n");
 			return ERR_CAST(io);
 		}
-		msc->mapped_hwpage_sz = msc_res->end - msc_res->start;
+		msc->mapped_hwpage_sz = resource_size(msc_res);
 		msc->mapped_hwpage = io;
 	} else if (msc->iface == MPAM_IFACE_PCC) {
 		u32 mpam_fb_msc_id;

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 3/7] dt-bindings: arm: Add MPAM MSC binding
  2026-11-09 10:05 [PATCH v5 0/7] arm-mpam: Add basic device tree support for resctrl Yin Li
  2026-11-09 10:05 ` [PATCH v5 1/7] arm_mpam: Fix the RIS index range check in mpam_ris_create_locked Yin Li
  2026-11-09 10:05 ` [PATCH v5 2/7] arm_mpam: Fix MSC MMIO window size off-by-one with resource_size() Yin Li
@ 2026-11-09 10:05 ` Yin Li
  2026-11-09 10:38   ` sashiko-bot
  2026-11-09 10:05 ` [PATCH v5 4/7] cacheinfo: Expose the code to generate a cache-id from a device_node Yin Li
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Yin Li @ 2026-11-09 10:05 UTC (permalink / raw)
  To: James Morse, Rob Herring, Shanker Donthineni, Ben Horgan,
	Krzysztof Kozlowski, Conor Dooley, Catalin Marinas,
	Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
	Reinette Chatre, Fenghua Yu, Jonathan Cameron, Bjorn Andersson,
	Konrad Dybcio, Gavin Shan
  Cc: Yin Li, Andre Przywara, Drew Fustini, Ilpo Järvinen,
	Shaopeng Tan, trilok.soni, aiqun.yu, ganapatrao.kulkarni,
	Srivathsa L Rao, Huang Yiwei, linux-arm-kernel, linux-arm-msm,
	linux-kernel, driver-core, devicetree, Ping Li

From: Rob Herring <robh@kernel.org>

The binding is designed around the assumption that an MSC will usually
be a sub-block of something else such as a memory controller or cache
controller. A memory-controller MSC may also stand on its own as a
top-level node, without being nested under a dedicated controller
node.

A key part of MPAM is we need to know about all of the MSCs in the system
before it can be enabled. This drives the need for the genericish
'arm,mpam-msc' compatible. Though we can't assume an MSC is accessible
until a h/w specific driver potentially enables the h/w.

This binding covers only the properties currently used in practice; it
can be extended as additional features are needed.

Cc: James Morse <james.morse@arm.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: James Morse <james.morse@arm.com>
[ Yin Li and Huang Yiwei: use oneOf for the compatible to allow both
  standalone arm,mpam-msc and the two-item combination; fix schema
  field order and yamllint spacing; reduce to minimal binding covering
  only properties in current use, dropping RIS child nodes, the
  explicit arm,mpam-device phandle form, cpus and interrupt-names;
  replace the memory-controller example with a new top-level one,
  showing the MSC as a direct child of the root node ]
Co-developed-by: Huang Yiwei <huang.yiwei@oss.qualcomm.com>
Signed-off-by: Huang Yiwei <huang.yiwei@oss.qualcomm.com>
Signed-off-by: Yin Li <yin.li@oss.qualcomm.com>
---
 .../devicetree/bindings/arm/arm,mpam-msc.yaml      | 62 ++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/arm,mpam-msc.yaml b/Documentation/devicetree/bindings/arm/arm,mpam-msc.yaml
new file mode 100644
index 000000000000..b52599b47a1c
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/arm,mpam-msc.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/arm,mpam-msc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Arm Memory System Resource Partitioning and Monitoring (MPAM)
+
+maintainers:
+  - Rob Herring <robh@kernel.org>
+
+description: |
+  The Arm MPAM specification can be found here:
+
+  https://developer.arm.com/documentation/ddi0598/latest
+
+properties:
+  compatible:
+    oneOf:
+      - const: arm,mpam-msc                   # Further details are discoverable
+      - items:
+          - const: arm,mpam-memory-controller-msc
+          - const: arm,mpam-msc
+
+  reg:
+    maxItems: 1
+    description: A memory region containing registers as defined in the MPAM
+      specification.
+
+  arm,not-ready-us:
+    description: The maximum time in microseconds for monitoring data to be
+      accurate after a settings change. For more information, see the
+      Not-Ready (NRDY) bit description in the MPAM specification.
+
+additionalProperties: false
+
+examples:
+  - |
+    L3: cache-controller@30000000 {
+        compatible = "foo,a-l3-cache", "cache";
+        cache-level = <3>;
+        cache-unified;
+        reg = <0x0 0x30000000 0x0 0x2000>;
+        ranges = <0x0 0x30000000 0x2000>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        msc@0 {
+            compatible = "arm,mpam-msc";
+            reg = <0x0 0x2000>;
+            arm,not-ready-us = <1>;
+            /* CPU affinity implied by parent cache node  */
+        };
+    };
+
+    ddr_msc: msc@40000000 {
+        compatible = "arm,mpam-memory-controller-msc", "arm,mpam-msc";
+        reg = <0x40000000 0x1000>;
+        arm,not-ready-us = <10>;
+    };
+
+...

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 4/7] cacheinfo: Expose the code to generate a cache-id from a device_node
  2026-11-09 10:05 [PATCH v5 0/7] arm-mpam: Add basic device tree support for resctrl Yin Li
                   ` (2 preceding siblings ...)
  2026-11-09 10:05 ` [PATCH v5 3/7] dt-bindings: arm: Add MPAM MSC binding Yin Li
@ 2026-11-09 10:05 ` Yin Li
  2026-11-09 10:05 ` [PATCH v5 5/7] arm_mpam: Add device tree support for MSC probing Yin Li
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Yin Li @ 2026-11-09 10:05 UTC (permalink / raw)
  To: James Morse, Rob Herring, Shanker Donthineni, Ben Horgan,
	Krzysztof Kozlowski, Conor Dooley, Catalin Marinas,
	Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
	Reinette Chatre, Fenghua Yu, Jonathan Cameron, Bjorn Andersson,
	Konrad Dybcio, Gavin Shan
  Cc: Yin Li, Andre Przywara, Drew Fustini, Ilpo Järvinen,
	Shaopeng Tan, trilok.soni, aiqun.yu, ganapatrao.kulkarni,
	Srivathsa L Rao, Huang Yiwei, linux-arm-kernel, linux-arm-msm,
	linux-kernel, driver-core, devicetree, Ping Li

From: James Morse <james.morse@arm.com>

The MPAM driver identifies caches by id for use with resctrl. It
needs to know the cache-id when probe-ing, but the value isn't set
in cacheinfo until device_initcall(). Even after device_initcall(),
the cache-id is only available if at least one CPU associated with
the cache is online.

Instead of making the driver wait, expose the code that generates the
cache-id. The parts of the MPAM driver that run early can use this to
set up the resctrl structures before cacheinfo is ready in
device_initcall().

Signed-off-by: James Morse <james.morse@arm.com>
Signed-off-by: Yin Li <yin.li@oss.qualcomm.com>
---
 drivers/base/cacheinfo.c  | 17 ++++++++++++-----
 include/linux/cacheinfo.h |  1 +
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c
index eb8a907f6d50..a4b10f3a9007 100644
--- a/drivers/base/cacheinfo.c
+++ b/drivers/base/cacheinfo.c
@@ -243,8 +243,7 @@ static bool match_cache_node(struct device_node *cpu,
 #define arch_compact_of_hwid(_x)	(_x)
 #endif
 
-static void cache_of_set_id(struct cacheinfo *this_leaf,
-			    struct device_node *cache_node)
+u32 cache_of_calculate_id(struct device_node *cache_node)
 {
 	struct device_node *cpu;
 	u32 min_id = ~0;
@@ -255,15 +254,23 @@ static void cache_of_set_id(struct cacheinfo *this_leaf,
 		id = arch_compact_of_hwid(id);
 		if (FIELD_GET(GENMASK_ULL(63, 32), id)) {
 			of_node_put(cpu);
-			return;
+			return ~0;
 		}
 
 		if (match_cache_node(cpu, cache_node))
 			min_id = min(min_id, id);
 	}
 
-	if (min_id != ~0) {
-		this_leaf->id = min_id;
+	return min_id;
+}
+
+static void cache_of_set_id(struct cacheinfo *this_leaf,
+			    struct device_node *cache_node)
+{
+	u32 id = cache_of_calculate_id(cache_node);
+
+	if (id != ~0) {
+		this_leaf->id = id;
 		this_leaf->attributes |= CACHE_ID;
 	}
 }
diff --git a/include/linux/cacheinfo.h b/include/linux/cacheinfo.h
index 56fa646df0d1..469d490968ac 100644
--- a/include/linux/cacheinfo.h
+++ b/include/linux/cacheinfo.h
@@ -114,6 +114,7 @@ int acpi_get_cache_info(unsigned int cpu,
 #endif
 
 const struct attribute_group *cache_get_priv_group(struct cacheinfo *this_leaf);
+u32 cache_of_calculate_id(struct device_node *np);
 
 /*
  * Get the cacheinfo structure for the cache associated with @cpu at

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 5/7] arm_mpam: Add device tree support for MSC probing
  2026-11-09 10:05 [PATCH v5 0/7] arm-mpam: Add basic device tree support for resctrl Yin Li
                   ` (3 preceding siblings ...)
  2026-11-09 10:05 ` [PATCH v5 4/7] cacheinfo: Expose the code to generate a cache-id from a device_node Yin Li
@ 2026-11-09 10:05 ` Yin Li
  2026-11-09 11:08   ` sashiko-bot
  2026-11-09 10:05 ` [PATCH v5 6/7] arm_mpam: Add support for memory controller MSC on DT platforms Yin Li
  2026-11-09 10:05 ` [PATCH v5 7/7] arm64: dts: qcom: nord: Add MPAM MSC nodes for the L2 caches Yin Li
  6 siblings, 1 reply; 15+ messages in thread
From: Yin Li @ 2026-11-09 10:05 UTC (permalink / raw)
  To: James Morse, Rob Herring, Shanker Donthineni, Ben Horgan,
	Krzysztof Kozlowski, Conor Dooley, Catalin Marinas,
	Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
	Reinette Chatre, Fenghua Yu, Jonathan Cameron, Bjorn Andersson,
	Konrad Dybcio, Gavin Shan
  Cc: Yin Li, Andre Przywara, Drew Fustini, Ilpo Järvinen,
	Shaopeng Tan, trilok.soni, aiqun.yu, ganapatrao.kulkarni,
	Srivathsa L Rao, Huang Yiwei, linux-arm-kernel, linux-arm-msm,
	linux-kernel, driver-core, devicetree, Ping Li

From: James Morse <james.morse@arm.com>

The MPAM driver currently discovers MSCs only via ACPI. Add a device
tree path so MSCs can be probed on DT-based platforms: parse MSC nodes
from the device tree, compute cache-id and affinity from the cache
nodes and create the RIS entries.

Signed-off-by: James Morse <james.morse@arm.com>
[ Yin Li: drop the ACPI-only stub of mpam_get_cpumask_from_cache_id();
  use of_node_get() for the cache parent to avoid a refcount underflow;
  reject out-of-range ris_idx after of_property_read_reg() before
  narrowing to u8; use u32 instead of unsigned long for cache-id values
  and compare against ~0U; fix mpam_dt_create_foundling_msc() to iterate
  MSC child nodes rather than creating a device for the cache node itself ]
Signed-off-by: Yin Li <yin.li@oss.qualcomm.com>
---
 drivers/resctrl/mpam_devices.c  | 250 +++++++++++++++++++++++++++++++++++++---
 drivers/resctrl/mpam_internal.h |   2 +-
 2 files changed, 234 insertions(+), 18 deletions(-)

diff --git a/drivers/resctrl/mpam_devices.c b/drivers/resctrl/mpam_devices.c
index bea231dac7e6..78caa8ae1349 100644
--- a/drivers/resctrl/mpam_devices.c
+++ b/drivers/resctrl/mpam_devices.c
@@ -22,6 +22,9 @@
 #include <linux/lockdep.h>
 #include <linux/mailbox_client.h>
 #include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/printk.h>
 #include <linux/property.h>
@@ -263,6 +266,171 @@ static void mpam_free_garbage(void)
 	}
 }
 
+/* Called recursively to walk the list of caches from a particular CPU */
+static void __mpam_get_cpumask_from_cache_id(int cpu, struct device_node *cache_node,
+					     u32 cache_id,
+					     u32 cache_level,
+					     cpumask_t *affinity)
+{
+	int err;
+	u32 iter_level;
+	u32 iter_cache_id;
+	struct device_node *iter_node __free(device_node) = of_find_next_cache_node(cache_node);
+
+	if (!iter_node)
+		return;
+
+	err = of_property_read_u32(iter_node, "cache-level", &iter_level);
+	if (err)
+		return;
+
+	/*
+	 * get_cpu_cacheinfo_id() isn't ready until sometime
+	 * during device_initcall(). Use cache_of_calculate_id().
+	 */
+	iter_cache_id = cache_of_calculate_id(iter_node);
+	if (iter_cache_id == ~0U)
+		return;
+
+	if (iter_level == cache_level && iter_cache_id == cache_id)
+		cpumask_set_cpu(cpu, affinity);
+
+	if (iter_level < cache_level)
+		__mpam_get_cpumask_from_cache_id(cpu, iter_node, cache_id,
+						 cache_level, affinity);
+}
+
+/*
+ * The cacheinfo structures are only populated when CPUs are online.
+ * This helper walks the device tree to include offline CPUs too.
+ */
+int mpam_get_cpumask_from_cache_id(u32 cache_id, u32 cache_level,
+				   cpumask_t *affinity)
+{
+	int cpu;
+
+	if (!acpi_disabled)
+		return acpi_pptt_get_cpumask_from_cache_id(cache_id, affinity);
+
+	for_each_possible_cpu(cpu) {
+		struct device_node *cpu_node __free(device_node) = of_get_cpu_node(cpu, NULL);
+		if (!cpu_node) {
+			pr_err("Failed to find cpu%d device node\n", cpu);
+			return -ENOENT;
+		}
+
+		__mpam_get_cpumask_from_cache_id(cpu, cpu_node, cache_id,
+						 cache_level, affinity);
+	}
+
+	return 0;
+}
+
+static int get_cpumask_from_cache(struct device_node *cache,
+				  cpumask_t *affinity)
+{
+	int err;
+	u32 cache_level;
+	u32 cache_id;
+
+	err = of_property_read_u32(cache, "cache-level", &cache_level);
+	if (err) {
+		pr_err("Failed to read cache-level from cache node\n");
+		return -ENOENT;
+	}
+
+	cache_id = cache_of_calculate_id(cache);
+	if (cache_id == ~0U) {
+		pr_err("Failed to calculate cache-id from cache node\n");
+		return -ENOENT;
+	}
+
+	return mpam_get_cpumask_from_cache_id(cache_id, cache_level, affinity);
+}
+
+static int mpam_dt_count_msc(void)
+{
+	int count = 0;
+	struct device_node *np;
+
+	for_each_compatible_node(np, NULL, "arm,mpam-msc") {
+		if (of_device_is_available(np))
+			count++;
+	}
+
+	return count;
+}
+
+static int mpam_dt_parse_resource(struct mpam_msc *msc, struct device_node *np,
+				  u8 ris_idx)
+{
+	int err = 0;
+	u32 level = 0;
+	u32 cache_id;
+	struct device *dev = &msc->pdev->dev;
+	struct device_node *cache __free(device_node) = NULL;
+	struct device_node *parent __free(device_node) = of_get_parent(np);
+
+	if (of_device_is_compatible(np, "arm,mpam-cache")) {
+		cache = of_parse_phandle(np, "arm,mpam-device", 0);
+		if (!cache) {
+			dev_err_once(dev, "Failed to read phandle\n");
+			return -EINVAL;
+		}
+	} else if (of_device_is_compatible(parent, "cache")) {
+		cache = of_node_get(parent);
+	} else {
+		/* For now, only caches are supported */
+		cache = NULL;
+		return err;
+	}
+
+	err = of_property_read_u32(cache, "cache-level", &level);
+	if (err) {
+		dev_err_once(dev, "Failed to read cache-level\n");
+		return err;
+	}
+
+	cache_id = cache_of_calculate_id(cache);
+	if (cache_id == ~0U) {
+		dev_err_once(dev, "Failed to calculate cache-id\n");
+		return -ENOENT;
+	}
+
+	return mpam_ris_create(msc, ris_idx, MPAM_CLASS_CACHE, level, cache_id);
+}
+
+static int mpam_dt_parse_resources(struct mpam_msc *msc, void *ignored)
+{
+	u64 ris_idx = 0;
+	int err, num_ris = 0;
+	struct device_node *np;
+
+	np = msc->pdev->dev.of_node;
+	for_each_available_child_of_node_scoped(np, iter) {
+		err = of_property_read_reg(iter, 0, &ris_idx, NULL);
+		if (!err) {
+			/*
+			 * ris_idx is read as u64 but indexes a 4-bit RIS selector
+			 * (0..MPAM_MSC_MAX_NUM_RIS). Reject out-of-range values here,
+			 * before it is narrowed to u8, so a large value cannot be
+			 * truncated into a valid-looking index.
+			 */
+			if (ris_idx >= MPAM_MSC_MAX_NUM_RIS)
+				return -EINVAL;
+			num_ris++;
+			err = mpam_dt_parse_resource(msc, iter, ris_idx);
+			if (err)
+				return err;
+		}
+	}
+
+	if (!num_ris)
+		err = mpam_dt_parse_resource(msc, np, 0);
+
+	return err;
+}
+
 /*
  * Once mpam is enabled, new requestors cannot further reduce the available
  * partid. Assert that the size is fixed, and new requestors will be turned
@@ -629,16 +797,6 @@ mpam_vmsc_find(struct mpam_component *comp, struct mpam_msc *msc)
 	return mpam_vmsc_alloc(comp, msc);
 }
 
-/*
- * The cacheinfo structures are only populated when CPUs are online.
- * This helper walks the acpi tables to include offline CPUs too.
- */
-int mpam_get_cpumask_from_cache_id(unsigned long cache_id, u32 cache_level,
-				   cpumask_t *affinity)
-{
-	return acpi_pptt_get_cpumask_from_cache_id(cache_id, affinity);
-}
-
 /*
  * cpumask_of_node() only knows about online CPUs. This can't tell us whether
  * a class is represented on all possible CPUs.
@@ -2392,15 +2550,34 @@ static int mpam_msc_setup_error_irq(struct mpam_msc *msc)
  */
 static void update_msc_accessibility(struct mpam_msc *msc)
 {
+	struct device *dev = &msc->pdev->dev;
+	struct device_node *parent;
 	u32 affinity_id;
 	int err;
 
-	err = device_property_read_u32(&msc->pdev->dev, "cpu_affinity",
-				       &affinity_id);
-	if (err)
+	if (!acpi_disabled) {
+		err = device_property_read_u32(&msc->pdev->dev, "cpu_affinity",
+					       &affinity_id);
+		if (err)
+			cpumask_copy(&msc->accessibility, cpu_possible_mask);
+		else
+			acpi_pptt_get_cpus_from_container(affinity_id,
+							  &msc->accessibility);
+
+		return;
+	}
+
+	/* Where an MSC can be accessed from depends on the path to of_node. */
+	parent = of_get_parent(msc->pdev->dev.of_node);
+	if (parent == of_root) {
 		cpumask_copy(&msc->accessibility, cpu_possible_mask);
-	else
-		acpi_pptt_get_cpus_from_container(affinity_id, &msc->accessibility);
+	} else {
+		if (of_device_is_compatible(parent, "cache"))
+			get_cpumask_from_cache(parent, &msc->accessibility);
+		else
+			dev_err_once(dev, "Cannot determine accessibility of MSC.\n");
+	}
+	of_node_put(parent);
 }
 
 /*
@@ -2561,7 +2738,10 @@ static int mpam_msc_drv_probe(struct platform_device *pdev)
 		return PTR_ERR(msc);
 
 	/* Create RIS entries described by firmware */
-	err = acpi_mpam_parse_resources(msc, plat_data);
+	if (!acpi_disabled)
+		err = acpi_mpam_parse_resources(msc, plat_data);
+	else
+		err = mpam_dt_parse_resources(msc, plat_data);
 	if (err) {
 		mpam_msc_drv_remove(pdev);
 		return err;
@@ -2574,15 +2754,45 @@ static int mpam_msc_drv_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct of_device_id mpam_of_match[] = {
+	{ .compatible = "arm,mpam-msc", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mpam_of_match);
+
 static struct platform_driver mpam_msc_driver = {
 	.driver = {
 		.name = "mpam_msc",
 		.suppress_bind_attrs = true,
+		.of_match_table = of_match_ptr(mpam_of_match),
 	},
 	.probe = mpam_msc_drv_probe,
 	.remove = mpam_msc_drv_remove,
 };
 
+/*
+ * MSCs that are declared by the firmware as being part of a cache may not
+ * be created automatically as platform devices, since there is no
+ * dedicated cache driver.
+ *
+ * Deal with theo MSCs here.
+ */
+static void mpam_dt_create_foundling_msc(void)
+{
+	for_each_compatible_node_scoped(cache, NULL, "cache") {
+		for_each_child_of_node_scoped(cache, child) {
+			if (!of_match_node(mpam_of_match, child))
+				continue;
+			if (!of_device_is_available(child))
+				continue;
+			if (of_node_check_flag(child, OF_POPULATED))
+				continue;
+			if (!of_platform_device_create(child, NULL, NULL))
+				pr_err("Failed to create MSC device for %pOF\n", child);
+		}
+	}
+}
+
 /* Any of these features mean the BWA_WD field is valid. */
 static bool mpam_has_bwa_wd_feature(struct mpam_props *props)
 {
@@ -3455,12 +3665,18 @@ static int __init mpam_msc_driver_init(void)
 
 	init_srcu_struct(&mpam_srcu);
 
-	fw_num_msc = acpi_mpam_count_msc();
+	if (!acpi_disabled)
+		fw_num_msc = acpi_mpam_count_msc();
+	else
+		fw_num_msc = mpam_dt_count_msc();
 	if (fw_num_msc <= 0) {
 		pr_err("No MSC devices found in firmware\n");
 		return -EINVAL;
 	}
 
+	if (acpi_disabled)
+		mpam_dt_create_foundling_msc();
+
 	return platform_driver_register(&mpam_msc_driver);
 }
 
diff --git a/drivers/resctrl/mpam_internal.h b/drivers/resctrl/mpam_internal.h
index 1f86cc158100..cd122f308eab 100644
--- a/drivers/resctrl/mpam_internal.h
+++ b/drivers/resctrl/mpam_internal.h
@@ -519,7 +519,7 @@ int mpam_msmon_read(struct mpam_component *comp, struct mon_cfg *ctx,
 		    enum mpam_device_features, u64 *val);
 void mpam_msmon_reset_mbwu(struct mpam_component *comp, struct mon_cfg *ctx);
 
-int mpam_get_cpumask_from_cache_id(unsigned long cache_id, u32 cache_level,
+int mpam_get_cpumask_from_cache_id(u32 cache_id, u32 cache_level,
 				   cpumask_t *affinity);
 
 #ifdef CONFIG_RESCTRL_FS

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 6/7] arm_mpam: Add support for memory controller MSC on DT platforms
  2026-11-09 10:05 [PATCH v5 0/7] arm-mpam: Add basic device tree support for resctrl Yin Li
                   ` (4 preceding siblings ...)
  2026-11-09 10:05 ` [PATCH v5 5/7] arm_mpam: Add device tree support for MSC probing Yin Li
@ 2026-11-09 10:05 ` Yin Li
  2026-11-09 11:20   ` sashiko-bot
  2026-11-09 11:27   ` Ping Li
  2026-11-09 10:05 ` [PATCH v5 7/7] arm64: dts: qcom: nord: Add MPAM MSC nodes for the L2 caches Yin Li
  6 siblings, 2 replies; 15+ messages in thread
From: Yin Li @ 2026-11-09 10:05 UTC (permalink / raw)
  To: James Morse, Rob Herring, Shanker Donthineni, Ben Horgan,
	Krzysztof Kozlowski, Conor Dooley, Catalin Marinas,
	Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
	Reinette Chatre, Fenghua Yu, Jonathan Cameron, Bjorn Andersson,
	Konrad Dybcio, Gavin Shan
  Cc: Yin Li, Andre Przywara, Drew Fustini, Ilpo Järvinen,
	Shaopeng Tan, trilok.soni, aiqun.yu, ganapatrao.kulkarni,
	Srivathsa L Rao, Huang Yiwei, linux-arm-kernel, linux-arm-msm,
	linux-kernel, driver-core, devicetree, Ping Li

From: Shanker Donthineni <sdonthineni@nvidia.com>

The MPAM DT path only handles cache MSCs. Memory-controller MSCs
cannot be probed yet.

Add support to discover memory-controller MSCs from the device tree:
derive the component id from the NUMA node and create a 'memory' class
RIS, and treat a memory parent as accessible from all CPUs.

Signed-off-by: Shanker Donthineni <sdonthineni@nvidia.com>
[ morse: split out of a bigger patch, added affinity piece ]
Signed-off-by: James Morse <james.morse@arm.com>
[ Yin Li: fix context offset conflicts; use u32 instead of unsigned long
  for component_id and compare against ~0U; remove the unused memory
  node reference in the arm,mpam-memory-controller-msc path ]
Signed-off-by: Yin Li <yin.li@oss.qualcomm.com>
---
 drivers/resctrl/mpam_devices.c | 54 ++++++++++++++++++++++++++++++------------
 1 file changed, 39 insertions(+), 15 deletions(-)

diff --git a/drivers/resctrl/mpam_devices.c b/drivers/resctrl/mpam_devices.c
index 78caa8ae1349..e0ac6ef83d6e 100644
--- a/drivers/resctrl/mpam_devices.c
+++ b/drivers/resctrl/mpam_devices.c
@@ -365,10 +365,12 @@ static int mpam_dt_parse_resource(struct mpam_msc *msc, struct device_node *np,
 				  u8 ris_idx)
 {
 	int err = 0;
-	u32 level = 0;
-	u32 cache_id;
+	u32 class_id = 0;
+	u32 component_id = 0;
 	struct device *dev = &msc->pdev->dev;
+	enum mpam_class_types type = MPAM_CLASS_UNKNOWN;
 	struct device_node *cache __free(device_node) = NULL;
+	struct device_node *memory __free(device_node) = NULL;
 	struct device_node *parent __free(device_node) = of_get_parent(np);
 
 	if (of_device_is_compatible(np, "arm,mpam-cache")) {
@@ -377,27 +379,47 @@ static int mpam_dt_parse_resource(struct mpam_msc *msc, struct device_node *np,
 			dev_err_once(dev, "Failed to read phandle\n");
 			return -EINVAL;
 		}
+		type = MPAM_CLASS_CACHE;
+
 	} else if (of_device_is_compatible(parent, "cache")) {
 		cache = of_node_get(parent);
+		type = MPAM_CLASS_CACHE;
+	} else if (of_device_is_compatible(np, "arm,mpam-memory")) {
+		memory = of_parse_phandle(np, "arm,mpam-device", 0);
+		if (!memory) {
+			dev_err_once(dev, "Failed to read phandle\n");
+			return -EINVAL;
+		}
+		type = MPAM_CLASS_MEMORY;
+	} else if (of_device_is_compatible(np, "arm,mpam-memory-controller-msc")) {
+		type = MPAM_CLASS_MEMORY;
 	} else {
-		/* For now, only caches are supported */
-		cache = NULL;
-		return err;
-	}
-
-	err = of_property_read_u32(cache, "cache-level", &level);
-	if (err) {
-		dev_err_once(dev, "Failed to read cache-level\n");
+		/*
+		 * For now, only caches and memory controllers are
+		 * supported.
+		 */
 		return err;
 	}
 
-	cache_id = cache_of_calculate_id(cache);
-	if (cache_id == ~0U) {
-		dev_err_once(dev, "Failed to calculate cache-id\n");
-		return -ENOENT;
+	/* Determine the class and component ids, based on type. */
+	if (type == MPAM_CLASS_CACHE) {
+		err = of_property_read_u32(cache, "cache-level", &class_id);
+		if (err) {
+			dev_err_once(dev, "Failed to read cache-level\n");
+			return err;
+		}
+		component_id = cache_of_calculate_id(cache);
+		if (component_id == ~0U) {
+			dev_err_once(dev, "Failed to calculate cache-id\n");
+			return -ENOENT;
+		}
+	} else if (type == MPAM_CLASS_MEMORY) {
+		err = of_node_to_nid(np);
+		component_id = (err == NUMA_NO_NODE) ? 0 : err;
+		class_id = MPAM_CLASS_ID_DEFAULT;
 	}
 
-	return mpam_ris_create(msc, ris_idx, MPAM_CLASS_CACHE, level, cache_id);
+	return mpam_ris_create(msc, ris_idx, type, class_id, component_id);
 }
 
 static int mpam_dt_parse_resources(struct mpam_msc *msc, void *ignored)
@@ -2574,6 +2596,8 @@ static void update_msc_accessibility(struct mpam_msc *msc)
 	} else {
 		if (of_device_is_compatible(parent, "cache"))
 			get_cpumask_from_cache(parent, &msc->accessibility);
+		else if (of_device_is_compatible(parent, "memory"))
+			cpumask_copy(&msc->accessibility, cpu_possible_mask);
 		else
 			dev_err_once(dev, "Cannot determine accessibility of MSC.\n");
 	}

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 7/7] arm64: dts: qcom: nord: Add MPAM MSC nodes for the L2 caches
  2026-11-09 10:05 [PATCH v5 0/7] arm-mpam: Add basic device tree support for resctrl Yin Li
                   ` (5 preceding siblings ...)
  2026-11-09 10:05 ` [PATCH v5 6/7] arm_mpam: Add support for memory controller MSC on DT platforms Yin Li
@ 2026-11-09 10:05 ` Yin Li
  2026-11-09 11:43   ` sashiko-bot
  6 siblings, 1 reply; 15+ messages in thread
From: Yin Li @ 2026-11-09 10:05 UTC (permalink / raw)
  To: James Morse, Rob Herring, Shanker Donthineni, Ben Horgan,
	Krzysztof Kozlowski, Conor Dooley, Catalin Marinas,
	Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
	Reinette Chatre, Fenghua Yu, Jonathan Cameron, Bjorn Andersson,
	Konrad Dybcio, Gavin Shan
  Cc: Yin Li, Andre Przywara, Drew Fustini, Ilpo Järvinen,
	Shaopeng Tan, trilok.soni, aiqun.yu, ganapatrao.kulkarni,
	Srivathsa L Rao, Huang Yiwei, linux-arm-kernel, linux-arm-msm,
	linux-kernel, driver-core, devicetree, Ping Li

Add an MPAM MSC device node for each L2 cache. Each MSC is nested
directly under its L2 cache node so that the cache node is the MSC's
parent device and its CPU affinity is derived from that cache.

The L2 cache nodes are placed directly under the root node rather than
under their CPU nodes, to allow the MSC register region to be mapped:
CPU nodes do not provide an MMIO address space, so an MSC nested under
a CPU-parented cache node cannot be mapped.

Co-developed-by: Huang Yiwei <huang.yiwei@oss.qualcomm.com>
Signed-off-by: Huang Yiwei <huang.yiwei@oss.qualcomm.com>
Signed-off-by: Yin Li <yin.li@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/nord.dtsi | 72 ++++++++++++++++++++++++++++----------
 1 file changed, 54 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/nord.dtsi b/arch/arm64/boot/dts/qcom/nord.dtsi
index fdbe290350dd..285c6a3e5cb7 100644
--- a/arch/arm64/boot/dts/qcom/nord.dtsi
+++ b/arch/arm64/boot/dts/qcom/nord.dtsi
@@ -23,12 +23,6 @@ cpu0: cpu@0 {
 			power-domain-names = "psci", "perf";
 			next-level-cache = <&l2_0>;
 			#cooling-cells = <2>;
-
-			l2_0: l2-cache {
-				compatible = "cache";
-				cache-level = <2>;
-				cache-unified;
-			};
 		};
 
 		cpu1: cpu@100 {
@@ -95,12 +89,6 @@ cpu6: cpu@10000 {
 			enable-method = "psci";
 			next-level-cache = <&l2_10000>;
 			#cooling-cells = <2>;
-
-			l2_10000: l2-cache {
-				compatible = "cache";
-				cache-level = <2>;
-				cache-unified;
-			};
 		};
 
 		cpu7: cpu@10100 {
@@ -167,12 +155,6 @@ cpu12: cpu@20000 {
 			power-domain-names = "psci", "perf";
 			next-level-cache = <&l2_20000>;
 			#cooling-cells = <2>;
-
-			l2_20000: l2-cache {
-				compatible = "cache";
-				cache-level = <2>;
-				cache-unified;
-			};
 		};
 
 		cpu13: cpu@20100 {
@@ -907,6 +889,60 @@ dump_mem: mem-dump-region {
 		};
 	};
 
+	l2_0: cache@19870000 {
+		compatible = "qcom,nord-l2-cache", "cache";
+		cache-level = <2>;
+		cache-unified;
+		cache-size = <0xc00000>;
+		reg = <0x0 0x19870000 0x0 0x2000>;
+		ranges = <0x0 0x0 0x19870000 0x2000>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		msc@0 {
+			compatible = "arm,mpam-msc";
+			reg = <0x0 0x2000>;
+			arm,not-ready-us = <1>;
+		};
+	};
+
+	l2_10000: cache@1a870000 {
+		compatible = "qcom,nord-l2-cache", "cache";
+		cache-level = <2>;
+		cache-unified;
+		cache-size = <0xc00000>;
+		reg = <0x0 0x1a870000 0x0 0x2000>;
+		ranges = <0x0 0x0 0x1a870000 0x2000>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		msc@0 {
+			compatible = "arm,mpam-msc";
+			reg = <0x0 0x2000>;
+			arm,not-ready-us = <1>;
+		};
+	};
+
+	l2_20000: cache@1b870000 {
+		compatible = "qcom,nord-l2-cache", "cache";
+		cache-level = <2>;
+		cache-unified;
+		cache-size = <0xc00000>;
+		reg = <0x0 0x1b870000 0x0 0x2000>;
+		ranges = <0x0 0x0 0x1b870000 0x2000>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		msc@0 {
+			compatible = "arm,mpam-msc";
+			reg = <0x0 0x2000>;
+			arm,not-ready-us = <1>;
+		};
+	};
+
 	soc: soc@0 {
 		compatible = "simple-bus";
 		#address-cells = <2>;

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 3/7] dt-bindings: arm: Add MPAM MSC binding
  2026-11-09 10:05 ` [PATCH v5 3/7] dt-bindings: arm: Add MPAM MSC binding Yin Li
@ 2026-11-09 10:38   ` sashiko-bot
  0 siblings, 0 replies; 15+ messages in thread
From: sashiko-bot @ 2026-11-09 10:38 UTC (permalink / raw)
  To: Yin Li; +Cc: devicetree, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 3 potential
issues to consider:
- [Low] dt-bindings: arm: arm,mpam-msc: 4-cell reg on 1-cell bus in
  example
- [Low] dt-bindings: arm: arm,mpam-msc: missing top-level required
  property list
- [Low] dt-bindings: arm: arm,mpam-msc: property order and unused labels
  in example
--

commit fcdcd9b567c42204dbc32cc6d1155a3dddba1926
Author: Rob Herring <robh@kernel.org>

dt-bindings: arm: Add MPAM MSC binding

This commit adds the Devicetree binding schema for Arm Memory System
Resource Partitioning and Monitoring (MPAM) Memory System Component (MSC)
nodes.

> diff --git a/Documentation/devicetree/bindings/arm/arm,mpam-msc.yaml b/Documentation/devicetree/bindings/arm/arm,mpam-msc.yaml
> new file mode 100644
> index 0000000000000..b52599b47a1cd
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/arm,mpam-msc.yaml
> @@ -0,0 +1,62 @@
[ ... ]
> +properties:
> +  compatible:
> +    oneOf:
> +      - const: arm,mpam-msc                   # Further details are discoverable
> +      - items:
> +          - const: arm,mpam-memory-controller-msc
> +          - const: arm,mpam-msc
> +
> +  reg:
> +    maxItems: 1
> +    description: A memory region containing registers as defined in the MPAM
> +      specification.
> +
> +  arm,not-ready-us:
> +    description: The maximum time in microseconds for monitoring data to be
> +      accurate after a settings change. For more information, see the
> +      Not-Ready (NRDY) bit description in the MPAM specification.
> +
> +additionalProperties: false

[Severity: Low]
Should this schema include a required section listing compatible and reg?
do_mpam_msc_drv_probe() unconditionally maps MMIO resource 0 when probing
DT MSC nodes, so nodes omitting reg will pass dtbs_check and then fail to
probe at runtime.

> +
> +examples:
> +  - |
> +    L3: cache-controller@30000000 {
> +        compatible = "foo,a-l3-cache", "cache";
> +        cache-level = <3>;
> +        cache-unified;
> +        reg = <0x0 0x30000000 0x0 0x2000>;
> +        ranges = <0x0 0x30000000 0x2000>;
> +        #address-cells = <1>;
> +        #size-cells = <1>;

[Severity: Low]
Should reg in cache-controller@30000000 be <0x30000000 0x2000>?  The
default example bus uses #address-cells = <1> and #size-cells = <1> (as
used by ranges here and by msc@40000000 below), so a 4-cell reg is parsed
as two regions starting at 0x0 and triggers a dtc simple_bus_reg unit
address mismatch warning during dt_binding_check.

> +
> +        msc@0 {
> +            compatible = "arm,mpam-msc";
> +            reg = <0x0 0x2000>;
> +            arm,not-ready-us = <1>;
> +            /* CPU affinity implied by parent cache node  */
> +        };
> +    };
> +
> +    ddr_msc: msc@40000000 {
> +        compatible = "arm,mpam-memory-controller-msc", "arm,mpam-msc";
> +        reg = <0x40000000 0x1000>;
> +        arm,not-ready-us = <10>;
> +    };

[Severity: Low]
This isn't a bug, but scripts/dtc/dt-check-style reports two style issues
in this example: in cache-controller@30000000, reg and ranges should come
immediately after compatible before cache-level and cache-unified, and the
unused labels L3 and ddr_msc should be dropped.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261109-mpam-resctrl-dt-knp-support-v5-0-150335a79381@oss.qualcomm.com?part=3

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 5/7] arm_mpam: Add device tree support for MSC probing
  2026-11-09 10:05 ` [PATCH v5 5/7] arm_mpam: Add device tree support for MSC probing Yin Li
@ 2026-11-09 11:08   ` sashiko-bot
  0 siblings, 0 replies; 15+ messages in thread
From: sashiko-bot @ 2026-11-09 11:08 UTC (permalink / raw)
  To: Yin Li; +Cc: devicetree, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 5 potential
issues to consider:
- [High] resctrl: mpam: DT MSCs all get id -1 and collide in
  mpam_vmsc_find()
- [Medium] resctrl: mpam: stale error returned by
  mpam_dt_parse_resources()
- [Medium] resctrl: mpam: uncleared cpumask in
  mpam_get_cpumask_from_cache_id()
- [Medium] arm_mpam: undocumented DT bindings and broken child handling
  in MSC probe
- [Medium] arm_mpam: broken DT parent and error checks in
  update_msc_accessibility()
--

commit 6c78e8406d4a4b369efac7e14139c25fdb9faa61
Author: James Morse <james.morse@arm.com>

arm_mpam: Add device tree support for MSC probing

This commit adds Device Tree probing support for MPAM MSCs, parsing MSC
and cache nodes to determine cache IDs, CPU accessibility masks, and RIS
entries.

> diff --git a/drivers/resctrl/mpam_devices.c b/drivers/resctrl/mpam_devices.c
> index bea231dac7e66..78caa8ae13490 100644
> --- a/drivers/resctrl/mpam_devices.c
> +++ b/drivers/resctrl/mpam_devices.c
[ ... ]
> @@ -263,6 +266,171 @@ static void mpam_free_garbage(void)
[ ... ]
> +/*
> + * The cacheinfo structures are only populated when CPUs are online.
> + * This helper walks the device tree to include offline CPUs too.
> + */
> +int mpam_get_cpumask_from_cache_id(u32 cache_id, u32 cache_level,
> +				   cpumask_t *affinity)
> +{
> +	int cpu;
> +
> +	if (!acpi_disabled)
> +		return acpi_pptt_get_cpumask_from_cache_id(cache_id, affinity);
> +
> +	for_each_possible_cpu(cpu) {
> +		struct device_node *cpu_node __free(device_node) = of_get_cpu_node(cpu, NULL);
> +		if (!cpu_node) {
> +			pr_err("Failed to find cpu%d device node\n", cpu);
> +			return -ENOENT;
> +		}
> +
> +		__mpam_get_cpumask_from_cache_id(cpu, cpu_node, cache_id,
> +						 cache_level, affinity);
> +	}
> +
> +	return 0;
> +}

[Severity: Medium]
Does the Device Tree path in mpam_get_cpumask_from_cache_id() leave stale or
uninitialized bits in affinity by not calling cpumask_clear(affinity) before
the loop?

Unlike acpi_pptt_get_cpumask_from_cache_id(), which clears the output mask on
entry, __mpam_get_cpumask_from_cache_id() only sets matching bits with
cpumask_set_cpu(). In traffic_matches_l3(), tmp_cpumask is allocated with
alloc_cpumask_var() without __GFP_ZERO when CONFIG_CPUMASK_OFFSTACK=y and
passed via find_l3_equivalent_bitmask() to mpam_get_cpumask_from_cache_id(),
leaving uninitialized heap bits in the cpumask_equal() comparison.

[ ... ]

> +static int mpam_dt_parse_resource(struct mpam_msc *msc, struct device_node *np,
> +				  u8 ris_idx)
> +{
> +	int err = 0;
> +	u32 level = 0;
> +	u32 cache_id;
> +	struct device *dev = &msc->pdev->dev;
> +	struct device_node *cache __free(device_node) = NULL;
> +	struct device_node *parent __free(device_node) = of_get_parent(np);
> +
> +	if (of_device_is_compatible(np, "arm,mpam-cache")) {
> +		cache = of_parse_phandle(np, "arm,mpam-device", 0);
> +		if (!cache) {
> +			dev_err_once(dev, "Failed to read phandle\n");
> +			return -EINVAL;
> +		}
> +	} else if (of_device_is_compatible(parent, "cache")) {
> +		cache = of_node_get(parent);
> +	} else {
> +		/* For now, only caches are supported */
> +		cache = NULL;
> +		return err;
> +	}
> +
> +	err = of_property_read_u32(cache, "cache-level", &level);
> +	if (err) {
> +		dev_err_once(dev, "Failed to read cache-level\n");
> +		return err;
> +	}
> +
> +	cache_id = cache_of_calculate_id(cache);
> +	if (cache_id == ~0U) {
> +		dev_err_once(dev, "Failed to calculate cache-id\n");
> +		return -ENOENT;
> +	}
> +
> +	return mpam_ris_create(msc, ris_idx, MPAM_CLASS_CACHE, level, cache_id);
> +}

[Severity: Medium]
Does mpam_dt_parse_resource() check the wrong parent node and rely on
undocumented Device Tree properties when called for a child RIS node?

Commit "dt-bindings: arm: Add MPAM MSC binding" only defines compatible, reg,
and arm,not-ready-us on the MSC node with additionalProperties: false,
without child RIS nodes, arm,mpam-cache, or arm,mpam-device. Even if a child
RIS node is passed as np from mpam_dt_parse_resources(), of_get_parent(np)
returns the arm,mpam-msc node rather than the parent cache node, so
of_device_is_compatible(parent, "cache") is false and the RIS is skipped.

> +
> +static int mpam_dt_parse_resources(struct mpam_msc *msc, void *ignored)
> +{
> +	u64 ris_idx = 0;
> +	int err, num_ris = 0;
> +	struct device_node *np;
> +
> +	np = msc->pdev->dev.of_node;
> +	for_each_available_child_of_node_scoped(np, iter) {
> +		err = of_property_read_reg(iter, 0, &ris_idx, NULL);
> +		if (!err) {
> +			/*
> +			 * ris_idx is read as u64 but indexes a 4-bit RIS selector
> +			 * (0..MPAM_MSC_MAX_NUM_RIS). Reject out-of-range values here,
> +			 * before it is narrowed to u8, so a large value cannot be
> +			 * truncated into a valid-looking index.
> +			 */
> +			if (ris_idx >= MPAM_MSC_MAX_NUM_RIS)
> +				return -EINVAL;
> +			num_ris++;
> +			err = mpam_dt_parse_resource(msc, iter, ris_idx);
> +			if (err)
> +				return err;
> +		}
> +	}
> +
> +	if (!num_ris)
> +		err = mpam_dt_parse_resource(msc, np, 0);
> +
> +	return err;
> +}

[Severity: Medium]
Can mpam_dt_parse_resources() return a stale error from
of_property_read_reg() and abort probing of an MSC with valid RIS children?

If an available child node with a valid reg property (incrementing num_ris)
is followed by an available child node without reg, of_property_read_reg()
sets err to a negative errno, the if (!num_ris) fallback is skipped because
num_ris is non-zero, and mpam_dt_parse_resources() returns that negative
errno to mpam_msc_drv_probe(), which tears down the MSC.

[ ... ]

> @@ -2392,15 +2550,34 @@ static int mpam_msc_setup_error_irq(struct mpam_msc *msc)
>   */
>  static void update_msc_accessibility(struct mpam_msc *msc)
>  {
> +	struct device *dev = &msc->pdev->dev;
> +	struct device_node *parent;
>  	u32 affinity_id;
>  	int err;
>  
> -	err = device_property_read_u32(&msc->pdev->dev, "cpu_affinity",
> -				       &affinity_id);
> -	if (err)
> +	if (!acpi_disabled) {
> +		err = device_property_read_u32(&msc->pdev->dev, "cpu_affinity",
> +					       &affinity_id);
> +		if (err)
> +			cpumask_copy(&msc->accessibility, cpu_possible_mask);
> +		else
> +			acpi_pptt_get_cpus_from_container(affinity_id,
> +							  &msc->accessibility);
> +
> +		return;
> +	}
> +
> +	/* Where an MSC can be accessed from depends on the path to of_node. */
> +	parent = of_get_parent(msc->pdev->dev.of_node);
> +	if (parent == of_root) {
>  		cpumask_copy(&msc->accessibility, cpu_possible_mask);
> -	else
> -		acpi_pptt_get_cpus_from_container(affinity_id, &msc->accessibility);
> +	} else {
> +		if (of_device_is_compatible(parent, "cache"))
> +			get_cpumask_from_cache(parent, &msc->accessibility);
> +		else
> +			dev_err_once(dev, "Cannot determine accessibility of MSC.\n");
> +	}
> +	of_node_put(parent);
>  }

[Severity: Medium]
Does update_msc_accessibility() leave msc->accessibility empty for standalone
MSCs placed under a bus node such as /soc?

When an MSC node is under a simple-bus node rather than directly under
of_root or a cache node, update_msc_accessibility() logs an error and leaves
msc->accessibility empty, causing do_mpam_msc_drv_probe() to fail with
-EINVAL and preventing mpam_num_msc from reaching fw_num_msc. In addition,
the return value of get_cpumask_from_cache() is ignored, so if
mpam_get_cpumask_from_cache_id() fails on a later CPU after setting earlier
CPU bits, probing continues with a partial accessibility mask. Also, as noted
earlier, mpam_dt_parse_resources() and mpam_dt_parse_resource() still contain
broken parent and error handling for undocumented child RIS nodes.

[ ... ]

> @@ -2574,15 +2754,45 @@ static int mpam_msc_drv_probe(struct platform_device *pdev)
[ ... ]
> +static void mpam_dt_create_foundling_msc(void)
> +{
> +	for_each_compatible_node_scoped(cache, NULL, "cache") {
> +		for_each_child_of_node_scoped(cache, child) {
> +			if (!of_match_node(mpam_of_match, child))
> +				continue;
> +			if (!of_device_is_available(child))
> +				continue;
> +			if (of_node_check_flag(child, OF_POPULATED))
> +				continue;
> +			if (!of_platform_device_create(child, NULL, NULL))
> +				pr_err("Failed to create MSC device for %pOF\n", child);
> +		}
> +	}
> +}

[Severity: High]
Do all Device Tree MSCs get msc->id == -1 and collide in mpam_vmsc_find()?

Platform devices created from Device Tree (both via
of_platform_default_populate() and of_platform_device_create()) have
pdev->id set to PLATFORM_DEVID_NONE (-1), which do_mpam_msc_drv_probe()
copies into msc->id:

drivers/resctrl/mpam_devices.c:do_mpam_msc_drv_probe() {
	...
	msc->id = pdev->id;
	msc->pdev = pdev;
	...
}

drivers/resctrl/mpam_devices.c:mpam_vmsc_find() {
	...
	list_for_each_entry(vmsc, &comp->vmsc, comp_list) {
		if (vmsc->msc->id == msc->id)
			return vmsc;
	}

	return mpam_vmsc_alloc(comp, msc);
}

When two DT MSCs create a RIS in the same mpam_component (for example,
multiple MSCs backing slices of the same cache, or undescribed RIS entries
placed into the shared MPAM_CLASS_UNKNOWN component during
mpam_msc_hw_probe()), mpam_vmsc_find() matches the first MSC's vmsc because
both have id == -1. The second MSC's RIS is then linked to the first MSC's
vmsc, so mpam_ris_hw_probe() and runtime configuration dereference
ris->vmsc->msc and access the first MSC without holding its locks, and
mpam_ris_destroy() later performs a use-after-free write in
clear_bit(ris->ris_idx, &msc->ris_idxs) if the first MSC was freed first.

Comparing vmsc->msc == msc in mpam_vmsc_find() (or assigning unique IDs to
DT MSCs) would avoid the collision.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261109-mpam-resctrl-dt-knp-support-v5-0-150335a79381@oss.qualcomm.com?part=5

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 6/7] arm_mpam: Add support for memory controller MSC on DT platforms
  2026-11-09 10:05 ` [PATCH v5 6/7] arm_mpam: Add support for memory controller MSC on DT platforms Yin Li
@ 2026-11-09 11:20   ` sashiko-bot
  2026-11-09 11:27   ` Ping Li
  1 sibling, 0 replies; 15+ messages in thread
From: sashiko-bot @ 2026-11-09 11:20 UTC (permalink / raw)
  To: Yin Li; +Cc: devicetree, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 4 potential
issues to consider:
- [High] arm_mpam: invalid compatible memory parent check in
  update_msc_accessibility()
- [High] arm_mpam: vMSC collision in mpam_vmsc_find() for DT memory MSCs
- [Medium] arm_mpam: mpam_dt_parse_resource() ignores memory phandle
  target node
- [Low] arm_mpam: undocumented arm,mpam-memory parsing in
  mpam_dt_parse_resource()
--

commit 76edb90c680c1ae30161829584d4c65a841ea202
Author: Shanker Donthineni <sdonthineni@nvidia.com>

arm_mpam: Add support for memory controller MSC on DT platforms

This commit adds Device Tree discovery support for memory-controller MSCs,
deriving the component ID from the NUMA node and marking MSCs under a memory
parent node as accessible from all CPUs.

> diff --git a/drivers/resctrl/mpam_devices.c b/drivers/resctrl/mpam_devices.c
> index 78caa8ae13490..e0ac6ef83d6e7 100644
> --- a/drivers/resctrl/mpam_devices.c
> +++ b/drivers/resctrl/mpam_devices.c
> @@ -365,10 +365,12 @@ static int mpam_dt_parse_resource(struct mpam_msc *msc, struct device_node *np,
>  				  u8 ris_idx)
>  {
>  	int err = 0;
> -	u32 level = 0;
> -	u32 cache_id;
> +	u32 class_id = 0;
> +	u32 component_id = 0;
>  	struct device *dev = &msc->pdev->dev;
> +	enum mpam_class_types type = MPAM_CLASS_UNKNOWN;
>  	struct device_node *cache __free(device_node) = NULL;
> +	struct device_node *memory __free(device_node) = NULL;
>  	struct device_node *parent __free(device_node) = of_get_parent(np);
>  
>  	if (of_device_is_compatible(np, "arm,mpam-cache")) {
> @@ -377,27 +379,47 @@ static int mpam_dt_parse_resource(struct mpam_msc *msc, struct device_node *np,
>  			dev_err_once(dev, "Failed to read phandle\n");
>  			return -EINVAL;
>  		}
> +		type = MPAM_CLASS_CACHE;
> +
>  	} else if (of_device_is_compatible(parent, "cache")) {
>  		cache = of_node_get(parent);
> +		type = MPAM_CLASS_CACHE;
> +	} else if (of_device_is_compatible(np, "arm,mpam-memory")) {
> +		memory = of_parse_phandle(np, "arm,mpam-device", 0);
> +		if (!memory) {
> +			dev_err_once(dev, "Failed to read phandle\n");
> +			return -EINVAL;
> +		}
> +		type = MPAM_CLASS_MEMORY;

[Severity: Low]
Is this arm,mpam-memory branch dead code?
Documentation/devicetree/bindings/arm/arm,mpam-msc.yaml only documents the
arm,mpam-msc and arm,mpam-memory-controller-msc compatible strings and does
not define arm,mpam-memory or the arm,mpam-device phandle property, and there
are no in-tree Device Tree users of memory-controller MSCs in this series.

> +	} else if (of_device_is_compatible(np, "arm,mpam-memory-controller-msc")) {
> +		type = MPAM_CLASS_MEMORY;
>  	} else {
> -		/* For now, only caches are supported */
> -		cache = NULL;
> -		return err;
> -	}
> -
> -	err = of_property_read_u32(cache, "cache-level", &level);
> -	if (err) {
> -		dev_err_once(dev, "Failed to read cache-level\n");
> +		/*
> +		 * For now, only caches and memory controllers are
> +		 * supported.
> +		 */
>  		return err;
>  	}
>  
> -	cache_id = cache_of_calculate_id(cache);
> -	if (cache_id == ~0U) {
> -		dev_err_once(dev, "Failed to calculate cache-id\n");
> -		return -ENOENT;
> +	/* Determine the class and component ids, based on type. */
> +	if (type == MPAM_CLASS_CACHE) {
> +		err = of_property_read_u32(cache, "cache-level", &class_id);
> +		if (err) {
> +			dev_err_once(dev, "Failed to read cache-level\n");
> +			return err;
> +		}
> +		component_id = cache_of_calculate_id(cache);
> +		if (component_id == ~0U) {
> +			dev_err_once(dev, "Failed to calculate cache-id\n");
> +			return -ENOENT;
> +		}
> +	} else if (type == MPAM_CLASS_MEMORY) {
> +		err = of_node_to_nid(np);
> +		component_id = (err == NUMA_NO_NODE) ? 0 : err;
> +		class_id = MPAM_CLASS_ID_DEFAULT;
>  	}

[Severity: Medium]
When np is compatible with "arm,mpam-memory", does calling of_node_to_nid(np)
ignore the target memory node resolved from the "arm,mpam-device" phandle?

The phandle target is stored in memory, but memory is never read afterwards.
Because numa-node-id is on the referenced memory node rather than on np,
of_node_to_nid(np) assigns the wrong component_id (falling back to 0 or to the
parent MSC's node ID when multiple RIS child nodes point at different NUMA
memory nodes).  Passing memory ? memory : np to of_node_to_nid() would query
the referenced node when present.

>  
> -	return mpam_ris_create(msc, ris_idx, MPAM_CLASS_CACHE, level, cache_id);
> +	return mpam_ris_create(msc, ris_idx, type, class_id, component_id);
>  }

[Severity: High]
When a Device Tree platform has more than one memory-controller MSC on the
same NUMA node (or when NUMA is disabled), will mpam_ris_create() attach every
MSC's RIS to the first MSC's vMSC?

For all Device Tree platform devices, pdev->id is PLATFORM_DEVID_NONE (-1), so
do_mpam_msc_drv_probe() sets msc->id = -1 on every MSC.  Because all
MPAM_CLASS_MEMORY resources on the same node get class_id =
MPAM_CLASS_ID_DEFAULT and the same component_id, they share one
mpam_component, where mpam_vmsc_find() matches by msc->id:

drivers/resctrl/mpam_devices.c:mpam_vmsc_find() {
	list_for_each_entry(vmsc, &comp->vmsc, comp_list) {
		if (vmsc->msc->id == msc->id)
			return vmsc;
	}
}

Since vmsc->msc->id == msc->id evaluates (-1 == -1), every subsequent memory
MSC on that node reuses the first MSC's vMSC.  During mpam_msc_hw_probe(),
mpam_ris_hw_probe() then resolves msc = ris->vmsc->msc to the first MSC while
holding the second MSC's probe_lock and part_sel_lock, triggering lockdep
assertions and performing unserialized MMIO accesses on the first MSC while
leaving the remaining memory MSCs unprobed and unconfigured.  Matching
vmsc->msc == msc in mpam_vmsc_find() (or assigning each DT MSC a unique ID)
would keep each MSC in its own vMSC.

> @@ -2574,6 +2596,8 @@ static void update_msc_accessibility(struct mpam_msc *msc)
>  	} else {
>  		if (of_device_is_compatible(parent, "cache"))
>  			get_cpumask_from_cache(parent, &msc->accessibility);
> +		else if (of_device_is_compatible(parent, "memory"))
> +			cpumask_copy(&msc->accessibility, cpu_possible_mask);
>  		else
>  			dev_err_once(dev, "Cannot determine accessibility of MSC.\n");
>  	}

[Severity: High]
Can update_msc_accessibility() ever succeed for a non-root memory-controller
MSC with of_device_is_compatible(parent, "memory")?

Standard Device Tree memory nodes use device_type = "memory" rather than
compatible = "memory", and MMIO memory-controller MSC nodes live under bus
nodes (such as simple-bus) or memory-controller nodes rather than of_root.
For those nodes, parent != of_root and of_device_is_compatible(parent,
"memory") is false, leaving msc->accessibility empty and causing
do_mpam_msc_drv_probe() to fail with -EINVAL.

Conversely, if an MSC node were placed under a parent with compatible =
"memory", neither of_platform_default_populate() nor
mpam_dt_create_foundling_msc() (which only iterates over compatible = "cache"
nodes) would create a platform_device for it, even though mpam_dt_count_msc()
counts it in fw_num_msc, preventing MPAM from ever enabling.  In addition,
mpam_dt_parse_resource() only checks of_device_is_compatible(parent, "cache")
and does not handle a memory parent.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261109-mpam-resctrl-dt-knp-support-v5-0-150335a79381@oss.qualcomm.com?part=6

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 6/7] arm_mpam: Add support for memory controller MSC on DT platforms
  2026-11-09 10:05 ` [PATCH v5 6/7] arm_mpam: Add support for memory controller MSC on DT platforms Yin Li
  2026-11-09 11:20   ` sashiko-bot
@ 2026-11-09 11:27   ` Ping Li
  2026-11-11  9:42     ` Yin Li
  1 sibling, 1 reply; 15+ messages in thread
From: Ping Li @ 2026-11-09 11:27 UTC (permalink / raw)
  To: yin.li
  Cc: sdonthineni, james.morse, robh, ben.horgan, linux-arm-kernel,
	devicetree, linux-kernel, Ping Li

Tested-by: Ping Li <leeonion.muyu@gmail.com>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 7/7] arm64: dts: qcom: nord: Add MPAM MSC nodes for the L2 caches
  2026-11-09 10:05 ` [PATCH v5 7/7] arm64: dts: qcom: nord: Add MPAM MSC nodes for the L2 caches Yin Li
@ 2026-11-09 11:43   ` sashiko-bot
  0 siblings, 0 replies; 15+ messages in thread
From: sashiko-bot @ 2026-11-09 11:43 UTC (permalink / raw)
  To: Yin Li; +Cc: devicetree, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [Low] arm64: dts: qcom: nord: undocumented qcom,nord-l2-cache
  compatible string
--

commit 945c2648afac411c203b55a624505e915359df08
Author: Yin Li <yin.li@oss.qualcomm.com>

arm64: dts: qcom: nord: Add MPAM MSC nodes for the L2 caches

This commit moves the L2 cache nodes out of the CPU nodes to the root node
and adds child MPAM MSC device nodes under each L2 cache.

> diff --git a/arch/arm64/boot/dts/qcom/nord.dtsi b/arch/arm64/boot/dts/qcom/nord.dtsi
> index fdbe290350ddd..285c6a3e5cb7d 100644
> --- a/arch/arm64/boot/dts/qcom/nord.dtsi
> +++ b/arch/arm64/boot/dts/qcom/nord.dtsi

[ ... ]

> @@ -907,6 +889,60 @@ dump_mem: mem-dump-region {
>  		};
>  	};
>  
> +	l2_0: cache@19870000 {
> +		compatible = "qcom,nord-l2-cache", "cache";
> +		cache-level = <2>;
> +		cache-unified;
> +		cache-size = <0xc00000>;
> +		reg = <0x0 0x19870000 0x0 0x2000>;
> +		ranges = <0x0 0x0 0x19870000 0x2000>;
> +
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +
> +		msc@0 {
> +			compatible = "arm,mpam-msc";
> +			reg = <0x0 0x2000>;
> +			arm,not-ready-us = <1>;
> +		};
> +	};
> +
> +	l2_10000: cache@1a870000 {
> +		compatible = "qcom,nord-l2-cache", "cache";
> +		cache-level = <2>;
> +		cache-unified;
> +		cache-size = <0xc00000>;
> +		reg = <0x0 0x1a870000 0x0 0x2000>;
> +		ranges = <0x0 0x0 0x1a870000 0x2000>;
> +
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +
> +		msc@0 {
> +			compatible = "arm,mpam-msc";
> +			reg = <0x0 0x2000>;
> +			arm,not-ready-us = <1>;
> +		};
> +	};
> +
> +	l2_20000: cache@1b870000 {
> +		compatible = "qcom,nord-l2-cache", "cache";
> +		cache-level = <2>;
> +		cache-unified;
> +		cache-size = <0xc00000>;
> +		reg = <0x0 0x1b870000 0x0 0x2000>;
> +		ranges = <0x0 0x0 0x1b870000 0x2000>;
> +
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +
> +		msc@0 {
> +			compatible = "arm,mpam-msc";
> +			reg = <0x0 0x2000>;
> +			arm,not-ready-us = <1>;
> +		};
> +	};

[Severity: Low]
Is a Devicetree binding schema missing for "qcom,nord-l2-cache"?

"qcom,nord-l2-cache" is not documented under
Documentation/devicetree/bindings/, and the generic schemas/cache.yaml in
dtschema only matches const "cache" with additionalProperties: false, which
rejects reg, ranges, #address-cells, #size-cells, and the child msc@0 node.
As a result, both checkpatch.pl and make dtbs_check fail validation on the
l2_0, l2_10000, and l2_20000 nodes.

Also, per Documentation/devicetree/bindings/dts-coding-style.rst, reg and
ranges should be placed immediately after compatible, before cache-level,
cache-unified, and cache-size.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261109-mpam-resctrl-dt-knp-support-v5-0-150335a79381@oss.qualcomm.com?part=7

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 6/7] arm_mpam: Add support for memory controller MSC on DT platforms
  2026-11-09 11:27   ` Ping Li
@ 2026-11-11  9:42     ` Yin Li
  2026-11-11 13:04       ` Ping Li
  0 siblings, 1 reply; 15+ messages in thread
From: Yin Li @ 2026-11-11  9:42 UTC (permalink / raw)
  To: Ping Li
  Cc: sdonthineni, james.morse, robh, ben.horgan, linux-arm-kernel,
	devicetree, linux-kernel



On 11/9/2026 7:27 PM, Ping Li wrote:
> Tested-by: Ping Li <leeonion.muyu@gmail.com>


Hi Ping,

Thank you for the Tested-by — it really helps move v5 forward.

To help the maintainers evaluate this series more quickly, could you
share some additional information about your use case?

1. Your SoC or platform name (if publicly available), or a brief
    description (e.g. "server SoC with an MPAM MSC on the DDR egress
    path").
2. The typical workload scenario where memory bandwidth QoS is useful
    for you (e.g. isolating bandwidth between tenants, preventing certain
    workloads from saturating DDR, etc.).
3. Which specific features did you verify on v5? (MSC probe, resctrl
    mount, MB allocation, mbm_total_bytes monitoring, etc.)

A real usage log showing the memory controller MSC working through
resctrl would also be very helpful — similar to what we have for the
cache MSC:

```
root@qcom-armv8a:/sys/fs/resctrl# cat schemata
     L2:0=fff;65536=fff;131072=fff
root@qcom-armv8a:/sys/fs/resctrl# echo "L2:0=111;65536=222;131072=333" > 
schemata
root@qcom-armv8a:/sys/fs/resctrl# cat schemata
     L2:0=111;65536=222;131072=333
root@qcom-armv8a:/sys/fs/resctrl#
```

This would give the maintainers a clearer picture of the real-world
value of these patches and help speed up the review.

Thanks,
Yin

-- 
Thx and BRs,
Yin


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 6/7] arm_mpam: Add support for memory controller MSC on DT platforms
  2026-11-11  9:42     ` Yin Li
@ 2026-11-11 13:04       ` Ping Li
  0 siblings, 0 replies; 15+ messages in thread
From: Ping Li @ 2026-11-11 13:04 UTC (permalink / raw)
  To: yin.li
  Cc: sdonthineni, james.morse, robh, ben.horgan, linux-arm-kernel,
	devicetree, linux-kernel, Ping Li

Hi Yin,

Happy to share more details.

1. Our SoC is an automotive-grade platform with an MPAM 1.1
compliant MSC on the DDR egress path for system-wide
bandwidth QoS.

2. The typical scenario is preventing memory-bandwidth-sensitive
workloads from saturating DDR: isolating bandwidth between
infotainment and ADAS domains, and preventing background
services from starving latency-critical workloads.

3. We verified on v5 (with the top-level memory controller MSC
node as a direct child of the root):
   - MSC probe from DT (dmesg: MPAM enabled)
   - resctrl mount with L3/MB/L3_MON resources
   - MB allocation through schemata writes
   - Dynamic throttle change while traffic is running
   - MBWU monitoring (mbm_total_bytes)
   - Monitor assignment across multiple groups

Usage log showing the memory controller MSC working through
resctrl on our board:

    root@hobot:~# mkdir /sys/fs/resctrl/group1
    root@hobot:~# echo "MB:0=50" > /sys/fs/resctrl/group1/schemata
    root@hobot:~# cat /sys/fs/resctrl/group1/schemata
        MB:0=50
        L3:0=ff

    root@hobot:~# my_app &
    root@hobot:~# echo $! > /sys/fs/resctrl/group1/tasks
    root@hobot:~# cat /sys/fs/resctrl/group1/mon_data/mon_L3_00/mbm_total_bytes
    1314

    # Dynamic throttle change while workload is running:
    root@hobot:~# cat /sys/fs/resctrl/schemata
        MB:0=100
        L3:0=ff
    root@hobot:~# echo "MB:0=20" > /sys/fs/resctrl/schemata
    root@hobot:~# echo "MB:0=100" > /sys/fs/resctrl/schemata
    root@hobot:~# cat /sys/fs/resctrl/schemata
        MB:0=100
        L3:0=ff

The bandwidth throttling takes effect immediately on schemata
writes - verified by observing the DDR bandwidth counter drop
and recover in sync with the throttle level changes.

Thanks,
Ping

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2026-11-11 13:05 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-09 10:05 [PATCH v5 0/7] arm-mpam: Add basic device tree support for resctrl Yin Li
2026-11-09 10:05 ` [PATCH v5 1/7] arm_mpam: Fix the RIS index range check in mpam_ris_create_locked Yin Li
2026-11-09 10:05 ` [PATCH v5 2/7] arm_mpam: Fix MSC MMIO window size off-by-one with resource_size() Yin Li
2026-11-09 10:05 ` [PATCH v5 3/7] dt-bindings: arm: Add MPAM MSC binding Yin Li
2026-11-09 10:38   ` sashiko-bot
2026-11-09 10:05 ` [PATCH v5 4/7] cacheinfo: Expose the code to generate a cache-id from a device_node Yin Li
2026-11-09 10:05 ` [PATCH v5 5/7] arm_mpam: Add device tree support for MSC probing Yin Li
2026-11-09 11:08   ` sashiko-bot
2026-11-09 10:05 ` [PATCH v5 6/7] arm_mpam: Add support for memory controller MSC on DT platforms Yin Li
2026-11-09 11:20   ` sashiko-bot
2026-11-09 11:27   ` Ping Li
2026-11-11  9:42     ` Yin Li
2026-11-11 13:04       ` Ping Li
2026-11-09 10:05 ` [PATCH v5 7/7] arm64: dts: qcom: nord: Add MPAM MSC nodes for the L2 caches Yin Li
2026-11-09 11:43   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox