87 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * POWER Data Stream Control Register (DSCR) fork test4 *5 * This testcase modifies the DSCR using mtspr, forks and then6 * verifies that the child process has the correct changed DSCR7 * value using mfspr.8 *9 * When using the privilege state SPR, the instructions such as10 * mfspr or mtspr are privileged and the kernel emulates them11 * for us. Instructions using problem state SPR can be executed12 * directly without any emulation if the HW supports them. Else13 * 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 else40 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