[PATCH v6 05/18] x86,arm,fs/resctrl: Introduce architecture hook to program global kernel mode

From: Babu Moger

Date: Thu Oct 01 2026 - 11:28:32 EST


RESCTRL_GLOBAL_ENABLE_PER_CPU mode enables kernel work to use different
allocation and monitoring associations than the originating user task.

The mode is enabled independently on each CPU, so the filesystem must
program hardware when the mode is activated, when CPUs are added or
removed, and when it is deactivated. Allocation and monitoring associations
can be done independently, so the architecture callback takes separate
control and monitoring options.

Add resctrl_arch_configure_kmode_global() with an x86 PLZA implementation
and an empty MPAM stub for ARM systems that do not support this mode.

Signed-off-by: Babu Moger <babu.moger@xxxxxxx>
---
v6: Rename to resctrl_arch_configure_kmode_global(). Rewrite changelog
for RESCTRL_GLOBAL_ENABLE_PER_CPU only (not a bugfix, not a code
restatement). Add arm to the subject. Document parameters first;
closid/rmid are always programmed. Split fs/arch contract from
call scenarios and name the mode explicitly.

v5: Fix kernel-doc for resctrl_arch_configure_kmode(), wire assign_ctrl
through to PLZA closid_en, and update the changelog.
Add calling context in API doc.

v4: Added assign_mon parameter in resctrl_arch_configure_kmode() to program the RMID
as discussed in below.
https://lore.kernel.org/lkml/20260605100642.1103628-1-qinyuntan@xxxxxxxxxxxxxxxxx/
Reintroduce independent monitoring assignment via assign_mon after removing
the task-based PLZA approach in v3.
Changed cpumask type to "const struct cpumask *cpu_mask".
Added MPAM stub to avoid any linking issues when resctrl_arch_configure_kmode()
is called from FS layer. Thanks to Qinyun.
Re-wrote the changelog to be generic.
Updated code comments.
v3: Removed task based PLZA implementation so related changes are removed.
Per-task RMID handling is replaced by group type selection in the fs layer.
Updated the change log with details.
Removed resctrl_arch_set_kmode() as arch only provides the modes supported.
It is FS which decided which mode to apply.
v2: Updated the commit message to include the sequence of steps to enable PLZA.
Added mode code comments for clarity.
Added kmode to function names to be generic.
---
arch/x86/kernel/cpu/resctrl/ctrlmondata.c | 38 +++++++++++++++++++++++
drivers/resctrl/mpam_resctrl.c | 7 +++++
include/linux/resctrl.h | 37 ++++++++++++++++++++++
3 files changed, 82 insertions(+)

diff --git a/arch/x86/kernel/cpu/resctrl/ctrlmondata.c b/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
index 62044489b052..a343dc0c71c5 100644
--- a/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
+++ b/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
@@ -137,3 +137,41 @@ int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable)

return 0;
}
+
+static void resctrl_kmode_set_one_amd(void *arg)
+{
+ union msr_pqr_plza_assoc *plza = arg;
+
+ wrmsrq(MSR_IA32_PQR_PLZA_ASSOC, plza->full);
+}
+
+/*
+ * resctrl_arch_configure_kmode_global - Program Privilege Level Zero
+ * Association (PLZA).
+ * @cpu_mask: CPUs whose PLZA MSR should be updated.
+ * @closid: CLOSID programmed into MSR_IA32_PQR_PLZA_ASSOC. Always
+ * written; required even when @assign_ctrl is false.
+ * @assign_ctrl: Whether PLZA should program the kernel-mode CLOSID.
+ * @rmid: RMID programmed into MSR_IA32_PQR_PLZA_ASSOC. Always
+ * written; required even when @assign_mon is false.
+ * @assign_mon: Whether PLZA should program the kernel-mode RMID.
+ * @enable: Whether PLZA should program the kernel-mode association.
+ *
+ * Program PLZA on @cpu_mask for %RESCTRL_GLOBAL_ENABLE_PER_CPU. See
+ * union msr_pqr_plza_assoc for the hardware field meanings.
+ */
+void resctrl_arch_configure_kmode_global(const struct cpumask *cpu_mask,
+ u32 closid, bool assign_ctrl,
+ u32 rmid, bool assign_mon,
+ bool enable)
+{
+ union msr_pqr_plza_assoc plza = { 0 };
+
+ plza.split.rmid = rmid;
+ plza.split.rmid_en = assign_mon;
+ plza.split.closid = closid;
+ plza.split.closid_en = assign_ctrl;
+ plza.split.plza_en = enable;
+
+ on_each_cpu_mask(cpu_mask, resctrl_kmode_set_one_amd, &plza, 1);
+}
diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
index f2c651e9f6ea..0c8594e98526 100644
--- a/drivers/resctrl/mpam_resctrl.c
+++ b/drivers/resctrl/mpam_resctrl.c
@@ -139,6 +139,13 @@ bool resctrl_arch_get_io_alloc_enabled(struct rdt_resource *r)
return false;
}

+void resctrl_arch_configure_kmode_global(const struct cpumask *cpu_mask,
+ u32 closid, bool assign_ctrl,
+ u32 rmid, bool assign_mon,
+ bool enable)
+{
+}
+
void resctrl_arch_pre_mount(void)
{
}
diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index f6adff7f4e1f..dcb0beb847b6 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -752,6 +752,43 @@ enum resctrl_kernel_mode {

#define RESCTRL_NUM_KERNEL_MODES (RESCTRL_KMODE_LAST + 1)

+/**
+ * resctrl_arch_configure_kmode_global() - Program RESCTRL_GLOBAL_ENABLE_PER_CPU
+ *
+ * @cpu_mask: CPUs whose kernel-mode association should be updated.
+ * @closid: CLOSID that matches the RMID to program kernel mode. Depending
+ * on the architecture, the counter may match traffic of both
+ * @closid and @rmid, or @rmid only. Always provided; a valid
+ * CLOSID is required even when @assign_ctrl is false.
+ * @assign_ctrl: true to assign @closid for kernel mode; false to inherit
+ * association from the user-space task.
+ * @rmid: RMID to program the kernel mode. Some architectures may use
+ * CLOSID/RMID separately, others will consider them together.
+ * Always provided; a valid RMID is required even when
+ * @assign_mon is false.
+ * @assign_mon: true to assign @rmid for kernel mode; false to inherit
+ * monitoring association from the user-space task.
+ * @enable: true to enable kernel mode association on CPUs in @cpu_mask;
+ * false to disable kernel mode.
+ *
+ * This callback programs %RESCTRL_GLOBAL_ENABLE_PER_CPU. It is called in
+ * the following scenarios:
+ * - If the mode is active when user space changes the configuration, it is
+ * first called to deactivate the mode on all CPUs where it is active.
+ * - When user space activates the mode, it is called with cpu_online_mask.
+ * - When user space adds a CPU to the active mode.
+ * - When user space removes a CPU from the active mode.
+ *
+ * Contract between fs and arch: resctrl fs always provides the same
+ * closid, assign_ctrl, rmid, and assign_mon when activating
+ * %RESCTRL_GLOBAL_ENABLE_PER_CPU, during CPU add/remove while the mode is
+ * active, and when deactivating the mode.
+ */
+void resctrl_arch_configure_kmode_global(const struct cpumask *cpu_mask,
+ u32 closid, bool assign_ctrl,
+ u32 rmid, bool assign_mon,
+ bool enable);
+
extern unsigned int resctrl_rmid_realloc_threshold;
extern unsigned int resctrl_rmid_realloc_limit;

--
2.43.0