]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
selftests/powerpc: Add support to fetch "platform" and "base platform" from auxv...
authorAthira Rajeev <atrajeev@linux.vnet.ibm.com>
Fri, 10 Jun 2022 13:40:40 +0000 (19:10 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 28 Jun 2022 13:56:46 +0000 (23:56 +1000)
The /proc/self/auxv contains information about "platform" on any system.
Also "base platform" which is an indication about platform string
corresponding to the real PVR. When systems are booted in compat mode,
say, power10 booted in power9 mode, "platform" will point to power9
whereas base platform will point to power10. Incase, if the distro
doesn't support platform indicated by real PVR, base platform will have
a default value.

The mismatch of platform/base platform is an indication of system booted
in compat mode. In such cases, distro will have a Generic Compat
registered which supports basic features for performance monitoring.

Some of the selftest needs to be handled differently ( ex: generic
events, alternative events, bhrb filter map) in Generic Compat PMU.
Hence selftest framework needs utility functions to identify such cases.
One way is make sure of auxv information. Below condition can be used to
detect if Generic Compat PMU is registered. ie:

  if ((AT_PLATFORM != AT_BASE_PLATFORM) && (AT_BASE_PLATFORM != PVR))

this indicates Generic Compat PMU.

Add utility function in "include/utils.h" to return:
AT_PLATFORM and AT_BASE_PLATFORM from auxv. Also update misc.c in
"sampling_tests" folder to add function to use above check to determine
presence of generic compat pmu.

In other architecture ( like x86 ), pmu_name is exposed via
"/sys/bus/event_source/devices/cpu/caps". The same could be used in
powerpc in future. Since currently we don't have the "caps" support in
powerpc, patch uses auxv information to detect platform type and compat
mode. But as placeholder utility function is added considering
possiblity of getting "caps" information via sysfs. If that doesn't
exist, fallback to using auxv information.

Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20220610134113.62991-3-atrajeev@linux.vnet.ibm.com
tools/testing/selftests/powerpc/include/utils.h
tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c
tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h

index b9fa9cd709df4c5ec4fc509cd0a3808250b39f55..e222a5858450c964f2434e6f2e7c7a92c3c01963 100644 (file)
@@ -74,6 +74,16 @@ static inline bool have_hwcap2(unsigned long ftr2)
 }
 #endif
 
+static inline char *auxv_base_platform(void)
+{
+       return ((char *)get_auxv_entry(AT_BASE_PLATFORM));
+}
+
+static inline char *auxv_platform(void)
+{
+       return ((char *)get_auxv_entry(AT_PLATFORM));
+}
+
 bool is_ppc64le(void);
 int using_hash_mmu(bool *using_hash);
 
index b984d1e162ac4325c2c00dcb73c35ad4c5abe435..6e30b455cbd6d3b62aefa982893816374412c2a7 100644 (file)
@@ -454,3 +454,53 @@ int get_thresh_cmp_val(struct event event)
                result = (exp << 8) | value;
        return result;
 }
+
+/*
+ * Utility function to check for generic compat PMU
+ * by comparing base_platform value from auxv and real
+ * PVR value.
+ */
+static bool auxv_generic_compat_pmu(void)
+{
+       int base_pvr = 0;
+
+       if (!strcmp(auxv_base_platform(), "power9"))
+               base_pvr = POWER9;
+       else if (!strcmp(auxv_base_platform(), "power10"))
+               base_pvr = POWER10;
+
+       return (!base_pvr);
+}
+
+/*
+ * Check for generic compat PMU.
+ * First check for presence of pmu_name from
+ * "/sys/bus/event_source/devices/cpu/caps".
+ * If doesn't exist, fallback to using value
+ * auxv.
+ */
+bool check_for_generic_compat_pmu(void)
+{
+       char pmu_name[256];
+
+       memset(pmu_name, 0, sizeof(pmu_name));
+       if (read_sysfs_file("bus/event_source/devices/cpu/caps/pmu_name",
+               pmu_name, sizeof(pmu_name)) < 0)
+               return auxv_generic_compat_pmu();
+
+       if (!strcmp(pmu_name, "ISAv3"))
+               return true;
+       else
+               return false;
+}
+
+/*
+ * Check if system is booted in compat mode.
+ */
+bool check_for_compat_mode(void)
+{
+       char *platform = auxv_platform();
+       char *base_platform = auxv_base_platform();
+
+       return strcmp(platform, base_platform);
+}
index 078120883fdef386f6cc48bb2cd6d48d067d4b20..c0e923f387933c7df4ed894214d1ee079dd5ec95 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright 2022, Kajol Jain, IBM Corp.
  */
 
+#include <sys/stat.h>
 #include "../event.h"
 
 #define POWER10 0x80
@@ -53,6 +54,8 @@ int collect_samples(void *sample_buff);
 u64 *get_intr_regs(struct event *event, void *sample_buff);
 u64 get_reg_value(u64 *intr_regs, char *register_name);
 int get_thresh_cmp_val(struct event event);
+bool check_for_generic_compat_pmu(void);
+bool check_for_compat_mode(void);
 
 static inline int get_mmcr0_fc56(u64 mmcr0, int pmc)
 {