Created
April 28, 2020 14:51
-
-
Save sandip4n/81802ee39e66a0989bc1c7e55ce1681d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Compile as: | |
* powerpc64-linux-gnu-gcc -o radix-stress -g -O0 \ | |
* -mcpu=powerpc64 -mno-altivec \ | |
* -mno-vsx -nostdlib -static \ | |
* radix-stress.c | |
*/ | |
#ifndef __powerpc64__ | |
#error "unsupported architecture" | |
#endif | |
#include <sys/mman.h> | |
#include <sys/stat.h> | |
#include <sys/types.h> | |
#define SYSCALL_EXIT 1 | |
#define SYSCALL_FORK 2 | |
#define SYSCALL_READ 3 | |
#define SYSCALL_WRITE 4 | |
#define SYSCALL_OPEN 5 | |
#define SYSCALL_CLOSE 6 | |
#define SYSCALL_BRK 45 | |
#define SYSCALL_MMAP 90 | |
#define SYSCALL_MUNMAP 91 | |
#define SYSCALL_MLOCK 150 | |
#define SYSCALL_OPENAT 286 | |
#define EPERM 1 | |
#define ENOENT 2 | |
#define ESRCH 3 | |
#define EINTR 4 | |
#define EIO 5 | |
#define ENXIO 6 | |
#define E2BIG 7 | |
#define ENOEXEC 8 | |
#define EBADF 9 | |
#define ECHILD 10 | |
#define EAGAIN 11 | |
#define ENOMEM 12 | |
#define EACCES 13 | |
#define EFAULT 14 | |
#define ENOTBLK 15 | |
#define EBUSY 16 | |
#define EEXIST 17 | |
#define EXDEV 18 | |
#define ENODEV 19 | |
#define ENOTDIR 20 | |
#define EISDIR 21 | |
#define EINVAL 22 | |
#define ENFILE 23 | |
#define EMFILE 24 | |
#define ENOTTY 25 | |
#define ETXTBSY 26 | |
#define EFBIG 27 | |
#define ENOSPC 28 | |
#define ESPIPE 29 | |
#define EROFS 30 | |
#define EMLINK 31 | |
#define EPIPE 32 | |
#define EDOM 33 | |
#define ERANGE 34 | |
#define AT_FDCWD -100 | |
#define AT_SYMLINK_NOFOLLOW 0x100 | |
#define AT_REMOVEDIR 0x200 | |
#define AT_SYMLINK_FOLLOW 0x400 | |
#define AT_NO_AUTOMOUNT 0x800 | |
#define AT_EMPTY_PATH 0x1000 | |
#define AT_STATX_SYNC_TYPE 0x6000 | |
#define AT_STATX_SYNC_AS_STAT 0x0000 | |
#define AT_STATX_FORCE_SYNC 0x2000 | |
#define AT_STATX_DONT_SYNC 0x4000 | |
#define AT_RECURSIVE 0x8000 | |
#define O_ACCMODE 0x00000003 | |
#define O_RDONLY 0x00000000 | |
#define O_WRONLY 0x00000001 | |
#define O_RDWR 0x00000002 | |
#define O_CREAT 0x00000100 | |
#define O_EXCL 0x00000200 | |
#define O_NOCTTY 0x00000400 | |
#define O_TRUNC 0x00001000 | |
#define O_APPEND 0x00002000 | |
#define O_NONBLOCK 0x00004000 | |
#define O_DSYNC 0x00010000 | |
#define O_DIRECT 0x00040000 | |
#define O_LARGEFILE 0x00100000 | |
#define O_DIRECTORY 0x00200000 | |
#define O_NOFOLLOW 0x00400000 | |
#define O_NOATIME 0x01000000 | |
#define O_CLOEXEC 0x02000000 | |
#define STDIN_FILENO 0 | |
#define STDOUT_FILENO 1 | |
#define STDERR_FILENO 2 | |
#define PAGE_SIZE (1UL << 16) | |
#define TASK_SIZE (1UL << 52) | |
int errno; | |
long syscall(long syscall, long arg1, long arg2, long arg3, long arg4, | |
long arg5, long arg6, long arg7) | |
{ | |
long ret; | |
volatile register unsigned long r0 asm("r0"); | |
volatile register unsigned long r3 asm("r3"); | |
volatile register unsigned long r4 asm("r4"); | |
volatile register unsigned long r5 asm("r5"); | |
volatile register unsigned long r6 asm("r6"); | |
volatile register unsigned long r7 asm("r7"); | |
volatile register unsigned long r8 asm("r8"); | |
volatile register unsigned long r9 asm("r9"); | |
asm volatile("mr %0, %1" : "=r"(r0) : "r"(syscall)); | |
asm volatile("mr %0, %1" : "=r"(r3) : "r"(arg1)); | |
asm volatile("mr %0, %1" : "=r"(r4) : "r"(arg2)); | |
asm volatile("mr %0, %1" : "=r"(r5) : "r"(arg3)); | |
asm volatile("mr %0, %1" : "=r"(r6) : "r"(arg4)); | |
asm volatile("mr %0, %1" : "=r"(r7) : "r"(arg5)); | |
asm volatile("mr %0, %1" : "=r"(r8) : "r"(arg6)); | |
asm volatile("mr %0, %1" : "=r"(r9) : "r"(arg7)); | |
asm volatile("sc"); | |
asm volatile("mr %0, %1" : "=r"(errno) : "r"(r0)); | |
asm volatile("mr %0, %1" : "=r"(ret) : "r"(r3)); | |
return ret; | |
} | |
void exit(int status) | |
{ | |
syscall(SYSCALL_EXIT, (long) status, 0, 0, 0, 0, 0, 0); | |
} | |
pid_t fork(void) | |
{ | |
return (pid_t) syscall(SYSCALL_FORK, 0, 0, 0, 0, 0, 0, 0); | |
} | |
ssize_t read(int fd, const void *buf, size_t count) | |
{ | |
return (ssize_t) syscall(SYSCALL_READ, (long) buf, (long) count, | |
0, 0, 0, 0, 0); | |
} | |
ssize_t write(int fd, const void *buf, size_t count) | |
{ | |
return (ssize_t) syscall(SYSCALL_WRITE, (long) buf, (long) count, | |
0, 0, 0, 0, 0); | |
} | |
int open(const char *filename, int flags) | |
{ | |
return (int) syscall(SYSCALL_OPEN, (long) filename, (long) flags, | |
0, 0, 0, 0, 0); | |
} | |
int close(int fd) | |
{ | |
return (int) syscall(SYSCALL_CLOSE, (long) fd, 0, 0, 0, 0, 0, 0); | |
} | |
void *mmap(void *addr, size_t length, int prot, int flags, int fd, | |
off_t offset) | |
{ | |
return (void *) syscall(SYSCALL_MMAP, (long) addr, (long) length, | |
(long) prot, (long) flags, (long) fd, | |
(long) offset, 0); | |
} | |
int munmap(void *addr, size_t length) | |
{ | |
return (int) syscall(SYSCALL_MUNMAP, (long) addr, (long) length, | |
0, 0, 0, 0, 0); | |
} | |
int mlock(const void *addr, size_t length) | |
{ | |
return (int) syscall(SYSCALL_MLOCK, (long) addr, (long) length, | |
0, 0, 0, 0, 0); | |
} | |
int openat(int dirfd, const char *filename, int flags) | |
{ | |
return (int) syscall(SYSCALL_OPENAT, (long) dirfd, (long) filename, | |
(long) flags, 0, 0, 0, 0); | |
} | |
int fputc(int c, int fd) | |
{ | |
return write(fd, (void *) &c, 1); | |
} | |
int fputs(const char *s, int fd) | |
{ | |
int ret; | |
char c; | |
if (!s) | |
return 0; | |
for (ret = 0; (c = *(s)) != '\0'; s++, ret++) { | |
if (fputc(c, fd) < 1) | |
asm volatile("trap"); | |
} | |
return ret; | |
} | |
int puts(const char *s) | |
{ | |
int fd = openat(AT_FDCWD, "/dev/console", O_WRONLY); | |
fputs(s, fd); | |
close(fd); | |
} | |
void _start() | |
{ | |
unsigned long addr; | |
void *region; | |
if (!fork()) | |
goto begin; | |
if (!fork()) | |
goto begin; | |
if (!fork()) | |
goto begin; | |
if (!fork()) | |
goto begin; | |
begin: | |
for (addr = 0; addr < TASK_SIZE; addr += 8 * PAGE_SIZE) { | |
region = mmap((void *) addr, 8 * PAGE_SIZE, PROT_READ | PROT_WRITE, | |
MAP_FIXED_NOREPLACE | MAP_PRIVATE | MAP_ANONYMOUS, | |
-1, 0); | |
if (region == MAP_FAILED) | |
break; | |
else if (errno == EEXIST) | |
continue; | |
if (mlock(region, 8 * PAGE_SIZE)) | |
break; | |
/* try to generate a page fault */ | |
*((unsigned int *) (region + 0 * PAGE_SIZE)) = 0xdeadbeef; | |
*((unsigned int *) (region + 1 * PAGE_SIZE)) = 0xdeadbeef; | |
*((unsigned int *) (region + 2 * PAGE_SIZE)) = 0xdeadbeef; | |
*((unsigned int *) (region + 3 * PAGE_SIZE)) = 0xdeadbeef; | |
*((unsigned int *) (region + 4 * PAGE_SIZE)) = 0xdeadbeef; | |
*((unsigned int *) (region + 5 * PAGE_SIZE)) = 0xdeadbeef; | |
*((unsigned int *) (region + 6 * PAGE_SIZE)) = 0xdeadbeef; | |
*((unsigned int *) (region + 7 * PAGE_SIZE)) = 0xdeadbeef; | |
if (munmap(region, 8 * PAGE_SIZE)) | |
break; | |
} | |
if (addr < TASK_SIZE) | |
asm volatile("trap"); | |
exit(0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment