diff --git a/tools/testing/selftests/powerpc/pmu/Makefile b/tools/testing/selftests/powerpc/pmu/Makefile
index 19046db995fe..e352eceac0a9 100644
--- a/tools/testing/selftests/powerpc/pmu/Makefile
+++ b/tools/testing/selftests/powerpc/pmu/Makefile
@@ -8,7 +8,7 @@ EXTRA_SOURCES := ../harness.c event.c lib.c ../utils.c
 top_srcdir = ../../../../..
 include ../../lib.mk
 
-all: $(TEST_GEN_PROGS) ebb
+all: $(TEST_GEN_PROGS) ebb mem_counters
 
 $(TEST_GEN_PROGS): $(EXTRA_SOURCES)
 
@@ -43,4 +43,7 @@ clean:
 ebb:
 	TARGET=$@; BUILD_TARGET=$$OUTPUT/$$TARGET; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $$TARGET all
 
-.PHONY: all run_tests clean ebb
+mem_counters:
+	TARGET=$@; BUILD_TARGET=$$OUTPUT/$$TARGET; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $$TARGET all
+
+.PHONY: all run_tests clean ebb mem_counters
diff --git a/tools/testing/selftests/powerpc/pmu/mem_counters/Makefile b/tools/testing/selftests/powerpc/pmu/mem_counters/Makefile
new file mode 100644
index 000000000000..f39ebe30ab70
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/mem_counters/Makefile
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0
+include ../../../../../../scripts/Kbuild.include
+
+noarg:
+	$(MAKE) -C ../../
+
+CFLAGS += -m64
+
+# Toolchains may build PIE by default which breaks the assembly
+no-pie-option := $(call try-run, echo 'int main() { return 0; }' | \
+        $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -no-pie -x c - -o "$$TMP", -no-pie)
+
+LDFLAGS += $(no-pie-option)
+
+TEST_GEN_PROGS := imc_global_lock_test
+
+top_srcdir = ../../../../../..
+include ../../../lib.mk
+
+$(TEST_GEN_PROGS): ../../harness.c ../../utils.c ../event.c ../lib.c ./mem_counters.c \
+			imc_global_lock_test.c
diff --git a/tools/testing/selftests/powerpc/pmu/mem_counters/imc_global_lock_test.c b/tools/testing/selftests/powerpc/pmu/mem_counters/imc_global_lock_test.c
new file mode 100644
index 000000000000..ea687ffc1990
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/mem_counters/imc_global_lock_test.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020, Madhavan Srinivasan, IBM Corp.
+ */
+
+#include "mem_counters.h"
+
+static int testcase(void)
+{
+	return 0;
+}
+
+static int imc_global_lock_test(void)
+{
+	return eat_cpu(testcase);
+}
+
+int main(void)
+{
+	return test_harness(imc_global_lock_test, "imc_global_lock_test");
+}
diff --git a/tools/testing/selftests/powerpc/pmu/mem_counters/mem_counters.c b/tools/testing/selftests/powerpc/pmu/mem_counters/mem_counters.c
new file mode 100644
index 000000000000..b0ee1319f018
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/mem_counters/mem_counters.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020, Madhavan Srinivasan, IBM Corp.
+ */
+
+#include "mem_counters.h"
+
+/*
+ * mem_counters.c will contain common/basic functions
+ * to support testcases for both In Memory Collection (IMC)
+ * and hv_24x7 counters.
+ */
+
+
+/*
+ * Since device type enum starts with 1,
+ * have the first entry in the array as a placeholder.
+ */
+const char mem_counters_dev_path[][30] = {
+	"",
+	"/sys/devices/thread_imc",
+	"/sys/devices/trace_imc",
+	"/sys/devices/core_imc",
+	"/sys/devices/hv_24x7",
+	"",
+};
+
+const char mem_counters_dev_type_path[][35] = {
+	"",
+	"/sys/devices/thread_imc/type",
+	"/sys/devices/trace_imc/type",
+	"/sys/devices/core_imc/type",
+	"/sys/devices/hv_24x7/type",
+	"",
+};
+
+
+static bool is_mem_counters_dev_registered(int dtype)
+{
+	if (!access(mem_counters_dev_path[dtype], F_OK))
+		return true;
+
+	return false;
+}
+
+bool is_mem_counters_device_enabled(int dtype)
+{
+	switch (dtype) {
+	case THREAD:
+		if (is_mem_counters_dev_registered(THREAD))
+			return true;
+	case TRACE:
+		if (is_mem_counters_dev_registered(TRACE))
+			return true;
+		break;
+	case CORE:
+		if (is_mem_counters_dev_registered(CORE))
+			return true;
+	case HV_24X7:
+		if (is_mem_counters_dev_registered(HV_24X7))
+			return true;
+	};
+
+	return false;
+}
+
+int get_mem_counters_pmu_type_val(int dtype)
+{
+	FILE *fp = NULL;
+	char buf[10];
+	int val;
+
+	fp = fopen(mem_counters_dev_type_path[dtype], "r");
+	if (!fp) {
+		perror("Failed to open\n");
+		return -1;
+	}
+
+	if (!fgets(buf, 10, fp)) {
+		perror("Failed to read\n");
+		return -1;
+	}
+
+	fclose(fp);
+	val = atoi(buf);
+	return val;
+}
+
+int setup_mem_counters_event(int dtype, struct event *e, u64 config, char *name)
+{
+	int val = get_mem_counters_pmu_type_val(dtype);
+
+	if (val > 0) {
+		event_init_opts(e, config, val, name);
+		return 0;
+	}
+
+	return -1;
+}
diff --git a/tools/testing/selftests/powerpc/pmu/mem_counters/mem_counters.h b/tools/testing/selftests/powerpc/pmu/mem_counters/mem_counters.h
new file mode 100644
index 000000000000..16456e5fc9de
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/mem_counters/mem_counters.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright 2020, Madhavan Srinivasan, IBM Corp.
+ */
+
+#ifndef _SELFTESTS_POWERPC_PMU_IMC_IMC_H
+#define _SELFTESTS_POWERPC_PMU_IMC_IMC_H
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <error.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/prctl.h>
+
+#include "../event.h"
+#include "../lib.h"
+
+
+enum MEM_COUNTERS_DEV_TYPE{
+	THREAD = 0x1,
+	TRACE,
+	CORE,
+	HV_24X7,
+};
+
+extern bool is_mem_counters_device_enabled(int dtype);
+extern int get_mem_counters_pmu_type_val(int dtype);
+extern int setup_mem_counters_event(int dtype, struct event *e, u64 config, char *name);
+
+#endif /* _SELFTESTS_POWERPC_PMU_IMC_IMC_H */
