[PATCH v3 11/12] resctrl: Hide kmode_cpus[_list] on groups not bound to kernel-mode

From: Babu Moger

Date: Thu Apr 30 2026 - 19:29:22 EST


The kmode_cpus and kmode_cpus_list files control the CPU scope of the
kernel-mode binding owned by resctrl_kcfg.k_rdtgrp. On any other
group they appeared as stub files, and writing to them reprogrammed
hardware as if the binding were active -- corrupting the real binding.

Hide both files via kernfs_show() on every rdtgroup that does not
currently own the binding. The kernel-mode lifecycle hooks toggle
visibility: hidden at mount on rdtgroup_default, hidden at mkdir for
new groups, shown by rdtgroup_config_kmode() on the group it binds,
and hidden again by rdtgroup_config_kmode_clear() (and through it,
rdtgroup_config_kmode_delete()) when the binding is released.

Signed-off-by: Babu Moger <babu.moger@xxxxxxx>
---
v3: New patch to hide/show "kmode_cpus" and "kmode_cpus_list" when kernel modes
binding changes.
---
fs/resctrl/rdtgroup.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)

diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index e155160ba2b1..cff306d28e79 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -1093,6 +1093,38 @@ static int resctrl_kernel_mode_show(struct kernfs_open_file *of,
return 0;
}

+/**
+ * resctrl_kmode_files_set_visible() - Toggle visibility of the per-group
+ * kernel-mode CPU files under @rdtgrp.
+ * @rdtgrp: Resctrl group whose "kmode_cpus" / "kmode_cpus_list" files
+ * should be hidden or shown.
+ * @visible: %true to expose the files, %false to hide them via
+ * kernfs_show().
+ *
+ * Each file is looked up independently as a sibling under @rdtgrp->kn.
+ * kernfs_find_and_get() failures are intentionally ignored: this helper
+ * is invoked early on rdtgroup_default before its rftype files have been
+ * populated, and is robust against any future rdtgroup variant whose
+ * kernfs tree does not include these files.
+ *
+ * Context: Caller must hold rdtgroup_mutex.
+ */
+static void resctrl_kmode_files_set_visible(struct rdtgroup *rdtgrp, bool visible)
+{
+ /* Keep in sync with res_common_files[] entries for these files. */
+ static const char * const files[] = { "kmode_cpus", "kmode_cpus_list" };
+ struct kernfs_node *kn;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(files); i++) {
+ kn = kernfs_find_and_get(rdtgrp->kn, files[i]);
+ if (!kn)
+ continue;
+ kernfs_show(kn, visible);
+ kernfs_put(kn);
+ }
+}
+
/**
* rdtgroup_config_kmode() - Push @rdtgrp's kernel CLOSID/RMID to hardware
* @rdtgrp: Resctrl group whose CLOSID/RMID should be programmed.
@@ -1161,6 +1193,7 @@ static int rdtgroup_config_kmode(struct rdtgroup *rdtgrp)
resctrl_arch_configure_kmode(disable_mask, closid, rmid, false);

rdtgrp->kmode = true;
+ resctrl_kmode_files_set_visible(rdtgrp, true);

free_cpumask_var(enable_mask);
if (need_disable)
@@ -1228,6 +1261,7 @@ static int rdtgroup_config_kmode_clear(struct rdtgroup *rdtgrp, int kmode)

out_clear:
cpumask_clear(&rdtgrp->kmode_cpu_mask);
+ resctrl_kmode_files_set_visible(rdtgrp, false);
rdtgrp->kmode = false;
return 0;
}
@@ -3387,6 +3421,8 @@ static int rdt_get_tree(struct fs_context *fc)
if (ret)
goto out_closid_exit;

+ /* Hide before activate; the kernfs hidden flag survives kernfs_activate(). */
+ resctrl_kmode_files_set_visible(&rdtgroup_default, false);
kernfs_activate(rdtgroup_default.kn);

ret = rdtgroup_create_info_dir(rdtgroup_default.kn);
@@ -4411,6 +4447,8 @@ static int rdtgroup_mkdir_mon(struct kernfs_node *parent_kn,
goto out_unlock;
}

+ /* Hide before activate; the kernfs hidden flag survives kernfs_activate(). */
+ resctrl_kmode_files_set_visible(rdtgrp, false);
kernfs_activate(rdtgrp->kn);

/*
@@ -4455,6 +4493,8 @@ static int rdtgroup_mkdir_ctrl_mon(struct kernfs_node *parent_kn,
if (ret)
goto out_closid_free;

+ /* Hide before activate; the kernfs hidden flag survives kernfs_activate(). */
+ resctrl_kmode_files_set_visible(rdtgrp, false);
kernfs_activate(rdtgrp->kn);

ret = rdtgroup_init_alloc(rdtgrp);
--
2.43.0