Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright 2014, Michael Ellerman, IBM Corp.
0004  */
0005 
0006 #include <signal.h>
0007 #include <stdio.h>
0008 #include <stdlib.h>
0009 #include <stdbool.h>
0010 #include <sys/types.h>
0011 #include <sys/wait.h>
0012 #include <unistd.h>
0013 #include <setjmp.h>
0014 
0015 #include "ebb.h"
0016 
0017 
0018 /*
0019  * Test that a fork clears the PMU state of the child. eg. BESCR/EBBHR/EBBRR
0020  * are cleared, and MMCR0_PMCC is reset, preventing the child from accessing
0021  * the PMU.
0022  */
0023 
0024 static struct event event;
0025 
0026 static int child(void)
0027 {
0028     /* Even though we have EBE=0 we can still see the EBB regs */
0029     FAIL_IF(mfspr(SPRN_BESCR) != 0);
0030     FAIL_IF(mfspr(SPRN_EBBHR) != 0);
0031     FAIL_IF(mfspr(SPRN_EBBRR) != 0);
0032 
0033     FAIL_IF(catch_sigill(write_pmc1));
0034 
0035     /* We can still read from the event, though it is on our parent */
0036     FAIL_IF(event_read(&event));
0037 
0038     return 0;
0039 }
0040 
0041 /* Tests that fork clears EBB state */
0042 int fork_cleanup(void)
0043 {
0044     pid_t pid;
0045 
0046     SKIP_IF(!ebb_is_supported());
0047 
0048     event_init_named(&event, 0x1001e, "cycles");
0049     event_leader_ebb_init(&event);
0050 
0051     FAIL_IF(event_open(&event));
0052 
0053     ebb_enable_pmc_counting(1);
0054     setup_ebb_handler(standard_ebb_callee);
0055     ebb_global_enable();
0056 
0057     FAIL_IF(ebb_event_enable(&event));
0058 
0059     mtspr(SPRN_MMCR0, MMCR0_FC);
0060     mtspr(SPRN_PMC1, pmc_sample_period(sample_period));
0061 
0062     /* Don't need to actually take any EBBs */
0063 
0064     pid = fork();
0065     if (pid == 0)
0066         exit(child());
0067 
0068     /* Child does the actual testing */
0069     FAIL_IF(wait_for_child(pid));
0070 
0071     /* After fork */
0072     event_close(&event);
0073 
0074     return 0;
0075 }
0076 
0077 int main(void)
0078 {
0079     return test_harness(fork_cleanup, "fork_cleanup");
0080 }