]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
x86,fs/resctrl: Fix NULL pointer dereference with events force-disabled in mbm_event...
authorBabu Moger <babu.moger@amd.com>
Thu, 16 Oct 2025 13:34:19 +0000 (08:34 -0500)
committerBorislav Petkov (AMD) <bp@alien8.de>
Mon, 20 Oct 2025 16:06:31 +0000 (18:06 +0200)
The following NULL pointer dereference is encountered on mount of resctrl fs
after booting a system that supports assignable counters with the
"rdt=!mbmtotal,!mbmlocal" kernel parameters:

  BUG: kernel NULL pointer dereference, address: 0000000000000008
  RIP: 0010:mbm_cntr_get
  Call Trace:
  rdtgroup_assign_cntr_event
  rdtgroup_assign_cntrs
  rdt_get_tree

Specifying the kernel parameter "rdt=!mbmtotal,!mbmlocal" effectively disables
the legacy X86_FEATURE_CQM_MBM_TOTAL and X86_FEATURE_CQM_MBM_LOCAL features
and the MBM events they represent. This results in the per-domain MBM event
related data structures to not be allocated during early initialization.

resctrl fs initialization follows by implicitly enabling both MBM total and
local events on a system that supports assignable counters (mbm_event mode),
but this enabling occurs after the per-domain data structures have been
created.

After booting, resctrl fs assumes that an enabled event can access all its
state. This results in NULL pointer dereference when resctrl attempts to
access the un-allocated structures of an enabled event.

Remove the late MBM event enabling from resctrl fs.

This leaves a problem where the X86_FEATURE_CQM_MBM_TOTAL and
X86_FEATURE_CQM_MBM_LOCAL features may be disabled while assignable counter
(mbm_event) mode is enabled without any events to support. Switching between
the "default" and "mbm_event" mode without any events is not practical.

Create a dependency between the X86_FEATURE_{CQM_MBM_TOTAL,CQM_MBM_LOCAL} and
X86_FEATURE_ABMC (assignable counter) hardware features. An x86 system that
supports assignable counters now requires support of X86_FEATURE_CQM_MBM_TOTAL
or X86_FEATURE_CQM_MBM_LOCAL.

This ensures all needed MBM related data structures are created before use and
that it is only possible to switch between "default" and "mbm_event" mode when
the same events are available in both modes. This dependency does not exist in
the hardware but this usage of these feature settings work for known systems.

  [ bp: Massage commit message. ]

Fixes: 13390861b426e ("x86,fs/resctrl: Detect Assignable Bandwidth Monitoring feature details")
Co-developed-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Link: https://patch.msgid.link/a62e6ac063d0693475615edd213d5be5e55443e6.1760560934.git.babu.moger@amd.com
arch/x86/kernel/cpu/resctrl/monitor.c
fs/resctrl/monitor.c

index 2cd25a0d4637ebd3ef40faee2652fcca6ab07212..fe1a2aa53c16aba1324e3690bb955ece0651759f 100644 (file)
@@ -458,7 +458,16 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
                r->mon.mbm_cfg_mask = ecx & MAX_EVT_CONFIG_BITS;
        }
 
-       if (rdt_cpu_has(X86_FEATURE_ABMC)) {
+       /*
+        * resctrl assumes a system that supports assignable counters can
+        * switch to "default" mode. Ensure that there is a "default" mode
+        * to switch to. This enforces a dependency between the independent
+        * X86_FEATURE_ABMC and X86_FEATURE_CQM_MBM_TOTAL/X86_FEATURE_CQM_MBM_LOCAL
+        * hardware features.
+        */
+       if (rdt_cpu_has(X86_FEATURE_ABMC) &&
+           (rdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL) ||
+            rdt_cpu_has(X86_FEATURE_CQM_MBM_LOCAL))) {
                r->mon.mbm_cntr_assignable = true;
                cpuid_count(0x80000020, 5, &eax, &ebx, &ecx, &edx);
                r->mon.num_mbm_cntrs = (ebx & GENMASK(15, 0)) + 1;
index 4076336fbba6db5e86f3b864ad394b16296e9f43..572a9925bd6ca073f499db3721b10277c56e3b61 100644 (file)
@@ -1782,15 +1782,13 @@ int resctrl_mon_resource_init(void)
                mba_mbps_default_event = QOS_L3_MBM_TOTAL_EVENT_ID;
 
        if (r->mon.mbm_cntr_assignable) {
-               if (!resctrl_is_mon_event_enabled(QOS_L3_MBM_TOTAL_EVENT_ID))
-                       resctrl_enable_mon_event(QOS_L3_MBM_TOTAL_EVENT_ID);
-               if (!resctrl_is_mon_event_enabled(QOS_L3_MBM_LOCAL_EVENT_ID))
-                       resctrl_enable_mon_event(QOS_L3_MBM_LOCAL_EVENT_ID);
-               mon_event_all[QOS_L3_MBM_TOTAL_EVENT_ID].evt_cfg = r->mon.mbm_cfg_mask;
-               mon_event_all[QOS_L3_MBM_LOCAL_EVENT_ID].evt_cfg = r->mon.mbm_cfg_mask &
-                                                                  (READS_TO_LOCAL_MEM |
-                                                                   READS_TO_LOCAL_S_MEM |
-                                                                   NON_TEMP_WRITE_TO_LOCAL_MEM);
+               if (resctrl_is_mon_event_enabled(QOS_L3_MBM_TOTAL_EVENT_ID))
+                       mon_event_all[QOS_L3_MBM_TOTAL_EVENT_ID].evt_cfg = r->mon.mbm_cfg_mask;
+               if (resctrl_is_mon_event_enabled(QOS_L3_MBM_LOCAL_EVENT_ID))
+                       mon_event_all[QOS_L3_MBM_LOCAL_EVENT_ID].evt_cfg = r->mon.mbm_cfg_mask &
+                                                                          (READS_TO_LOCAL_MEM |
+                                                                           READS_TO_LOCAL_S_MEM |
+                                                                           NON_TEMP_WRITE_TO_LOCAL_MEM);
                r->mon.mbm_assign_on_mkdir = true;
                resctrl_file_fflags_init("num_mbm_cntrs",
                                         RFTYPE_MON_INFO | RFTYPE_RES_CACHE);