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