[PATCH v10 09/17] x86/resctrl: Add PMT registration API for AET enumeration callbacks

From: Tony Luck

Date: Wed Jul 29 2026 - 15:05:22 EST


resctrl is always built-in; INTEL_PMT_TELEMETRY may be a module. Add, and
export, register/unregister functions so the PMT module can supply/clear
enumeration callback functions when loaded/unloaded.

Suggested-by: Christoph Hellwig <hch@xxxxxxxxxxxxx>
Signed-off-by: Tony Luck <tony.luck@xxxxxxxxx>
---
v10:
Move declaration and stubs for registration functions out
of <asm/resctrl.h> and into <linux/intel_vsec.h>
Defer adding aet_register_lock mutex until mount/unmount
changes where it is needed.

include/linux/intel_vsec.h | 12 ++++++++++++
arch/x86/kernel/cpu/resctrl/intel_aet.c | 24 ++++++++++++++++++++++++
2 files changed, 36 insertions(+)

diff --git a/include/linux/intel_vsec.h b/include/linux/intel_vsec.h
index 843cda8f8644..c04b1d0f3143 100644
--- a/include/linux/intel_vsec.h
+++ b/include/linux/intel_vsec.h
@@ -257,4 +257,16 @@ static inline void
intel_pmt_put_feature_group(struct pmt_feature_group *feature_group) {}
#endif

+#ifdef CONFIG_X86_CPU_RESCTRL_INTEL_AET
+void intel_aet_register_enumeration(struct module *module,
+ struct pmt_feature_group *(*get)(enum pmt_feature_id id),
+ void (*put)(struct pmt_feature_group *p));
+void intel_aet_unregister_enumeration(void);
+#else
+static inline void intel_aet_register_enumeration(struct module *module,
+ struct pmt_feature_group *(*get)(enum pmt_feature_id id),
+ void (*put)(struct pmt_feature_group *p)) { }
+static inline void intel_aet_unregister_enumeration(void) { }
+#endif /* CONFIG_X86_CPU_RESCTRL_INTEL_AET */
+
#endif
diff --git a/arch/x86/kernel/cpu/resctrl/intel_aet.c b/arch/x86/kernel/cpu/resctrl/intel_aet.c
index e6cc57206381..407c9aba5eea 100644
--- a/arch/x86/kernel/cpu/resctrl/intel_aet.c
+++ b/arch/x86/kernel/cpu/resctrl/intel_aet.c
@@ -17,12 +17,14 @@
#include <linux/cpumask.h>
#include <linux/err.h>
#include <linux/errno.h>
+#include <linux/export.h>
#include <linux/gfp_types.h>
#include <linux/init.h>
#include <linux/intel_pmt_features.h>
#include <linux/intel_vsec.h>
#include <linux/io.h>
#include <linux/minmax.h>
+#include <linux/module.h>
#include <linux/printk.h>
#include <linux/rculist.h>
#include <linux/rcupdate.h>
@@ -291,6 +293,10 @@ static enum pmt_feature_id lookup_pfid(const char *pfname)
return FEATURE_INVALID;
}

+static struct module *pmt_module;
+static struct pmt_feature_group *(*get_feature)(enum pmt_feature_id id);
+static void (*put_feature)(struct pmt_feature_group *p);
+
/*
* Request a copy of struct pmt_feature_group for each event group. If there is
* one, the returned structure has an array of telemetry_region structures,
@@ -334,6 +340,24 @@ void __init intel_aet_init(void)
(*peg)->num_rmid = min(max_rmid, (*peg)->num_rmid);
}

+void intel_aet_register_enumeration(struct module *module,
+ struct pmt_feature_group *(*get)(enum pmt_feature_id id),
+ void (*put)(struct pmt_feature_group *p))
+{
+ get_feature = get;
+ put_feature = put;
+ pmt_module = module;
+}
+EXPORT_SYMBOL_NS_GPL(intel_aet_register_enumeration, "INTEL_PMT");
+
+void intel_aet_unregister_enumeration(void)
+{
+ pmt_module = NULL;
+ get_feature = NULL;
+ put_feature = NULL;
+}
+EXPORT_SYMBOL_NS_GPL(intel_aet_unregister_enumeration, "INTEL_PMT");
+
void __exit intel_aet_exit(void)
{
struct event_group **peg;
--
2.55.0