linux/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * POWER Data Stream Control Register (DSCR) fork test
   4 *
   5 * This testcase modifies the DSCR using mtspr, forks and then
   6 * verifies that the child process has the correct changed DSCR
   7 * value using mfspr.
   8 *
   9 * When using the privilege state SPR, the instructions such as
  10 * mfspr or mtspr are priviledged and the kernel emulates them
  11 * for us. Instructions using problem state SPR can be exuecuted
  12 * directly without any emulation if the HW supports them. Else
  13 * they also get emulated by the kernel.
  14 *
  15 * Copyright 2012, Anton Blanchard, IBM Corporation.
  16 * Copyright 2015, Anshuman Khandual, IBM Corporation.
  17 */
  18#include "dscr.h"
  19
  20int dscr_inherit(void)
  21{
  22        unsigned long i, dscr = 0;
  23        pid_t pid;
  24
  25        srand(getpid());
  26        set_dscr(dscr);
  27
  28        for (i = 0; i < COUNT; i++) {
  29                unsigned long cur_dscr, cur_dscr_usr;
  30
  31                dscr++;
  32                if (dscr > DSCR_MAX)
  33                        dscr = 0;
  34
  35                if (i % 2 == 0)
  36                        set_dscr_usr(dscr);
  37                else
  38                        set_dscr(dscr);
  39
  40                pid = fork();
  41                if (pid == -1) {
  42                        perror("fork() failed");
  43                        exit(1);
  44                } else if (pid) {
  45                        int status;
  46
  47                        if (waitpid(pid, &status, 0) == -1) {
  48                                perror("waitpid() failed");
  49                                exit(1);
  50                        }
  51
  52                        if (!WIFEXITED(status)) {
  53                                fprintf(stderr, "Child didn't exit cleanly\n");
  54                                exit(1);
  55                        }
  56
  57                        if (WEXITSTATUS(status) != 0) {
  58                                fprintf(stderr, "Child didn't exit cleanly\n");
  59                                return 1;
  60                        }
  61                } else {
  62                        cur_dscr = get_dscr();
  63                        if (cur_dscr != dscr) {
  64                                fprintf(stderr, "Kernel DSCR should be %ld "
  65                                        "but is %ld\n", dscr, cur_dscr);
  66                                exit(1);
  67                        }
  68
  69                        cur_dscr_usr = get_dscr_usr();
  70                        if (cur_dscr_usr != dscr) {
  71                                fprintf(stderr, "User DSCR should be %ld "
  72                                        "but is %ld\n", dscr, cur_dscr_usr);
  73                                exit(1);
  74                        }
  75                        exit(0);
  76                }
  77        }
  78        return 0;
  79}
  80
  81int main(int argc, char *argv[])
  82{
  83        return test_harness(dscr_inherit, "dscr_inherit_test");
  84}
  85