diff --git a/tools/perf/tests/expand-cgroup.c b/tools/perf/tests/expand-cgroup.c
index 9c1a1f18db75..50e128ddb474 100644
--- a/tools/perf/tests/expand-cgroup.c
+++ b/tools/perf/tests/expand-cgroup.c
@@ -187,7 +187,7 @@ static int expand_metric_events(void)
 
 	rblist__init(&metric_events);
 	pme_test = find_core_metrics_table("testarch", "testcpu");
-	ret = metricgroup__parse_groups_test(evlist, pme_test, metric_str, &metric_events);
+	ret = metricgroup__parse_groups_test(evlist, pme_test, NULL, metric_str, &metric_events);
 	if (ret < 0) {
 		pr_debug("failed to parse '%s' metric\n", metric_str);
 		goto out;
diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metric.c
index 2c28fb50dc24..e146f1193294 100644
--- a/tools/perf/tests/parse-metric.c
+++ b/tools/perf/tests/parse-metric.c
@@ -95,7 +95,7 @@ static int __compute_metric(const char *name, struct value *vals,
 
 	/* Parse the metric into metric_events list. */
 	pme_test = find_core_metrics_table("testarch", "testcpu");
-	err = metricgroup__parse_groups_test(evlist, pme_test, name,
+	err = metricgroup__parse_groups_test(evlist, pme_test, NULL, name,
 					     &metric_events);
 	if (err)
 		goto out;
diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c
index 64383fc34ef1..de571fd11cd7 100644
--- a/tools/perf/tests/pmu-events.c
+++ b/tools/perf/tests/pmu-events.c
@@ -798,9 +798,9 @@ struct metric {
 	struct metric_ref metric_ref;
 };
 
-static int test__parsing_callback(const struct pmu_metric *pm,
+static int _test__parsing_callback(const struct pmu_metric *pm,
 				  const struct pmu_metrics_table *table,
-				  void *data)
+				  void *data, bool is_cpu_table)
 {
 	int *failures = data;
 	int k;
@@ -811,6 +811,8 @@ static int test__parsing_callback(const struct pmu_metric *pm,
 		.nr_entries = 0,
 	};
 	int err = 0;
+	const struct pmu_metrics_table *cpu_table = is_cpu_table ? table : NULL;
+	const struct pmu_metrics_table *sys_table = is_cpu_table ? NULL : table;
 
 	if (!pm->metric_expr)
 		return 0;
@@ -834,7 +836,8 @@ static int test__parsing_callback(const struct pmu_metric *pm,
 
 	perf_evlist__set_maps(&evlist->core, cpus, NULL);
 
-	err = metricgroup__parse_groups_test(evlist, table, pm->metric_name, &metric_events);
+	err = metricgroup__parse_groups_test(evlist, cpu_table, sys_table,
+					     pm->metric_name, &metric_events);
 	if (err) {
 		if (!strcmp(pm->metric_name, "M1") || !strcmp(pm->metric_name, "M2") ||
 		    !strcmp(pm->metric_name, "M3")) {
@@ -890,13 +893,27 @@ static int test__parsing_callback(const struct pmu_metric *pm,
 	return err;
 }
 
-static int test__parsing(struct test_suite *test __maybe_unused,
+static int test__parsing_callback_cpu(const struct pmu_metric *pm,
+				  const struct pmu_metrics_table *table,
+				  void *data)
+{
+	return _test__parsing_callback(pm, table, data, true);
+}
+
+static int test__parsing_callback_sys(const struct pmu_metric *pm,
+				  const struct pmu_metrics_table *table,
+				  void *data)
+{
+	return _test__parsing_callback(pm, table, data, false);
+}
+
+static __maybe_unused int test__parsing(struct test_suite *test __maybe_unused,
 			 int subtest __maybe_unused)
 {
 	int failures = 0;
 
-	pmu_for_each_core_metric(test__parsing_callback, &failures);
-	pmu_for_each_sys_metric(test__parsing_callback, &failures);
+	pmu_for_each_core_metric(test__parsing_callback_cpu, &failures);
+	pmu_for_each_sys_metric(test__parsing_callback_sys, &failures);
 
 	return failures == 0 ? TEST_OK : TEST_FAIL;
 }
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
index 8d2ac2513530..520436fbe99d 100644
--- a/tools/perf/util/metricgroup.c
+++ b/tools/perf/util/metricgroup.c
@@ -1232,13 +1232,14 @@ static int metricgroup__add_metric(const char *pmu, const char *metric_name, con
 				   const char *user_requested_cpu_list,
 				   bool system_wide,
 				   struct list_head *metric_list,
-				   const struct pmu_metrics_table *table)
+				   const struct pmu_metrics_table *cpu_table,
+				   const struct pmu_metrics_table *sys_table)
 {
 	LIST_HEAD(list);
 	int ret;
 	bool has_match = false;
 
-	{
+	if (cpu_table) {
 		struct metricgroup__add_metric_data data = {
 			.list = &list,
 			.pmu = pmu,
@@ -1254,7 +1255,7 @@ static int metricgroup__add_metric(const char *pmu, const char *metric_name, con
 		 * Iterate over all metrics seeing if metric matches either the
 		 * name or group. When it does add the metric to the list.
 		 */
-		ret = pmu_metrics_table_for_each_metric(table, metricgroup__add_metric_callback,
+		ret = pmu_metrics_table_for_each_metric(cpu_table, metricgroup__add_metric_callback,
 						       &data);
 		if (ret)
 			goto out;
@@ -1267,7 +1268,21 @@ static int metricgroup__add_metric(const char *pmu, const char *metric_name, con
 		goto out;
 	}
 
-	{
+	if (sys_table) {
+		struct metricgroup_add_iter_data data = {
+			.metric_list = &list,
+			.pmu = pmu,
+			.metric_name = metric_name,
+			.modifier = modifier,
+			.metric_no_group = metric_no_group,
+			.user_requested_cpu_list = user_requested_cpu_list,
+			.system_wide = system_wide,
+			.has_match = &has_match,
+			.ret = &ret,
+		};
+		pmu_metrics_table_for_each_metric(sys_table,
+			metricgroup__add_metric_sys_event_iter, &data);
+	} else {
 		struct metricgroup_iter_data data = {
 			.fn = metricgroup__add_metric_sys_event_iter,
 			.data = (void *) &(struct metricgroup_add_iter_data) {
@@ -1320,7 +1335,8 @@ static int metricgroup__add_metric_list(const char *pmu, const char *list,
 					bool metric_no_threshold,
 					const char *user_requested_cpu_list,
 					bool system_wide, struct list_head *metric_list,
-					const struct pmu_metrics_table *table)
+					const struct pmu_metrics_table *cpu_table,
+					const struct pmu_metrics_table *sys_table)
 {
 	char *list_itr, *list_copy, *metric_name, *modifier;
 	int ret, count = 0;
@@ -1338,7 +1354,8 @@ static int metricgroup__add_metric_list(const char *pmu, const char *list,
 		ret = metricgroup__add_metric(pmu, metric_name, modifier,
 					      metric_no_group, metric_no_threshold,
 					      user_requested_cpu_list,
-					      system_wide, metric_list, table);
+					      system_wide, metric_list, cpu_table,
+					      sys_table);
 		if (ret == -EINVAL)
 			pr_err("Cannot find metric or group `%s'\n", metric_name);
 
@@ -1534,7 +1551,8 @@ static int parse_groups(struct evlist *perf_evlist,
 			bool system_wide,
 			struct perf_pmu *fake_pmu,
 			struct rblist *metric_events_list,
-			const struct pmu_metrics_table *table)
+			const struct pmu_metrics_table *cpu_table,
+			const struct pmu_metrics_table *sys_table)
 {
 	struct evlist *combined_evlist = NULL;
 	LIST_HEAD(metric_list);
@@ -1547,7 +1565,7 @@ static int parse_groups(struct evlist *perf_evlist,
 		metricgroup__rblist_init(metric_events_list);
 	ret = metricgroup__add_metric_list(pmu, str, metric_no_group, metric_no_threshold,
 					   user_requested_cpu_list,
-					   system_wide, &metric_list, table);
+					   system_wide, &metric_list, cpu_table, sys_table);
 	if (ret)
 		goto out;
 
@@ -1697,18 +1715,19 @@ int metricgroup__parse_groups(struct evlist *perf_evlist,
 			      bool system_wide,
 			      struct rblist *metric_events)
 {
-	const struct pmu_metrics_table *table = pmu_metrics_table__find();
+	const struct pmu_metrics_table *cpu_table = pmu_metrics_table__find();
 
-	if (!table)
+	if (!cpu_table)
 		return -EINVAL;
 
 	return parse_groups(perf_evlist, pmu, str, metric_no_group, metric_no_merge,
 			    metric_no_threshold, user_requested_cpu_list, system_wide,
-			    /*fake_pmu=*/NULL, metric_events, table);
+			    /*fake_pmu=*/NULL, metric_events, cpu_table, NULL);
 }
 
 int metricgroup__parse_groups_test(struct evlist *evlist,
-				   const struct pmu_metrics_table *table,
+				   const struct pmu_metrics_table *cpu_table,
+				   const struct pmu_metrics_table *sys_table,
 				   const char *str,
 				   struct rblist *metric_events)
 {
@@ -1718,7 +1737,7 @@ int metricgroup__parse_groups_test(struct evlist *evlist,
 			    /*metric_no_threshold=*/false,
 			    /*user_requested_cpu_list=*/NULL,
 			    /*system_wide=*/false,
-			    &perf_pmu__fake, metric_events, table);
+			    &perf_pmu__fake, metric_events, cpu_table, sys_table);
 }
 
 struct metricgroup__has_metric_data {
diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h
index d5325c6ec8e1..b5f0d598eaec 100644
--- a/tools/perf/util/metricgroup.h
+++ b/tools/perf/util/metricgroup.h
@@ -79,7 +79,8 @@ int metricgroup__parse_groups(struct evlist *perf_evlist,
 			      bool system_wide,
 			      struct rblist *metric_events);
 int metricgroup__parse_groups_test(struct evlist *evlist,
-				   const struct pmu_metrics_table *table,
+				   const struct pmu_metrics_table *cpu_table,
+				   const struct pmu_metrics_table *sys_table,
 				   const char *str,
 				   struct rblist *metric_events);
 
