Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
56c5c22
arm_mpam: Ensure in_reset_state is false after applying configuration
henryZe Mar 13, 2026
7ee6d7e
arm_mpam: Reset when feature configuration bit unset
benhor01 Mar 13, 2026
fda7c04
arm64/sysreg: Add MPAMSM_EL1 register
benhor01 Mar 13, 2026
7cd3213
KVM: arm64: Preserve host MPAM configuration when changing traps
benhor01 Mar 13, 2026
9582e6b
KVM: arm64: Make MPAMSM_EL1 accesses UNDEF
benhor01 Mar 13, 2026
d9c282a
arm64: mpam: Context switch the MPAM registers
Mar 13, 2026
c8aa1e4
arm64: mpam: Re-initialise MPAM regs when CPU comes online
Mar 13, 2026
b918129
arm64: mpam: Drop the CONFIG_EXPERT restriction
benhor01 Mar 13, 2026
ec9ca24
arm64: mpam: Advertise the CPUs MPAM limits to the driver
Mar 13, 2026
09b7f4a
arm64: mpam: Add cpu_pm notifier to restore MPAM sysregs
Mar 13, 2026
59052b9
arm64: mpam: Initialise and context switch the MPAMSM_EL1 register
benhor01 Mar 13, 2026
72f39fc
arm64: mpam: Add helpers to change a task or cpu's MPAM PARTID/PMG va…
Mar 13, 2026
9abe429
arm_mpam: resctrl: Add boilerplate cpuhp and domain allocation
Mar 13, 2026
df36b5d
arm_mpam: resctrl: Pick the caches we will use as resctrl resources
Mar 13, 2026
389f57a
arm_mpam: resctrl: Implement resctrl_arch_reset_all_ctrls()
Mar 13, 2026
80222a1
arm_mpam: resctrl: Add resctrl_arch_get_config()
Mar 13, 2026
1494922
arm_mpam: resctrl: Implement helpers to update configuration
Mar 13, 2026
8f40733
arm_mpam: resctrl: Add plumbing against arm64 task and cpu hooks
Mar 13, 2026
6c5b86f
arm_mpam: resctrl: Add CDP emulation
Mar 13, 2026
9d3f995
arm_mpam: resctrl: Hide CDP emulation behind CONFIG_EXPERT
benhor01 Mar 13, 2026
0acbe7f
arm_mpam: resctrl: Convert to/from MPAMs fixed-point formats
Mar 13, 2026
1ed0a8b
arm_mpam: resctrl: Add rmid index helpers
benhor01 Mar 13, 2026
b4563f7
arm_mpam: resctrl: Wait for cacheinfo to be ready
benhor01 Mar 13, 2026
7b96a39
arm_mpam: resctrl: Add support for 'MB' resource
Mar 13, 2026
7ddb679
arm_mpam: resctrl: Add kunit test for control format conversions
Mar 13, 2026
fd735b3
arm_mpam: resctrl: Add monitor initialisation and domain boilerplate
benhor01 Mar 13, 2026
d5bf8d6
arm_mpam: resctrl: Add support for csu counters
Mar 13, 2026
3cb16f9
arm_mpam: resctrl: Allow resctrl to allocate monitors
Mar 13, 2026
648fcf6
arm_mpam: resctrl: Add resctrl_arch_rmid_read()
Mar 13, 2026
bcd6ddf
arm_mpam: resctrl: Update the rmid reallocation limit
Mar 13, 2026
07e5934
arm_mpam: resctrl: Add empty definitions for assorted resctrl functions
Mar 13, 2026
2a7ceaa
ALSA: usb-audio: Replace hard-coded number with MAX_CHANNELS
tiwai Mar 27, 2026
4d8652f
arm64: mpam: Select ARCH_HAS_CPU_RESCTRL
Mar 13, 2026
0a83d7d
arm_mpam: resctrl: Call resctrl_init() on platforms that can support …
Mar 13, 2026
7be0a28
arm_mpam: Add quirk framework
shankerd04 Mar 13, 2026
142f08e
arm_mpam: Add workaround for T241-MPAM-1
shankerd04 Mar 13, 2026
daaba65
arm_mpam: Add workaround for T241-MPAM-4
shankerd04 Mar 13, 2026
afd5caa
arm_mpam: Add workaround for T241-MPAM-6
shankerd04 Mar 13, 2026
b8b6604
arm_mpam: Quirk CMN-650's CSU NRDY behaviour
Mar 13, 2026
8ffcb19
arm64: mpam: Add initial MPAM documentation
benhor01 Mar 13, 2026
6b66479
fs/resctrl: Report invalid domain ID when parsing io_alloc_cbm
aarontomlin Mar 25, 2026
1218d71
fs/resctrl: Add "*" shorthand to set io_alloc CBM for all domains
aarontomlin Mar 25, 2026
925133a
MAINTAINERS: Update resctrl entry
rchatre Apr 7, 2026
3336c19
fs/resctrl: Add missing return value descriptions
rchatre Apr 7, 2026
c277571
arm_mpam: resctrl: Fix MBA CDP alloc_capable handling on unmount
henryZe Apr 13, 2026
db2a725
arm_mpam: resctrl: Fix the check for no monitor components found
benhor01 Apr 14, 2026
1baee4f
arm_mpam: resctrl: Make resctrl_mon_ctx_waiters static
benhor01 Apr 14, 2026
b5091e9
NVIDIA: SAUCE: Update annotations to set CONFIG_RESCTRL_FS
fyu1 Apr 30, 2026
7e8229c
NVIDIA: SAUCE: untested: arm_mpam: resctrl: pick classes for use as m…
Sep 7, 2021
c4943d9
NVIDIA: SAUCE: arm_mpam: resctrl: Pre-allocate free running monitors
Jul 15, 2025
6ed6643
NVIDIA: SAUCE: arm_mpam: resctrl: Pre-allocate assignable monitors
Oct 15, 2025
4168f4f
NVIDIA: SAUCE: arm_mpam: resctrl: Add resctrl_arch_config_cntr() for …
Oct 15, 2025
e28af1f
NVIDIA: SAUCE: arm_mpam: resctrl: Add resctrl_arch_rmid_read() and re…
Jun 25, 2021
6051973
NVIDIA: SAUCE: arm_mpam: resctrl: Add resctrl_arch_cntr_read() & resc…
Aug 26, 2025
234af59
NVIDIA: SAUCE: arm_mpam: Add resctrl_arch_round_bw()
Aug 15, 2025
5d555ee
NVIDIA: SAUCE: fs/resctrl,x86/resctrl: Factor mba rounding to be per-…
Aug 15, 2025
f51e766
NVIDIA: SAUCE: x86/resctrl: Add stub to allow other architecture to d…
Mar 15, 2024
5668a90
NVIDIA: SAUCE: arm_mpam: resctrl: Determine if any exposed counter ca…
Mar 15, 2024
8f4ab74
NVIDIA: SAUCE: fs/restrl: Allow the overflow handler to be disabled
Mar 15, 2024
2986c09
NVIDIA: SAUCE: arm_mpam: Allow cmax/cmin to be configured
Aug 27, 2024
f5e2f58
NVIDIA: SAUCE: arm_mpam: Rename mbw conversion to 'fract16' for code …
Nov 19, 2024
42ecd8a
NVIDIA: SAUCE: fs/resctrl: Group all the MBA specific properties in a…
Nov 18, 2024
0c10131
NVIDIA: SAUCE: fs/resctrl: Abstract duplicate domain test to a helper
Sep 10, 2024
8d3aebe
NVIDIA: SAUCE: fs/resctrl: Move MBA supported check to parse_line() i…
Nov 19, 2024
53042fe
NVIDIA: SAUCE: fs/resctrl: Rename resctrl_get_default_ctrl() to inclu…
Nov 19, 2024
c2883c7
NVIDIA: SAUCE: fs/resctrl: Add a schema format to the schema, allowin…
Nov 20, 2024
3206f1a
NVIDIA: SAUCE: fs/resctrl: Add specific schema types for 'range'
Nov 20, 2024
3f64183
NVIDIA: SAUCE: x86/resctrl: Move over to specifying MBA control formats
Nov 20, 2024
fb20cd1
NVIDIA: SAUCE: fs/resctrl: Add additional files for percentage and bi…
Nov 20, 2024
1a694ea
NVIDIA: SAUCE: fs/resctrl: Add fflags_from_schema() for files based o…
Nov 20, 2024
bcd6704
NVIDIA: SAUCE: fs/resctrl: Expose the schema format to user-space
Sep 10, 2024
fba318c
NVIDIA: SAUCE: fs/resctrl: Add L2 and L3 'MAX' resource schema
Nov 19, 2024
a60fe92
NVIDIA: SAUCE: arm_mpam: resctrl: Add the glue code to convert to/fro…
Nov 19, 2024
fde0f3c
NVIDIA: SAUCE: arm_mpam: Include all associated MSC components during…
shankerd04 Nov 24, 2025
d7c3069
NVIDIA: SAUCE: resctrl/mpam: reset RIS by applying explicit default c…
shankerd04 Mar 4, 2026
c290cca
NVIDIA: SAUCE: Fix mbm_L3_assign and mon_local_bytes
fyu1 May 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Documentation/arch/arm64/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ ARM64 Architecture
memory
memory-tagging-extension
mops
mpam
perf
pointer-authentication
ptdump
Expand Down
72 changes: 72 additions & 0 deletions Documentation/arch/arm64/mpam.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
.. SPDX-License-Identifier: GPL-2.0

