xref: /linux/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
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