]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
x86,fs/resctrl: Create 'event_filter' files read only if they're not configurable
authorBen Horgan <ben.horgan@arm.com>
Wed, 6 May 2026 08:28:50 +0000 (09:28 +0100)
committerBorislav Petkov (AMD) <bp@alien8.de>
Wed, 6 May 2026 17:06:57 +0000 (19:06 +0200)
When the counter assignment mode is mbm_event resctrl assumes the MBM
events are configurable and exposes the 'event_filter' files. These files
live at info/L3_MON/event_configs/<event>/event_filter and are used to
display and set the event configuration.

The MPAM architecture has support for configuring the memory bandwidth
utilization (MBWU) counters to only count reads or only count
writes. However, in MPAM, this event filtering support is optional in the
hardware (and not yet implemented in the MPAM driver) but MBM counter
assignment is always possible for MPAM MBWU counters.

In order to support mbm_event mode with MPAM, create the 'event_filter'
files read only if the event configuration can't be changed. A user can
still chmod the file and so also return early with an error from
event_filter_write().

Introduce a new monitor property, mbm_cntr_configurable, to indicate
whether or not assignable MBM counters are configurable. On x86, set this
to true whenever mbm_cntr_assignable is true to keep existing behaviour.

Signed-off-by: Ben Horgan <ben.horgan@arm.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Reviewed-by: Babu Moger <babu.moger@amd.com>
Tested-by: Babu Moger <babu.moger@amd.com>
Link: https://lore.kernel.org/20260506082855.3694761-1-ben.horgan@arm.com
Documentation/filesystems/resctrl.rst
arch/x86/kernel/cpu/resctrl/monitor.c
fs/resctrl/internal.h
fs/resctrl/monitor.c
fs/resctrl/rdtgroup.c
include/linux/resctrl.h

index b003bed339fddd7e44a5feadf2ad5baa12e076fe..2898a51e6f4be382b66bc541f6f2a7625950da8f 100644 (file)
@@ -427,9 +427,9 @@ with the following files:
 
        Two MBM events are supported by default: mbm_local_bytes and mbm_total_bytes.
        Each MBM event's sub-directory contains a file named "event_filter" that is
-       used to view and modify which memory transactions the MBM event is configured
-       with. The file is accessible only when "mbm_event" counter assignment mode is
-       enabled.
+       used to view and (if writable) modify which memory transactions the MBM event
+       is configured with. The file is accessible only when "mbm_event" counter
+       assignment mode is enabled.
 
        List of memory transaction types supported:
 
@@ -454,9 +454,8 @@ with the following files:
          # cat /sys/fs/resctrl/info/L3_MON/event_configs/mbm_local_bytes/event_filter
          local_reads,local_non_temporal_writes,local_reads_slow_memory
 
-       Modify the event configuration by writing to the "event_filter" file within
-       the "event_configs" directory. The read/write "event_filter" file contains the
-       configuration of the event that reflects which memory transactions are counted by it.
+       The memory transactions the MBM event is configured with can be changed
+       if "event_filter" is writable.
 
        For example::
 