====
MPAM
====

What is MPAM
============
MPAM (Memory Partitioning and Monitoring) is a feature in the CPUs and memory
system components such as the caches or memory controllers that allow memory
traffic to be labelled, partitioned and monitored.

Traffic is labelled by the CPU, based on the control or monitor group the
current task is assigned to using resctrl. Partitioning policy can be set
using the schemata file in resctrl, and monitor values read via resctrl.
See Documentation/filesystems/resctrl.rst for more details.

This allows tasks that share memory system resources, such as caches, to be
isolated from each other according to the partitioning policy (so called noisy
neighbours).

Supported Platforms
===================
Use of this feature requires CPU support, support in the memory system
components, and a description from firmware of where the MPAM device controls
are in the MMIO address space. (e.g. the 'MPAM' ACPI table).

The MMIO device that provides MPAM controls/monitors for a memory system
component is called a memory system component. (MSC).

Because the user interface to MPAM is via resctrl, only MPAM features that are
compatible with resctrl can be exposed to user-space.

MSC are considered as a group based on the topology. MSC that correspond with
the L3 cache are considered together, it is not possible to mix MSC between L2
and L3 to 'cover' a resctrl schema.

The supported features are:

* Cache portion bitmap controls (CPOR) on the L2 or L3 caches. To expose
CPOR at L2 or L3, every CPU must have a corresponding CPU cache at this
level that also supports the feature. Mismatched big/little platforms are
not supported as resctrl's controls would then also depend on task
placement.

