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

fork_cleanup_test.c (1545B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright 2014, Michael Ellerman, IBM Corp.
      4 */
      5
      6#include <signal.h>
      7#include <stdio.h>
      8#include <stdlib.h>
      9#include <stdbool.h>
     10#include <sys/types.h>
     11#include <sys/wait.h>
     12#include <unistd.h>
     13#include <setjmp.h>
     14
     15#include "ebb.h"
     16
     17
     18/*
     19 * Test that a fork clears the PMU state of the child. eg. BESCR/EBBHR/EBBRR
     20 * are cleared, and MMCR0_PMCC is reset, preventing the child from accessing
     21 * the PMU.
     22 */
     23
     24static struct event event;
     25
     26static int child(void)
     27{
     28	/* Even though we have EBE=0 we can still see the EBB regs */
     29	FAIL_IF(mfspr(SPRN_BESCR) != 0);
     30	FAIL_IF(mfspr(SPRN_EBBHR) != 0);
     31	FAIL_IF(mfspr(SPRN_EBBRR) != 0);
     32
     33	FAIL_IF(catch_sigill(write_pmc1));
     34
     35	/* We can still read from the event, though it is on our parent */
     36	FAIL_IF(event_read(&event));
     37
     38	return 0;
     39}
     40
     41/* Tests that fork clears EBB state */
     42int fork_cleanup(void)
     43{
     44	pid_t pid;
     45
     46	SKIP_IF(!ebb_is_supported());
     47
     48	event_init_named(&event, 0x1001e, "cycles");
     49	event_leader_ebb_init(&event);
     50
     51	FAIL_IF(event_open(&event));
     52
     53	ebb_enable_pmc_counting(1);
     54	setup_ebb_handler(standard_ebb_callee);
     55	ebb_global_enable();
     56
     57	FAIL_IF(ebb_event_enable(&event));
     58
     59	mtspr(SPRN_MMCR0, MMCR0_FC);
     60	mtspr(SPRN_PMC1, pmc_sample_period(sample_period));
     61
     62	/* Don't need to actually take any EBBs */
     63
     64	pid = fork();
     65	if (pid == 0)
     66		exit(child());
     67
     68	/* Child does the actual testing */
     69	FAIL_IF(wait_for_child(pid));
     70
     71	/* After fork */
     72	event_close(&event);
     73
     74	return 0;
     75}
     76
     77int main(void)
     78{
     79	return test_harness(fork_cleanup, "fork_cleanup");
     80}