summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-02-25 11:00:06 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2023-02-25 11:00:06 -0800
commitd0a32f5520a33e7f2ace396db6913625e0d29544 (patch)
tree988e993eda872c2c30d6befe2c40095736dde493 /tools
parent5596c6adb04d00cad445641a35f1f1745de57119 (diff)
parentf82cdc37c4bd4ba905bf99ade9782a639b5c12e9 (diff)
Merge tag 'powerpc-6.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc updates from Michael Ellerman: - Support for configuring secure boot with user-defined keys on PowerVM LPARs - Simplify the replay of soft-masked IRQs by making it non-recursive - Add support for KCSAN on 64-bit Book3S - Improvements to the API & code which interacts with RTAS (pseries firmware) - Change 32-bit powermac to assign PCI bus numbers per domain by default - Some improvements to the 32-bit BPF JIT - Various other small features and fixes Thanks to Anders Roxell, Andrew Donnellan, Andrew Jeffery, Benjamin Gray, Christophe Leroy, Frederic Barrat, Ganesh Goudar, Geoff Levand, Greg Kroah-Hartman, Jan-Benedict Glaw, Josh Poimboeuf, Kajol Jain, Laurent Dufour, Mahesh Salgaonkar, Mathieu Desnoyers, Mimi Zohar, Murphy Zhou, Nathan Chancellor, Nathan Lynch, Nayna Jain, Nicholas Piggin, Pali Rohár, Petr Mladek, Rohan McLure, Russell Currey, Sachin Sant, Sathvika Vasireddy, Sourabh Jain, Stefan Berger, Stephen Rothwell, and Sudhakar Kuppusamy. * tag 'powerpc-6.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (114 commits) powerpc/pseries: Avoid hcall in plpks_is_available() on non-pseries powerpc: dts: turris1x.dts: Set lower priority for CPLD syscon-reboot powerpc/e500: Add missing prototype for 'relocate_init' powerpc/64: Fix unannotated intra-function call warning powerpc/epapr: Don't use wrteei on non booke powerpc: Pass correct CPU reference to assembler powerpc/mm: Rearrange if-else block to avoid clang warning powerpc/nohash: Fix build with llvm-as powerpc/nohash: Fix build error with binutils >= 2.38 powerpc/pseries: Fix endianness issue when parsing PLPKS secvar flags macintosh: windfarm: Use unsigned type for 1-bit bitfields powerpc/kexec_file: print error string on usable memory property update failure powerpc/machdep: warn when machine_is() used too early powerpc/64: Replace -mcpu=e500mc64 by -mcpu=e5500 powerpc/eeh: Set channel state after notifying the drivers selftests/powerpc: Fix incorrect kernel headers search path powerpc/rtas: arch-wide function token lookup conversions powerpc/rtas: introduce rtas_function_token() API powerpc/pseries/lpar: convert to papr_sysparm API powerpc/pseries/hv-24x7: convert to papr_sysparm API ...
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/selftests/powerpc/dscr/dscr.h34
-rw-r--r--tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c25
-rw-r--r--tools/testing/selftests/powerpc/include/utils.h20
-rw-r--r--tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c52
-rw-r--r--tools/testing/selftests/powerpc/pmu/lib.c34
-rw-r--r--tools/testing/selftests/powerpc/ptrace/Makefile2
-rw-r--r--tools/testing/selftests/powerpc/ptrace/core-pkey.c28
-rw-r--r--tools/testing/selftests/powerpc/security/Makefile2
-rw-r--r--tools/testing/selftests/powerpc/security/entry_flush.c12
-rw-r--r--tools/testing/selftests/powerpc/security/rfi_flush.c12
-rw-r--r--tools/testing/selftests/powerpc/security/uaccess_flush.c18
-rw-r--r--tools/testing/selftests/powerpc/syscalls/Makefile4
-rw-r--r--tools/testing/selftests/powerpc/syscalls/rtas_filter.c81
-rw-r--r--tools/testing/selftests/powerpc/tm/Makefile2
-rw-r--r--tools/testing/selftests/powerpc/utils.c412
15 files changed, 435 insertions, 303 deletions
diff --git a/tools/testing/selftests/powerpc/dscr/dscr.h b/tools/testing/selftests/powerpc/dscr/dscr.h
index b703714e7d98..2c54998d4715 100644
--- a/tools/testing/selftests/powerpc/dscr/dscr.h
+++ b/tools/testing/selftests/powerpc/dscr/dscr.h
@@ -64,48 +64,26 @@ inline void set_dscr_usr(unsigned long val)
/* Default DSCR access */
unsigned long get_default_dscr(void)
{
- int fd = -1, ret;
- char buf[16];
+ int err;
unsigned long val;
- if (fd == -1) {
- fd = open(DSCR_DEFAULT, O_RDONLY);
- if (fd == -1) {
- perror("open() failed");
- exit(1);
- }
- }
- memset(buf, 0, sizeof(buf));
- lseek(fd, 0, SEEK_SET);
- ret = read(fd, buf, sizeof(buf));
- if (ret == -1) {
+ err = read_ulong(DSCR_DEFAULT, &val, 16);
+ if (err) {
perror("read() failed");
exit(1);
}
- sscanf(buf, "%lx", &val);
- close(fd);
return val;
}
void set_default_dscr(unsigned long val)
{
- int fd = -1, ret;
- char buf[16];
+ int err;
- if (fd == -1) {
- fd = open(DSCR_DEFAULT, O_RDWR);
- if (fd == -1) {
- perror("open() failed");
- exit(1);
- }
- }
- sprintf(buf, "%lx\n", val);
- ret = write(fd, buf, strlen(buf));
- if (ret == -1) {
+ err = write_ulong(DSCR_DEFAULT, val, 16);
+ if (err) {
perror("write() failed");
exit(1);
}
- close(fd);
}
double uniform_deviate(int seed)
diff --git a/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c b/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
index f20d1c166d1e..4f1fef6198fc 100644
--- a/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
+++ b/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
@@ -12,27 +12,16 @@
static int check_cpu_dscr_default(char *file, unsigned long val)
{
- char buf[10];
- int fd, rc;
+ unsigned long cpu_dscr;
+ int err;
- fd = open(file, O_RDWR);
- if (fd == -1) {
- perror("open() failed");
- return 1;
- }
-
- rc = read(fd, buf, sizeof(buf));
- if (rc == -1) {
- perror("read() failed");
- close(fd);
- return 1;
- }
- close(fd);
+ err = read_ulong(file, &cpu_dscr, 16);
+ if (err)
+ return err;
- buf[rc] = '\0';
- if (strtol(buf, NULL, 16) != val) {
+ if (cpu_dscr != val) {
printf("DSCR match failed: %ld (system) %ld (cpu)\n",
- val, strtol(buf, NULL, 16));
+ val, cpu_dscr);
return 1;
}
return 0;
diff --git a/tools/testing/selftests/powerpc/include/utils.h b/tools/testing/selftests/powerpc/include/utils.h
index e222a5858450..eed7dd7582b2 100644
--- a/tools/testing/selftests/powerpc/include/utils.h
+++ b/tools/testing/selftests/powerpc/include/utils.h
@@ -33,8 +33,24 @@ void *get_auxv_entry(int type);
int pick_online_cpu(void);
-int read_debugfs_file(char *debugfs_file, int *result);
-int write_debugfs_file(char *debugfs_file, int result);
+int parse_intmax(const char *buffer, size_t count, intmax_t *result, int base);
+int parse_uintmax(const char *buffer, size_t count, uintmax_t *result, int base);
+int parse_int(const char *buffer, size_t count, int *result, int base);
+int parse_uint(const char *buffer, size_t count, unsigned int *result, int base);
+int parse_long(const char *buffer, size_t count, long *result, int base);
+int parse_ulong(const char *buffer, size_t count, unsigned long *result, int base);
+
+int read_file(const char *path, char *buf, size_t count, size_t *len);
+int write_file(const char *path, const char *buf, size_t count);
+int read_file_alloc(const char *path, char **buf, size_t *len);
+int read_long(const char *path, long *result, int base);
+int write_long(const char *path, long result, int base);
+int read_ulong(const char *path, unsigned long *result, int base);
+int write_ulong(const char *path, unsigned long result, int base);
+int read_debugfs_file(const char *debugfs_file, char *buf, size_t count);
+int write_debugfs_file(const char *debugfs_file, const char *buf, size_t count);
+int read_debugfs_int(const char *debugfs_file, int *result);
+int write_debugfs_int(const char *debugfs_file, int result);
int read_sysfs_file(char *debugfs_file, char *result, size_t result_size);
int perf_event_open_counter(unsigned int type,
unsigned long config, int group_fd);
diff --git a/tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c b/tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c
index 095195a25687..4de079923ccb 100644
--- a/tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c
+++ b/tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c
@@ -143,54 +143,6 @@ int gzip_header_blank(char *buf)
return i;
}
-/* Caller must free the allocated buffer return nonzero on error. */
-int read_alloc_input_file(char *fname, char **buf, size_t *bufsize)
-{
- struct stat statbuf;
- FILE *fp;
- char *p;
- size_t num_bytes;
-
- if (stat(fname, &statbuf)) {
- perror(fname);
- return(-1);
- }
- fp = fopen(fname, "r");
- if (fp == NULL) {
- perror(fname);
- return(-1);
- }
- assert(NULL != (p = (char *) malloc(statbuf.st_size)));
- num_bytes = fread(p, 1, statbuf.st_size, fp);
- if (ferror(fp) || (num_bytes != statbuf.st_size)) {
- perror(fname);
- return(-1);
- }
- *buf = p;
- *bufsize = num_bytes;
- return 0;
-}
-
-/* Returns nonzero on error */
-int write_output_file(char *fname, char *buf, size_t bufsize)
-{
- FILE *fp;
- size_t num_bytes;
-
- fp = fopen(fname, "w");
- if (fp == NULL) {
- perror(fname);
- return(-1);
- }
- num_bytes = fwrite(buf, 1, bufsize, fp);
- if (ferror(fp) || (num_bytes != bufsize)) {
- perror(fname);
- return(-1);
- }
- fclose(fp);
- return 0;
-}
-
/*
* Z_SYNC_FLUSH as described in zlib.h.
* Returns number of appended bytes
@@ -257,7 +209,7 @@ int compress_file(int argc, char **argv, void *handle)
fprintf(stderr, "usage: %s <fname>\n", argv[0]);
exit(-1);
}
- if (read_alloc_input_file(argv[1], &inbuf, &inlen))
+ if (read_file_alloc(argv[1], &inbuf, &inlen))
exit(-1);
fprintf(stderr, "file %s read, %ld bytes\n", argv[1], inlen);
@@ -399,7 +351,7 @@ int compress_file(int argc, char **argv, void *handle)
assert(FNAME_MAX > (strlen(argv[1]) + strlen(FEXT)));
strcpy(outname, argv[1]);
strcat(outname, FEXT);
- if (write_output_file(outname, outbuf, dsttotlen)) {
+ if (write_file(outname, outbuf, dsttotlen)) {
fprintf(stderr, "write error: %s\n", outname);
exit(-1);
}
diff --git a/tools/testing/selftests/powerpc/pmu/lib.c b/tools/testing/selftests/powerpc/pmu/lib.c
index 88690b97b7b9..719f94f10d41 100644
--- a/tools/testing/selftests/powerpc/pmu/lib.c
+++ b/tools/testing/selftests/powerpc/pmu/lib.c
@@ -190,38 +190,14 @@ int parse_proc_maps(void)
bool require_paranoia_below(int level)
{
+ int err;
long current;
- char *end, buf[16];
- FILE *f;
- bool rc;
-
- rc = false;
-
- f = fopen(PARANOID_PATH, "r");
- if (!f) {
- perror("fopen");
- goto out;
- }
- if (!fgets(buf, sizeof(buf), f)) {
- printf("Couldn't read " PARANOID_PATH "?\n");
- goto out_close;
- }
-
- current = strtol(buf, &end, 10);
-
- if (end == buf) {
+ err = read_long(PARANOID_PATH, &current, 10);
+ if (err) {
printf("Couldn't parse " PARANOID_PATH "?\n");
- goto out_close;
+ return false;
}
- if (current >= level)
- goto out_close;
-
- rc = true;
-out_close:
- fclose(f);
-out:
- return rc;
+ return current < level;
}
-
diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile b/tools/testing/selftests/powerpc/ptrace/Makefile
index 2f02cb54224d..cbeeaeae8837 100644
--- a/tools/testing/selftests/powerpc/ptrace/Makefile
+++ b/tools/testing/selftests/powerpc/ptrace/Makefile
@@ -33,7 +33,7 @@ TESTS_64 := $(patsubst %,$(OUTPUT)/%,$(TESTS_64))
$(TESTS_64): CFLAGS += -m64
$(TM_TESTS): CFLAGS += -I../tm -mhtm
-CFLAGS += -I../../../../../usr/include -fno-pie
+CFLAGS += $(KHDR_INCLUDES) -fno-pie
$(OUTPUT)/ptrace-gpr: ptrace-gpr.S
$(OUTPUT)/ptrace-pkey $(OUTPUT)/core-pkey: LDLIBS += -pthread
diff --git a/tools/testing/selftests/powerpc/ptrace/core-pkey.c b/tools/testing/selftests/powerpc/ptrace/core-pkey.c
index 4e8d0ce1ff58..f6f8596ce8e1 100644
--- a/tools/testing/selftests/powerpc/ptrace/core-pkey.c
+++ b/tools/testing/selftests/powerpc/ptrace/core-pkey.c
@@ -348,15 +348,11 @@ static int parent(struct shared_info *info, pid_t pid)
static int write_core_pattern(const char *core_pattern)
{
- size_t len = strlen(core_pattern), ret;
- FILE *f;
+ int err;
- f = fopen(core_pattern_file, "w");
- SKIP_IF_MSG(!f, "Try with root privileges");
-
- ret = fwrite(core_pattern, 1, len, f);
- fclose(f);
- if (ret != len) {
+ err = write_file(core_pattern_file, core_pattern, strlen(core_pattern));
+ if (err) {
+ SKIP_IF_MSG(err == -EPERM, "Try with root privileges");
perror("Error writing to core_pattern file");
return TEST_FAIL;
}
@@ -366,8 +362,8 @@ static int write_core_pattern(const char *core_pattern)
static int setup_core_pattern(char **core_pattern_, bool *changed_)
{
- FILE *f;
char *core_pattern;
+ size_t len;
int ret;
core_pattern = malloc(PATH_MAX);
@@ -376,22 +372,14 @@ static int setup_core_pattern(char **core_pattern_, bool *changed_)
return TEST_FAIL;
}
- f = fopen(core_pattern_file, "r");
- if (!f) {
- perror("Error opening core_pattern file");
- ret = TEST_FAIL;
- goto out;
- }
-
- ret = fread(core_pattern, 1, PATH_MAX - 1, f);
- fclose(f);
- if (!ret) {
+ ret = read_file(core_pattern_file, core_pattern, PATH_MAX - 1, &len);
+ if (ret) {
perror("Error reading core_pattern file");
ret = TEST_FAIL;
goto out;
}
- core_pattern[ret] = '\0';
+ core_pattern[len] = '\0';
/* Check whether we can predict the name of the core file. */
if (!strcmp(core_pattern, "core") || !strcmp(core_pattern, "core.%p"))
diff --git a/tools/testing/selftests/powerpc/security/Makefile b/tools/testing/selftests/powerpc/security/Makefile
index 7488315fd847..e0d979ab0204 100644
--- a/tools/testing/selftests/powerpc/security/Makefile
+++ b/tools/testing/selftests/powerpc/security/Makefile
@@ -5,7 +5,7 @@ TEST_PROGS := mitigation-patching.sh
top_srcdir = ../../../../..
-CFLAGS += -I../../../../../usr/include
+CFLAGS += $(KHDR_INCLUDES)
include ../../lib.mk
diff --git a/tools/testing/selftests/powerpc/security/entry_flush.c b/tools/testing/selftests/powerpc/security/entry_flush.c
index 68ce377b205e..e01c573deadd 100644
--- a/tools/testing/selftests/powerpc/security/entry_flush.c
+++ b/tools/testing/selftests/powerpc/security/entry_flush.c
@@ -34,18 +34,18 @@ int entry_flush_test(void)
// The PMU event we use only works on Power7 or later
SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06));
- if (read_debugfs_file("powerpc/rfi_flush", &rfi_flush_orig) < 0) {
+ if (read_debugfs_int("powerpc/rfi_flush", &rfi_flush_orig) < 0) {
perror("Unable to read powerpc/rfi_flush debugfs file");
SKIP_IF(1);
}
- if (read_debugfs_file("powerpc/entry_flush", &entry_flush_orig) < 0) {
+ if (read_debugfs_int("powerpc/entry_flush", &entry_flush_orig) < 0) {
perror("Unable to read powerpc/entry_flush debugfs file");
SKIP_IF(1);
}
if (rfi_flush_orig != 0) {
- if (write_debugfs_file("powerpc/rfi_flush", 0) < 0) {
+ if (write_debugfs_int("powerpc/rfi_flush", 0) < 0) {
perror("error writing to powerpc/rfi_flush debugfs file");
FAIL_IF(1);
}
@@ -105,7 +105,7 @@ again:
if (entry_flush == entry_flush_orig) {
entry_flush = !entry_flush_orig;
- if (write_debugfs_file("powerpc/entry_flush", entry_flush) < 0) {
+ if (write_debugfs_int("powerpc/entry_flush", entry_flush) < 0) {
perror("error writing to powerpc/entry_flush debugfs file");
return 1;
}
@@ -120,12 +120,12 @@ again:
set_dscr(0);
- if (write_debugfs_file("powerpc/rfi_flush", rfi_flush_orig) < 0) {
+ if (write_debugfs_int("powerpc/rfi_flush", rfi_flush_orig) < 0) {
perror("unable to restore original value of powerpc/rfi_flush debugfs file");
return 1;
}
- if (write_debugfs_file("powerpc/entry_flush", entry_flush_orig) < 0) {
+ if (write_debugfs_int("powerpc/entry_flush", entry_flush_orig) < 0) {
perror("unable to restore original value of powerpc/entry_flush debugfs file");
return 1;
}
diff --git a/tools/testing/selftests/powerpc/security/rfi_flush.c b/tools/testing/selftests/powerpc/security/rfi_flush.c
index f73484a6470f..6bedc86443a6 100644
--- a/tools/testing/selftests/powerpc/security/rfi_flush.c
+++ b/tools/testing/selftests/powerpc/security/rfi_flush.c
@@ -34,18 +34,18 @@ int rfi_flush_test(void)
// The PMU event we use only works on Power7 or later
SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06));
- if (read_debugfs_file("powerpc/rfi_flush", &rfi_flush_orig) < 0) {
+ if (read_debugfs_int("powerpc/rfi_flush", &rfi_flush_orig) < 0) {
perror("Unable to read powerpc/rfi_flush debugfs file");
SKIP_IF(1);
}
- if (read_debugfs_file("powerpc/entry_flush", &entry_flush_orig) < 0) {
+ if (read_debugfs_int("powerpc/entry_flush", &entry_flush_orig) < 0) {
have_entry_flush = 0;
} else {
have_entry_flush = 1;
if (entry_flush_orig != 0) {
- if (write_debugfs_file("powerpc/entry_flush", 0) < 0) {
+ if (write_debugfs_int("powerpc/entry_flush", 0) < 0) {
perror("error writing to powerpc/entry_flush debugfs file");
return 1;
}
@@ -105,7 +105,7 @@ again:
if (rfi_flush == rfi_flush_orig) {
rfi_flush = !rfi_flush_orig;
- if (write_debugfs_file("powerpc/rfi_flush", rfi_flush) < 0) {
+ if (write_debugfs_int("powerpc/rfi_flush", rfi_flush) < 0) {
perror("error writing to powerpc/rfi_flush debugfs file");
return 1;
}
@@ -120,13 +120,13 @@ again:
set_dscr(0);
- if (write_debugfs_file("powerpc/rfi_flush", rfi_flush_orig) < 0) {
+ if (write_debugfs_int("powerpc/rfi_flush", rfi_flush_orig) < 0) {
perror("unable to restore original value of powerpc/rfi_flush debugfs file");
return 1;
}
if (have_entry_flush) {
- if (write_debugfs_file("powerpc/entry_flush", entry_flush_orig) < 0) {
+ if (write_debugfs_int("powerpc/entry_flush", entry_flush_orig) < 0) {
perror("unable to restore original value of powerpc/entry_flush "
"debugfs file");
return 1;
diff --git a/tools/testing/selftests/powerpc/security/uaccess_flush.c b/tools/testing/selftests/powerpc/security/uaccess_flush.c
index cf80f960e38a..fcf23ea9b183 100644
--- a/tools/testing/selftests/powerpc/security/uaccess_flush.c
+++ b/tools/testing/selftests/powerpc/security/uaccess_flush.c
@@ -36,30 +36,30 @@ int uaccess_flush_test(void)
// The PMU event we use only works on Power7 or later
SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06));
- if (read_debugfs_file("powerpc/rfi_flush", &rfi_flush_orig) < 0) {
+ if (read_debugfs_int("powerpc/rfi_flush", &rfi_flush_orig) < 0) {
perror("Unable to read powerpc/rfi_flush debugfs file");
SKIP_IF(1);
}
- if (read_debugfs_file("powerpc/entry_flush", &entry_flush_orig) < 0) {
+ if (read_debugfs_int("powerpc/entry_flush", &entry_flush_orig) < 0) {
perror("Unable to read powerpc/entry_flush debugfs file");
SKIP_IF(1);
}
- if (read_debugfs_file("powerpc/uaccess_flush", &uaccess_flush_orig) < 0) {
+ if (read_debugfs_int("powerpc/uaccess_flush", &uaccess_flush_orig) < 0) {
perror("Unable to read powerpc/entry_flush debugfs file");
SKIP_IF(1);
}
if (rfi_flush_orig != 0) {
- if (write_debugfs_file("powerpc/rfi_flush", 0) < 0) {
+ if (write_debugfs_int("powerpc/rfi_flush", 0) < 0) {
perror("error writing to powerpc/rfi_flush debugfs file");
FAIL_IF(1);
}
}
if (entry_flush_orig != 0) {
- if (write_debugfs_file("powerpc/entry_flush", 0) < 0) {
+ if (write_debugfs_int("powerpc/entry_flush", 0) < 0) {
perror("error writing to powerpc/entry_flush debugfs file");
FAIL_IF(1);
}
@@ -119,7 +119,7 @@ again:
if (uaccess_flush == uaccess_flush_orig) {
uaccess_flush = !uaccess_flush_orig;
- if (write_debugfs_file("powerpc/uaccess_flush", uaccess_flush) < 0) {
+ if (write_debugfs_int("powerpc/uaccess_flush", uaccess_flush) < 0) {
perror("error writing to powerpc/uaccess_flush debugfs file");
return 1;
}
@@ -134,17 +134,17 @@ again:
set_dscr(0);
- if (write_debugfs_file("powerpc/rfi_flush", rfi_flush_orig) < 0) {
+ if (write_debugfs_int("powerpc/rfi_flush", rfi_flush_orig) < 0) {
perror("unable to restore original value of powerpc/rfi_flush debugfs file");
return 1;
}
- if (write_debugfs_file("powerpc/entry_flush", entry_flush_orig) < 0) {
+ if (write_debugfs_int("powerpc/entry_flush", entry_flush_orig) < 0) {
perror("unable to restore original value of powerpc/entry_flush debugfs file");
return 1;
}
- if (write_debugfs_file("powerpc/uaccess_flush", uaccess_flush_orig) < 0) {
+ if (write_debugfs_int("powerpc/uaccess_flush", uaccess_flush_orig) < 0) {
perror("unable to restore original value of powerpc/uaccess_flush debugfs file");
return 1;
}
diff --git a/tools/testing/selftests/powerpc/syscalls/Makefile b/tools/testing/selftests/powerpc/syscalls/Makefile
index b63f8459c704..ee1740ddfb0c 100644
--- a/tools/testing/selftests/powerpc/syscalls/Makefile
+++ b/tools/testing/selftests/powerpc/syscalls/Makefile
@@ -1,9 +1,9 @@
# SPDX-License-Identifier: GPL-2.0-only
TEST_GEN_PROGS := ipc_unmuxed rtas_filter
-CFLAGS += -I../../../../../usr/include
+CFLAGS += $(KHDR_INCLUDES)
top_srcdir = ../../../../..
include ../../lib.mk
-$(TEST_GEN_PROGS): ../harness.c
+$(TEST_GEN_PROGS): ../harness.c ../utils.c
diff --git a/tools/testing/selftests/powerpc/syscalls/rtas_filter.c b/tools/testing/selftests/powerpc/syscalls/rtas_filter.c
index 03b487f18d00..9b17780f0b18 100644
--- a/tools/testing/selftests/powerpc/syscalls/rtas_filter.c
+++ b/tools/testing/selftests/powerpc/syscalls/rtas_filter.c
@@ -8,6 +8,7 @@
#include <byteswap.h>
#include <stdint.h>
#include <inttypes.h>
+#include <linux/limits.h>
#include <stdio.h>
#include <string.h>
#include <sys/syscall.h>
@@ -50,70 +51,16 @@ struct region {
struct region *next;
};
-int read_entire_file(int fd, char **buf, size_t *len)
-{
- size_t buf_size = 0;
- size_t off = 0;
- int rc;
-
- *buf = NULL;
- do {
- buf_size += BLOCK_SIZE;
- if (*buf == NULL)
- *buf = malloc(buf_size);
- else
- *buf = realloc(*buf, buf_size);
-
- if (*buf == NULL)
- return -ENOMEM;
-
- rc = read(fd, *buf + off, BLOCK_SIZE);
- if (rc < 0)
- return -EIO;
-
- off += rc;
- } while (rc == BLOCK_SIZE);
-
- if (len)
- *len = off;
-
- return 0;
-}
-
-static int open_prop_file(const char *prop_path, const char *prop_name, int *fd)
-{
- char *path;
- int len;
-
- /* allocate enough for two string, a slash and trailing NULL */
- len = strlen(prop_path) + strlen(prop_name) + 1 + 1;
- path = malloc(len);
- if (path == NULL)
- return -ENOMEM;
-
- snprintf(path, len, "%s/%s", prop_path, prop_name);
-
- *fd = open(path, O_RDONLY);
- free(path);
- if (*fd < 0)
- return -errno;
-
- return 0;
-}
-
static int get_property(const char *prop_path, const char *prop_name,
char **prop_val, size_t *prop_len)
{
- int rc, fd;
-
- rc = open_prop_file(prop_path, prop_name, &fd);
- if (rc)
- return rc;
+ char path[PATH_MAX];
- rc = read_entire_file(fd, prop_val, prop_len);
- close(fd);
+ int len = snprintf(path, sizeof(path), "%s/%s", prop_path, prop_name);
+ if (len < 0 || len >= sizeof(path))
+ return -ENOMEM;
- return rc;
+ return read_file_alloc(path, prop_val, prop_len);
}
int rtas_token(const char *call_name)
@@ -138,22 +85,14 @@ err:
static int read_kregion_bounds(struct region *kregion)
{
char *buf;
- int fd;
- int rc;
+ int err;
- fd = open("/proc/ppc64/rtas/rmo_buffer", O_RDONLY);
- if (fd < 0) {
- printf("Could not open rmo_buffer file\n");
+ err = read_file_alloc("/proc/ppc64/rtas/rmo_buffer", &buf, NULL);
+ if (err) {
+ perror("Could not open rmo_buffer file");
return RTAS_IO_ASSERT;
}
- rc = read_entire_file(fd, &buf, NULL);
- close(fd);
- if (rc) {
- free(buf);
- return rc;
- }
-
sscanf(buf, "%" SCNx64 " %x", &kregion->addr, &kregion->size);
free(buf);
diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile
index 5881e97c73c1..3876805c2f31 100644
--- a/tools/testing/selftests/powerpc/tm/Makefile
+++ b/tools/testing/selftests/powerpc/tm/Makefile
@@ -17,7 +17,7 @@ $(TEST_GEN_PROGS): ../harness.c ../utils.c
CFLAGS += -mhtm
$(OUTPUT)/tm-syscall: tm-syscall-asm.S
-$(OUTPUT)/tm-syscall: CFLAGS += -I../../../../../usr/include
+$(OUTPUT)/tm-syscall: CFLAGS += $(KHDR_INCLUDES)
$(OUTPUT)/tm-tmspr: CFLAGS += -pthread
$(OUTPUT)/tm-vmx-unavail: CFLAGS += -pthread -m64
$(OUTPUT)/tm-resched-dscr: ../pmu/lib.c
diff --git a/tools/testing/selftests/powerpc/utils.c b/tools/testing/selftests/powerpc/utils.c
index 1f36ee1a909a..7c8cfedb012a 100644
--- a/tools/testing/selftests/powerpc/utils.c
+++ b/tools/testing/selftests/powerpc/utils.c
@@ -8,6 +8,8 @@
#include <elf.h>
#include <errno.h>
#include <fcntl.h>
+#include <inttypes.h>
+#include <limits.h>
#include <link.h>
#include <sched.h>
#include <stdio.h>
@@ -26,34 +28,360 @@
static char auxv[4096];
-int read_auxv(char *buf, ssize_t buf_size)
+int read_file(const char *path, char *buf, size_t count, size_t *len)
{
- ssize_t num;
- int rc, fd;
+ ssize_t rc;
+ int fd;
+ int err;
+ char eof;
- fd = open("/proc/self/auxv", O_RDONLY);
- if (fd == -1) {
- perror("open");
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
return -errno;
+
+ rc = read(fd, buf, count);
+ if (rc < 0) {
+ err = -errno;
+ goto out;
}
- num = read(fd, buf, buf_size);
- if (num < 0) {
- perror("read");
- rc = -EIO;
+ if (len)
+ *len = rc;
+
+ /* Overflow if there are still more bytes after filling the buffer */
+ if (rc == count) {
+ rc = read(fd, &eof, 1);
+ if (rc != 0) {
+ err = -EOVERFLOW;
+ goto out;
+ }
+ }
+
+ err = 0;
+
+out:
+ close(fd);
+ errno = -err;
+ return err;
+}
+
+int read_file_alloc(const char *path, char **buf, size_t *len)
+{
+ size_t read_offset = 0;
+ size_t buffer_len = 0;
+ char *buffer = NULL;
+ int err;
+ int fd;
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return -errno;
+
+ /*
+ * We don't use stat & preallocate st_size because some non-files
+ * report 0 file size. Instead just dynamically grow the buffer
+ * as needed.
+ */
+ while (1) {
+ ssize_t rc;
+
+ if (read_offset >= buffer_len / 2) {
+ char *next_buffer;
+
+ buffer_len = buffer_len ? buffer_len * 2 : 4096;
+ next_buffer = realloc(buffer, buffer_len);
+ if (!next_buffer) {
+ err = -errno;
+ goto out;
+ }
+ buffer = next_buffer;
+ }
+
+ rc = read(fd, buffer + read_offset, buffer_len - read_offset);
+ if (rc < 0) {
+ err = -errno;
+ goto out;
+ }
+
+ if (rc == 0)
+ break;
+
+ read_offset += rc;
+ }
+
+ *buf = buffer;
+ if (len)
+ *len = read_offset;
+
+ err = 0;
+
+out:
+ close(fd);
+ if (err)
+ free(buffer);
+ errno = -err;
+ return err;
+}
+
+int write_file(const char *path, const char *buf, size_t count)
+{
+ int fd;
+ int err;
+ ssize_t rc;
+
+ fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ if (fd < 0)
+ return -errno;
+
+ rc = write(fd, buf, count);
+ if (rc < 0) {
+ err = -errno;
goto out;
}
- if (num > buf_size) {
- printf("overflowed auxv buffer\n");
- rc = -EOVERFLOW;
+ if (rc != count) {
+ err = -EOVERFLOW;
goto out;
}
- rc = 0;
+ err = 0;
+
out:
close(fd);
- return rc;
+ errno = -err;
+ return err;
+}
+
+int read_auxv(char *buf, ssize_t buf_size)
+{
+ int err;
+
+ err = read_file("/proc/self/auxv", buf, buf_size, NULL);
+ if (err) {
+ perror("Error reading /proc/self/auxv");
+ return err;
+ }
+
+ return 0;
+}
+
+int read_debugfs_file(const char *subpath, char *buf, size_t count)
+{
+ char path[PATH_MAX] = "/sys/kernel/debug/";
+
+ strncat(path, subpath, sizeof(path) - strlen(path) - 1);
+
+ return read_file(path, buf, count, NULL);
+}
+
+int write_debugfs_file(const char *subpath, const char *buf, size_t count)
+{
+ char path[PATH_MAX] = "/sys/kernel/debug/";
+
+ strncat(path, subpath, sizeof(path) - strlen(path) - 1);
+
+ return write_file(path, buf, count);
+}
+
+static int validate_int_parse(const char *buffer, size_t count, char *end)
+{
+ int err = 0;
+
+ /* Require at least one digit */
+ if (end == buffer) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ /* Require all remaining characters be whitespace-ish */
+ for (; end < buffer + count; end++) {
+ if (*end == '\0')
+ break;
+
+ if (*end != ' ' && *end != '\n') {
+ err = -EINVAL;
+ goto out;
+ }
+ }
+
+out:
+ errno = -err;
+ return err;
+}
+
+static int parse_bounded_int(const char *buffer, size_t count, intmax_t *result,
+ int base, intmax_t min, intmax_t max)
+{
+ int err;
+ char *end;
+
+ errno = 0;
+ *result = strtoimax(buffer, &end, base);
+
+ if (errno)
+ return -errno;
+
+ err = validate_int_parse(buffer, count, end);
+ if (err)
+ goto out;
+
+ if (*result < min || *result > max)
+ err = -EOVERFLOW;
+
+out:
+ errno = -err;
+ return err;
+}
+
+static int parse_bounded_uint(const char *buffer, size_t count, uintmax_t *result,
+ int base, uintmax_t max)
+{
+ int err = 0;
+ char *end;
+
+ errno = 0;
+ *result = strtoumax(buffer, &end, base);
+
+ if (errno)
+ return -errno;
+
+ err = validate_int_parse(buffer, count, end);
+ if (err)
+ goto out;
+
+ if (*result > max)
+ err = -EOVERFLOW;
+
+out:
+ errno = -err;
+ return err;
+}
+
+int parse_intmax(const char *buffer, size_t count, intmax_t *result, int base)
+{
+ return parse_bounded_int(buffer, count, result, base, INTMAX_MIN, INTMAX_MAX);
+}
+
+int parse_uintmax(const char *buffer, size_t count, uintmax_t *result, int base)
+{
+ return parse_bounded_uint(buffer, count, result, base, UINTMAX_MAX);
+}
+
+int parse_int(const char *buffer, size_t count, int *result, int base)
+{
+ intmax_t parsed;
+ int err = parse_bounded_int(buffer, count, &parsed, base, INT_MIN, INT_MAX);
+
+ *result = parsed;
+ return err;
+}
+
+int parse_uint(const char *buffer, size_t count, unsigned int *result, int base)
+{
+ uintmax_t parsed;
+ int err = parse_bounded_uint(buffer, count, &parsed, base, UINT_MAX);
+
+ *result = parsed;
+ return err;
+}
+
+int parse_long(const char *buffer, size_t count, long *result, int base)
+{
+ intmax_t parsed;
+ int err = parse_bounded_int(buffer, count, &parsed, base, LONG_MIN, LONG_MAX);
+
+ *result = parsed;
+ return err;
+}
+
+int parse_ulong(const char *buffer, size_t count, unsigned long *result, int base)
+{
+ uintmax_t parsed;
+ int err = parse_bounded_uint(buffer, count, &parsed, base, ULONG_MAX);
+
+ *result = parsed;
+ return err;
+}
+
+int read_long(const char *path, long *result, int base)
+{
+ int err;
+ char buffer[32] = {0};
+
+ err = read_file(path, buffer, sizeof(buffer) - 1, NULL);
+ if (err)
+ return err;
+
+ return parse_long(buffer, sizeof(buffer), result, base);
+}
+
+int read_ulong(const char *path, unsigned long *result, int base)
+{
+ int err;
+ char buffer[32] = {0};
+
+ err = read_file(path, buffer, sizeof(buffer) - 1, NULL);
+ if (err)
+ return err;
+
+ return parse_ulong(buffer, sizeof(buffer), result, base);
+}
+
+int write_long(const char *path, long result, int base)
+{
+ int err;
+ int len;
+ char buffer[32];
+
+ /* Decimal only for now: no format specifier for signed hex values */
+ if (base != 10) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ len = snprintf(buffer, sizeof(buffer), "%ld", result);
+ if (len < 0 || len >= sizeof(buffer)) {
+ err = -EOVERFLOW;
+ goto out;
+ }
+
+ err = write_file(path, buffer, len);
+
+out:
+ errno = -err;
+ return err;
+}
+
+int write_ulong(const char *path, unsigned long result, int base)
+{
+ int err;
+ int len;
+ char buffer[32];
+ char *fmt;
+
+ switch (base) {
+ case 10:
+ fmt = "%lu";
+ break;
+ case 16:
+ fmt = "%lx";
+ break;
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+
+ len = snprintf(buffer, sizeof(buffer), fmt, result);
+ if (len < 0 || len >= sizeof(buffer)) {
+ err = -errno;
+ goto out;
+ }
+
+ err = write_file(path, buffer, len);
+
+out:
+ errno = -err;
+ return err;
}
void *find_auxv_entry(int type, char *auxv)
@@ -142,65 +470,31 @@ bool is_ppc64le(void)
int read_sysfs_file(char *fpath, char *result, size_t result_size)
{
char path[PATH_MAX] = "/sys/";
- int rc = -1, fd;
strncat(path, fpath, PATH_MAX - strlen(path) - 1);
- if ((fd = open(path, O_RDONLY)) < 0)
- return rc;
-
- rc = read(fd, result, result_size);
-
- close(fd);
-
- if (rc < 0)
- return rc;
-
- return 0;
+ return read_file(path, result, result_size, NULL);
}
-int read_debugfs_file(char *debugfs_file, int *result)
+int read_debugfs_int(const char *debugfs_file, int *result)
{
- int rc = -1, fd;
- char path[PATH_MAX];
- char value[16];
-
- strcpy(path, "/sys/kernel/debug/");
- strncat(path, debugfs_file, PATH_MAX - strlen(path) - 1);
+ int err;
+ char value[16] = {0};
- if ((fd = open(path, O_RDONLY)) < 0)
- return rc;
+ err = read_debugfs_file(debugfs_file, value, sizeof(value) - 1);
+ if (err)
+ return err;
- if ((rc = read(fd, value, sizeof(value))) < 0)
- return rc;
-
- value[15] = 0;
- *result = atoi(value);
- close(fd);
-
- return 0;
+ return parse_int(value, sizeof(value), result, 10);
}
-int write_debugfs_file(char *debugfs_file, int result)
+int write_debugfs_int(const char *debugfs_file, int result)
{
- int rc = -1, fd;
- char path[PATH_MAX];
char value[16];
- strcpy(path, "/sys/kernel/debug/");
- strncat(path, debugfs_file, PATH_MAX - strlen(path) - 1);
-
- if ((fd = open(path, O_WRONLY)) < 0)
- return rc;
-
snprintf(value, 16, "%d", result);
- if ((rc = write(fd, value, strlen(value))) < 0)
- return rc;
-
- close(fd);
-
- return 0;
+ return write_debugfs_file(debugfs_file, value, strlen(value));
}
static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,