* Memory bandwidth maximum controls (MBW_MAX) on or after the L3 cache.
resctrl uses the L3 cache-id to identify where the memory bandwidth
control is applied. For this reason the platform must have an L3 cache
with cache-id's supplied by firmware. (It doesn't need to support MPAM.)

To be exported as the 'MB' schema, the topology of the group of MSC chosen
must match the topology of the L3 cache so that the cache-id's can be
repainted. For example: Platforms with Memory bandwidth maximum controls
on CPU-less NUMA nodes cannot expose the 'MB' schema to resctrl as these
nodes do not have a corresponding L3 cache. If the memory bandwidth
control is on the memory rather than the L3 then there must be a single
global L3 as otherwise it is unknown which L3 the traffic came from. There
must be no caches between the L3 and the memory so that the two ends of
the path have equivalent traffic.

When the MPAM driver finds multiple groups of MSC it can use for the 'MB'
schema, it prefers the group closest to the L3 cache.

* Cache Storage Usage (CSU) counters can expose the 'llc_occupancy' provided
there is at least one CSU monitor on each MSC that makes up the L3 group.
Exposing CSU counters from other caches or devices is not supported.

Reporting Bugs
==============
If you are not seeing the counters or controls you expect please share the
debug messages produced when enabling dynamic debug and booting with:
dyndbg="file mpam_resctrl.c +pl"
9 changes: 9 additions & 0 deletions Documentation/arch/arm64/silicon-errata.rst
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,9 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| ARM | SI L1 | #4311569 | ARM64_ERRATUM_4311569 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | CMN-650 | #3642720 | N/A |
+----------------+-----------------+-----------------+-----------------------------+
+----------------+-----------------+-----------------+-----------------------------+
| Broadcom | Brahma-B53 | N/A | ARM64_ERRATUM_845719 |
+----------------+-----------------+-----------------+-----------------------------+
| Broadcom | Brahma-B53 | N/A | ARM64_ERRATUM_843419 |
Expand Down Expand Up @@ -247,6 +250,12 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| NVIDIA | T241 GICv3/4.x | T241-FABRIC-4 | N/A |
+----------------+-----------------+-----------------+-----------------------------+
| NVIDIA | T241 MPAM | T241-MPAM-1 | N/A |
+----------------+-----------------+-----------------+-----------------------------+
| NVIDIA | T241 MPAM | T241-MPAM-4 | N/A |
+----------------+-----------------+-----------------+-----------------------------+
| NVIDIA | T241 MPAM | T241-MPAM-6 | N/A |
+----------------+-----------------+-----------------+-----------------------------+
+----------------+-----------------+-----------------+-----------------------------+
| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
+----------------+-----------------+-----------------+-----------------------------+
Expand Down
15 changes: 11 additions & 4 deletions Documentation/filesystems/resctrl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,14 @@ related to allocation:
# cat /sys/fs/resctrl/info/L3/io_alloc_cbm
0=00ff;1=000f

