0001
0002
0003
0004
0005
0006
0007 #define __SANE_USERSPACE_TYPES__
0008
0009 #include <sys/types.h>
0010 #include <stdint.h>
0011 #include <unistd.h>
0012 #include <signal.h>
0013 #include <stdlib.h>
0014 #include <string.h>
0015 #include <stdio.h>
0016 #include <sys/utsname.h>
0017 #include "utils.h"
0018 #include "flush_utils.h"
0019
0020 static inline __u64 load(void *addr)
0021 {
0022 __u64 tmp;
0023
0024 asm volatile("ld %0,0(%1)" : "=r"(tmp) : "b"(addr));
0025
0026 return tmp;
0027 }
0028
0029 void syscall_loop(char *p, unsigned long iterations,
0030 unsigned long zero_size)
0031 {
0032 for (unsigned long i = 0; i < iterations; i++) {
0033 for (unsigned long j = 0; j < zero_size; j += CACHELINE_SIZE)
0034 load(p + j);
0035 getppid();
0036 }
0037 }
0038
0039 void syscall_loop_uaccess(char *p, unsigned long iterations,
0040 unsigned long zero_size)
0041 {
0042 struct utsname utsname;
0043
0044 for (unsigned long i = 0; i < iterations; i++) {
0045 for (unsigned long j = 0; j < zero_size; j += CACHELINE_SIZE)
0046 load(p + j);
0047 uname(&utsname);
0048 }
0049 }
0050
0051 static void sigill_handler(int signr, siginfo_t *info, void *unused)
0052 {
0053 static int warned;
0054 ucontext_t *ctx = (ucontext_t *)unused;
0055 unsigned long *pc = &UCONTEXT_NIA(ctx);
0056
0057
0058 if ((*((unsigned int *)*pc) & 0xfc1fffff) == 0x7c0303a6) {
0059 if (!warned++)
0060 printf("WARNING: Skipping over dscr setup. Consider running 'ppc64_cpu --dscr=1' manually.\n");
0061 *pc += 4;
0062 } else {
0063 printf("SIGILL at %p\n", pc);
0064 abort();
0065 }
0066 }
0067
0068 void set_dscr(unsigned long val)
0069 {
0070 static int init;
0071 struct sigaction sa;
0072
0073 if (!init) {
0074 memset(&sa, 0, sizeof(sa));
0075 sa.sa_sigaction = sigill_handler;
0076 sa.sa_flags = SA_SIGINFO;
0077 if (sigaction(SIGILL, &sa, NULL))
0078 perror("sigill_handler");
0079 init = 1;
0080 }
0081
0082 asm volatile("mtspr %1,%0" : : "r" (val), "i" (SPRN_DSCR));
0083 }