diff options
author | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-11 10:41:07 +0300 |
---|---|---|
committer | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-13 08:17:18 +0300 |
commit | e09b41010ba33a20a87472ee821fa407a5b8da36 (patch) | |
tree | d10dc367189862e7ca5c592f033dc3726e1df4e3 /kernel/tools/testing/selftests/powerpc | |
parent | f93b97fd65072de626c074dbe099a1fff05ce060 (diff) |
These changes are the raw update to linux-4.4.6-rt14. Kernel sources
are taken from kernel.org, and rt patch from the rt wiki download page.
During the rebasing, the following patch collided:
Force tick interrupt and get rid of softirq magic(I70131fb85).
Collisions have been removed because its logic was found on the
source already.
Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769
Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'kernel/tools/testing/selftests/powerpc')
48 files changed, 1062 insertions, 23 deletions
diff --git a/kernel/tools/testing/selftests/powerpc/Makefile b/kernel/tools/testing/selftests/powerpc/Makefile index 5ad042345..0c2706bda 100644 --- a/kernel/tools/testing/selftests/powerpc/Makefile +++ b/kernel/tools/testing/selftests/powerpc/Makefile @@ -12,7 +12,17 @@ CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CUR export CFLAGS -SUB_DIRS = pmu copyloops mm tm primitives stringloops vphn switch_endian +SUB_DIRS = benchmarks \ + copyloops \ + dscr \ + mm \ + pmu \ + primitives \ + stringloops \ + switch_endian \ + syscalls \ + tm \ + vphn endif diff --git a/kernel/tools/testing/selftests/powerpc/benchmarks/.gitignore b/kernel/tools/testing/selftests/powerpc/benchmarks/.gitignore new file mode 100644 index 000000000..b4709ea58 --- /dev/null +++ b/kernel/tools/testing/selftests/powerpc/benchmarks/.gitignore @@ -0,0 +1 @@ +gettimeofday diff --git a/kernel/tools/testing/selftests/powerpc/benchmarks/Makefile b/kernel/tools/testing/selftests/powerpc/benchmarks/Makefile new file mode 100644 index 000000000..5fa487020 --- /dev/null +++ b/kernel/tools/testing/selftests/powerpc/benchmarks/Makefile @@ -0,0 +1,12 @@ +TEST_PROGS := gettimeofday + +CFLAGS += -O2 + +all: $(TEST_PROGS) + +$(TEST_PROGS): ../harness.c + +include ../../lib.mk + +clean: + rm -f $(TEST_PROGS) *.o diff --git a/kernel/tools/testing/selftests/powerpc/benchmarks/gettimeofday.c b/kernel/tools/testing/selftests/powerpc/benchmarks/gettimeofday.c new file mode 100644 index 000000000..3af3c21e8 --- /dev/null +++ b/kernel/tools/testing/selftests/powerpc/benchmarks/gettimeofday.c @@ -0,0 +1,31 @@ +/* + * Copyright 2015, Anton Blanchard, IBM Corp. + * Licensed under GPLv2. + */ + +#include <sys/time.h> +#include <stdio.h> + +#include "utils.h" + +static int test_gettimeofday(void) +{ + int i; + + struct timeval tv_start, tv_end; + + gettimeofday(&tv_start, NULL); + + for(i = 0; i < 100000000; i++) { + gettimeofday(&tv_end, NULL); + } + + printf("time = %.6f\n", tv_end.tv_sec - tv_start.tv_sec + (tv_end.tv_usec - tv_start.tv_usec) * 1e-6); + + return 0; +} + +int main(void) +{ + return test_harness(test_gettimeofday, "gettimeofday"); +} diff --git a/kernel/tools/testing/selftests/powerpc/dscr/.gitignore b/kernel/tools/testing/selftests/powerpc/dscr/.gitignore new file mode 100644 index 000000000..b585c6c15 --- /dev/null +++ b/kernel/tools/testing/selftests/powerpc/dscr/.gitignore @@ -0,0 +1,7 @@ +dscr_default_test +dscr_explicit_test +dscr_inherit_exec_test +dscr_inherit_test +dscr_sysfs_test +dscr_sysfs_thread_test +dscr_user_test diff --git a/kernel/tools/testing/selftests/powerpc/dscr/Makefile b/kernel/tools/testing/selftests/powerpc/dscr/Makefile new file mode 100644 index 000000000..49327ee84 --- /dev/null +++ b/kernel/tools/testing/selftests/powerpc/dscr/Makefile @@ -0,0 +1,14 @@ +TEST_PROGS := dscr_default_test dscr_explicit_test dscr_user_test \ + dscr_inherit_test dscr_inherit_exec_test dscr_sysfs_test \ + dscr_sysfs_thread_test + +dscr_default_test: LDLIBS += -lpthread + +all: $(TEST_PROGS) + +$(TEST_PROGS): ../harness.c + +include ../../lib.mk + +clean: + rm -f $(TEST_PROGS) *.o diff --git a/kernel/tools/testing/selftests/powerpc/dscr/dscr.h b/kernel/tools/testing/selftests/powerpc/dscr/dscr.h new file mode 100644 index 000000000..a36af1b2c --- /dev/null +++ b/kernel/tools/testing/selftests/powerpc/dscr/dscr.h @@ -0,0 +1,127 @@ +/* + * POWER Data Stream Control Register (DSCR) + * + * This header file contains helper functions and macros + * required for all the DSCR related test cases. + * + * Copyright 2012, Anton Blanchard, IBM Corporation. + * Copyright 2015, Anshuman Khandual, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ +#ifndef _SELFTESTS_POWERPC_DSCR_DSCR_H +#define _SELFTESTS_POWERPC_DSCR_DSCR_H + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <dirent.h> +#include <pthread.h> +#include <sched.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> + +#include "utils.h" + +#define SPRN_DSCR 0x11 /* Privilege state SPR */ +#define SPRN_DSCR_USR 0x03 /* Problem state SPR */ +#define THREADS 100 /* Max threads */ +#define COUNT 100 /* Max iterations */ +#define DSCR_MAX 16 /* Max DSCR value */ +#define LEN_MAX 100 /* Max name length */ + +#define DSCR_DEFAULT "/sys/devices/system/cpu/dscr_default" +#define CPU_PATH "/sys/devices/system/cpu/" + +#define rmb() asm volatile("lwsync":::"memory") +#define wmb() asm volatile("lwsync":::"memory") + +#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x)) + +/* Prilvilege state DSCR access */ +inline unsigned long get_dscr(void) +{ + unsigned long ret; + + asm volatile("mfspr %0,%1" : "=r" (ret): "i" (SPRN_DSCR)); + + return ret; +} + +inline void set_dscr(unsigned long val) +{ + asm volatile("mtspr %1,%0" : : "r" (val), "i" (SPRN_DSCR)); +} + +/* Problem state DSCR access */ +inline unsigned long get_dscr_usr(void) +{ + unsigned long ret; + + asm volatile("mfspr %0,%1" : "=r" (ret): "i" (SPRN_DSCR_USR)); + + return ret; +} + +inline void set_dscr_usr(unsigned long val) +{ + asm volatile("mtspr %1,%0" : : "r" (val), "i" (SPRN_DSCR_USR)); +} + +/* Default DSCR access */ +unsigned long get_default_dscr(void) +{ + int fd = -1, ret; + char buf[16]; + 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) { + 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]; + + 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) { + perror("write() failed"); + exit(1); + } + close(fd); +} + +double uniform_deviate(int seed) +{ + return seed * (1.0 / (RAND_MAX + 1.0)); +} +#endif /* _SELFTESTS_POWERPC_DSCR_DSCR_H */ diff --git a/kernel/tools/testing/selftests/powerpc/dscr/dscr_default_test.c b/kernel/tools/testing/selftests/powerpc/dscr/dscr_default_test.c new file mode 100644 index 000000000..df17c3bab --- /dev/null +++ b/kernel/tools/testing/selftests/powerpc/dscr/dscr_default_test.c @@ -0,0 +1,127 @@ +/* + * POWER Data Stream Control Register (DSCR) default test + * + * This test modifies the system wide default DSCR through + * it's sysfs interface and then verifies that all threads + * see the correct changed DSCR value immediately. + * + * Copyright 2012, Anton Blanchard, IBM Corporation. + * Copyright 2015, Anshuman Khandual, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ +#include "dscr.h" + +static unsigned long dscr; /* System DSCR default */ +static unsigned long sequence; +static unsigned long result[THREADS]; + +static void *do_test(void *in) +{ + unsigned long thread = (unsigned long)in; + unsigned long i; + + for (i = 0; i < COUNT; i++) { + unsigned long d, cur_dscr, cur_dscr_usr; + unsigned long s1, s2; + + s1 = ACCESS_ONCE(sequence); + if (s1 & 1) + continue; + rmb(); + + d = dscr; + cur_dscr = get_dscr(); + cur_dscr_usr = get_dscr_usr(); + + rmb(); + s2 = sequence; + + if (s1 != s2) + continue; + + if (cur_dscr != d) { + fprintf(stderr, "thread %ld kernel DSCR should be %ld " + "but is %ld\n", thread, d, cur_dscr); + result[thread] = 1; + pthread_exit(&result[thread]); + } + + if (cur_dscr_usr != d) { + fprintf(stderr, "thread %ld user DSCR should be %ld " + "but is %ld\n", thread, d, cur_dscr_usr); + result[thread] = 1; + pthread_exit(&result[thread]); + } + } + result[thread] = 0; + pthread_exit(&result[thread]); +} + +int dscr_default(void) +{ + pthread_t threads[THREADS]; + unsigned long i, *status[THREADS]; + unsigned long orig_dscr_default; + + orig_dscr_default = get_default_dscr(); + + /* Initial DSCR default */ + dscr = 1; + set_default_dscr(dscr); + + /* Spawn all testing threads */ + for (i = 0; i < THREADS; i++) { + if (pthread_create(&threads[i], NULL, do_test, (void *)i)) { + perror("pthread_create() failed"); + goto fail; + } + } + + srand(getpid()); + + /* Keep changing the DSCR default */ + for (i = 0; i < COUNT; i++) { + double ret = uniform_deviate(rand()); + + if (ret < 0.0001) { + sequence++; + wmb(); + + dscr++; + if (dscr > DSCR_MAX) + dscr = 0; + + set_default_dscr(dscr); + + wmb(); + sequence++; + } + } + + /* Individual testing thread exit status */ + for (i = 0; i < THREADS; i++) { + if (pthread_join(threads[i], (void **)&(status[i]))) { + perror("pthread_join() failed"); + goto fail; + } + + if (*status[i]) { + printf("%ldth thread failed to join with %ld status\n", + i, *status[i]); + goto fail; + } + } + set_default_dscr(orig_dscr_default); + return 0; +fail: + set_default_dscr(orig_dscr_default); + return 1; +} + +int main(int argc, char *argv[]) +{ + return test_harness(dscr_default, "dscr_default_test"); +} diff --git a/kernel/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c b/kernel/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c new file mode 100644 index 000000000..ad9c3ec26 --- /dev/null +++ b/kernel/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c @@ -0,0 +1,71 @@ +/* + * POWER Data Stream Control Register (DSCR) explicit test + * + * This test modifies the DSCR value using mtspr instruction and + * verifies the change with mfspr instruction. It uses both the + * privilege state SPR and the problem state SPR for this purpose. + * + * When using the privilege state SPR, the instructions such as + * mfspr or mtspr are priviledged and the kernel emulates them + * for us. Instructions using problem state SPR can be exuecuted + * directly without any emulation if the HW supports them. Else + * they also get emulated by the kernel. + * + * Copyright 2012, Anton Blanchard, IBM Corporation. + * Copyright 2015, Anshuman Khandual, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ +#include "dscr.h" + +int dscr_explicit(void) +{ + unsigned long i, dscr = 0; + + srand(getpid()); + set_dscr(dscr); + + for (i = 0; i < COUNT; i++) { + unsigned long cur_dscr, cur_dscr_usr; + double ret = uniform_deviate(rand()); + + if (ret < 0.001) { + dscr++; + if (dscr > DSCR_MAX) + dscr = 0; + + set_dscr(dscr); + } + + cur_dscr = get_dscr(); + if (cur_dscr != dscr) { + fprintf(stderr, "Kernel DSCR should be %ld but " + "is %ld\n", dscr, cur_dscr); + return 1; + } + + ret = uniform_deviate(rand()); + if (ret < 0.001) { + dscr++; + if (dscr > DSCR_MAX) + dscr = 0; + + set_dscr_usr(dscr); + } + + cur_dscr_usr = get_dscr_usr(); + if (cur_dscr_usr != dscr) { + fprintf(stderr, "User DSCR should be %ld but " + "is %ld\n", dscr, cur_dscr_usr); + return 1; + } + } + return 0; +} + +int main(int argc, char *argv[]) +{ + return test_harness(dscr_explicit, "dscr_explicit_test"); +} diff --git a/kernel/tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c b/kernel/tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c new file mode 100644 index 000000000..8265504de --- /dev/null +++ b/kernel/tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c @@ -0,0 +1,117 @@ +/* + * POWER Data Stream Control Register (DSCR) fork exec test + * + * This testcase modifies the DSCR using mtspr, forks & execs and + * verifies that the child is using the changed DSCR using mfspr. + * + * When using the privilege state SPR, the instructions such as + * mfspr or mtspr are priviledged and the kernel emulates them + * for us. Instructions using problem state SPR can be exuecuted + * directly without any emulation if the HW supports them. Else + * they also get emulated by the kernel. + * + * Copyright 2012, Anton Blanchard, IBM Corporation. + * Copyright 2015, Anshuman Khandual, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ +#include "dscr.h" + +static char prog[LEN_MAX]; + +static void do_exec(unsigned long parent_dscr) +{ + unsigned long cur_dscr, cur_dscr_usr; + + cur_dscr = get_dscr(); + cur_dscr_usr = get_dscr_usr(); + + if (cur_dscr != parent_dscr) { + fprintf(stderr, "Parent DSCR %ld was not inherited " + "over exec (kernel value)\n", parent_dscr); + exit(1); + } + + if (cur_dscr_usr != parent_dscr) { + fprintf(stderr, "Parent DSCR %ld was not inherited " + "over exec (user value)\n", parent_dscr); + exit(1); + } + exit(0); +} + +int dscr_inherit_exec(void) +{ + unsigned long i, dscr = 0; + pid_t pid; + + for (i = 0; i < COUNT; i++) { + dscr++; + if (dscr > DSCR_MAX) + dscr = 0; + + if (dscr == get_default_dscr()) + continue; + + if (i % 2 == 0) + set_dscr_usr(dscr); + else + set_dscr(dscr); + + /* + * XXX: Force a context switch out so that DSCR + * current value is copied into the thread struct + * which is required for the child to inherit the + * changed value. + */ + sleep(1); + + pid = fork(); + if (pid == -1) { + perror("fork() failed"); + exit(1); + } else if (pid) { + int status; + + if (waitpid(pid, &status, 0) == -1) { + perror("waitpid() failed"); + exit(1); + } + + if (!WIFEXITED(status)) { + fprintf(stderr, "Child didn't exit cleanly\n"); + exit(1); + } + + if (WEXITSTATUS(status) != 0) { + fprintf(stderr, "Child didn't exit cleanly\n"); + return 1; + } + } else { + char dscr_str[16]; + + sprintf(dscr_str, "%ld", dscr); + execlp(prog, prog, "exec", dscr_str, NULL); + exit(1); + } + } + return 0; +} + +int main(int argc, char *argv[]) +{ + if (argc == 3 && !strcmp(argv[1], "exec")) { + unsigned long parent_dscr; + + parent_dscr = atoi(argv[2]); + do_exec(parent_dscr); + } else if (argc != 1) { + fprintf(stderr, "Usage: %s\n", argv[0]); + exit(1); + } + + strncpy(prog, argv[0], strlen(argv[0])); + return test_harness(dscr_inherit_exec, "dscr_inherit_exec_test"); +} diff --git a/kernel/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c b/kernel/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c new file mode 100644 index 000000000..4e414caf7 --- /dev/null +++ b/kernel/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c @@ -0,0 +1,95 @@ +/* + * POWER Data Stream Control Register (DSCR) fork test + * + * This testcase modifies the DSCR using mtspr, forks and then + * verifies that the child process has the correct changed DSCR + * value using mfspr. + * + * When using the privilege state SPR, the instructions such as + * mfspr or mtspr are priviledged and the kernel emulates them + * for us. Instructions using problem state SPR can be exuecuted + * directly without any emulation if the HW supports them. Else + * they also get emulated by the kernel. + * + * Copyright 2012, Anton Blanchard, IBM Corporation. + * Copyright 2015, Anshuman Khandual, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ +#include "dscr.h" + +int dscr_inherit(void) +{ + unsigned long i, dscr = 0; + pid_t pid; + + srand(getpid()); + set_dscr(dscr); + + for (i = 0; i < COUNT; i++) { + unsigned long cur_dscr, cur_dscr_usr; + + dscr++; + if (dscr > DSCR_MAX) + dscr = 0; + + if (i % 2 == 0) + set_dscr_usr(dscr); + else + set_dscr(dscr); + + /* + * XXX: Force a context switch out so that DSCR + * current value is copied into the thread struct + * which is required for the child to inherit the + * changed value. + */ + sleep(1); + + pid = fork(); + if (pid == -1) { + perror("fork() failed"); + exit(1); + } else if (pid) { + int status; + + if (waitpid(pid, &status, 0) == -1) { + perror("waitpid() failed"); + exit(1); + } + + if (!WIFEXITED(status)) { + fprintf(stderr, "Child didn't exit cleanly\n"); + exit(1); + } + + if (WEXITSTATUS(status) != 0) { + fprintf(stderr, "Child didn't exit cleanly\n"); + return 1; + } + } else { + cur_dscr = get_dscr(); + if (cur_dscr != dscr) { + fprintf(stderr, "Kernel DSCR should be %ld " + "but is %ld\n", dscr, cur_dscr); + exit(1); + } + + cur_dscr_usr = get_dscr_usr(); + if (cur_dscr_usr != dscr) { + fprintf(stderr, "User DSCR should be %ld " + "but is %ld\n", dscr, cur_dscr_usr); + exit(1); + } + exit(0); + } + } + return 0; +} + +int main(int argc, char *argv[]) +{ + return test_harness(dscr_inherit, "dscr_inherit_test"); +} diff --git a/kernel/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c b/kernel/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c new file mode 100644 index 000000000..17fb1b43c --- /dev/null +++ b/kernel/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c @@ -0,0 +1,97 @@ +/* + * POWER Data Stream Control Register (DSCR) sysfs interface test + * + * This test updates to system wide DSCR default through the sysfs interface + * and then verifies that all the CPU specific DSCR defaults are updated as + * well verified from their sysfs interfaces. + * + * Copyright 2015, Anshuman Khandual, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ +#include "dscr.h" + +static int check_cpu_dscr_default(char *file, unsigned long val) +{ + char buf[10]; + int fd, rc; + + 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"); + return 1; + } + close(fd); + + buf[rc] = '\0'; + if (strtol(buf, NULL, 16) != val) { + printf("DSCR match failed: %ld (system) %ld (cpu)\n", + val, strtol(buf, NULL, 16)); + return 1; + } + return 0; +} + +static int check_all_cpu_dscr_defaults(unsigned long val) +{ + DIR *sysfs; + struct dirent *dp; + char file[LEN_MAX]; + + sysfs = opendir(CPU_PATH); + if (!sysfs) { + perror("opendir() failed"); + return 1; + } + + while ((dp = readdir(sysfs))) { + if (!(dp->d_type & DT_DIR)) + continue; + if (!strcmp(dp->d_name, "cpuidle")) + continue; + if (!strstr(dp->d_name, "cpu")) + continue; + + sprintf(file, "%s%s/dscr", CPU_PATH, dp->d_name); + if (access(file, F_OK)) + continue; + + if (check_cpu_dscr_default(file, val)) + return 1; + } + closedir(sysfs); + return 0; +} + +int dscr_sysfs(void) +{ + unsigned long orig_dscr_default; + int i, j; + + orig_dscr_default = get_default_dscr(); + for (i = 0; i < COUNT; i++) { + for (j = 0; j < DSCR_MAX; j++) { + set_default_dscr(j); + if (check_all_cpu_dscr_defaults(j)) + goto fail; + } + } + set_default_dscr(orig_dscr_default); + return 0; +fail: + set_default_dscr(orig_dscr_default); + return 1; +} + +int main(int argc, char *argv[]) +{ + return test_harness(dscr_sysfs, "dscr_sysfs_test"); +} diff --git a/kernel/tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c b/kernel/tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c new file mode 100644 index 000000000..ad97b592e --- /dev/null +++ b/kernel/tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c @@ -0,0 +1,80 @@ +/* + * POWER Data Stream Control Register (DSCR) sysfs thread test + * + * This test updates the system wide DSCR default value through + * sysfs interface which should then update all the CPU specific + * DSCR default values which must also be then visible to threads + * executing on individual CPUs on the system. + * + * Copyright 2015, Anshuman Khandual, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ +#define _GNU_SOURCE +#include "dscr.h" + +static int test_thread_dscr(unsigned long val) +{ + unsigned long cur_dscr, cur_dscr_usr; + + cur_dscr = get_dscr(); + cur_dscr_usr = get_dscr_usr(); + + if (val != cur_dscr) { + printf("[cpu %d] Kernel DSCR should be %ld but is %ld\n", + sched_getcpu(), val, cur_dscr); + return 1; + } + + if (val != cur_dscr_usr) { + printf("[cpu %d] User DSCR should be %ld but is %ld\n", + sched_getcpu(), val, cur_dscr_usr); + return 1; + } + return 0; +} + +static int check_cpu_dscr_thread(unsigned long val) +{ + cpu_set_t mask; + int cpu; + + for (cpu = 0; cpu < CPU_SETSIZE; cpu++) { + CPU_ZERO(&mask); + CPU_SET(cpu, &mask); + if (sched_setaffinity(0, sizeof(mask), &mask)) + continue; + + if (test_thread_dscr(val)) + return 1; + } + return 0; + +} + +int dscr_sysfs_thread(void) +{ + unsigned long orig_dscr_default; + int i, j; + + orig_dscr_default = get_default_dscr(); + for (i = 0; i < COUNT; i++) { + for (j = 0; j < DSCR_MAX; j++) { + set_default_dscr(j); + if (check_cpu_dscr_thread(j)) + goto fail; + } + } + set_default_dscr(orig_dscr_default); + return 0; +fail: + set_default_dscr(orig_dscr_default); + return 1; +} + +int main(int argc, char *argv[]) +{ + return test_harness(dscr_sysfs_thread, "dscr_sysfs_thread_test"); +} diff --git a/kernel/tools/testing/selftests/powerpc/dscr/dscr_user_test.c b/kernel/tools/testing/selftests/powerpc/dscr/dscr_user_test.c new file mode 100644 index 000000000..77d16b5e7 --- /dev/null +++ b/kernel/tools/testing/selftests/powerpc/dscr/dscr_user_test.c @@ -0,0 +1,61 @@ +/* + * POWER Data Stream Control Register (DSCR) SPR test + * + * This test modifies the DSCR value through both the SPR number + * based mtspr instruction and then makes sure that the same is + * reflected through mfspr instruction using either of the SPR + * numbers. + * + * When using the privilege state SPR, the instructions such as + * mfspr or mtspr are priviledged and the kernel emulates them + * for us. Instructions using problem state SPR can be exuecuted + * directly without any emulation if the HW supports them. Else + * they also get emulated by the kernel. + * + * Copyright 2013, Anton Blanchard, IBM Corporation. + * Copyright 2015, Anshuman Khandual, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ +#include "dscr.h" + +static int check_dscr(char *str) +{ + unsigned long cur_dscr, cur_dscr_usr; + + cur_dscr = get_dscr(); + cur_dscr_usr = get_dscr_usr(); + if (cur_dscr != cur_dscr_usr) { + printf("%s set, kernel get %lx != user get %lx\n", + str, cur_dscr, cur_dscr_usr); + return 1; + } + return 0; +} + +int dscr_user(void) +{ + int i; + + check_dscr(""); + + for (i = 0; i < COUNT; i++) { + set_dscr(i); + if (check_dscr("kernel")) + return 1; + } + + for (i = 0; i < COUNT; i++) { + set_dscr_usr(i); + if (check_dscr("user")) + return 1; + } + return 0; +} + +int main(int argc, char *argv[]) +{ + return test_harness(dscr_user, "dscr_user_test"); +} diff --git a/kernel/tools/testing/selftests/powerpc/mm/Makefile b/kernel/tools/testing/selftests/powerpc/mm/Makefile index 41cc3ed66..ee179e223 100644 --- a/kernel/tools/testing/selftests/powerpc/mm/Makefile +++ b/kernel/tools/testing/selftests/powerpc/mm/Makefile @@ -2,8 +2,9 @@ noarg: $(MAKE) -C ../ TEST_PROGS := hugetlb_vs_thp_test subpage_prot +TEST_FILES := tempfile -all: $(TEST_PROGS) tempfile +all: $(TEST_PROGS) $(TEST_FILES) $(TEST_PROGS): ../harness.c diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/back_to_back_ebbs_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/back_to_back_ebbs_test.c index 66ea765c0..94110b1dc 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/back_to_back_ebbs_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/back_to_back_ebbs_test.c @@ -63,6 +63,8 @@ int back_to_back_ebbs(void) { struct event event; + SKIP_IF(!ebb_is_supported()); + event_init_named(&event, 0x1001e, "cycles"); event_leader_ebb_init(&event); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/close_clears_pmcc_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/close_clears_pmcc_test.c index 0f0423dba..ac18cf617 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/close_clears_pmcc_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/close_clears_pmcc_test.c @@ -20,6 +20,8 @@ int close_clears_pmcc(void) { struct event event; + SKIP_IF(!ebb_is_supported()); + event_init_named(&event, 0x1001e, "cycles"); event_leader_ebb_init(&event); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c index d3ed64d5d..f0632e7fd 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c @@ -43,6 +43,8 @@ int cpu_event_pinned_vs_ebb(void) int cpu, rc; pid_t pid; + SKIP_IF(!ebb_is_supported()); + cpu = pick_online_cpu(); FAIL_IF(cpu < 0); FAIL_IF(bind_to_cpu(cpu)); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_vs_ebb_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_vs_ebb_test.c index 8b972c2aa..33e56a234 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_vs_ebb_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_vs_ebb_test.c @@ -41,6 +41,8 @@ int cpu_event_vs_ebb(void) int cpu, rc; pid_t pid; + SKIP_IF(!ebb_is_supported()); + cpu = pick_online_cpu(); FAIL_IF(cpu < 0); FAIL_IF(bind_to_cpu(cpu)); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/cycles_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/cycles_test.c index 8590fc1bf..7c57a8d79 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/cycles_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/cycles_test.c @@ -16,6 +16,8 @@ int cycles(void) { struct event event; + SKIP_IF(!ebb_is_supported()); + event_init_named(&event, 0x1001e, "cycles"); event_leader_ebb_init(&event); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/cycles_with_freeze_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/cycles_with_freeze_test.c index 754b3f200..ecf5ee328 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/cycles_with_freeze_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/cycles_with_freeze_test.c @@ -56,6 +56,8 @@ int cycles_with_freeze(void) uint64_t val; bool fc_cleared; + SKIP_IF(!ebb_is_supported()); + event_init_named(&event, 0x1001e, "cycles"); event_leader_ebb_init(&event); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c index d43029b08..c0faba520 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c @@ -26,6 +26,8 @@ int cycles_with_mmcr2(void) int i; bool bad_mmcr2; + SKIP_IF(!ebb_is_supported()); + event_init_named(&event, 0x1001e, "cycles"); event_leader_ebb_init(&event); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb.c index d7a72ce69..9729d9f90 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb.c @@ -13,6 +13,7 @@ #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> +#include <linux/auxvec.h> #include "trace.h" #include "reg.h" @@ -319,6 +320,16 @@ void ebb_global_disable(void) mb(); } +bool ebb_is_supported(void) +{ +#ifdef PPC_FEATURE2_EBB + /* EBB requires at least POWER8 */ + return ((long)get_auxv_entry(AT_HWCAP2) & PPC_FEATURE2_EBB); +#else + return false; +#endif +} + void event_ebb_init(struct event *e) { e->attr.config |= (1ull << 63); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb.h b/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb.h index e44eee5d9..f87e761f8 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb.h +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb.h @@ -52,6 +52,7 @@ void standard_ebb_callee(void); int ebb_event_enable(struct event *e); void ebb_global_enable(void); void ebb_global_disable(void); +bool ebb_is_supported(void); void ebb_freeze_pmcs(void); void ebb_unfreeze_pmcs(void); void event_ebb_init(struct event *e); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb_on_child_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb_on_child_test.c index c45f94814..1e7b7fe23 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb_on_child_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb_on_child_test.c @@ -47,6 +47,8 @@ int ebb_on_child(void) struct event event; pid_t pid; + SKIP_IF(!ebb_is_supported()); + FAIL_IF(pipe(read_pipe.fds) == -1); FAIL_IF(pipe(write_pipe.fds) == -1); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb_on_willing_child_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb_on_willing_child_test.c index 11acf1d55..a991d2ea8 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb_on_willing_child_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb_on_willing_child_test.c @@ -54,6 +54,8 @@ int ebb_on_willing_child(void) struct event event; pid_t pid; + SKIP_IF(!ebb_is_supported()); + FAIL_IF(pipe(read_pipe.fds) == -1); FAIL_IF(pipe(write_pipe.fds) == -1); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb_vs_cpu_event_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb_vs_cpu_event_test.c index be4dd5a4e..af20a2b36 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb_vs_cpu_event_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/ebb_vs_cpu_event_test.c @@ -41,6 +41,8 @@ int ebb_vs_cpu_event(void) int cpu, rc; pid_t pid; + SKIP_IF(!ebb_is_supported()); + cpu = pick_online_cpu(); FAIL_IF(cpu < 0); FAIL_IF(bind_to_cpu(cpu)); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/event_attributes_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/event_attributes_test.c index 7e78153f0..7762ab26e 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/event_attributes_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/event_attributes_test.c @@ -16,6 +16,8 @@ int event_attributes(void) { struct event event, leader; + SKIP_IF(!ebb_is_supported()); + event_init(&event, 0x1001e); event_leader_ebb_init(&event); /* Expected to succeed */ diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/fork_cleanup_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/fork_cleanup_test.c index 9e7af6e76..167135bd9 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/fork_cleanup_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/fork_cleanup_test.c @@ -44,6 +44,8 @@ int fork_cleanup(void) { pid_t pid; + SKIP_IF(!ebb_is_supported()); + event_init_named(&event, 0x1001e, "cycles"); event_leader_ebb_init(&event); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c index f8190fa29..5da355135 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c @@ -111,6 +111,8 @@ int instruction_count(void) struct event event; uint64_t overhead; + SKIP_IF(!ebb_is_supported()); + event_init_named(&event, 0x400FA, "PM_RUN_INST_CMPL"); event_leader_ebb_init(&event); event.attr.exclude_kernel = 1; diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/lost_exception_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/lost_exception_test.c index 0c9dd9b2e..eb8acb78b 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/lost_exception_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/lost_exception_test.c @@ -23,6 +23,8 @@ static int test_body(void) int i, orig_period, max_period; struct event event; + SKIP_IF(!ebb_is_supported()); + /* We use PMC4 to make sure the kernel switches all counters correctly */ event_init_named(&event, 0x40002, "instructions"); event_leader_ebb_init(&event); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/multi_counter_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/multi_counter_test.c index 67d78af32..6ff8c8ff2 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/multi_counter_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/multi_counter_test.c @@ -18,6 +18,8 @@ int multi_counter(void) struct event events[6]; int i, group_fd; + SKIP_IF(!ebb_is_supported()); + event_init_named(&events[0], 0x1001C, "PM_CMPLU_STALL_THRD"); event_init_named(&events[1], 0x2D016, "PM_CMPLU_STALL_FXU"); event_init_named(&events[2], 0x30006, "PM_CMPLU_STALL_OTHER_CMPL"); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/multi_ebb_procs_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/multi_ebb_procs_test.c index b8dc371f9..037cb6154 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/multi_ebb_procs_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/multi_ebb_procs_test.c @@ -79,6 +79,8 @@ int multi_ebb_procs(void) pid_t pids[NR_CHILDREN]; int cpu, rc, i; + SKIP_IF(!ebb_is_supported()); + cpu = pick_online_cpu(); FAIL_IF(cpu < 0); FAIL_IF(bind_to_cpu(cpu)); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/no_handler_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/no_handler_test.c index 2f9bf8edf..8341d7778 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/no_handler_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/no_handler_test.c @@ -19,6 +19,8 @@ static int no_handler_test(void) u64 val; int i; + SKIP_IF(!ebb_is_supported()); + event_init_named(&event, 0x1001e, "cycles"); event_leader_ebb_init(&event); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/pmae_handling_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/pmae_handling_test.c index 986500fd2..c5fa64790 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/pmae_handling_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/pmae_handling_test.c @@ -58,6 +58,8 @@ static int test_body(void) { struct event event; + SKIP_IF(!ebb_is_supported()); + event_init_named(&event, 0x1001e, "cycles"); event_leader_ebb_init(&event); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/pmc56_overflow_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/pmc56_overflow_test.c index a503fa70c..c22860ab9 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/pmc56_overflow_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/pmc56_overflow_test.c @@ -49,6 +49,8 @@ int pmc56_overflow(void) { struct event event; + SKIP_IF(!ebb_is_supported()); + /* Use PMC2 so we set PMCjCE, which enables PMC5/6 */ event_init(&event, 0x2001e); event_leader_ebb_init(&event); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/reg_access_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/reg_access_test.c index 0cae66f65..5b1188f10 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/reg_access_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/reg_access_test.c @@ -18,6 +18,8 @@ int reg_access(void) { uint64_t val, expected; + SKIP_IF(!ebb_is_supported()); + expected = 0x8000000100000000ull; mtspr(SPRN_BESCR, expected); val = mfspr(SPRN_BESCR); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/task_event_pinned_vs_ebb_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/task_event_pinned_vs_ebb_test.c index d56607e4f..1846f4e84 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/task_event_pinned_vs_ebb_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/task_event_pinned_vs_ebb_test.c @@ -42,6 +42,8 @@ int task_event_pinned_vs_ebb(void) pid_t pid; int rc; + SKIP_IF(!ebb_is_supported()); + FAIL_IF(pipe(read_pipe.fds) == -1); FAIL_IF(pipe(write_pipe.fds) == -1); diff --git a/kernel/tools/testing/selftests/powerpc/pmu/ebb/task_event_vs_ebb_test.c b/kernel/tools/testing/selftests/powerpc/pmu/ebb/task_event_vs_ebb_test.c index eba32196d..e3bc6e92a 100644 --- a/kernel/tools/testing/selftests/powerpc/pmu/ebb/task_event_vs_ebb_test.c +++ b/kernel/tools/testing/selftests/powerpc/pmu/ebb/task_event_vs_ebb_test.c @@ -40,6 +40,8 @@ int task_event_vs_ebb(void) pid_t pid; int rc; + SKIP_IF(!ebb_is_supported()); + FAIL_IF(pipe(read_pipe.fds) == -1); FAIL_IF(pipe(write_pipe.fds) == -1); diff --git a/kernel/tools/testing/selftests/powerpc/primitives/load_unaligned_zeropad.c b/kernel/tools/testing/selftests/powerpc/primitives/load_unaligned_zeropad.c index d1b647509..6cae06117 100644 --- a/kernel/tools/testing/selftests/powerpc/primitives/load_unaligned_zeropad.c +++ b/kernel/tools/testing/selftests/powerpc/primitives/load_unaligned_zeropad.c @@ -25,10 +25,19 @@ #define FIXUP_SECTION ".ex_fixup" +static inline unsigned long __fls(unsigned long x); + #include "word-at-a-time.h" #include "utils.h" +static inline unsigned long __fls(unsigned long x) +{ + int lz; + + asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (x)); + return sizeof(unsigned long) - 1 - lz; +} static int page_size; static char *mem_region; diff --git a/kernel/tools/testing/selftests/powerpc/switch_endian/Makefile b/kernel/tools/testing/selftests/powerpc/switch_endian/Makefile index 081473db2..e21d10674 100644 --- a/kernel/tools/testing/selftests/powerpc/switch_endian/Makefile +++ b/kernel/tools/testing/selftests/powerpc/switch_endian/Makefile @@ -1,9 +1,8 @@ -CC := $(CROSS_COMPILE)gcc -PROGS := switch_endian_test +TEST_PROGS := switch_endian_test ASFLAGS += -O2 -Wall -g -nostdlib -m64 -all: $(PROGS) +all: $(TEST_PROGS) switch_endian_test: check-reversed.S @@ -13,12 +12,7 @@ check-reversed.o: check.o check-reversed.S: check-reversed.o hexdump -v -e '/1 ".byte 0x%02X\n"' $< > $@ -run_tests: all - @-for PROG in $(PROGS); do \ - ./$$PROG; \ - done; +include ../../lib.mk clean: - rm -f $(PROGS) *.o check-reversed.S - -.PHONY: all run_tests clean + rm -f $(TEST_PROGS) *.o check-reversed.S diff --git a/kernel/tools/testing/selftests/powerpc/syscalls/.gitignore b/kernel/tools/testing/selftests/powerpc/syscalls/.gitignore new file mode 100644 index 000000000..f0f3fcc9d --- /dev/null +++ b/kernel/tools/testing/selftests/powerpc/syscalls/.gitignore @@ -0,0 +1 @@ +ipc_unmuxed diff --git a/kernel/tools/testing/selftests/powerpc/syscalls/Makefile b/kernel/tools/testing/selftests/powerpc/syscalls/Makefile new file mode 100644 index 000000000..b35c7945b --- /dev/null +++ b/kernel/tools/testing/selftests/powerpc/syscalls/Makefile @@ -0,0 +1,12 @@ +TEST_PROGS := ipc_unmuxed + +CFLAGS += -I../../../../../usr/include + +all: $(TEST_PROGS) + +$(TEST_PROGS): ../harness.c + +include ../../lib.mk + +clean: + rm -f $(TEST_PROGS) *.o diff --git a/kernel/tools/testing/selftests/powerpc/syscalls/ipc.h b/kernel/tools/testing/selftests/powerpc/syscalls/ipc.h new file mode 100644 index 000000000..fbebc022e --- /dev/null +++ b/kernel/tools/testing/selftests/powerpc/syscalls/ipc.h @@ -0,0 +1,47 @@ +#ifdef __NR_semop +DO_TEST(semop, __NR_semop) +#endif + +#ifdef __NR_semget +DO_TEST(semget, __NR_semget) +#endif + +#ifdef __NR_semctl +DO_TEST(semctl, __NR_semctl) +#endif + +#ifdef __NR_semtimedop +DO_TEST(semtimedop, __NR_semtimedop) +#endif + +#ifdef __NR_msgsnd +DO_TEST(msgsnd, __NR_msgsnd) +#endif + +#ifdef __NR_msgrcv +DO_TEST(msgrcv, __NR_msgrcv) +#endif + +#ifdef __NR_msgget +DO_TEST(msgget, __NR_msgget) +#endif + +#ifdef __NR_msgctl +DO_TEST(msgctl, __NR_msgctl) +#endif + +#ifdef __NR_shmat +DO_TEST(shmat, __NR_shmat) +#endif + +#ifdef __NR_shmdt +DO_TEST(shmdt, __NR_shmdt) +#endif + +#ifdef __NR_shmget +DO_TEST(shmget, __NR_shmget) +#endif + +#ifdef __NR_shmctl +DO_TEST(shmctl, __NR_shmctl) +#endif diff --git a/kernel/tools/testing/selftests/powerpc/syscalls/ipc_unmuxed.c b/kernel/tools/testing/selftests/powerpc/syscalls/ipc_unmuxed.c new file mode 100644 index 000000000..2ac02706f --- /dev/null +++ b/kernel/tools/testing/selftests/powerpc/syscalls/ipc_unmuxed.c @@ -0,0 +1,61 @@ +/* + * Copyright 2015, Michael Ellerman, IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * This test simply tests that certain syscalls are implemented. It doesn't + * actually exercise their logic in any way. + */ + +#define _GNU_SOURCE +#include <errno.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/syscall.h> + +#include "utils.h" + + +#define DO_TEST(_name, _num) \ +static int test_##_name(void) \ +{ \ + int rc; \ + printf("Testing " #_name); \ + errno = 0; \ + rc = syscall(_num, -1, 0, 0, 0, 0, 0); \ + printf("\treturned %d, errno %d\n", rc, errno); \ + return errno == ENOSYS; \ +} + +#include "ipc.h" +#undef DO_TEST + +static int ipc_unmuxed(void) +{ + int tests_done = 0; + +#define DO_TEST(_name, _num) \ + FAIL_IF(test_##_name()); \ + tests_done++; + +#include "ipc.h" +#undef DO_TEST + + /* + * If we ran no tests then it means none of the syscall numbers were + * defined, possibly because we were built against old headers. But it + * means we didn't really test anything, so instead of passing mark it + * as a skip to give the user a clue. + */ + SKIP_IF(tests_done == 0); + + return 0; +} + +int main(void) +{ + return test_harness(ipc_unmuxed, "ipc_unmuxed"); +} diff --git a/kernel/tools/testing/selftests/powerpc/tm/Makefile b/kernel/tools/testing/selftests/powerpc/tm/Makefile index 6bff955e1..4bea62a31 100644 --- a/kernel/tools/testing/selftests/powerpc/tm/Makefile +++ b/kernel/tools/testing/selftests/powerpc/tm/Makefile @@ -1,11 +1,11 @@ -TEST_PROGS := tm-resched-dscr +TEST_PROGS := tm-resched-dscr tm-syscall all: $(TEST_PROGS) $(TEST_PROGS): ../harness.c tm-syscall: tm-syscall-asm.S -tm-syscall: CFLAGS += -mhtm +tm-syscall: CFLAGS += -mhtm -I../../../../../usr/include include ../../lib.mk diff --git a/kernel/tools/testing/selftests/powerpc/tm/tm-syscall.c b/kernel/tools/testing/selftests/powerpc/tm/tm-syscall.c index 3ed8d4b25..e835bf7ec 100644 --- a/kernel/tools/testing/selftests/powerpc/tm/tm-syscall.c +++ b/kernel/tools/testing/selftests/powerpc/tm/tm-syscall.c @@ -77,12 +77,23 @@ pid_t getppid_tm(bool suspend) exit(-1); } +static inline bool have_htm_nosc(void) +{ +#ifdef PPC_FEATURE2_HTM_NOSC + return ((long)get_auxv_entry(AT_HWCAP2) & PPC_FEATURE2_HTM_NOSC); +#else + printf("PPC_FEATURE2_HTM_NOSC not defined, can't check AT_HWCAP2\n"); + return false; +#endif +} + int tm_syscall(void) { unsigned count = 0; struct timeval end, now; - SKIP_IF(!((long)get_auxv_entry(AT_HWCAP2) & PPC_FEATURE2_HTM)); + SKIP_IF(!have_htm_nosc()); + setbuf(stdout, NULL); printf("Testing transactional syscalls for %d seconds...\n", TEST_DURATION); diff --git a/kernel/tools/testing/selftests/powerpc/vphn/Makefile b/kernel/tools/testing/selftests/powerpc/vphn/Makefile index e539f775f..a485f2e28 100644 --- a/kernel/tools/testing/selftests/powerpc/vphn/Makefile +++ b/kernel/tools/testing/selftests/powerpc/vphn/Makefile @@ -1,15 +1,12 @@ -PROG := test-vphn +TEST_PROGS := test-vphn CFLAGS += -m64 -all: $(PROG) +all: $(TEST_PROGS) -$(PROG): ../harness.c +$(TEST_PROGS): ../harness.c -run_tests: all - ./$(PROG) +include ../../lib.mk clean: - rm -f $(PROG) - -.PHONY: all run_tests clean + rm -f $(TEST_PROGS) |