An ID of "*" configures all domains with the provided CBM.

Example on a system that does not require a minimum number of consecutive bits in the mask::

# echo "*=0" > /sys/fs/resctrl/info/L3/io_alloc_cbm
# cat /sys/fs/resctrl/info/L3/io_alloc_cbm
0=0;1=0

When CDP is enabled "io_alloc_cbm" associated with the CDP_DATA and CDP_CODE
resources may reflect the same values. For example, values read from and
written to /sys/fs/resctrl/info/L3DATA/io_alloc_cbm may be reflected by
Expand All @@ -228,12 +236,11 @@ with respect to allocation:
user can request.

"bandwidth_gran":
The granularity in which the memory bandwidth
The approximate granularity in which the memory bandwidth
percentage is allocated. The allocated
b/w percentage is rounded off to the next
control step available on the hardware. The
available bandwidth control steps are:
min_bandwidth + N * bandwidth_gran.
control step available on the hardware. The available
steps are at least as small as this value.

"delay_linear":
Indicates if the delay scale is linear or
Expand Down
2 changes: 2 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -22198,11 +22198,13 @@ F: tools/testing/selftests/net/rds/
RDT - RESOURCE ALLOCATION
M: Tony Luck <tony.luck@intel.com>
M: Reinette Chatre <reinette.chatre@intel.com>
M: x86@kernel.org
R: Dave Martin <Dave.Martin@arm.com>
R: James Morse <james.morse@arm.com>
R: Babu Moger <babu.moger@amd.com>
L: linux-kernel@vger.kernel.org
S: Supported
P: Documentation/process/maintainer-tip.rst
F: Documentation/filesystems/resctrl.rst
F: arch/x86/include/asm/resctrl.h
F: arch/x86/kernel/cpu/resctrl/
Expand Down
6 changes: 4 additions & 2 deletions arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2017,8 +2017,8 @@ config ARM64_TLB_RANGE

config ARM64_MPAM
bool "Enable support for MPAM"
select ARM64_MPAM_DRIVER if EXPERT # does nothing yet
select ACPI_MPAM if ACPI
select ARM64_MPAM_DRIVER
select ARCH_HAS_CPU_RESCTRL
help
Memory System Resource Partitioning and Monitoring (MPAM) is an
optional extension to the Arm architecture that allows each
Expand All @@ -2040,6 +2040,8 @@ config ARM64_MPAM

MPAM is exposed to user-space via the resctrl pseudo filesystem.

This option enables the extra context switch code.

endmenu # "ARMv8.4 architectural features"

menu "ARMv8.5 architectural features"
Expand Down
3 changes: 2 additions & 1 deletion arch/arm64/include/asm/el2_setup.h
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,8 @@
check_override id_aa64pfr0, ID_AA64PFR0_EL1_MPAM_SHIFT, .Linit_mpam_\@, .Lskip_mpam_\@, x1, x2

.Linit_mpam_\@:
msr_s SYS_MPAM2_EL2, xzr // use the default partition
mov x0, #MPAM2_EL2_EnMPAMSM_MASK
msr_s SYS_MPAM2_EL2, x0 // use the default partition,
// and disable lower traps
mrs_s x0, SYS_MPAMIDR_EL1
tbz x0, #MPAMIDR_EL1_HAS_HCR_SHIFT, .Lskip_mpam_\@ // skip if no MPAMHCR reg
Expand Down
96 changes: 96 additions & 0 deletions arch/arm64/include/asm/mpam.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2025 Arm Ltd. */

