From: Pavithra <pavrampu@linux.ibm.com>
To: shuah@kernel.org
Cc: linux-kselftest@vger.kernel.org, pavrampu@linux.ibm.com
Subject: [PATCH] selftests/powerpc: add papr_pseries test suite
Date: Sat, 5 Sep 2026 23:56:42 +0530 [thread overview]
Message-ID: <20260905182656.993870-1-pavrampu@linux.ibm.com> (raw)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 19734 bytes --]
Add a set of selftests for pSeries/PowerVM-specific kernel interfaces:
- lparcfg_test: validates /proc/ppc64/lparcfg fields (partition_id,
shared_processor_mode, processor counts, partition_entitled_capacity,
partition_name, system_type)
- dtl_test: validates the vpa_dtl perf PMU by running perf record
against the DTL event source and confirming samples are captured;
skips gracefully if the PMU is absent or perf is not installed
- pseries_energy_test: validates CPU frequency from /proc/cpuinfo and
power management fields from /proc/ppc64/lparcfg
(partition_entitled_capacity, partition_max_entitled_capacity,
power_mode_data as a 16-character hex string)
- papr_rtas_common_test: exercises RTAS work-area serialisation by
issuing 1000 concurrent get-time-of-day calls across 10 threads via
syscall(__NR_rtas) and asserting every call returns status 0
Signed-off-by: Pavithra <pavrampu@linux.ibm.com>
---
tools/testing/selftests/powerpc/Makefile | 1 +
.../selftests/powerpc/papr_pseries/Makefile | 19 ++
.../selftests/powerpc/papr_pseries/dtl_test.c | 93 ++++++++++
.../powerpc/papr_pseries/lparcfg_test.c | 125 +++++++++++++
.../papr_pseries/papr_rtas_common_test.c | 171 ++++++++++++++++++
.../papr_pseries/pseries_energy_test.c | 155 ++++++++++++++++
.../selftests/powerpc/papr_pseries/utils.h | 19 ++
7 files changed, 583 insertions(+)
create mode 100644 tools/testing/selftests/powerpc/papr_pseries/Makefile
create mode 100644 tools/testing/selftests/powerpc/papr_pseries/dtl_test.c
create mode 100644 tools/testing/selftests/powerpc/papr_pseries/lparcfg_test.c
create mode 100644 tools/testing/selftests/powerpc/papr_pseries/papr_rtas_common_test.c
create mode 100644 tools/testing/selftests/powerpc/papr_pseries/pseries_energy_test.c
create mode 100644 tools/testing/selftests/powerpc/papr_pseries/utils.h
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index b175e94e1901..93aaa7a90a1b 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -26,6 +26,7 @@ SUB_DIRS = alignment \
vphn \
math \
papr_attributes \
+ papr_pseries \
papr_vpd \
papr_sysparm \
ptrace \
diff --git a/tools/testing/selftests/powerpc/papr_pseries/Makefile b/tools/testing/selftests/powerpc/papr_pseries/Makefile
new file mode 100644
index 000000000000..2016a6e3a8e7
--- /dev/null
+++ b/tools/testing/selftests/powerpc/papr_pseries/Makefile
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: GPL-2.0
+noarg:
+ $(MAKE) -C ../
+
+TEST_GEN_PROGS := lparcfg_test
+TEST_GEN_PROGS += dtl_test
+TEST_GEN_PROGS += pseries_energy_test
+TEST_GEN_PROGS += papr_rtas_common_test
+
+top_srcdir = ../../../../..
+include ../../lib.mk
+include ../flags.mk
+
+$(TEST_GEN_PROGS): ../harness.c ../utils.c
+
+$(OUTPUT)/papr_rtas_common_test: CFLAGS += $(KHDR_INCLUDES)
+$(OUTPUT)/papr_rtas_common_test: LDFLAGS += -lpthread
+
+$(OUTPUT)/dtl_test: CFLAGS += $(KHDR_INCLUDES)
diff --git a/tools/testing/selftests/powerpc/papr_pseries/dtl_test.c b/tools/testing/selftests/powerpc/papr_pseries/dtl_test.c
new file mode 100644
index 000000000000..097c80def4c9
--- /dev/null
+++ b/tools/testing/selftests/powerpc/papr_pseries/dtl_test.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Dispatch Trace Log (DTL) Test
+ * Copyright (C) 2025 IBM Corporation
+ *
+ * Validates the vpa_dtl perf PMU on PowerVM LPARs. The PMU sysfs directory
+ * is created by the DTL subsystem when FW_FEATURE_SPLPAR is set.
+ *
+ * The test SKIPs when the vpa_dtl PMU is absent or perf is not installed.
+ * The test FAILs when the PMU is present and perf is installed but the
+ * event cannot be opened or produces no samples.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include "utils.h"
+
+#define VPA_DTL_PMU_PATH "/sys/bus/event_source/devices/vpa_dtl"
+
+static int perf_is_installed(void)
+{
+ return system("perf version >/dev/null 2>&1") == 0;
+}
+
+static int test_dtl_via_perf(void)
+{
+ char outfile[] = "/tmp/dtl_test_XXXXXX";
+ char cmd[256];
+ struct stat st;
+ int fd, ret;
+
+ fd = mkstemp(outfile);
+ if (fd < 0) {
+ fprintf(stderr, "[FAIL] mkstemp failed\n");
+ return -1;
+ }
+ close(fd);
+
+ snprintf(cmd, sizeof(cmd),
+ "perf record -e vpa_dtl/dtl_all/ -a -o %s sleep 1 2>/dev/null",
+ outfile);
+
+ printf("Running: %s\n", cmd);
+ ret = system(cmd);
+
+ if (ret != 0) {
+ fprintf(stderr,
+ "[FAIL] perf record failed (exit %d) -- vpa_dtl PMU present but perf could not open the event\n",
+ WEXITSTATUS(ret));
+ unlink(outfile);
+ return -1;
+ }
+
+ if (stat(outfile, &st) != 0) {
+ fprintf(stderr,
+ "[FAIL] perf record succeeded but output file was not created\n");
+ unlink(outfile);
+ return -1;
+ }
+
+ if (st.st_size < 1024) {
+ fprintf(stderr,
+ "[FAIL] perf.data is only %ld bytes -- vpa_dtl PMU opened but delivered no samples\n",
+ (long)st.st_size);
+ unlink(outfile);
+ return -1;
+ }
+
+ printf("vpa_dtl PMU: %ld bytes of samples captured\n",
+ (long)st.st_size);
+ unlink(outfile);
+ return 0;
+}
+
+int main(void)
+{
+ test_harness_set_timeout(30);
+
+ SKIP_IF_MSG(access(VPA_DTL_PMU_PATH, F_OK) != 0,
+ "vpa_dtl PMU not present (" VPA_DTL_PMU_PATH " missing)");
+
+ SKIP_IF_MSG(!perf_is_installed(),
+ "perf binary not found -- install perf to run this test");
+
+ printf("vpa_dtl PMU present, perf available\n");
+ FAIL_IF(test_dtl_via_perf() != 0);
+
+ printf("dtl_test passed\n");
+ return 0;
+}
diff --git a/tools/testing/selftests/powerpc/papr_pseries/lparcfg_test.c b/tools/testing/selftests/powerpc/papr_pseries/lparcfg_test.c
new file mode 100644
index 000000000000..b43af7e1c4e7
--- /dev/null
+++ b/tools/testing/selftests/powerpc/papr_pseries/lparcfg_test.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * LPAR Configuration Test
+ * Copyright (C) 2026 IBM Corporation
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "utils.h"
+
+#define LPARCFG_PATH "/proc/ppc64/lparcfg"
+
+struct lparcfg_data {
+ int partition_id;
+ char partition_name[256];
+ char system_type[256];
+ int shared_processor_mode;
+ int system_active_processors;
+ int partition_active_processors;
+ int partition_potential_processors;
+ int partition_entitled_capacity;
+ int found_fields;
+};
+
+static int parse_lparcfg(struct lparcfg_data *data)
+{
+ FILE *fp;
+ char line[512];
+ char key[128], value[256];
+
+ memset(data, 0, sizeof(*data));
+
+ fp = fopen(LPARCFG_PATH, "r");
+ if (!fp)
+ return -1;
+
+ while (fgets(line, sizeof(line), fp)) {
+ if (sscanf(line, "%127[^=]=%255[^\n]", key, value) == 2) {
+ if (strcmp(key, "partition_id") == 0) {
+ data->partition_id = atoi(value);
+ data->found_fields++;
+ } else if (strcmp(key, "partition_name") == 0) {
+ snprintf(data->partition_name,
+ sizeof(data->partition_name),
+ "%s", value);
+ data->found_fields++;
+ } else if (strcmp(key, "system_type") == 0) {
+ snprintf(data->system_type,
+ sizeof(data->system_type),
+ "%s", value);
+ data->found_fields++;
+ } else if (strcmp(key, "shared_processor_mode") == 0) {
+ data->shared_processor_mode = atoi(value);
+ data->found_fields++;
+ } else if (strcmp(key, "system_active_processors") == 0) {
+ data->system_active_processors = atoi(value);
+ data->found_fields++;
+ } else if (strcmp(key, "partition_active_processors") == 0) {
+ data->partition_active_processors = atoi(value);
+ data->found_fields++;
+ } else if (strcmp(key, "partition_potential_processors") == 0) {
+ data->partition_potential_processors = atoi(value);
+ data->found_fields++;
+ } else if (strcmp(key, "partition_entitled_capacity") == 0) {
+ data->partition_entitled_capacity = atoi(value);
+ data->found_fields++;
+ }
+ }
+ }
+
+ fclose(fp);
+ return 0;
+}
+
+int main(void)
+{
+ struct lparcfg_data data;
+
+ test_harness_set_timeout(10);
+
+ SKIP_IF(access(LPARCFG_PATH, R_OK) != 0);
+
+ FAIL_IF(parse_lparcfg(&data) != 0);
+
+ FAIL_IF_MSG(data.found_fields < 5,
+ "Only found %d fields (expected at least 5)", data.found_fields);
+
+ FAIL_IF_MSG(data.partition_id == 0, "partition_id is 0 (invalid)");
+ printf("partition_id: %d\n", data.partition_id);
+
+ FAIL_IF_MSG(data.shared_processor_mode != 0 && data.shared_processor_mode != 1,
+ "shared_processor_mode is %d (expected 0 or 1)",
+ data.shared_processor_mode);
+ printf("shared_processor_mode: %d\n", data.shared_processor_mode);
+
+ FAIL_IF_MSG(data.system_active_processors <= 0,
+ "system_active_processors is %d (expected > 0)",
+ data.system_active_processors);
+ printf("system_active_processors: %d\n", data.system_active_processors);
+
+ FAIL_IF_MSG(data.partition_active_processors <= 0,
+ "partition_active_processors is %d (expected > 0)",
+ data.partition_active_processors);
+ printf("partition_active_processors: %d\n", data.partition_active_processors);
+
+ FAIL_IF_MSG(data.partition_potential_processors > 0 &&
+ data.partition_active_processors > data.partition_potential_processors,
+ "partition_active_processors (%d) > partition_potential_processors (%d)",
+ data.partition_active_processors, data.partition_potential_processors);
+
+ FAIL_IF_MSG(data.partition_entitled_capacity == 0,
+ "partition_entitled_capacity is 0 (invalid)");
+ printf("partition_entitled_capacity: %d\n", data.partition_entitled_capacity);
+
+ FAIL_IF_MSG(strlen(data.partition_name) == 0, "partition_name is empty");
+ printf("partition_name: %s\n", data.partition_name);
+
+ FAIL_IF_MSG(strlen(data.system_type) == 0, "system_type is empty");
+ printf("system_type: %s\n", data.system_type);
+
+ printf("lparcfg test passed\n");
+ return 0;
+}
diff --git a/tools/testing/selftests/powerpc/papr_pseries/papr_rtas_common_test.c b/tools/testing/selftests/powerpc/papr_pseries/papr_rtas_common_test.c
new file mode 100644
index 000000000000..56e4ec6aa0fd
--- /dev/null
+++ b/tools/testing/selftests/powerpc/papr_pseries/papr_rtas_common_test.c
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * PAPR RTAS Work-Area Locking Test
+ * Copyright (C) 2026 IBM Corporation
+ *
+ * Exercises the kernel's RTAS work-area serialisation under concurrent load
+ * by spawning multiple threads that simultaneously issue the get-time-of-day
+ * RTAS call via __NR_rtas. Every call must return status 0; a non-zero
+ * status indicates work-area corruption caused by a locking failure.
+ */
+
+#include <byteswap.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/syscall.h>
+#include "utils.h"
+
+#ifndef __NR_rtas
+#error "This test requires a pSeries kernel (__NR_rtas is not defined)"
+#endif
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define cpu_to_be32(x) bswap_32(x)
+#define be32_to_cpu(x) bswap_32(x)
+#else
+#define cpu_to_be32(x) (x)
+#define be32_to_cpu(x) (x)
+#endif
+
+#define OFDT_RTAS_PATH "/proc/device-tree/rtas"
+#define RTAS_UNKNOWN_OP (-1099)
+
+#define NUM_THREADS 10
+#define ITERATIONS 100
+
+struct rtas_args {
+ __be32 token;
+ __be32 nargs;
+ __be32 nret;
+ __be32 args[16];
+ __be32 *rets;
+};
+
+static int gtod_token = RTAS_UNKNOWN_OP;
+
+static int rtas_get_token(const char *call_name)
+{
+ char path[256];
+ __be32 raw;
+ ssize_t n;
+ int fd;
+
+ snprintf(path, sizeof(path), "%s/%s", OFDT_RTAS_PATH, call_name);
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return RTAS_UNKNOWN_OP;
+
+ n = read(fd, &raw, sizeof(raw));
+ close(fd);
+
+ if (n != (ssize_t)sizeof(raw))
+ return RTAS_UNKNOWN_OP;
+
+ return (int)be32_to_cpu(raw);
+}
+
+static int rtas_call_gtod(void)
+{
+ struct rtas_args args;
+
+ memset(&args, 0, sizeof(args));
+ args.token = cpu_to_be32(gtod_token);
+ args.nargs = cpu_to_be32(0);
+ args.nret = cpu_to_be32(1);
+ args.rets = &args.args[0];
+
+ if (syscall(__NR_rtas, &args) != 0)
+ return -errno;
+
+ return (int)be32_to_cpu(args.args[0]);
+}
+
+struct thread_data {
+ int thread_id;
+ int success_count;
+ int error_count;
+};
+
+static void *rtas_worker(void *arg)
+{
+ struct thread_data *data = (struct thread_data *)arg;
+ int i, rc;
+
+ for (i = 0; i < ITERATIONS; i++) {
+ rc = rtas_call_gtod();
+ if (rc != 0) {
+ fprintf(stderr,
+ "[FAIL] thread %d iteration %d: get-time-of-day returned %d\n",
+ data->thread_id, i, rc);
+ data->error_count++;
+ } else {
+ data->success_count++;
+ }
+ }
+
+ return NULL;
+}
+
+int main(void)
+{
+ pthread_t threads[NUM_THREADS];
+ struct thread_data thread_data[NUM_THREADS];
+ int total_success = 0;
+ int total_errors = 0;
+ int i, rc;
+
+ test_harness_set_timeout(60);
+
+ SKIP_IF(access(OFDT_RTAS_PATH, R_OK) != 0);
+
+ gtod_token = rtas_get_token("get-time-of-day");
+ SKIP_IF(gtod_token == RTAS_UNKNOWN_OP);
+ printf("get-time-of-day token: %d\n", gtod_token);
+
+ rc = rtas_call_gtod();
+ FAIL_IF_MSG(rc != 0,
+ "Baseline get-time-of-day failed with status %d", rc);
+ printf("Baseline get-time-of-day: OK\n");
+
+ printf("Spawning %d threads, %d RTAS calls each...\n",
+ NUM_THREADS, ITERATIONS);
+
+ for (i = 0; i < NUM_THREADS; i++) {
+ thread_data[i].thread_id = i;
+ thread_data[i].success_count = 0;
+ thread_data[i].error_count = 0;
+
+ FAIL_IF(pthread_create(&threads[i], NULL, rtas_worker,
+ &thread_data[i]) != 0);
+ }
+
+ for (i = 0; i < NUM_THREADS; i++) {
+ FAIL_IF(pthread_join(threads[i], NULL) != 0);
+ total_success += thread_data[i].success_count;
+ total_errors += thread_data[i].error_count;
+ printf("Thread %2d: %d ok, %d errors\n",
+ i, thread_data[i].success_count,
+ thread_data[i].error_count);
+ }
+
+ printf("Total: %d successful RTAS calls, %d errors\n",
+ total_success, total_errors);
+
+ FAIL_IF_MSG(total_errors != 0,
+ "%d of %d concurrent RTAS calls returned non-zero status; "
+ "possible work-area lock corruption",
+ total_errors, NUM_THREADS * ITERATIONS);
+
+ FAIL_IF_MSG(total_success != NUM_THREADS * ITERATIONS,
+ "Expected %d successful calls, got %d",
+ NUM_THREADS * ITERATIONS, total_success);
+
+ printf("papr_rtas_common_test passed\n");
+ return 0;
+}
diff --git a/tools/testing/selftests/powerpc/papr_pseries/pseries_energy_test.c b/tools/testing/selftests/powerpc/papr_pseries/pseries_energy_test.c
new file mode 100644
index 000000000000..db6eb86d4647
--- /dev/null
+++ b/tools/testing/selftests/powerpc/papr_pseries/pseries_energy_test.c
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * pseries Energy/Power Management Test
+ * Copyright (C) 2026 IBM Corporation
+ *
+ * Validates CPU frequency and power management on pSeries LPARs by reading
+ * /proc/cpuinfo and /proc/ppc64/lparcfg directly.
+ *
+ * Tests performed:
+ * 1. CPU clock frequency is readable from /proc/cpuinfo and is > 0.
+ * 2. partition_entitled_capacity is present in lparcfg and is > 0.
+ * 3. partition_max_entitled_capacity is present and >= entitled_capacity.
+ * 4. power_mode_data is present and is a 16-character hex string.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#include "utils.h"
+
+#define PROC_CPUINFO "/proc/cpuinfo"
+#define LPARCFG "/proc/ppc64/lparcfg"
+
+#define POWER_MODE_DATA_LEN 16
+
+static double read_cpuinfo_freq(void)
+{
+ FILE *fp;
+ char line[256];
+ double mhz = 0.0;
+
+ fp = fopen(PROC_CPUINFO, "r");
+ if (!fp)
+ return 0.0;
+
+ while (fgets(line, sizeof(line), fp)) {
+ char *colon;
+
+ /* "clock : <value>MHz" — pSeries dedicated-mode LPAR */
+ if (strncmp(line, "clock", 5) == 0) {
+ colon = strchr(line, ':');
+ if (colon)
+ mhz = strtod(colon + 1, NULL);
+ break;
+ }
+
+ /* "cpu MHz : <value>" — other Power configurations */
+ if (strncmp(line, "cpu MHz", 7) == 0) {
+ colon = strchr(line, ':');
+ if (colon)
+ mhz = strtod(colon + 1, NULL);
+ break;
+ }
+ }
+
+ fclose(fp);
+ return mhz;
+}
+
+static int read_lparcfg_ulong(FILE *fp, const char *key, unsigned long *out)
+{
+ char line[256];
+ size_t keylen = strlen(key);
+ char *endptr;
+
+ rewind(fp);
+ while (fgets(line, sizeof(line), fp)) {
+ if (strncmp(line, key, keylen) == 0 && line[keylen] == '=') {
+ *out = strtoul(line + keylen + 1, &endptr, 10);
+ if (endptr == line + keylen + 1)
+ return -1;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static int read_lparcfg_str(FILE *fp, const char *key, char *buf, size_t size)
+{
+ char line[256];
+ size_t keylen = strlen(key);
+
+ rewind(fp);
+ while (fgets(line, sizeof(line), fp)) {
+ if (strncmp(line, key, keylen) == 0 && line[keylen] == '=') {
+ char *val = line + keylen + 1;
+ size_t vlen;
+
+ val[strcspn(val, "\n")] = 0;
+ vlen = strlen(val);
+ if (vlen == 0 || vlen >= size)
+ return -1;
+ memcpy(buf, val, vlen + 1);
+ return 0;
+ }
+ }
+ return -1;
+}
+
+/* ------------------------------------------------------------------ */
+
+int main(void)
+{
+ double mhz;
+ FILE *fp;
+ unsigned long entitled, max_entitled;
+ char power_mode[32];
+ size_t i;
+
+ test_harness_set_timeout(10);
+
+ SKIP_IF(access(LPARCFG, R_OK) != 0);
+
+ mhz = read_cpuinfo_freq();
+ FAIL_IF_MSG(mhz <= 0.0,
+ "Could not read a valid CPU frequency from " PROC_CPUINFO);
+ printf("CPU frequency: %.3f GHz\n", mhz / 1000.0);
+
+ fp = fopen(LPARCFG, "r");
+ FAIL_IF_MSG(!fp, "Cannot open " LPARCFG);
+
+ FAIL_IF_MSG(read_lparcfg_ulong(fp, "partition_entitled_capacity",
+ &entitled) != 0,
+ "partition_entitled_capacity missing from " LPARCFG);
+ FAIL_IF_MSG(entitled == 0, "partition_entitled_capacity is 0");
+ printf("partition_entitled_capacity: %lu\n", entitled);
+
+ FAIL_IF_MSG(read_lparcfg_ulong(fp, "partition_max_entitled_capacity",
+ &max_entitled) != 0,
+ "partition_max_entitled_capacity missing from " LPARCFG);
+ printf("partition_max_entitled_capacity: %lu\n", max_entitled);
+ FAIL_IF_MSG(max_entitled < entitled,
+ "partition_max_entitled_capacity (%lu) < partition_entitled_capacity (%lu)",
+ max_entitled, entitled);
+
+ FAIL_IF_MSG(read_lparcfg_str(fp, "power_mode_data",
+ power_mode, sizeof(power_mode)) != 0,
+ "power_mode_data missing from " LPARCFG);
+ fclose(fp);
+ fp = NULL;
+ printf("power_mode_data: %s\n", power_mode);
+ FAIL_IF_MSG(strlen(power_mode) != POWER_MODE_DATA_LEN,
+ "power_mode_data '%s' is %zu chars, expected %d",
+ power_mode, strlen(power_mode), POWER_MODE_DATA_LEN);
+ for (i = 0; i < POWER_MODE_DATA_LEN; i++) {
+ FAIL_IF_MSG(!isxdigit((unsigned char)power_mode[i]),
+ "power_mode_data '%s' has non-hex char '%c' at position %zu",
+ power_mode, power_mode[i], i);
+ }
+
+ printf("pseries_energy test passed\n");
+ return 0;
+}
diff --git a/tools/testing/selftests/powerpc/papr_pseries/utils.h b/tools/testing/selftests/powerpc/papr_pseries/utils.h
new file mode 100644
index 000000000000..6eb88958a0ba
--- /dev/null
+++ b/tools/testing/selftests/powerpc/papr_pseries/utils.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Local test utilities for papr_pseries selftests.
+ */
+#ifndef _PAPR_PSERIES_TEST_UTILS_H
+#define _PAPR_PSERIES_TEST_UTILS_H
+
+#include "../include/utils.h"
+
+#undef FAIL_IF_MSG
+#define FAIL_IF_MSG(x, fmt, ...) \
+do { \
+ if ((x)) { \
+ fprintf(stderr, "[FAIL] " fmt "\n", ##__VA_ARGS__); \
+ return 1; \
+ } \
+} while (0)
+
+#endif /* _PAPR_PSERIES_TEST_UTILS_H */
--
2.55.0
next reply other threads:[~2026-09-05 18:27 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-05 18:26 Pavithra [this message]
2026-09-06 3:23 ` [PATCH] selftests/powerpc: add papr_pseries test suite Ritesh Harjani
2026-09-07 9:21 ` pavrampu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260905182656.993870-1-pavrampu@linux.ibm.com \
--to=pavrampu@linux.ibm.com \
--cc=linux-kselftest@vger.kernel.org \
--cc=shuah@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.