linux/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c
<<
>>
Prefs
   1/*
   2 * POWER Data Stream Control Register (DSCR) fork test
   3 *
   4 * This testcase modifies the DSCR using mtspr, forks and then
   5 * verifies that the child process has the correct changed DSCR
   6 * value using mfspr.
   7 *
   8 * When using the privilege state SPR, the instructions such as
   9 * mfspr or mtspr are priviledged and the kernel emulates them
  10 * for us. Instructions using problem state SPR can be exuecuted
  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 * This program is free software; you can redistribute it and/or modify it
  18 * under the terms of the GNU General Public License version 2 as published
  19 * by the Free Software Foundation.
  20 */
  21#include "dscr.h"
  22
  23int dscr_inherit(void)
  24{
  25        unsigned long i, dscr = 0;
  26        pid_t pid;
  27
  28        srand(getpid());
  29        set_dscr(dscr);
  30
  31        for (i = 0; i < COUNT; i++) {
  32                unsigned long cur_dscr, cur_dscr_usr;
  33
  34                dscr++;
  35                if (dscr > DSCR_MAX)
  36                        dscr = 0;
  37
  38                if (i % 2 == 0)
  39                        set_dscr_usr(dscr);
  40                else
  41                        set_dscr(dscr);
  42
  43                pid = fork();
  44                if (pid == -1) {
  45                        perror("fork() failed");
  46                        exit(1);
  47                } else if (pid) {
  48                        int status;
  49
  50                        if (waitpid(pid, &status, 0) == -1) {
  51                                perror("waitpid() failed");
  52                                exit(1);
  53                        }
  54
  55                        if (!WIFEXITED(status)) {
  56                                fprintf(stderr, "Child didn't exit cleanly\n");
  57                                exit(1);
  58                        }
  59
  60                        if (WEXITSTATUS(status) != 0) {
  61                                fprintf(stderr, "Child didn't exit cleanly\n");
  62                                return 1;
  63                        }
  64                } else {
  65                        cur_dscr = get_dscr();
  66                        if (cur_dscr != dscr) {
  67                                fprintf(stderr, "Kernel DSCR should be %ld "
  68                                        "but is %ld\n", dscr, cur_dscr);
  69                                exit(1);
  70                        }
  71
  72                        cur_dscr_usr = get_dscr_usr();
  73                        if (cur_dscr_usr != dscr) {
  74                                fprintf(stderr, "User DSCR should be %ld "
  75                                        "but is %ld\n", dscr, cur_dscr_usr);
  76                                exit(1);
  77                        }
  78                        exit(0);
  79                }
  80        }
  81        return 0;
  82}
  83
  84int main(int argc, char *argv[])
  85{
  86        return test_harness(dscr_inherit, "dscr_inherit_test");
  87}
  88