#ifndef __ASM__MPAM_H
#define __ASM__MPAM_H

#include <linux/arm_mpam.h>
#include <linux/bitfield.h>
#include <linux/jump_label.h>
#include <linux/percpu.h>
#include <linux/sched.h>

#include <asm/sysreg.h>

DECLARE_STATIC_KEY_FALSE(mpam_enabled);
DECLARE_PER_CPU(u64, arm64_mpam_default);
DECLARE_PER_CPU(u64, arm64_mpam_current);

/*
* The value of the MPAM0_EL1 sysreg when a task is in resctrl's default group.
* This is used by the context switch code to use the resctrl CPU property
* instead. The value is modified when CDP is enabled/disabled by mounting
* the resctrl filesystem.
*/
extern u64 arm64_mpam_global_default;

#ifdef CONFIG_ARM64_MPAM
static inline u64 __mpam_regval(u16 partid_d, u16 partid_i, u8 pmg_d, u8 pmg_i)
{
return FIELD_PREP(MPAM0_EL1_PARTID_D, partid_d) |
FIELD_PREP(MPAM0_EL1_PARTID_I, partid_i) |
FIELD_PREP(MPAM0_EL1_PMG_D, pmg_d) |
FIELD_PREP(MPAM0_EL1_PMG_I, pmg_i);
}

static inline void mpam_set_cpu_defaults(int cpu, u16 partid_d, u16 partid_i,
u8 pmg_d, u8 pmg_i)
{
u64 default_val = __mpam_regval(partid_d, partid_i, pmg_d, pmg_i);

WRITE_ONCE(per_cpu(arm64_mpam_default, cpu), default_val);
}

/*
* The resctrl filesystem writes to the partid/pmg values for threads and CPUs,
* which may race with reads in mpam_thread_switch(). Ensure only one of the old
* or new values are used. Particular care should be taken with the pmg field as
* mpam_thread_switch() may read a partid and pmg that don't match, causing this
* value to be stored with cache allocations, despite being considered 'free' by
* resctrl.
*/
static inline u64 mpam_get_regval(struct task_struct *tsk)
{
return READ_ONCE(task_thread_info(tsk)->mpam_partid_pmg);
}

static inline void mpam_set_task_partid_pmg(struct task_struct *tsk,
u16 partid_d, u16 partid_i,
u8 pmg_d, u8 pmg_i)
{
u64 regval = __mpam_regval(partid_d, partid_i, pmg_d, pmg_i);

WRITE_ONCE(task_thread_info(tsk)->mpam_partid_pmg, regval);
}

static inline void mpam_thread_switch(struct task_struct *tsk)
{
u64 oldregval;
int cpu = smp_processor_id();
u64 regval = mpam_get_regval(tsk);

if (!static_branch_likely(&mpam_enabled))
return;

if (regval == READ_ONCE(arm64_mpam_global_default))
regval = READ_ONCE(per_cpu(arm64_mpam_default, cpu));

oldregval = READ_ONCE(per_cpu(arm64_mpam_current, cpu));
if (oldregval == regval)
return;

write_sysreg_s(regval | MPAM1_EL1_MPAMEN, SYS_MPAM1_EL1);
if (system_supports_sme())
write_sysreg_s(regval & (MPAMSM_EL1_PARTID_D | MPAMSM_EL1_PMG_D), SYS_MPAMSM_EL1);
isb();

/* Synchronising the EL0 write is left until the ERET to EL0 */
write_sysreg_s(regval, SYS_MPAM0_EL1);

WRITE_ONCE(per_cpu(arm64_mpam_current, cpu), regval);
}
#else
static inline void mpam_thread_switch(struct task_struct *tsk) {}
#endif /* CONFIG_ARM64_MPAM */

