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 "utils.h" 18 #include "flush_utils.h" 19 20 static inline __u64 load(void *addr) 21 { 22 __u64 tmp; 23 24 asm volatile("ld %0,0(%1)" : "=r"(tmp) : "b"(addr)); 25 26 return tmp; 27 } 28 29 void syscall_loop(char *p, unsigned long iterations, 30 unsigned long zero_size) 31 { 32 for (unsigned long i = 0; i < iterations; i++) { 33 for (unsigned long j = 0; j < zero_size; j += CACHELINE_SIZE) 34 load(p + j); 35 getppid(); 36 } 37 } 38 39 void syscall_loop_uaccess(char *p, unsigned long iterations, 40 unsigned long zero_size) 41 { 42 struct utsname utsname; 43 44 for (unsigned long i = 0; i < iterations; i++) { 45 for (unsigned long j = 0; j < zero_size; j += CACHELINE_SIZE) 46 load(p + j); 47 uname(&utsname); 48 } 49 } 50 51 static void sigill_handler(int signr, siginfo_t *info, void *unused) 52 { 53 static int warned; 54 ucontext_t *ctx = (ucontext_t *)unused; 55 unsigned long *pc = &UCONTEXT_NIA(ctx); 56 57 /* mtspr 3,RS to check for move to DSCR below */ 58 if ((*((unsigned int *)*pc) & 0xfc1fffff) == 0x7c0303a6) { 59 if (!warned++) 60 printf("WARNING: Skipping over dscr setup. Consider running 'ppc64_cpu --dscr=1' manually.\n"); 61 *pc += 4; 62 } else { 63 printf("SIGILL at %p\n", pc); 64 abort(); 65 } 66 } 67 68 void set_dscr(unsigned long val) 69 { 70 static int init; 71 struct sigaction sa; 72 73 if (!init) { 74 memset(&sa, 0, sizeof(sa)); 75 sa.sa_sigaction = sigill_handler; 76 sa.sa_flags = SA_SIGINFO; 77 if (sigaction(SIGILL, &sa, NULL)) 78 perror("sigill_handler"); 79 init = 1; 80 } 81 82 asm volatile("mtspr %1,%0" : : "r" (val), "i" (SPRN_DSCR)); 83 } 84