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        SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));
  26
  27        srand(getpid());
  28        set_dscr(dscr);
  29
  30        for (i = 0; i < COUNT; i++) {
  31                unsigned long cur_dscr, cur_dscr_usr;
  32
  33                dscr++;
  34                if (dscr > DSCR_MAX)
  35                        dscr = 0;
  36
  37                if (i % 2 == 0)
  38                        set_dscr_usr(dscr);
  39                else
  40                        set_dscr(dscr);
  41
  42                pid = fork();
  43                if (pid == -1) {
  44                        perror("fork() failed");
  45                        exit(1);
  46                } else if (pid) {
  47                        int status;
  48
  49                        if (waitpid(pid, &status, 0) == -1) {
  50                                perror("waitpid() failed");
  51                                exit(1);
  52                        }
  53
  54                        if (!WIFEXITED(status)) {
  55                                fprintf(stderr, "Child didn't exit cleanly\n");
  56                                exit(1);
  57                        }
  58
  59                        if (WEXITSTATUS(status) != 0) {
  60                                fprintf(stderr, "Child didn't exit cleanly\n");
  61                                return 1;
  62                        }
  63                } else {
  64                        cur_dscr = get_dscr();
  65                        if (cur_dscr != dscr) {
  66                                fprintf(stderr, "Kernel DSCR should be %ld "
  67                                        "but is %ld\n", dscr, cur_dscr);
  68                                exit(1);
  69                        }
  70
  71                        cur_dscr_usr = get_dscr_usr();
  72                        if (cur_dscr_usr != dscr) {
  73                                fprintf(stderr, "User DSCR should be %ld "
  74                                        "but is %ld\n", dscr, cur_dscr_usr);
  75                                exit(1);
  76                        }
  77                        exit(0);
  78                }
  79        }
  80        return 0;
  81}
  82
  83int main(int argc, char *argv[])
  84{
  85        return test_harness(dscr_inherit, "dscr_inherit_test");
  86}
  87