/* * Copyright IBM Corp. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2.1 of the GNU Lesser General Public License * as published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "utils.h" char *file_name; int in_test; volatile int faulted; volatile void *dar; int errors; static void segv(int signum, siginfo_t *info, void *ctxt_v) { ucontext_t *ctxt = (ucontext_t *)ctxt_v; struct pt_regs *regs = ctxt->uc_mcontext.regs; if (!in_test) { fprintf(stderr, "Segfault outside of test !\n"); exit(1); } faulted = 1; dar = (void *)regs->dar; regs->nip += 4; } static inline void do_read(const volatile void *addr) { int ret; asm volatile("lwz %0,0(%1); twi 0,%0,0; isync;\n" : "=r" (ret) : "r" (addr) : "memory"); } static inline void do_write(const volatile void *addr) { int val = 0x1234567; asm volatile("stw %0,0(%1); sync; \n" : : "r" (val), "r" (addr) : "memory"); } static inline void check_faulted(void *addr, long page, long subpage, int write) { int want_fault = (subpage == ((page + 3) % 16)); if (write) want_fault |= (subpage == ((page + 1) % 16)); if (faulted != want_fault) { printf("Failed at %p (p=%ld,sp=%ld,w=%d), want=%s, got=%s !\n", addr, page, subpage, write, want_fault ? "fault" : "pass", faulted ? "fault" : "pass"); ++errors; } if (faulted) { if (dar != addr) { printf("Fault expected at %p and happened at %p !\n", addr, dar); } faulted = 0; asm volatile("sync" : : : "memory"); } } static int run_test(void *addr, unsigned long size) { unsigned int *map; long i, j, pages, err; pages = size / 0x10000; map = malloc(pages * 4); assert(map); /* * for each page, mark subpage i % 16 read only and subpage * (i + 3) % 16 inaccessible */ for (i = 0; i < pages; i++) { map[i] = (0x40000000 >> (((i + 1) * 2) % 32)) | (0xc0000000 >> (((i + 3) * 2) % 32)); } err = syscall(__NR_subpage_prot, addr, size, map); if (err) { perror("subpage_perm"); return 1; } free(map); in_test = 1; errors = 0; for (i = 0; i < pages; i++) { for (j = 0; j < 16; j++, addr += 0x1000) { do_read(addr); check_faulted(addr, i, j, 0); do_write(addr); check_faulted(addr, i, j, 1); } } in_test = 0; if (errors) { printf("%d errors detected\n", errors); return 1; } return 0; } int test_anon(void) { unsigned long align; struct sigaction act = { .sa_sigaction = segv, .sa_flags = SA_SIGINFO }; void *mallocblock; unsigned long mallocsize; if (getpagesize() != 0x10000) { fprintf(stderr, "Kernel page size must be 64K!\n"); return 1; } sigaction(SIGSEGV, &act, NULL); mallocsize = 4 * 16 * 1024 * 1024; FAIL_IF(posix_memalign(&mallocblock, 64 * 1024, mallocsize)); align = (unsigned long)mallocblock; if (align & 0xffff) align = (align | 0xffff) + 1; mallocblock = (void *)align; printf("allocated malloc block of 0x%lx bytes at %p\n", mallocsize, mallocblock); printf("testing malloc block...\n"); return run_test(mallocblock, mallocsize); } int test_file(void) { struct sigaction act = { .sa_sigaction = segv, .sa_flags = SA_SIGINFO }; void *fileblock; off_t filesize; int fd; fd = open(file_name, O_RDWR); if (fd == -1) { perror("failed to open file"); return 1; } sigaction(SIGSEGV, &act, NULL); filesize = lseek(fd, 0, SEEK_END); if (filesize & 0xffff) filesize &= ~0xfffful; fileblock = mmap(NULL, filesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (fileblock == MAP_FAILED) { perror("failed to map file"); return 1; } printf("allocated %s for 0x%lx bytes at %p\n", file_name, filesize, fileblock); printf("testing file map...\n"); return run_test(fileblock, filesize); } int main(int argc, char *argv[]) { int rc; rc = test_harness(test_anon, "subpage_prot_anon"); if (rc) return rc; if (argc > 1) file_name = argv[1]; else file_name = "tempfile"; return test_harness(test_file, "subpage_prot_file"); } ?id=cbf304e420da96992eae50bb6d51035681340ab8'>logplain -rw-r--r--annotate.c44411logplain -rw-r--r--annotate.h5583logplain -rw-r--r--auxtrace.c47774logplain -rw-r--r--auxtrace.h22142logplain -rw-r--r--block-range.c6948logplain -rw-r--r--block-range.h1607logplain -rw-r--r--bpf-loader.c40787logplain -rw-r--r--bpf-loader.h6215logplain -rw-r--r--bpf-prologue.c11226logplain -rw-r--r--bpf-prologue.h847logplain -rw-r--r--build-id.c19054logplain -rw-r--r--build-id.h1859logplain d---------c++184logplain -rw-r--r--cache.h733logplain -rw-r--r--call-path.c2893logplain -rw-r--r--call-path.h2203logplain -rw-r--r--callchain.c29332logplain -rw-r--r--callchain.h7881logplain -rw-r--r--cgroup.c3195logplain -rw-r--r--cgroup.h359logplain -rw-r--r--cloexec.c1950logplain -rw-r--r--cloexec.h251logplain -rw-r--r--color.c4787logplain -rw-r--r--color.h1647logplain -rw-r--r--comm.c2239logplain -rw-r--r--comm.h561logplain -rw-r--r--config.c16262logplain -rw-r--r--config.h2113logplain -rw-r--r--counts.c1026logplain -rw-r--r--counts.h790logplain -rw-r--r--cpumap.c12627logplain -rw-r--r--cpumap.h1954logplain -rw-r--r--cs-etm.h2061logplain -rw-r--r--ctype.c2018logplain -rw-r--r--data-convert-bt.c36671logplain -rw-r--r--data-convert-bt.h302logplain -rw-r--r--data-convert.h141logplain -rw-r--r--data.c3459logplain -rw-r--r--data.h1369logplain -rw-r--r--db-export.c11434logplain -rw-r--r--db-export.h3816logplain -rw-r--r--debug.c4417logplain -rw-r--r--debug.h2023logplain -rw-r--r--demangle-java.c4219logplain -rw-r--r--demangle-java.h249logplain -rw-r--r--demangle-rust.c6602logplain -rw-r--r--demangle-rust.h170logplain -rw-r--r--drv_configs.c1834logplain -rw-r--r--drv_configs.h844logplain -rw-r--r--dso.c31994logplain -rw-r--r--dso.h10399logplain -rw-r--r--dwarf-aux.c33828logplain -rw-r--r--dwarf-aux.h5101logplain -rw-r--r--dwarf-regs.c1816logplain -rw-r--r--env.c1884logplain -rw-r--r--env.h1268logplain -rw-r--r--event.c36670logplain -rw-r--r--event.h15997logplain -rw-r--r--evlist.c47104logplain -rw-r--r--evlist.h12584logplain -rw-r--r--evsel.c63917logplain -rw-r--r--evsel.h13041logplain -rw-r--r--evsel_fprintf.c5831logplain -rw-r--r--find-vdso-map.c581logplain -rw-r--r--genelf.c11653logplain -rw-r--r--genelf.h1814logplain -rw-r--r--genelf_debug.c14374logplain -rwxr-xr-xgenerate-cmdlist.sh1141logplain -rw-r--r--group.h122logplain -rw-r--r--header.c73410logplain -rw-r--r--header.h4365logplain -rw-r--r--help-unknown-cmd.c3221logplain