| // 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); | |
| } |