xref: /linux/tools/testing/selftests/powerpc/security/flush_utils.c (revision 954ea91fb68b771dba6d87cfa61b68e09cc2497f)
1  // SPDX-License-Identifier: GPL-2.0+
2  
3  /*
4   * Copyright 2018 IBM Corporation.
5   */
6  
7  #define __SANE_USERSPACE_TYPES__
8  
9  #include <sys/types.h>
10  #include <stdint.h>
11  #include <unistd.h>
12  #include <signal.h>
13  #include <stdlib.h>
14  #include <string.h>
15  #include <stdio.h>
16  #include <sys/utsname.h>
17  #include "reg.h"
18  #include "utils.h"
19  #include "flush_utils.h"
20  
21  static inline __u64 load(void *addr)
22  {
23  	__u64 tmp;
24  
25  	asm volatile("ld %0,0(%1)" : "=r"(tmp) : "b"(addr));
26  
27  	return tmp;
28  }
29  
30  void syscall_loop(char *p, unsigned long iterations,
31  		  unsigned long zero_size)
32  {
33  	for (unsigned long i = 0; i < iterations; i++) {
34  		for (unsigned long j = 0; j < zero_size; j += CACHELINE_SIZE)
35  			load(p + j);
36  		getppid();
37  	}
38  }
39  
40  void syscall_loop_uaccess(char *p, unsigned long iterations,
41  			  unsigned long zero_size)
42  {
43  	struct utsname utsname;
44  
45  	for (unsigned long i = 0; i < iterations; i++) {
46  		for (unsigned long j = 0; j < zero_size; j += CACHELINE_SIZE)
47  			load(p + j);
48  		uname(&utsname);
49  	}
50  }
51  
52  static void sigill_handler(int signr, siginfo_t *info, void *unused)
53  {
54  	static int warned;
55  	ucontext_t *ctx = (ucontext_t *)unused;
56  	unsigned long *pc = &UCONTEXT_NIA(ctx);
57  
58  	/* mtspr 3,RS to check for move to DSCR below */
59  	if ((*((unsigned int *)*pc) & 0xfc1fffff) == 0x7c0303a6) {
60  		if (!warned++)
61  			printf("WARNING: Skipping over dscr setup. Consider running 'ppc64_cpu --dscr=1' manually.\n");
62  		*pc += 4;
63  	} else {
64  		printf("SIGILL at %p\n", pc);
65  		abort();
66  	}
67  }
68  
69  void set_dscr(unsigned long val)
70  {
71  	static int init;
72  	struct sigaction sa;
73  
74  	if (!init) {
75  		memset(&sa, 0, sizeof(sa));
76  		sa.sa_sigaction = sigill_handler;
77  		sa.sa_flags = SA_SIGINFO;
78  		if (sigaction(SIGILL, &sa, NULL))
79  			perror("sigill_handler");
80  		init = 1;
81  	}
82  
83  	mtspr(SPRN_DSCR, val);
84  }
85