Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * POWER Data Stream Control Register (DSCR) fork exec test
0004  *
0005  * This testcase modifies the DSCR using mtspr, forks & execs and
0006  * verifies that the child is using the changed DSCR using mfspr.
0007  *
0008  * When using the privilege state SPR, the instructions such as
0009  * mfspr or mtspr are privileged and the kernel emulates them
0010  * for us. Instructions using problem state SPR can be executed
0011  * directly without any emulation if the HW supports them. Else
0012  * they also get emulated by the kernel.
0013  *
0014  * Copyright 2012, Anton Blanchard, IBM Corporation.
0015  * Copyright 2015, Anshuman Khandual, IBM Corporation.
0016  */
0017 #include "dscr.h"
0018 
0019 static char *prog;
0020 
0021 static void do_exec(unsigned long parent_dscr)
0022 {
0023     unsigned long cur_dscr, cur_dscr_usr;
0024 
0025     cur_dscr = get_dscr();
0026     cur_dscr_usr = get_dscr_usr();
0027 
0028     if (cur_dscr != parent_dscr) {
0029         fprintf(stderr, "Parent DSCR %ld was not inherited "
0030                 "over exec (kernel value)\n", parent_dscr);
0031         exit(1);
0032     }
0033 
0034     if (cur_dscr_usr != parent_dscr) {
0035         fprintf(stderr, "Parent DSCR %ld was not inherited "
0036                 "over exec (user value)\n", parent_dscr);
0037         exit(1);
0038     }
0039     exit(0);
0040 }
0041 
0042 int dscr_inherit_exec(void)
0043 {
0044     unsigned long i, dscr = 0;
0045     pid_t pid;
0046 
0047     SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));
0048 
0049     for (i = 0; i < COUNT; i++) {
0050         dscr++;
0051         if (dscr > DSCR_MAX)
0052             dscr = 0;
0053 
0054         if (dscr == get_default_dscr())
0055             continue;
0056 
0057         if (i % 2 == 0)
0058             set_dscr_usr(dscr);
0059         else
0060             set_dscr(dscr);
0061 
0062         pid = fork();
0063         if (pid == -1) {
0064             perror("fork() failed");
0065             exit(1);
0066         } else if (pid) {
0067             int status;
0068 
0069             if (waitpid(pid, &status, 0) == -1) {
0070                 perror("waitpid() failed");
0071                 exit(1);
0072             }
0073 
0074             if (!WIFEXITED(status)) {
0075                 fprintf(stderr, "Child didn't exit cleanly\n");
0076                 exit(1);
0077             }
0078 
0079             if (WEXITSTATUS(status) != 0) {
0080                 fprintf(stderr, "Child didn't exit cleanly\n");
0081                 return 1;
0082             }
0083         } else {
0084             char dscr_str[16];
0085 
0086             sprintf(dscr_str, "%ld", dscr);
0087             execlp(prog, prog, "exec", dscr_str, NULL);
0088             exit(1);
0089         }
0090     }
0091     return 0;
0092 }
0093 
0094 int main(int argc, char *argv[])
0095 {
0096     if (argc == 3 && !strcmp(argv[1], "exec")) {
0097         unsigned long parent_dscr;
0098 
0099         parent_dscr = atoi(argv[2]);
0100         do_exec(parent_dscr);
0101     } else if (argc != 1) {
0102         fprintf(stderr, "Usage: %s\n", argv[0]);
0103         exit(1);
0104     }
0105 
0106     prog = argv[0];
0107     return test_harness(dscr_inherit_exec, "dscr_inherit_exec_test");
0108 }