| // SPDX-License-Identifier: GPL-2.0+ |
| |
| /* |
| * Copyright 2018 IBM Corporation. |
| */ |
| |
| #define __SANE_USERSPACE_TYPES__ |
| |
| #include <sys/types.h> |
| #include <stdint.h> |
| #include <unistd.h> |
| #include <signal.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <stdio.h> |
| #include <sys/utsname.h> |
| #include "reg.h" |
| #include "utils.h" |
| #include "flush_utils.h" |
| |
| static inline __u64 load(void *addr) |
| { |
| __u64 tmp; |
| |
| asm volatile("ld %0,0(%1)" : "=r"(tmp) : "b"(addr)); |
| |
| return tmp; |
| } |
| |
| void syscall_loop(char *p, unsigned long iterations, |
| unsigned long zero_size) |
| { |
| for (unsigned long i = 0; i < iterations; i++) { |
| for (unsigned long j = 0; j < zero_size; j += CACHELINE_SIZE) |
| load(p + j); |
| getppid(); |
| } |
| } |
| |
| void syscall_loop_uaccess(char *p, unsigned long iterations, |
| unsigned long zero_size) |
| { |
| struct utsname utsname; |
| |
| for (unsigned long i = 0; i < iterations; i++) { |
| for (unsigned long j = 0; j < zero_size; j += CACHELINE_SIZE) |
| load(p + j); |
| uname(&utsname); |
| } |
| } |
| |
| static void sigill_handler(int signr, siginfo_t *info, void *unused) |
| { |
| static int warned; |
| ucontext_t *ctx = (ucontext_t *)unused; |
| unsigned long *pc = &UCONTEXT_NIA(ctx); |
| |
| /* mtspr 3,RS to check for move to DSCR below */ |
| if ((*((unsigned int *)*pc) & 0xfc1fffff) == 0x7c0303a6) { |
| if (!warned++) |
| printf("WARNING: Skipping over dscr setup. Consider running 'ppc64_cpu --dscr=1' manually.\n"); |
| *pc += 4; |
| } else { |
| printf("SIGILL at %p\n", pc); |
| abort(); |
| } |
| } |
| |
| void set_dscr(unsigned long val) |
| { |
| static int init; |
| struct sigaction sa; |
| |
| if (!init) { |
| memset(&sa, 0, sizeof(sa)); |
| sa.sa_sigaction = sigill_handler; |
| sa.sa_flags = SA_SIGINFO; |
| if (sigaction(SIGILL, &sa, NULL)) |
| perror("sigill_handler"); |
| init = 1; |
| } |
| |
| mtspr(SPRN_DSCR, val); |
| } |