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