Merge tag 'powerpc-4.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux
Pull powerpc updates from Michael Ellerman: - disable the 32-bit vdso when building LE, so we can build with a 64-bit only toolchain. - EEH fixes from Gavin & Richard. - enable the sys_kcmp syscall from Laurent. - sysfs control for fastsleep workaround from Shreyas. - expose OPAL events as an irq chip by Alistair. - MSI ops moved to pci_controller_ops by Daniel. - fix for kernel to userspace backtraces for perf from Anton. - merge pseries and pseries_le defconfigs from Cyril. - CXL in-kernel API from Mikey. - OPAL prd driver from Jeremy. - fix for DSCR handling & tests from Anshuman. - Powernv flash mtd driver from Cyril. - dynamic DMA Window support on powernv from Alexey. - LLVM clang fixes & workarounds from Anton. - reworked version of the patch to abort syscalls when transactional. - fix the swap encoding to support 4TB, from Aneesh. - various fixes as usual. - Freescale updates from Scott: Highlights include more 8xx optimizations, an e6500 hugetlb optimization, QMan device tree nodes, t1024/t1023 support, and various fixes and cleanup. * tag 'powerpc-4.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux: (180 commits) cxl: Fix typo in debug print cxl: Add CXL_KERNEL_API config option powerpc/powernv: Fix wrong IOMMU table in pnv_ioda_setup_bus_dma() powerpc/mm: Change the swap encoding in pte. powerpc/mm: PTE_RPN_MAX is not used, remove the same powerpc/tm: Abort syscalls in active transactions powerpc/iommu/ioda2: Enable compile with IOV=on and IOMMU_API=off powerpc/include: Add opal-prd to installed uapi headers powerpc/powernv: fix construction of opal PRD messages powerpc/powernv: Increase opal-irqchip initcall priority powerpc: Make doorbell check preemption safe powerpc/powernv: pnv_init_idle_states() should only run on powernv macintosh/nvram: Remove as unused powerpc: Don't use gcc specific options on clang powerpc: Don't use -mno-strict-align on clang powerpc: Only use -mtraceback=no, -mno-string and -msoft-float if toolchain supports it powerpc: Only use -mabi=altivec if toolchain supports it powerpc: Fix duplicate const clang warning in user access code vfio: powerpc/spapr: Support Dynamic DMA windows vfio: powerpc/spapr: Register memory and define IOMMU v2 ...
This commit is contained in:
@@ -12,7 +12,7 @@ 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 = pmu copyloops mm tm primitives stringloops vphn switch_endian dscr
|
||||
|
||||
endif
|
||||
|
||||
|
7
tools/testing/selftests/powerpc/dscr/.gitignore
vendored
Normal file
7
tools/testing/selftests/powerpc/dscr/.gitignore
vendored
Normal file
@@ -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
|
14
tools/testing/selftests/powerpc/dscr/Makefile
Normal file
14
tools/testing/selftests/powerpc/dscr/Makefile
Normal file
@@ -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
|
127
tools/testing/selftests/powerpc/dscr/dscr.h
Normal file
127
tools/testing/selftests/powerpc/dscr/dscr.h
Normal file
@@ -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 */
|
127
tools/testing/selftests/powerpc/dscr/dscr_default_test.c
Normal file
127
tools/testing/selftests/powerpc/dscr/dscr_default_test.c
Normal file
@@ -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");
|
||||
}
|
71
tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c
Normal file
71
tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c
Normal file
@@ -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");
|
||||
}
|
117
tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c
Normal file
117
tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c
Normal file
@@ -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");
|
||||
}
|
95
tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c
Normal file
95
tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c
Normal file
@@ -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");
|
||||
}
|
97
tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
Normal file
97
tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
Normal file
@@ -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");
|
||||
}
|
@@ -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");
|
||||
}
|
61
tools/testing/selftests/powerpc/dscr/dscr_user_test.c
Normal file
61
tools/testing/selftests/powerpc/dscr/dscr_user_test.c
Normal file
@@ -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");
|
||||
}
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -82,7 +82,8 @@ int tm_syscall(void)
|
||||
unsigned count = 0;
|
||||
struct timeval end, now;
|
||||
|
||||
SKIP_IF(!((long)get_auxv_entry(AT_HWCAP2) & PPC_FEATURE2_HTM));
|
||||
SKIP_IF(!((long)get_auxv_entry(AT_HWCAP2)
|
||||
& PPC_FEATURE2_HTM_NOSC));
|
||||
setbuf(stdout, NULL);
|
||||
|
||||
printf("Testing transactional syscalls for %d seconds...\n", TEST_DURATION);
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user