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