#endif /* __ASM__MPAM_H */
2 changes: 2 additions & 0 deletions arch/arm64/include/asm/resctrl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/arm_mpam.h>
3 changes: 3 additions & 0 deletions arch/arm64/include/asm/thread_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ struct thread_info {
#ifdef CONFIG_SHADOW_CALL_STACK
void *scs_base;
void *scs_sp;
#endif
#ifdef CONFIG_ARM64_MPAM
u64 mpam_partid_pmg;
#endif
u32 cpu;
};
Expand Down
1 change: 1 addition & 0 deletions arch/arm64/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o
obj-$(CONFIG_ARM64_PTR_AUTH) += pointer_auth.o
obj-$(CONFIG_ARM64_MPAM) += mpam.o
obj-$(CONFIG_ARM64_MTE) += mte.o
obj-y += vdso-wrap.o
obj-$(CONFIG_COMPAT_VDSO) += vdso32-wrap.o
Expand Down
21 changes: 14 additions & 7 deletions arch/arm64/kernel/cpufeature.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
#include <asm/kvm_host.h>
#include <asm/mmu.h>
#include <asm/mmu_context.h>
#include <asm/mpam.h>
#include <asm/mte.h>
#include <asm/hypervisor.h>
#include <asm/processor.h>
Expand Down Expand Up @@ -2501,13 +2502,19 @@ test_has_mpam(const struct arm64_cpu_capabilities *entry, int scope)
static void
cpu_enable_mpam(const struct arm64_cpu_capabilities *entry)
{
/*
* Access by the kernel (at EL1) should use the reserved PARTID
* which is configured unrestricted. This avoids priority-inversion
* where latency sensitive tasks have to wait for a task that has
* been throttled to release the lock.
*/
write_sysreg_s(0, SYS_MPAM1_EL1);
int cpu = smp_processor_id();
u64 regval = 0;

if (IS_ENABLED(CONFIG_ARM64_MPAM) && static_branch_likely(&mpam_enabled))
regval = READ_ONCE(per_cpu(arm64_mpam_current, cpu));

write_sysreg_s(regval | MPAM1_EL1_MPAMEN, SYS_MPAM1_EL1);
if (cpus_have_cap(ARM64_SME))
write_sysreg_s(regval & (MPAMSM_EL1_PARTID_D | MPAMSM_EL1_PMG_D), SYS_MPAMSM_EL1);
isb();

/* Synchronising the EL0 write is left until the ERET to EL0 */
write_sysreg_s(regval, SYS_MPAM0_EL1);
}

static bool
Expand Down
62 changes: 62 additions & 0 deletions arch/arm64/kernel/mpam.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2025 Arm Ltd. */

#include <asm/mpam.h>

#include <linux/arm_mpam.h>
#include <linux/cpu_pm.h>
#include <linux/jump_label.h>
#include <linux/percpu.h>

DEFINE_STATIC_KEY_FALSE(mpam_enabled);
DEFINE_PER_CPU(u64, arm64_mpam_default);
DEFINE_PER_CPU(u64, arm64_mpam_current);

u64 arm64_mpam_global_default;

static int mpam_pm_notifier(struct notifier_block *self,
unsigned long cmd, void *v)
{
u64 regval;
int cpu = smp_processor_id();

switch (cmd) {
case CPU_PM_EXIT:
/*
* Don't use mpam_thread_switch() as the system register
* value has changed under our feet.
*/
regval = READ_ONCE(per_cpu(arm64_mpam_current, cpu));
write_sysreg_s(regval | MPAM1_EL1_MPAMEN, SYS_MPAM1_EL1);
if (system_supports_sme()) {
write_sysreg_s(regval & (MPAMSM_EL1_PARTID_D | MPAMSM_EL1_PMG_D),
SYS_MPAMSM_EL1);
}
isb();

write_sysreg_s(regval, SYS_MPAM0_EL1);

return NOTIFY_OK;
default:
return NOTIFY_DONE;
}
}

static struct notifier_block mpam_pm_nb = {
.notifier_call = mpam_pm_notifier,
};

static int __init arm64_mpam_register_cpus(void)
{
u64 mpamidr = read_sanitised_ftr_reg(SYS_MPAMIDR_EL1);
u16 partid_max = FIELD_GET(MPAMIDR_EL1_PARTID_MAX, mpamidr);
u8 pmg_max = FIELD_GET(MPAMIDR_EL1_PMG_MAX, mpamidr);

if (!system_supports_mpam())
return 0;

cpu_pm_register_notifier(&mpam_pm_nb);
return mpam_register_requestor(partid_max, pmg_max);
}
/* Must occur before mpam_msc_driver_init() from subsys_initcall() */
arch_initcall(arm64_mpam_register_cpus)
Loading
Loading