Home | History | Annotate | Download | only in dscr
      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 
     23 int 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 
     84 int main(int argc, char *argv[])
     85 {
     86 	return test_harness(dscr_inherit, "dscr_inherit_test");
     87 }
     88