1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2cf9c4a5eSAnshuman Khandual /*
3cf9c4a5eSAnshuman Khandual * POWER Data Stream Control Register (DSCR) fork test
4cf9c4a5eSAnshuman Khandual *
5cf9c4a5eSAnshuman Khandual * This testcase modifies the DSCR using mtspr, forks and then
6cf9c4a5eSAnshuman Khandual * verifies that the child process has the correct changed DSCR
7cf9c4a5eSAnshuman Khandual * value using mfspr.
8cf9c4a5eSAnshuman Khandual *
9cf9c4a5eSAnshuman Khandual * When using the privilege state SPR, the instructions such as
10*15f0c260SBenjamin Gray * mfspr or mtspr are privileged and the kernel emulates them
11*15f0c260SBenjamin Gray * for us. Instructions using problem state SPR can be executed
12cf9c4a5eSAnshuman Khandual * directly without any emulation if the HW supports them. Else
13cf9c4a5eSAnshuman Khandual * they also get emulated by the kernel.
14cf9c4a5eSAnshuman Khandual *
15cf9c4a5eSAnshuman Khandual * Copyright 2012, Anton Blanchard, IBM Corporation.
16cf9c4a5eSAnshuman Khandual * Copyright 2015, Anshuman Khandual, IBM Corporation.
17cf9c4a5eSAnshuman Khandual */
18cf9c4a5eSAnshuman Khandual #include "dscr.h"
19cf9c4a5eSAnshuman Khandual
dscr_inherit(void)20cf9c4a5eSAnshuman Khandual int dscr_inherit(void)
21cf9c4a5eSAnshuman Khandual {
22cf9c4a5eSAnshuman Khandual unsigned long i, dscr = 0;
23cf9c4a5eSAnshuman Khandual pid_t pid;
24cf9c4a5eSAnshuman Khandual
254c3c3c50SMichael Ellerman SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));
264c3c3c50SMichael Ellerman
27cf9c4a5eSAnshuman Khandual srand(getpid());
28cf9c4a5eSAnshuman Khandual set_dscr(dscr);
29cf9c4a5eSAnshuman Khandual
30cf9c4a5eSAnshuman Khandual for (i = 0; i < COUNT; i++) {
31cf9c4a5eSAnshuman Khandual unsigned long cur_dscr, cur_dscr_usr;
32cf9c4a5eSAnshuman Khandual
33cf9c4a5eSAnshuman Khandual dscr++;
34cf9c4a5eSAnshuman Khandual if (dscr > DSCR_MAX)
35cf9c4a5eSAnshuman Khandual dscr = 0;
36cf9c4a5eSAnshuman Khandual
37cf9c4a5eSAnshuman Khandual if (i % 2 == 0)
38cf9c4a5eSAnshuman Khandual set_dscr_usr(dscr);
39cf9c4a5eSAnshuman Khandual else
40cf9c4a5eSAnshuman Khandual set_dscr(dscr);
41cf9c4a5eSAnshuman Khandual
42cf9c4a5eSAnshuman Khandual pid = fork();
43cf9c4a5eSAnshuman Khandual if (pid == -1) {
44cf9c4a5eSAnshuman Khandual perror("fork() failed");
45cf9c4a5eSAnshuman Khandual exit(1);
46cf9c4a5eSAnshuman Khandual } else if (pid) {
47cf9c4a5eSAnshuman Khandual int status;
48cf9c4a5eSAnshuman Khandual
49cf9c4a5eSAnshuman Khandual if (waitpid(pid, &status, 0) == -1) {
50cf9c4a5eSAnshuman Khandual perror("waitpid() failed");
51cf9c4a5eSAnshuman Khandual exit(1);
52cf9c4a5eSAnshuman Khandual }
53cf9c4a5eSAnshuman Khandual
54cf9c4a5eSAnshuman Khandual if (!WIFEXITED(status)) {
55cf9c4a5eSAnshuman Khandual fprintf(stderr, "Child didn't exit cleanly\n");
56cf9c4a5eSAnshuman Khandual exit(1);
57cf9c4a5eSAnshuman Khandual }
58cf9c4a5eSAnshuman Khandual
59cf9c4a5eSAnshuman Khandual if (WEXITSTATUS(status) != 0) {
60cf9c4a5eSAnshuman Khandual fprintf(stderr, "Child didn't exit cleanly\n");
61cf9c4a5eSAnshuman Khandual return 1;
62cf9c4a5eSAnshuman Khandual }
63cf9c4a5eSAnshuman Khandual } else {
64cf9c4a5eSAnshuman Khandual cur_dscr = get_dscr();
65cf9c4a5eSAnshuman Khandual if (cur_dscr != dscr) {
66cf9c4a5eSAnshuman Khandual fprintf(stderr, "Kernel DSCR should be %ld "
67cf9c4a5eSAnshuman Khandual "but is %ld\n", dscr, cur_dscr);
68cf9c4a5eSAnshuman Khandual exit(1);
69cf9c4a5eSAnshuman Khandual }
70cf9c4a5eSAnshuman Khandual
71cf9c4a5eSAnshuman Khandual cur_dscr_usr = get_dscr_usr();
72cf9c4a5eSAnshuman Khandual if (cur_dscr_usr != dscr) {
73cf9c4a5eSAnshuman Khandual fprintf(stderr, "User DSCR should be %ld "
74cf9c4a5eSAnshuman Khandual "but is %ld\n", dscr, cur_dscr_usr);
75cf9c4a5eSAnshuman Khandual exit(1);
76cf9c4a5eSAnshuman Khandual }
77cf9c4a5eSAnshuman Khandual exit(0);
78cf9c4a5eSAnshuman Khandual }
79cf9c4a5eSAnshuman Khandual }
80cf9c4a5eSAnshuman Khandual return 0;
81cf9c4a5eSAnshuman Khandual }
82cf9c4a5eSAnshuman Khandual
main(int argc,char * argv[])83cf9c4a5eSAnshuman Khandual int main(int argc, char *argv[])
84cf9c4a5eSAnshuman Khandual {
85cf9c4a5eSAnshuman Khandual return test_harness(dscr_inherit, "dscr_inherit_test");
86cf9c4a5eSAnshuman Khandual }
87