* [PATCH] perf/x86/intel/uncore: Add Granite Rapids CMS PMU support
@ 2026-10-13 19:40 Zide Chen
2026-10-13 20:02 ` sashiko-bot
0 siblings, 1 reply; 2+ messages in thread
From: Zide Chen @ 2026-10-13 19:40 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, stable, Dapeng Mi, Zide Chen
Add support for the CMS (Common Mesh Stop) uncore PMON unit, shared by
GNR, SRF, GRR, and CWF. One CMS box exists per CHA box, at a fixed MSR
address: 0x3400 + 0x10 * unit_no + <reg offset>.
CMS is not enumerated in the discovery table, so it is added as an
extra MSR uncore type instead of going through the normal gnr_uncores[]
array. Since the CMS unit numbering matches the CHA unit numbering,
build the CMS box rb-tree by mirroring the discovered CHA (die, id)
pairs, ensuring CMS boxes only appear where a corresponding CHA exists.
Make generic_uncore_msr_ops global so the CMS type can reuse it.
Opportunistically add the intel_ prefix to match the naming convention.
Cc: stable@vger.kernel.org
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
arch/x86/events/intel/uncore_discovery.c | 4 +-
arch/x86/events/intel/uncore_discovery.h | 1 +
arch/x86/events/intel/uncore_snbep.c | 81 +++++++++++++++++++++++-
3 files changed, 82 insertions(+), 4 deletions(-)
diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
index 0a22edf4d509..170f299385a0 100644
--- a/arch/x86/events/intel/uncore_discovery.c
+++ b/arch/x86/events/intel/uncore_discovery.c
@@ -532,7 +532,7 @@ static void intel_generic_uncore_msr_disable_event(struct intel_uncore_box *box,
wrmsrq(hwc->config_base, 0);
}
-static struct intel_uncore_ops generic_uncore_msr_ops = {
+struct intel_uncore_ops intel_generic_uncore_msr_ops = {
.init_box = intel_generic_uncore_msr_init_box,
.disable_box = intel_generic_uncore_msr_disable_box,
.enable_box = intel_generic_uncore_msr_enable_box,
@@ -743,7 +743,7 @@ static bool uncore_update_uncore_type(enum uncore_access_type type_id,
switch (type_id) {
case UNCORE_ACCESS_MSR:
- uncore->ops = &generic_uncore_msr_ops;
+ uncore->ops = &intel_generic_uncore_msr_ops;
break;
case UNCORE_ACCESS_PCI:
uncore->ops = &generic_uncore_pci_ops;
diff --git a/arch/x86/events/intel/uncore_discovery.h b/arch/x86/events/intel/uncore_discovery.h
index 142e1b56cfc2..cececf6ecdc5 100644
--- a/arch/x86/events/intel/uncore_discovery.h
+++ b/arch/x86/events/intel/uncore_discovery.h
@@ -151,6 +151,7 @@ void intel_uncore_generic_uncore_mmio_init(void);
int intel_generic_uncore_msr_init_box(struct intel_uncore_box *box);
void intel_generic_uncore_msr_disable_box(struct intel_uncore_box *box);
void intel_generic_uncore_msr_enable_box(struct intel_uncore_box *box);
+extern struct intel_uncore_ops intel_generic_uncore_msr_ops;
int intel_generic_uncore_mmio_init_box(struct intel_uncore_box *box);
void intel_generic_uncore_mmio_disable_box(struct intel_uncore_box *box);
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index a97cd029db36..3abbc1bbf577 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -6492,6 +6492,32 @@ int gnr_uncore_units_ignore[] = {
UNCORE_IGNORE_END
};
+/*
+ * One CMS box exists per CHA box, at a fixed MSR address:
+ * 0x3400 + 0x10 * unit_no + <reg offset>.
+ */
+#define GNR_CMS_MSR_PMON_BOX_CTL 0x3400
+#define GNR_CMS_MSR_PMON_CTL0 0x02
+#define GNR_CMS_MSR_PMON_CTR0 0x08
+#define GNR_CMS_MSR_OFFSET 0x10
+/* Type ID for CMS */
+#define UNCORE_GNR_CMS 50
+
+static struct intel_uncore_type gnr_uncore_cms = {
+ /* Keep the PMU name aligned with the published CHACMS event list. */
+ .name = "chacms",
+ .type_id = UNCORE_GNR_CMS,
+ .event_mask = SNBEP_PMON_RAW_EVENT_MASK,
+ .num_counters = 4,
+ .perf_ctr_bits = 48,
+ .event_ctl = GNR_CMS_MSR_PMON_CTL0,
+ .perf_ctr = GNR_CMS_MSR_PMON_CTR0,
+ .ops = &intel_generic_uncore_msr_ops,
+ .format_group = &snbep_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+ .cleanup_extra_boxes = spr_extra_boxes_cleanup,
+};
+
static struct intel_uncore_type gnr_uncore_ubox = {
.name = "ubox",
.attr_update = uncore_alias_groups,
@@ -6595,15 +6621,66 @@ static struct freerunning_counters gnr_iio_freerunning[] = {
[SPR_IIO_MSR_BW_OUT] = { 0x2e0e, 0x10, 0x80, 8, 48 },
};
+/*
+ * Neither the free-running IIO counters nor CMS are covered by the
+ * discovery table, so both are added as "extra" MSR uncore types, in
+ * addition to the ones enumerated in gnr_uncores[].
+ */
+#define UNCORE_GNR_MSR_EXTRA_UNCORES 2
+
+static struct intel_uncore_type *gnr_msr_uncores[UNCORE_GNR_MSR_EXTRA_UNCORES] = {
+ &spr_uncore_iio_free_running,
+ &gnr_uncore_cms,
+};
+
+/* Build the CMS boxes rb-tree by mirroring CHA's discovered boxes. */
+static void gnr_uncore_cms_init_boxes(struct intel_uncore_type **uncores)
+{
+ struct intel_uncore_discovery_unit *cha_unit, *cms_unit;
+ struct intel_uncore_type *cha;
+ struct rb_root *root;
+ struct rb_node *node;
+ u16 num_units = 0;
+
+ cha = uncore_find_type_by_id(uncores, UNCORE_SPR_CHA);
+ if (!cha || !cha->boxes)
+ return;
+
+ root = kzalloc_obj(*root);
+ if (!root)
+ return;
+ *root = RB_ROOT;
+
+ for (node = rb_first(cha->boxes); node; node = rb_next(node)) {
+ cha_unit = rb_entry(node, struct intel_uncore_discovery_unit, node);
+
+ cms_unit = kzalloc_obj(*cms_unit);
+ if (!cms_unit)
+ break;
+
+ cms_unit->id = cha_unit->id;
+ cms_unit->die = cha_unit->die;
+ cms_unit->addr = GNR_CMS_MSR_PMON_BOX_CTL +
+ cha_unit->id * GNR_CMS_MSR_OFFSET;
+
+ uncore_find_add_unit(cms_unit, root, &num_units);
+ }
+
+ gnr_uncore_cms.boxes = root;
+ gnr_uncore_cms.num_boxes = num_units;
+}
+
void gnr_uncore_cpu_init(void)
{
uncore_msr_uncores = uncore_get_uncores(UNCORE_ACCESS_MSR,
- UNCORE_SPR_MSR_EXTRA_UNCORES,
- spr_msr_uncores,
+ UNCORE_GNR_MSR_EXTRA_UNCORES,
+ gnr_msr_uncores,
UNCORE_GNR_NUM_UNCORE_TYPES,
gnr_uncores);
spr_uncore_iio_free_running.num_boxes = uncore_type_max_boxes(uncore_msr_uncores, UNCORE_SPR_IIO);
spr_uncore_iio_free_running.freerunning = gnr_iio_freerunning;
+
+ gnr_uncore_cms_init_boxes(uncore_msr_uncores);
}
int gnr_uncore_pci_init(void)
--
2.55.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] perf/x86/intel/uncore: Add Granite Rapids CMS PMU support
2026-10-13 19:40 [PATCH] perf/x86/intel/uncore: Add Granite Rapids CMS PMU support Zide Chen
@ 2026-10-13 20:02 ` sashiko-bot
0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-10-13 20:02 UTC (permalink / raw)
To: Zide Chen; +Cc: linux-perf-users
> Add support for the CMS (Common Mesh Stop) uncore PMON unit, shared by
> GNR, SRF, GRR, and CWF. One CMS box exists per CHA box, at a fixed MSR
> address: 0x3400 + 0x10 * unit_no + <reg offset>.
>
> CMS is not enumerated in the discovery table, so it is added as an
> extra MSR uncore type instead of going through the normal gnr_uncores[]
> array. Since the CMS unit numbering matches the CHA unit numbering,
> build the CMS box rb-tree by mirroring the discovered CHA (die, id)
> pairs, ensuring CMS boxes only appear where a corresponding CHA exists.
>
> Make generic_uncore_msr_ops global so the CMS type can reuse it.
> Opportunistically add the intel_ prefix to match the naming convention.
>
> Cc: stable@vger.kernel.org
> Signed-off-by: Zide Chen <zide.chen@intel.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261013194005.96615-1-zide.chen@intel.com?part=1
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-13 20:02 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-13 19:40 [PATCH] perf/x86/intel/uncore: Add Granite Rapids CMS PMU support Zide Chen
2026-10-13 20:02 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox