root/tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. do_exec
  2. dscr_inherit_exec
  3. main

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * POWER Data Stream Control Register (DSCR) fork exec test
   4  *
   5  * This testcase modifies the DSCR using mtspr, forks & execs and
   6  * verifies that the child is using the changed DSCR using mfspr.
   7  *
   8  * When using the privilege state SPR, the instructions such as
   9  * mfspr or mtspr are privileged and the kernel emulates them
  10  * for us. Instructions using problem state SPR can be executed
  11  * directly without any emulation if the HW supports them. Else
  12  * they also get emulated by the kernel.
  13  *
  14  * Copyright 2012, Anton Blanchard, IBM Corporation.
  15  * Copyright 2015, Anshuman Khandual, IBM Corporation.
  16  */
  17 #include "dscr.h"
  18 
  19 static char *prog;
  20 
  21 static void do_exec(unsigned long parent_dscr)
  22 {
  23         unsigned long cur_dscr, cur_dscr_usr;
  24 
  25         cur_dscr = get_dscr();
  26         cur_dscr_usr = get_dscr_usr();
  27 
  28         if (cur_dscr != parent_dscr) {
  29                 fprintf(stderr, "Parent DSCR %ld was not inherited "
  30                                 "over exec (kernel value)\n", parent_dscr);
  31                 exit(1);
  32         }
  33 
  34         if (cur_dscr_usr != parent_dscr) {
  35                 fprintf(stderr, "Parent DSCR %ld was not inherited "
  36                                 "over exec (user value)\n", parent_dscr);
  37                 exit(1);
  38         }
  39         exit(0);
  40 }
  41 
  42 int dscr_inherit_exec(void)
  43 {
  44         unsigned long i, dscr = 0;
  45         pid_t pid;
  46 
  47         for (i = 0; i < COUNT; i++) {
  48                 dscr++;
  49                 if (dscr > DSCR_MAX)
  50                         dscr = 0;
  51 
  52                 if (dscr == get_default_dscr())
  53                         continue;
  54 
  55                 if (i % 2 == 0)
  56                         set_dscr_usr(dscr);
  57                 else
  58                         set_dscr(dscr);
  59 
  60                 pid = fork();
  61                 if (pid == -1) {
  62                         perror("fork() failed");
  63                         exit(1);
  64                 } else if (pid) {
  65                         int status;
  66 
  67                         if (waitpid(pid, &status, 0) == -1) {
  68                                 perror("waitpid() failed");
  69                                 exit(1);
  70                         }
  71 
  72                         if (!WIFEXITED(status)) {
  73                                 fprintf(stderr, "Child didn't exit cleanly\n");
  74                                 exit(1);
  75                         }
  76 
  77                         if (WEXITSTATUS(status) != 0) {
  78                                 fprintf(stderr, "Child didn't exit cleanly\n");
  79                                 return 1;
  80                         }
  81                 } else {
  82                         char dscr_str[16];
  83 
  84                         sprintf(dscr_str, "%ld", dscr);
  85                         execlp(prog, prog, "exec", dscr_str, NULL);
  86                         exit(1);
  87                 }
  88         }
  89         return 0;
  90 }
  91 
  92 int main(int argc, char *argv[])
  93 {
  94         if (argc == 3 && !strcmp(argv[1], "exec")) {
  95                 unsigned long parent_dscr;
  96 
  97                 parent_dscr = atoi(argv[2]);
  98                 do_exec(parent_dscr);
  99         } else if (argc != 1) {
 100                 fprintf(stderr, "Usage: %s\n", argv[0]);
 101                 exit(1);
 102         }
 103 
 104         prog = argv[0];
 105         return test_harness(dscr_inherit_exec, "dscr_inherit_exec_test");
 106 }

/* [<][>][^][v][top][bottom][index][help] */