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