All of lore.kernel.org
 help / color / mirror / Atom feed
* [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
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ 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] 4+ 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
  2026-10-13 23:47 ` Stephane Eranian
  2026-10-14  1:27 ` Mi, Dapeng
  2 siblings, 0 replies; 4+ 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] 4+ 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
@ 2026-10-13 23:47 ` Stephane Eranian
  2026-10-14  1:27 ` Mi, Dapeng
  2 siblings, 0 replies; 4+ messages in thread
From: Stephane Eranian @ 2026-10-13 23:47 UTC (permalink / raw)
  To: Zide Chen
  Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, linux-kernel, linux-perf-users, stable, Dapeng Mi

On Tue, Oct 13, 2026 at 12:50 PM Zide Chen <zide.chen@intel.com> wrote:
>
> 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,

I think this SPR uncore IIO is not relvalent to the patch here. It
should be split.
Thanks.

>
> +       &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	[flat|nested] 4+ 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
  2026-10-13 23:47 ` Stephane Eranian
@ 2026-10-14  1:27 ` Mi, Dapeng
  2 siblings, 0 replies; 4+ messages in thread
From: Mi, Dapeng @ 2026-10-14  1:27 UTC (permalink / raw)
  To: Zide Chen, 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

LGTM. Thanks.

Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>


On 10/14/2026 3:40 AM, Zide Chen wrote:
> 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)

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-14  1:27 UTC | newest]

Thread overview: 4+ 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
2026-10-13 23:47 ` Stephane Eranian
2026-10-14  1:27 ` Mi, Dapeng

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.