Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * POWER Data Stream Control Register (DSCR) fork test
0004  *
0005  * This testcase modifies the DSCR using mtspr, forks and then
0006  * verifies that the child process has the correct changed DSCR
0007  * value using mfspr.
0008  *
0009  * When using the privilege state SPR, the instructions such as
0010  * mfspr or mtspr are priviledged and the kernel emulates them
0011  * for us. Instructions using problem state SPR can be exuecuted
0012  * directly without any emulation if the HW supports them. Else
0013  * they also get emulated by the kernel.
0014  *
0015  * Copyright 2012, Anton Blanchard, IBM Corporation.
0016  * Copyright 2015, Anshuman Khandual, IBM Corporation.
0017  */
0018 #include "dscr.h"
0019 
0020 int dscr_inherit(void)
0021 {
0022     unsigned long i, dscr = 0;
0023     pid_t pid;
0024 
0025     SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));
0026 
0027     srand(getpid());
0028     set_dscr(dscr);
0029 
0030     for (i = 0; i < COUNT; i++) {
0031         unsigned long cur_dscr, cur_dscr_usr;
0032 
0033         dscr++;
0034         if (dscr > DSCR_MAX)
0035             dscr = 0;
0036 
0037         if (i % 2 == 0)
0038             set_dscr_usr(dscr);
0039         else
0040             set_dscr(dscr);
0041 
0042         pid = fork();
0043         if (pid == -1) {
0044             perror("fork() failed");
0045             exit(1);
0046         } else if (pid) {
0047             int status;
0048 
0049             if (waitpid(pid, &status, 0) == -1) {
0050                 perror("waitpid() failed");
0051                 exit(1);
0052             }
0053 
0054             if (!WIFEXITED(status)) {
0055                 fprintf(stderr, "Child didn't exit cleanly\n");
0056                 exit(1);
0057             }
0058 
0059             if (WEXITSTATUS(status) != 0) {
0060                 fprintf(stderr, "Child didn't exit cleanly\n");
0061                 return 1;
0062             }
0063         } else {
0064             cur_dscr = get_dscr();
0065             if (cur_dscr != dscr) {
0066                 fprintf(stderr, "Kernel DSCR should be %ld "
0067                     "but is %ld\n", dscr, cur_dscr);
0068                 exit(1);
0069             }
0070 
0071             cur_dscr_usr = get_dscr_usr();
0072             if (cur_dscr_usr != dscr) {
0073                 fprintf(stderr, "User DSCR should be %ld "
0074                     "but is %ld\n", dscr, cur_dscr_usr);
0075                 exit(1);
0076             }
0077             exit(0);
0078         }
0079     }
0080     return 0;
0081 }
0082 
0083 int main(int argc, char *argv[])
0084 {
0085     return test_harness(dscr_inherit, "dscr_inherit_test");
0086 }