VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

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