index 9bd87bae4983420911c6ffea9799c5a1cfbe6c35..794a6fb175e4e945e2d243c274602d69ae52c613 100644 (file)
@@ -454,6 +454,7 @@ int __init rdt_get_l3_mon_config(struct rdt_resource *r)
            (rdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL) ||
             rdt_cpu_has(X86_FEATURE_CQM_MBM_LOCAL))) {
                r->mon.mbm_cntr_assignable = true;
+               r->mon.mbm_cntr_configurable = true;
                cpuid_count(0x80000020, 5, &eax, &ebx, &ecx, &edx);
                r->mon.num_mbm_cntrs = (ebx & GENMASK(15, 0)) + 1;
                hw_res->mbm_cntr_assign_enabled = true;
index 1a9b29119f88f8630aa61802033b53f56af98817..48af75b9dc855872783edfb0fb4e129439114711 100644 (file)
@@ -408,6 +408,8 @@ void __check_limbo(struct rdt_l3_mon_domain *d, bool force_free);
 
 void resctrl_file_fflags_init(const char *config, unsigned long fflags);
 
+void resctrl_file_mode_init(const char *config, umode_t mode);
+
 void rdt_staged_configs_clear(void);
 
 bool closid_allocated(unsigned int closid);
index 9fd901c78dc66484c37236135cf0730b627905ab..916f7a9d56581ffbfef5431a159359d61870c6ab 100644 (file)
@@ -1422,6 +1422,11 @@ ssize_t event_filter_write(struct kernfs_open_file *of, char *buf, size_t nbytes
                ret = -EINVAL;
                goto out_unlock;
        }
+       if (!r->mon.mbm_cntr_configurable) {
+               rdt_last_cmd_puts("event_filter is not configurable\n");
+               ret = -EPERM;
+               goto out_unlock;
+       }
 
        ret = resctrl_parse_mem_transactions(buf, &evt_cfg);
        if (!ret && mevt->evt_cfg != evt_cfg) {
@@ -1886,6 +1891,8 @@ int resctrl_l3_mon_resource_init(void)
                resctrl_file_fflags_init("available_mbm_cntrs",
                                         RFTYPE_MON_INFO | RFTYPE_RES_CACHE);
                resctrl_file_fflags_init("event_filter", RFTYPE_ASSIGN_CONFIG);
+               if (r->mon.mbm_cntr_configurable)
+                       resctrl_file_mode_init("event_filter", 0644);
                resctrl_file_fflags_init("mbm_assign_on_mkdir", RFTYPE_MON_INFO |
                                         RFTYPE_RES_CACHE);
                resctrl_file_fflags_init("mbm_L3_assignments", RFTYPE_MON_BASE);
index eca3bb67987d4961ea98526bdbb4e08d327c47a0..7d800b306056242583d58444377c4b13967c423e 100644 (file)
@@ -2022,7 +2022,7 @@ static struct rftype res_common_files[] = {
        },
        {
                .name           = "event_filter",
-               .mode           = 0644,
+               .mode           = 0444,
                .kf_ops         = &rdtgroup_kf_single_ops,
                .seq_show       = event_filter_show,
                .write          = event_filter_write,
@@ -2215,6 +2215,15 @@ void resctrl_file_fflags_init(const char *config, unsigned long fflags)
                rft->fflags = fflags;
 }
 
+void resctrl_file_mode_init(const char *config, umode_t mode)
+{
+       struct rftype *rft;
+
+       rft = rdtgroup_get_rftype_by_name(config);
+       if (rft)
+               rft->mode = mode;
+}
+
 /**
  * rdtgroup_kn_mode_restrict - Restrict user access to named resctrl file
  * @r: The resource group with which the file is associated.
index 006e57fd7ca589beca6e79262f3193d07ac3b4c6..06e8c72e8660f2aaef0d425b97edd1103d0b8216 100644 (file)
@@ -286,13 +286,14 @@ enum resctrl_schema_fmt {
 
 /**
  * struct resctrl_mon - Monitoring related data of a resctrl resource.
- * @num_rmid:          Number of RMIDs available.
- * @mbm_cfg_mask:      Memory transactions that can be tracked when bandwidth
- *                     monitoring events can be configured.
- * @num_mbm_cntrs:     Number of assignable counters.
- * @mbm_cntr_assignable:Is system capable of supporting counter assignment?
- * @mbm_assign_on_mkdir:True if counters should automatically be assigned to MBM
- *                     events of monitor groups created via mkdir.
+ * @num_rmid:                  Number of RMIDs available.
+ * @mbm_cfg_mask:              Memory transactions that can be tracked when
+ *                             bandwidth monitoring events can be configured.
+ * @num_mbm_cntrs:             Number of assignable counters.
+ * @mbm_cntr_assignable:       Is system capable of supporting counter assignment?
+ * @mbm_assign_on_mkdir:       True if counters should automatically be assigned to MBM
+ *                             events of monitor groups created via mkdir.
+ * @mbm_cntr_configurable:     True if assignable counters are configurable.
  */
 struct resctrl_mon {
        u32                     num_rmid;
@@ -300,6 +301,7 @@ struct resctrl_mon {
        int                     num_mbm_cntrs;
        bool                    mbm_cntr_assignable;
        bool                    mbm_assign_on_mkdir;
+       bool                    mbm_cntr_configurable;
 };
 
 /**