Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: GPL-2.0-only
dscr_default_test
dscr_explicit_test
dscr_inherit_exec_test
dscr_inherit_test
dscr_sysfs_test
dscr_sysfs_thread_test
dscr_user_test
@@ -0,0 +1,13 @@
# SPDX-License-Identifier: GPL-2.0
TEST_GEN_PROGS := dscr_default_test dscr_explicit_test dscr_user_test \
dscr_inherit_test dscr_inherit_exec_test dscr_sysfs_test \
dscr_sysfs_thread_test
top_srcdir = ../../../../..
include ../../lib.mk
include ../flags.mk
$(OUTPUT)/dscr_default_test: LDLIBS += -lpthread
$(OUTPUT)/dscr_explicit_test: LDLIBS += -lpthread
$(TEST_GEN_PROGS): ../harness.c ../utils.c
@@ -0,0 +1,89 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* 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.
*/
#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 "reg.h"
#include "utils.h"
#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 READ_ONCE(x) (*(volatile typeof(x) *)&(x))
/* Prilvilege state DSCR access */
inline unsigned long get_dscr(void)
{
return mfspr(SPRN_DSCR_PRIV);
}
inline void set_dscr(unsigned long val)
{
mtspr(SPRN_DSCR_PRIV, val);
}
/* Problem state DSCR access */
inline unsigned long get_dscr_usr(void)
{
return mfspr(SPRN_DSCR);
}
inline void set_dscr_usr(unsigned long val)
{
mtspr(SPRN_DSCR, val);
}
/* Default DSCR access */
unsigned long get_default_dscr(void)
{
int err;
unsigned long val;
err = read_ulong(DSCR_DEFAULT, &val, 16);
if (err) {
perror("read() failed");
exit(1);
}
return val;
}
void set_default_dscr(unsigned long val)
{
int err;
err = write_ulong(DSCR_DEFAULT, val, 16);
if (err) {
perror("write() failed");
exit(1);
}
}
#endif /* _SELFTESTS_POWERPC_DSCR_DSCR_H */
@@ -0,0 +1,169 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* 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.
*/
#define _GNU_SOURCE
#include "dscr.h"
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
static void *dscr_default_lockstep_writer(void *arg)
{
sem_t *reader_sem = (sem_t *)arg;
sem_t *writer_sem = (sem_t *)arg + 1;
unsigned long expected_dscr = 0;
for (int i = 0; i < COUNT; i++) {
FAIL_IF_EXIT(sem_wait(writer_sem));
set_default_dscr(expected_dscr);
expected_dscr = (expected_dscr + 1) % DSCR_MAX;
FAIL_IF_EXIT(sem_post(reader_sem));
}
return NULL;
}
int dscr_default_lockstep_test(void)
{
pthread_t writer;
sem_t rw_semaphores[2];
sem_t *reader_sem = &rw_semaphores[0];
sem_t *writer_sem = &rw_semaphores[1];
unsigned long expected_dscr = 0;
SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));
FAIL_IF(sem_init(reader_sem, 0, 0));
FAIL_IF(sem_init(writer_sem, 0, 1)); /* writer starts first */
FAIL_IF(bind_to_cpu(BIND_CPU_ANY) < 0);
FAIL_IF(pthread_create(&writer, NULL, dscr_default_lockstep_writer, (void *)rw_semaphores));
for (int i = 0; i < COUNT ; i++) {
FAIL_IF(sem_wait(reader_sem));
FAIL_IF(get_dscr() != expected_dscr);
FAIL_IF(get_dscr_usr() != expected_dscr);
expected_dscr = (expected_dscr + 1) % DSCR_MAX;
FAIL_IF(sem_post(writer_sem));
}
FAIL_IF(pthread_join(writer, NULL));
FAIL_IF(sem_destroy(reader_sem));
FAIL_IF(sem_destroy(writer_sem));
return 0;
}
struct random_thread_args {
pthread_t thread_id;
unsigned long *expected_system_dscr;
pthread_rwlock_t *rw_lock;
pthread_barrier_t *barrier;
};
static void *dscr_default_random_thread(void *in)
{
struct random_thread_args *args = (struct random_thread_args *)in;
unsigned long *expected_dscr_p = args->expected_system_dscr;
pthread_rwlock_t *rw_lock = args->rw_lock;
int err;
srand(gettid());
err = pthread_barrier_wait(args->barrier);
FAIL_IF_EXIT(err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD);
for (int i = 0; i < COUNT; i++) {
unsigned long expected_dscr;
unsigned long current_dscr;
unsigned long current_dscr_usr;
FAIL_IF_EXIT(pthread_rwlock_rdlock(rw_lock));
expected_dscr = *expected_dscr_p;
current_dscr = get_dscr();
current_dscr_usr = get_dscr_usr();
FAIL_IF_EXIT(pthread_rwlock_unlock(rw_lock));
FAIL_IF_EXIT(current_dscr != expected_dscr);
FAIL_IF_EXIT(current_dscr_usr != expected_dscr);
if (rand() % 10 == 0) {
unsigned long next_dscr;
FAIL_IF_EXIT(pthread_rwlock_wrlock(rw_lock));
next_dscr = (*expected_dscr_p + 1) % DSCR_MAX;
set_default_dscr(next_dscr);
*expected_dscr_p = next_dscr;
FAIL_IF_EXIT(pthread_rwlock_unlock(rw_lock));
}
}
pthread_exit((void *)0);
}
int dscr_default_random_test(void)
{
struct random_thread_args threads[THREADS];
unsigned long expected_system_dscr = 0;
pthread_rwlockattr_t rwlock_attr;
pthread_rwlock_t rw_lock;
pthread_barrier_t barrier;
SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));
FAIL_IF(pthread_rwlockattr_setkind_np(&rwlock_attr,
PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP));
FAIL_IF(pthread_rwlock_init(&rw_lock, &rwlock_attr));
FAIL_IF(pthread_barrier_init(&barrier, NULL, THREADS));
set_default_dscr(expected_system_dscr);
for (int i = 0; i < THREADS; i++) {
threads[i].expected_system_dscr = &expected_system_dscr;
threads[i].rw_lock = &rw_lock;
threads[i].barrier = &barrier;
FAIL_IF(pthread_create(&threads[i].thread_id, NULL,
dscr_default_random_thread, (void *)&threads[i]));
}
for (int i = 0; i < THREADS; i++)
FAIL_IF(pthread_join(threads[i].thread_id, NULL));
FAIL_IF(pthread_barrier_destroy(&barrier));
FAIL_IF(pthread_rwlock_destroy(&rw_lock));
return 0;
}
int main(int argc, char *argv[])
{
unsigned long orig_dscr_default = 0;
int err = 0;
if (have_hwcap2(PPC_FEATURE2_DSCR))
orig_dscr_default = get_default_dscr();
err |= test_harness(dscr_default_lockstep_test, "dscr_default_lockstep_test");
err |= test_harness(dscr_default_random_test, "dscr_default_random_test");
if (have_hwcap2(PPC_FEATURE2_DSCR))
set_default_dscr(orig_dscr_default);
return err;
}
@@ -0,0 +1,173 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* 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 privileged and the kernel emulates them
* for us. Instructions using problem state SPR can be executed
* 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.
*/
#define _GNU_SOURCE
#include "dscr.h"
#include "utils.h"
#include <pthread.h>
#include <sched.h>
#include <semaphore.h>
void *dscr_explicit_lockstep_thread(void *args)
{
sem_t *prev = (sem_t *)args;
sem_t *next = (sem_t *)args + 1;
unsigned long expected_dscr = 0;
set_dscr(expected_dscr);
srand(gettid());
for (int i = 0; i < COUNT; i++) {
FAIL_IF_EXIT(sem_wait(prev));
FAIL_IF_EXIT(expected_dscr != get_dscr());
FAIL_IF_EXIT(expected_dscr != get_dscr_usr());
expected_dscr = (expected_dscr + 1) % DSCR_MAX;
set_dscr(expected_dscr);
FAIL_IF_EXIT(sem_post(next));
}
return NULL;
}
int dscr_explicit_lockstep_test(void)
{
pthread_t thread;
sem_t semaphores[2];
sem_t *prev = &semaphores[1]; /* reversed prev/next than for the other thread */
sem_t *next = &semaphores[0];
unsigned long expected_dscr = 0;
SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));
srand(gettid());
set_dscr(expected_dscr);
FAIL_IF(sem_init(prev, 0, 0));
FAIL_IF(sem_init(next, 0, 1)); /* other thread starts first */
FAIL_IF(bind_to_cpu(BIND_CPU_ANY) < 0);
FAIL_IF(pthread_create(&thread, NULL, dscr_explicit_lockstep_thread, (void *)semaphores));
for (int i = 0; i < COUNT; i++) {
FAIL_IF(sem_wait(prev));
FAIL_IF(expected_dscr != get_dscr());
FAIL_IF(expected_dscr != get_dscr_usr());
expected_dscr = (expected_dscr - 1) % DSCR_MAX;
set_dscr(expected_dscr);
FAIL_IF(sem_post(next));
}
FAIL_IF(pthread_join(thread, NULL));
FAIL_IF(sem_destroy(prev));
FAIL_IF(sem_destroy(next));
return 0;
}
struct random_thread_args {
pthread_t thread_id;
bool do_yields;
pthread_barrier_t *barrier;
};
void *dscr_explicit_random_thread(void *in)
{
struct random_thread_args *args = (struct random_thread_args *)in;
unsigned long expected_dscr = 0;
int err;
srand(gettid());
err = pthread_barrier_wait(args->barrier);
FAIL_IF_EXIT(err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD);
for (int i = 0; i < COUNT; i++) {
expected_dscr = rand() % DSCR_MAX;
set_dscr(expected_dscr);
for (int j = rand() % 5; j > 0; --j) {
FAIL_IF_EXIT(get_dscr() != expected_dscr);
FAIL_IF_EXIT(get_dscr_usr() != expected_dscr);
if (args->do_yields && rand() % 2)
sched_yield();
}
expected_dscr = rand() % DSCR_MAX;
set_dscr_usr(expected_dscr);
for (int j = rand() % 5; j > 0; --j) {
FAIL_IF_EXIT(get_dscr() != expected_dscr);
FAIL_IF_EXIT(get_dscr_usr() != expected_dscr);
if (args->do_yields && rand() % 2)
sched_yield();
}
}
return NULL;
}
int dscr_explicit_random_test(void)
{
struct random_thread_args threads[THREADS];
pthread_barrier_t barrier;
SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));
FAIL_IF(pthread_barrier_init(&barrier, NULL, THREADS));
for (int i = 0; i < THREADS; i++) {
threads[i].do_yields = i % 2 == 0;
threads[i].barrier = &barrier;
FAIL_IF(pthread_create(&threads[i].thread_id, NULL,
dscr_explicit_random_thread, (void *)&threads[i]));
}
for (int i = 0; i < THREADS; i++)
FAIL_IF(pthread_join(threads[i].thread_id, NULL));
FAIL_IF(pthread_barrier_destroy(&barrier));
return 0;
}
int main(int argc, char *argv[])
{
unsigned long orig_dscr_default = 0;
int err = 0;
if (have_hwcap2(PPC_FEATURE2_DSCR))
orig_dscr_default = get_default_dscr();
err |= test_harness(dscr_explicit_lockstep_test, "dscr_explicit_lockstep_test");
err |= test_harness(dscr_explicit_random_test, "dscr_explicit_random_test");
if (have_hwcap2(PPC_FEATURE2_DSCR))
set_default_dscr(orig_dscr_default);
return err;
}
@@ -0,0 +1,108 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* 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 privileged and the kernel emulates them
* for us. Instructions using problem state SPR can be executed
* 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.
*/
#include "dscr.h"
static char *prog;
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;
SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));
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);
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);
}
prog = argv[0];
return test_harness(dscr_inherit_exec, "dscr_inherit_exec_test");
}
@@ -0,0 +1,86 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* 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 privileged and the kernel emulates them
* for us. Instructions using problem state SPR can be executed
* 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.
*/
#include "dscr.h"
int dscr_inherit(void)
{
unsigned long i, dscr = 0;
pid_t pid;
SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));
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);
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");
}
@@ -0,0 +1,89 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* 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.
*/
#include "dscr.h"
static int check_cpu_dscr_default(char *file, unsigned long val)
{
unsigned long cpu_dscr;
int err;
err = read_ulong(file, &cpu_dscr, 16);
if (err)
return err;
if (cpu_dscr != val) {
printf("DSCR match failed: %ld (system) %ld (cpu)\n",
val, cpu_dscr);
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))) {
int len;
if (!(dp->d_type & DT_DIR))
continue;
if (!strcmp(dp->d_name, "cpuidle"))
continue;
if (!strstr(dp->d_name, "cpu"))
continue;
len = snprintf(file, LEN_MAX, "%s%s/dscr", CPU_PATH, dp->d_name);
if (len >= LEN_MAX)
continue;
if (access(file, F_OK))
continue;
if (check_cpu_dscr_default(file, val)) {
closedir(sysfs);
return 1;
}
}
closedir(sysfs);
return 0;
}
int dscr_sysfs(void)
{
unsigned long orig_dscr_default;
SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));
orig_dscr_default = get_default_dscr();
for (int i = 0; i < DSCR_MAX; i++) {
set_default_dscr(i);
if (check_all_cpu_dscr_defaults(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_sysfs, "dscr_sysfs_test");
}
@@ -0,0 +1,79 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* 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.
*/
#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;
SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));
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");
}
@@ -0,0 +1,60 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* 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 privileged and the kernel emulates them
* for us. Instructions using problem state SPR can be executed
* 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.
*/
#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;
SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));
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");
}
@@ -0,0 +1 @@
timeout=130