brintos

brintos / linux-shallow public Read only

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