cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dscr_inherit_test.c (1896B)


      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}