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 19static 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 28void 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 38static 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 55void 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