^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <sys/mman.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <sys/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <sys/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <longjmp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <os.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define ARBITRARY_ADDR -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define FAILURE_PID -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define STAT_PATH_LEN sizeof("/proc/#######/stat\0")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define COMM_SCANF "%*[^)])"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) unsigned long os_process_pc(int pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) char proc_stat[STAT_PATH_LEN], buf[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) unsigned long pc = ARBITRARY_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int fd, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) sprintf(proc_stat, "/proc/%d/stat", pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) fd = open(proc_stat, O_RDONLY, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) if (fd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) printk(UM_KERN_ERR "os_process_pc - couldn't open '%s', "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) "errno = %d\n", proc_stat, errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) CATCH_EINTR(err = read(fd, buf, sizeof(buf)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) printk(UM_KERN_ERR "os_process_pc - couldn't read '%s', "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) "err = %d\n", proc_stat, errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) goto out_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) os_close_file(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) pc = ARBITRARY_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) "%*d %*d %*d %*d %*d %lu", &pc) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) printk(UM_KERN_ERR "os_process_pc - couldn't find pc in '%s'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) out_close:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) int os_process_parent(int pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) char stat[STAT_PATH_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) char data[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int parent = FAILURE_PID, n, fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (pid == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) fd = open(stat, O_RDONLY, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (fd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) printk(UM_KERN_ERR "Couldn't open '%s', errno = %d\n", stat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) CATCH_EINTR(n = read(fd, data, sizeof(data)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (n < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) printk(UM_KERN_ERR "Couldn't read '%s', errno = %d\n", stat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) parent = FAILURE_PID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) n = sscanf(data, "%*d " COMM_SCANF " %*c %d", &parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (n != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) printk(UM_KERN_ERR "Failed to scan '%s'\n", data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) void os_alarm_process(int pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) kill(pid, SIGALRM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) void os_stop_process(int pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) kill(pid, SIGSTOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) void os_kill_process(int pid, int reap_child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) kill(pid, SIGKILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (reap_child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) CATCH_EINTR(waitpid(pid, NULL, __WALL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* Kill off a ptraced child by all means available. kill it normally first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * then PTRACE_KILL it, then PTRACE_CONT it in case it's in a run state from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * which it can't exit directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) void os_kill_ptraced_process(int pid, int reap_child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) kill(pid, SIGKILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ptrace(PTRACE_KILL, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ptrace(PTRACE_CONT, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (reap_child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) CATCH_EINTR(waitpid(pid, NULL, __WALL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* Don't use the glibc version, which caches the result in TLS. It misses some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * syscalls, and also breaks with clone(), which does not unshare the TLS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int os_getpid(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return syscall(__NR_getpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int os_getpgrp(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return getpgrp();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int r, int w, int x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) void *loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int prot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) (x ? PROT_EXEC : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) fd, off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (loc == MAP_FAILED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) (x ? PROT_EXEC : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (mprotect(addr, len, prot) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) int os_unmap_memory(void *addr, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) err = munmap(addr, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #ifndef MADV_REMOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define MADV_REMOVE KERNEL_MADV_REMOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int os_drop_memory(void *addr, int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) err = madvise(addr, length, MADV_REMOVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) err = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) int __init can_drop_memory(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) void *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) int fd, ok = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) printk(UM_KERN_INFO "Checking host MADV_REMOVE support...");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) fd = create_mem_file(UM_KERN_PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (fd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) printk(UM_KERN_ERR "Creating test memory file failed, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) "err = %d\n", -fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) MAP_SHARED, fd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (addr == MAP_FAILED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) printk(UM_KERN_ERR "Mapping test memory file failed, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) "err = %d\n", -errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) goto out_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) printk(UM_KERN_ERR "MADV_REMOVE failed, err = %d\n", -errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) printk(UM_KERN_CONT "OK\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ok = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) out_unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) munmap(addr, UM_KERN_PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) out_close:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static int os_page_mincore(void *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) char vec[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ret = mincore(addr, UM_KERN_PAGE_SIZE, vec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (errno == ENOMEM || errno == EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return vec[0] & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int os_mincore(void *addr, unsigned long len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) char *vec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (len <= UM_KERN_PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return os_page_mincore(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) vec = calloc(1, (len + UM_KERN_PAGE_SIZE - 1) / UM_KERN_PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (!vec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ret = mincore(addr, UM_KERN_PAGE_SIZE, vec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (errno == ENOMEM || errno == EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) for (i = 0; i < ((len + UM_KERN_PAGE_SIZE - 1) / UM_KERN_PAGE_SIZE); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (!(vec[i] & 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) free(vec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) void init_new_thread_signals(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) set_handler(SIGSEGV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) set_handler(SIGTRAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) set_handler(SIGFPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) set_handler(SIGILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) set_handler(SIGBUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) signal(SIGHUP, SIG_IGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) set_handler(SIGIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) signal(SIGWINCH, SIG_IGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }