aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/Kconfig_net2
-rw-r--r--arch/um/Makefile32
-rw-r--r--arch/um/Makefile-i38630
-rw-r--r--arch/um/Makefile-x86_646
-rw-r--r--arch/um/drivers/Makefile19
-rw-r--r--arch/um/drivers/cow.h4
-rw-r--r--arch/um/drivers/hostaudio_kern.c4
-rw-r--r--arch/um/drivers/mconsole_kern.c2
-rw-r--r--arch/um/kernel/exitcode.c2
-rw-r--r--arch/um/kernel/helper.c14
-rw-r--r--arch/um/kernel/process.c83
-rw-r--r--arch/um/kernel/process_kern.c2
-rw-r--r--arch/um/kernel/reboot.c6
-rw-r--r--arch/um/kernel/skas/process.c2
-rw-r--r--arch/um/kernel/skas/syscall_user.c4
-rw-r--r--arch/um/kernel/skas/trap_user.c1
-rw-r--r--arch/um/kernel/time_kern.c5
-rw-r--r--arch/um/kernel/um_arch.c19
-rw-r--r--arch/um/kernel/uml.lds.S4
-rw-r--r--arch/um/os-Linux/elf_aux.c5
-rw-r--r--arch/um/os-Linux/user_syms.c3
-rw-r--r--arch/um/scripts/Makefile.unmap4
-rw-r--r--arch/um/sys-i386/ldt.c114
-rw-r--r--arch/um/sys-i386/stub_segv.c6
-rw-r--r--arch/um/sys-i386/unmap.c2
-rw-r--r--arch/um/sys-x86_64/signal.c2
-rw-r--r--arch/um/sys-x86_64/unmap.c2
27 files changed, 228 insertions, 151 deletions
diff --git a/arch/um/Kconfig_net b/arch/um/Kconfig_net
index 1c2f9a70d91d..fa2ab2dd78b7 100644
--- a/arch/um/Kconfig_net
+++ b/arch/um/Kconfig_net
@@ -135,7 +135,7 @@ config UML_NET_MCAST
135 135
136config UML_NET_PCAP 136config UML_NET_PCAP
137 bool "pcap transport" 137 bool "pcap transport"
138 depends on UML_NET && BROKEN 138 depends on UML_NET && EXPERIMENTAL
139 help 139 help
140 The pcap transport makes a pcap packet stream on the host look 140 The pcap transport makes a pcap packet stream on the host look
141 like an ethernet device inside UML. This is useful for making 141 like an ethernet device inside UML. This is useful for making
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 4a375bbac109..f5a83a72aa75 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -51,25 +51,26 @@ MRPROPER_DIRS += $(ARCH_DIR)/include2
51endif 51endif
52SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH) 52SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH)
53 53
54include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) 54# -Dvmap=kernel_vmap affects everything, and prevents anything from
55# referencing the libpcap.o symbol so named.
56
57CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
58 $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap
55 59
56core-y += $(SUBARCH_CORE) 60USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
57libs-y += $(SUBARCH_LIBS) 61USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
62 $(MODE_INCLUDE)
58 63
59# -Derrno=kernel_errno - This turns all kernel references to errno into 64# -Derrno=kernel_errno - This turns all kernel references to errno into
60# kernel_errno to separate them from the libc errno. This allows -fno-common 65# kernel_errno to separate them from the libc errno. This allows -fno-common
61# in CFLAGS. Otherwise, it would cause ld to complain about the two different 66# in CFLAGS. Otherwise, it would cause ld to complain about the two different
62# errnos. 67# errnos.
63 68
64CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
65 $(ARCH_INCLUDE) $(MODE_INCLUDE)
66
67USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
68USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
69 $(MODE_INCLUDE) $(ARCH_USER_CFLAGS)
70CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask 69CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask
71CFLAGS += $(call cc-option,-fno-unit-at-a-time,) 70CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
72 71
72include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
73
73#This will adjust *FLAGS accordingly to the platform. 74#This will adjust *FLAGS accordingly to the platform.
74include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS) 75include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
75 76
@@ -116,18 +117,19 @@ CONFIG_KERNEL_STACK_ORDER ?= 2
116STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) 117STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
117 118
118ifndef START 119ifndef START
119 START = $$(($(TOP_ADDR) - $(SIZE))) 120 START = $(shell echo $$[ $(TOP_ADDR) - $(SIZE) ] )
120endif 121endif
121 122
122CPPFLAGS_vmlinux.lds = $(shell echo -U$(SUBARCH) \ 123CPPFLAGS_vmlinux.lds = -U$(SUBARCH) \
123 -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \ 124 -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
124 -DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE-y) \ 125 -DELF_FORMAT="$(ELF_FORMAT)" $(CPP_MODE-y) \
125 -DKERNEL_STACK_SIZE=$(STACK_SIZE) -DSUBARCH=$(SUBARCH)) 126 -DKERNEL_STACK_SIZE=$(STACK_SIZE) \
127 -DUNMAP_PATH=arch/um/sys-$(SUBARCH)/unmap_fin.o
126 128
127#The wrappers will select whether using "malloc" or the kernel allocator. 129#The wrappers will select whether using "malloc" or the kernel allocator.
128LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc 130LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
129 131
130CFLAGS_vmlinux = $(LINK-y) $(LINK_WRAPS) 132CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS)
131define cmd_vmlinux__ 133define cmd_vmlinux__
132 $(CC) $(CFLAGS_vmlinux) -o $@ \ 134 $(CC) $(CFLAGS_vmlinux) -o $@ \
133 -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \ 135 -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \
@@ -243,7 +245,7 @@ $(ARCH_DIR)/util: scripts_basic $(SYS_DIR)/sc.h $(ARCH_DIR)/kernel-offsets.h FOR
243$(ARCH_DIR)/kernel/skas/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE 245$(ARCH_DIR)/kernel/skas/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
244 $(Q)$(MAKE) $(build)=$@ 246 $(Q)$(MAKE) $(build)=$@
245 247
246$(ARCH_DIR)/os-$(OS)/util: scripts_basic FORCE 248$(ARCH_DIR)/os-$(OS)/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
247 $(Q)$(MAKE) $(build)=$@ 249 $(Q)$(MAKE) $(build)=$@
248 250
249export SUBARCH USER_CFLAGS OS 251export SUBARCH USER_CFLAGS OS
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index 301059062a3e..a777e57dbf89 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -1,4 +1,4 @@
1SUBARCH_CORE := arch/um/sys-i386/ arch/i386/crypto/ 1core-y += arch/um/sys-i386/ arch/i386/crypto/
2 2
3TOP_ADDR := $(CONFIG_TOP_ADDR) 3TOP_ADDR := $(CONFIG_TOP_ADDR)
4 4
@@ -8,21 +8,33 @@ ifeq ($(CONFIG_MODE_SKAS),y)
8 endif 8 endif
9endif 9endif
10 10
11LDFLAGS += -m elf_i386
12ELF_ARCH := $(SUBARCH)
13ELF_FORMAT := elf32-$(SUBARCH)
14OBJCOPYFLAGS := -O binary -R .note -R .comment -S
15
16ifeq ("$(origin SUBARCH)", "command line")
17ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)")
18CFLAGS += $(call cc-option,-m32)
19USER_CFLAGS += $(call cc-option,-m32)
20HOSTCFLAGS += $(call cc-option,-m32)
21HOSTLDFLAGS += $(call cc-option,-m32)
22AFLAGS += $(call cc-option,-m32)
23LINK-y += $(call cc-option,-m32)
24UML_OBJCOPYFLAGS += -F $(ELF_FORMAT)
25
26export LDFLAGS HOSTCFLAGS HOSTLDFLAGS UML_OBJCOPYFLAGS
27endif
28endif
29
11CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH) $(STUB_CFLAGS) 30CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH) $(STUB_CFLAGS)
12ARCH_USER_CFLAGS :=
13 31
14ifneq ($(CONFIG_GPROF),y) 32ifneq ($(CONFIG_GPROF),y)
15ARCH_CFLAGS += -DUM_FASTCALL 33ARCH_CFLAGS += -DUM_FASTCALL
16endif 34endif
17 35
18ELF_ARCH := $(SUBARCH)
19ELF_FORMAT := elf32-$(SUBARCH)
20
21OBJCOPYFLAGS := -O binary -R .note -R .comment -S
22
23SYS_UTIL_DIR := $(ARCH_DIR)/sys-i386/util 36SYS_UTIL_DIR := $(ARCH_DIR)/sys-i386/util
24 37SYS_HEADERS := $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
25SYS_HEADERS := $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
26 38
27prepare: $(SYS_HEADERS) 39prepare: $(SYS_HEADERS)
28 40
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index d80bd0052e6b..aa2f7174ebca 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -1,11 +1,13 @@
1# Copyright 2003 - 2004 Pathscale, Inc 1# Copyright 2003 - 2004 Pathscale, Inc
2# Released under the GPL 2# Released under the GPL
3 3
4SUBARCH_LIBS := arch/um/sys-x86_64/ 4libs-y += arch/um/sys-x86_64/
5START := 0x60000000 5START := 0x60000000
6 6
7#We #undef __x86_64__ for kernelspace, not for userspace where
8#it's needed for headers to work!
7CFLAGS += -U__$(SUBARCH)__ -fno-builtin $(STUB_CFLAGS) 9CFLAGS += -U__$(SUBARCH)__ -fno-builtin $(STUB_CFLAGS)
8ARCH_USER_CFLAGS := -D__x86_64__ 10USER_CFLAGS += -fno-builtin
9 11
10ELF_ARCH := i386:x86-64 12ELF_ARCH := i386:x86-64
11ELF_FORMAT := elf64-x86-64 13ELF_FORMAT := elf64-x86-64
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index b2de9916c32c..de17d4c6e02d 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -10,7 +10,6 @@ slip-objs := slip_kern.o slip_user.o
10slirp-objs := slirp_kern.o slirp_user.o 10slirp-objs := slirp_kern.o slirp_user.o
11daemon-objs := daemon_kern.o daemon_user.o 11daemon-objs := daemon_kern.o daemon_user.o
12mcast-objs := mcast_kern.o mcast_user.o 12mcast-objs := mcast_kern.o mcast_user.o
13#pcap-objs := pcap_kern.o pcap_user.o $(PCAP)
14net-objs := net_kern.o net_user.o 13net-objs := net_kern.o net_user.o
15mconsole-objs := mconsole_kern.o mconsole_user.o 14mconsole-objs := mconsole_kern.o mconsole_user.o
16hostaudio-objs := hostaudio_kern.o 15hostaudio-objs := hostaudio_kern.o
@@ -18,6 +17,19 @@ ubd-objs := ubd_kern.o ubd_user.o
18port-objs := port_kern.o port_user.o 17port-objs := port_kern.o port_user.o
19harddog-objs := harddog_kern.o harddog_user.o 18harddog-objs := harddog_kern.o harddog_user.o
20 19
20LDFLAGS_pcap.o := -r $(shell $(CC) $(CFLAGS) -print-file-name=libpcap.a)
21
22targets := pcap_kern.o pcap_user.o
23
24$(obj)/pcap.o: $(obj)/pcap_kern.o $(obj)/pcap_user.o
25 $(LD) -r -dp -o $@ $^ $(LDFLAGS) $(LDFLAGS_pcap.o)
26#XXX: The call below does not work because the flags are added before the
27# object name, so nothing from the library gets linked.
28#$(call if_changed,ld)
29
30# When the above is fixed, don't forget to add this too!
31#targets += $(obj)/pcap.o
32
21obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o 33obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o
22obj-$(CONFIG_SSL) += ssl.o 34obj-$(CONFIG_SSL) += ssl.o
23obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o 35obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o
@@ -26,7 +38,7 @@ obj-$(CONFIG_UML_NET_SLIP) += slip.o slip_common.o
26obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o 38obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o
27obj-$(CONFIG_UML_NET_DAEMON) += daemon.o 39obj-$(CONFIG_UML_NET_DAEMON) += daemon.o
28obj-$(CONFIG_UML_NET_MCAST) += mcast.o 40obj-$(CONFIG_UML_NET_MCAST) += mcast.o
29#obj-$(CONFIG_UML_NET_PCAP) += pcap.o $(PCAP) 41obj-$(CONFIG_UML_NET_PCAP) += pcap.o
30obj-$(CONFIG_UML_NET) += net.o 42obj-$(CONFIG_UML_NET) += net.o
31obj-$(CONFIG_MCONSOLE) += mconsole.o 43obj-$(CONFIG_MCONSOLE) += mconsole.o
32obj-$(CONFIG_MMAPPER) += mmapper_kern.o 44obj-$(CONFIG_MMAPPER) += mmapper_kern.o
@@ -41,6 +53,7 @@ obj-$(CONFIG_UML_WATCHDOG) += harddog.o
41obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o 53obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
42obj-$(CONFIG_UML_RANDOM) += random.o 54obj-$(CONFIG_UML_RANDOM) += random.o
43 55
44USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o 56# pcap_user.o must be added explicitly.
57USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o pcap_user.o
45 58
46include arch/um/scripts/Makefile.rules 59include arch/um/scripts/Makefile.rules
diff --git a/arch/um/drivers/cow.h b/arch/um/drivers/cow.h
index 4fcbe8b1b77e..4fcf3a8d13f4 100644
--- a/arch/um/drivers/cow.h
+++ b/arch/um/drivers/cow.h
@@ -3,10 +3,10 @@
3 3
4#include <asm/types.h> 4#include <asm/types.h>
5 5
6#if __BYTE_ORDER == __BIG_ENDIAN 6#if defined(__BIG_ENDIAN)
7# define ntohll(x) (x) 7# define ntohll(x) (x)
8# define htonll(x) (x) 8# define htonll(x) (x)
9#elif __BYTE_ORDER == __LITTLE_ENDIAN 9#elif defined(__LITTLE_ENDIAN)
10# define ntohll(x) bswap_64(x) 10# define ntohll(x) bswap_64(x)
11# define htonll(x) bswap_64(x) 11# define htonll(x) bswap_64(x)
12#else 12#else
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
index d5742783e19d..59602b81b240 100644
--- a/arch/um/drivers/hostaudio_kern.c
+++ b/arch/um/drivers/hostaudio_kern.c
@@ -57,10 +57,10 @@ __uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP);
57 57
58#else /*MODULE*/ 58#else /*MODULE*/
59 59
60MODULE_PARM(dsp, "s"); 60module_param(dsp, charp, 0644);
61MODULE_PARM_DESC(dsp, DSP_HELP); 61MODULE_PARM_DESC(dsp, DSP_HELP);
62 62
63MODULE_PARM(mixer, "s"); 63module_param(mixer, charp, 0644);
64MODULE_PARM_DESC(mixer, MIXER_HELP); 64MODULE_PARM_DESC(mixer, MIXER_HELP);
65 65
66#endif 66#endif
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 404de41a4f67..c190c2414197 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -557,7 +557,7 @@ static int create_proc_mconsole(void)
557 557
558 ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL); 558 ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL);
559 if(ent == NULL){ 559 if(ent == NULL){
560 printk("create_proc_mconsole : create_proc_entry failed\n"); 560 printk(KERN_INFO "create_proc_mconsole : create_proc_entry failed\n");
561 return(0); 561 return(0);
562 } 562 }
563 563
diff --git a/arch/um/kernel/exitcode.c b/arch/um/kernel/exitcode.c
index 0ea87f24b36f..d21ebad666b4 100644
--- a/arch/um/kernel/exitcode.c
+++ b/arch/um/kernel/exitcode.c
@@ -48,7 +48,7 @@ static int make_proc_exitcode(void)
48 48
49 ent = create_proc_entry("exitcode", 0600, &proc_root); 49 ent = create_proc_entry("exitcode", 0600, &proc_root);
50 if(ent == NULL){ 50 if(ent == NULL){
51 printk("make_proc_exitcode : Failed to register " 51 printk(KERN_WARNING "make_proc_exitcode : Failed to register "
52 "/proc/exitcode\n"); 52 "/proc/exitcode\n");
53 return(0); 53 return(0);
54 } 54 }
diff --git a/arch/um/kernel/helper.c b/arch/um/kernel/helper.c
index 13b1f5c2f7ee..f83e1e8e2392 100644
--- a/arch/um/kernel/helper.c
+++ b/arch/um/kernel/helper.c
@@ -13,6 +13,7 @@
13#include "user.h" 13#include "user.h"
14#include "kern_util.h" 14#include "kern_util.h"
15#include "user_util.h" 15#include "user_util.h"
16#include "helper.h"
16#include "os.h" 17#include "os.h"
17 18
18struct helper_data { 19struct helper_data {
@@ -149,7 +150,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
149 return(pid); 150 return(pid);
150} 151}
151 152
152int helper_wait(int pid, int block) 153int helper_wait(int pid)
153{ 154{
154 int ret; 155 int ret;
155 156
@@ -160,14 +161,3 @@ int helper_wait(int pid, int block)
160 } 161 }
161 return(ret); 162 return(ret);
162} 163}
163
164/*
165 * Overrides for Emacs so that we follow Linus's tabbing style.
166 * Emacs will notice this stuff at the end of the file and automatically
167 * adjust the settings for this buffer only. This must remain at the end
168 * of the file.
169 * ---------------------------------------------------------------------------
170 * Local variables:
171 * c-file-style: "linux"
172 * End:
173 */
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index c45a60e9c92d..67acd92c5322 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -131,7 +131,7 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack,
131 return(arg.pid); 131 return(arg.pid);
132} 132}
133 133
134static int ptrace_child(void) 134static int ptrace_child(void *arg)
135{ 135{
136 int ret; 136 int ret;
137 int pid = os_getpid(), ppid = getppid(); 137 int pid = os_getpid(), ppid = getppid();
@@ -160,16 +160,20 @@ static int ptrace_child(void)
160 _exit(ret); 160 _exit(ret);
161} 161}
162 162
163static int start_ptraced_child(void) 163static int start_ptraced_child(void **stack_out)
164{ 164{
165 void *stack;
166 unsigned long sp;
165 int pid, n, status; 167 int pid, n, status;
166 168
167 pid = fork(); 169 stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
168 if(pid == 0) 170 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
169 ptrace_child(); 171 if(stack == MAP_FAILED)
170 172 panic("check_ptrace : mmap failed, errno = %d", errno);
173 sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
174 pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
171 if(pid < 0) 175 if(pid < 0)
172 panic("check_ptrace : fork failed, errno = %d", errno); 176 panic("check_ptrace : clone failed, errno = %d", errno);
173 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 177 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
174 if(n < 0) 178 if(n < 0)
175 panic("check_ptrace : wait failed, errno = %d", errno); 179 panic("check_ptrace : wait failed, errno = %d", errno);
@@ -177,6 +181,7 @@ static int start_ptraced_child(void)
177 panic("check_ptrace : expected SIGSTOP, got status = %d", 181 panic("check_ptrace : expected SIGSTOP, got status = %d",
178 status); 182 status);
179 183
184 *stack_out = stack;
180 return(pid); 185 return(pid);
181} 186}
182 187
@@ -184,12 +189,12 @@ static int start_ptraced_child(void)
184 * just avoid using sysemu, not panic, but only if SYSEMU features are broken. 189 * just avoid using sysemu, not panic, but only if SYSEMU features are broken.
185 * So only for SYSEMU features we test mustpanic, while normal host features 190 * So only for SYSEMU features we test mustpanic, while normal host features
186 * must work anyway!*/ 191 * must work anyway!*/
187static int stop_ptraced_child(int pid, int exitcode, int mustexit) 192static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic)
188{ 193{
189 int status, n, ret = 0; 194 int status, n, ret = 0;
190 195
191 if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) 196 if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
192 panic("stop_ptraced_child : ptrace failed, errno = %d", errno); 197 panic("check_ptrace : ptrace failed, errno = %d", errno);
193 CATCH_EINTR(n = waitpid(pid, &status, 0)); 198 CATCH_EINTR(n = waitpid(pid, &status, 0));
194 if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { 199 if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
195 int exit_with = WEXITSTATUS(status); 200 int exit_with = WEXITSTATUS(status);
@@ -200,24 +205,40 @@ static int stop_ptraced_child(int pid, int exitcode, int mustexit)
200 printk("check_ptrace : child exited with exitcode %d, while " 205 printk("check_ptrace : child exited with exitcode %d, while "
201 "expecting %d; status 0x%x", exit_with, 206 "expecting %d; status 0x%x", exit_with,
202 exitcode, status); 207 exitcode, status);
203 if (mustexit) 208 if (mustpanic)
204 panic("\n"); 209 panic("\n");
205 else 210 else
206 printk("\n"); 211 printk("\n");
207 ret = -1; 212 ret = -1;
208 } 213 }
209 214
215 if(munmap(stack, PAGE_SIZE) < 0)
216 panic("check_ptrace : munmap failed, errno = %d", errno);
210 return ret; 217 return ret;
211} 218}
212 219
213static int force_sysemu_disabled = 0; 220static int force_sysemu_disabled = 0;
214 221
222int ptrace_faultinfo = 1;
223int proc_mm = 1;
224
225static int __init skas0_cmd_param(char *str, int* add)
226{
227 ptrace_faultinfo = proc_mm = 0;
228 return 0;
229}
230
215static int __init nosysemu_cmd_param(char *str, int* add) 231static int __init nosysemu_cmd_param(char *str, int* add)
216{ 232{
217 force_sysemu_disabled = 1; 233 force_sysemu_disabled = 1;
218 return 0; 234 return 0;
219} 235}
220 236
237__uml_setup("skas0", skas0_cmd_param,
238 "skas0\n"
239 " Disables SKAS3 usage, so that SKAS0 is used, unless you \n"
240 " specify mode=tt.\n\n");
241
221__uml_setup("nosysemu", nosysemu_cmd_param, 242__uml_setup("nosysemu", nosysemu_cmd_param,
222 "nosysemu\n" 243 "nosysemu\n"
223 " Turns off syscall emulation patch for ptrace (SYSEMU) on.\n" 244 " Turns off syscall emulation patch for ptrace (SYSEMU) on.\n"
@@ -228,11 +249,12 @@ __uml_setup("nosysemu", nosysemu_cmd_param,
228 249
229static void __init check_sysemu(void) 250static void __init check_sysemu(void)
230{ 251{
252 void *stack;
231 int pid, syscall, n, status, count=0; 253 int pid, syscall, n, status, count=0;
232 254
233 printk("Checking syscall emulation patch for ptrace..."); 255 printk("Checking syscall emulation patch for ptrace...");
234 sysemu_supported = 0; 256 sysemu_supported = 0;
235 pid = start_ptraced_child(); 257 pid = start_ptraced_child(&stack);
236 258
237 if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) 259 if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0)
238 goto fail; 260 goto fail;
@@ -250,7 +272,7 @@ static void __init check_sysemu(void)
250 panic("check_sysemu : failed to modify system " 272 panic("check_sysemu : failed to modify system "
251 "call return, errno = %d", errno); 273 "call return, errno = %d", errno);
252 274
253 if (stop_ptraced_child(pid, 0, 0) < 0) 275 if (stop_ptraced_child(pid, stack, 0, 0) < 0)
254 goto fail_stopped; 276 goto fail_stopped;
255 277
256 sysemu_supported = 1; 278 sysemu_supported = 1;
@@ -258,7 +280,7 @@ static void __init check_sysemu(void)
258 set_using_sysemu(!force_sysemu_disabled); 280 set_using_sysemu(!force_sysemu_disabled);
259 281
260 printk("Checking advanced syscall emulation patch for ptrace..."); 282 printk("Checking advanced syscall emulation patch for ptrace...");
261 pid = start_ptraced_child(); 283 pid = start_ptraced_child(&stack);
262 while(1){ 284 while(1){
263 count++; 285 count++;
264 if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) 286 if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0)
@@ -283,7 +305,7 @@ static void __init check_sysemu(void)
283 break; 305 break;
284 } 306 }
285 } 307 }
286 if (stop_ptraced_child(pid, 0, 0) < 0) 308 if (stop_ptraced_child(pid, stack, 0, 0) < 0)
287 goto fail_stopped; 309 goto fail_stopped;
288 310
289 sysemu_supported = 2; 311 sysemu_supported = 2;
@@ -294,17 +316,18 @@ static void __init check_sysemu(void)
294 return; 316 return;
295 317
296fail: 318fail:
297 stop_ptraced_child(pid, 1, 0); 319 stop_ptraced_child(pid, stack, 1, 0);
298fail_stopped: 320fail_stopped:
299 printk("missing\n"); 321 printk("missing\n");
300} 322}
301 323
302void __init check_ptrace(void) 324void __init check_ptrace(void)
303{ 325{
326 void *stack;
304 int pid, syscall, n, status; 327 int pid, syscall, n, status;
305 328
306 printk("Checking that ptrace can change system call numbers..."); 329 printk("Checking that ptrace can change system call numbers...");
307 pid = start_ptraced_child(); 330 pid = start_ptraced_child(&stack);
308 331
309 if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) 332 if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
310 panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); 333 panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno);
@@ -331,7 +354,7 @@ void __init check_ptrace(void)
331 break; 354 break;
332 } 355 }
333 } 356 }
334 stop_ptraced_child(pid, 0, 1); 357 stop_ptraced_child(pid, stack, 0, 1);
335 printk("OK\n"); 358 printk("OK\n");
336 check_sysemu(); 359 check_sysemu();
337} 360}
@@ -359,22 +382,22 @@ void forward_pending_sigio(int target)
359 kill(target, SIGIO); 382 kill(target, SIGIO);
360} 383}
361 384
362int ptrace_faultinfo = 0;
363int proc_mm = 1;
364
365extern void *__syscall_stub_start, __syscall_stub_end; 385extern void *__syscall_stub_start, __syscall_stub_end;
366 386
367#ifdef UML_CONFIG_MODE_SKAS 387#ifdef UML_CONFIG_MODE_SKAS
388
368static inline void check_skas3_ptrace_support(void) 389static inline void check_skas3_ptrace_support(void)
369{ 390{
370 struct ptrace_faultinfo fi; 391 struct ptrace_faultinfo fi;
392 void *stack;
371 int pid, n; 393 int pid, n;
372 394
373 printf("Checking for the skas3 patch in the host..."); 395 printf("Checking for the skas3 patch in the host...");
374 pid = start_ptraced_child(); 396 pid = start_ptraced_child(&stack);
375 397
376 n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); 398 n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
377 if (n < 0) { 399 if (n < 0) {
400 ptrace_faultinfo = 0;
378 if(errno == EIO) 401 if(errno == EIO)
379 printf("not found\n"); 402 printf("not found\n");
380 else { 403 else {
@@ -382,12 +405,14 @@ static inline void check_skas3_ptrace_support(void)
382 } 405 }
383 } 406 }
384 else { 407 else {
385 ptrace_faultinfo = 1; 408 if (!ptrace_faultinfo)
386 printf("found\n"); 409 printf("found but disabled on command line\n");
410 else
411 printf("found\n");
387 } 412 }
388 413
389 init_registers(pid); 414 init_registers(pid);
390 stop_ptraced_child(pid, 1, 1); 415 stop_ptraced_child(pid, stack, 1, 1);
391} 416}
392 417
393int can_do_skas(void) 418int can_do_skas(void)
@@ -396,13 +421,13 @@ int can_do_skas(void)
396 if (os_access("/proc/mm", OS_ACC_W_OK) < 0) { 421 if (os_access("/proc/mm", OS_ACC_W_OK) < 0) {
397 proc_mm = 0; 422 proc_mm = 0;
398 printf("not found\n"); 423 printf("not found\n");
399 goto out; 424 } else {
400 } 425 if (!proc_mm)
401 else { 426 printf("found but disabled on command line\n");
402 printf("found\n"); 427 else
428 printf("found\n");
403 } 429 }
404 430
405out:
406 check_skas3_ptrace_support(); 431 check_skas3_ptrace_support();
407 return 1; 432 return 1;
408} 433}
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index d4036ed680bc..c23d8a08d0ff 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -412,7 +412,7 @@ int __init make_proc_sysemu(void)
412 412
413 if (ent == NULL) 413 if (ent == NULL)
414 { 414 {
415 printk("Failed to register /proc/sysemu\n"); 415 printk(KERN_WARNING "Failed to register /proc/sysemu\n");
416 return(0); 416 return(0);
417 } 417 }
418 418
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index fcec51da1d37..a637e885c583 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -49,23 +49,17 @@ void machine_restart(char * __unused)
49 CHOOSE_MODE(reboot_tt(), reboot_skas()); 49 CHOOSE_MODE(reboot_tt(), reboot_skas());
50} 50}
51 51
52EXPORT_SYMBOL(machine_restart);
53
54void machine_power_off(void) 52void machine_power_off(void)
55{ 53{
56 uml_cleanup(); 54 uml_cleanup();
57 CHOOSE_MODE(halt_tt(), halt_skas()); 55 CHOOSE_MODE(halt_tt(), halt_skas());
58} 56}
59 57
60EXPORT_SYMBOL(machine_power_off);
61
62void machine_halt(void) 58void machine_halt(void)
63{ 59{
64 machine_power_off(); 60 machine_power_off();
65} 61}
66 62
67EXPORT_SYMBOL(machine_halt);
68
69/* 63/*
70 * Overrides for Emacs so that we follow Linus's tabbing style. 64 * Overrides for Emacs so that we follow Linus's tabbing style.
71 * Emacs will notice this stuff at the end of the file and automatically 65 * Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index ba671dab8878..6dd9e5bf18ed 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -64,7 +64,7 @@ void wait_stub_done(int pid, int sig, char * fname)
64 (WSTOPSIG(status) == SIGVTALRM)); 64 (WSTOPSIG(status) == SIGVTALRM));
65 65
66 if((n < 0) || !WIFSTOPPED(status) || 66 if((n < 0) || !WIFSTOPPED(status) ||
67 (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status != SIGTRAP))){ 67 (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){
68 panic("%s : failed to wait for SIGUSR1/SIGTRAP, " 68 panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
69 "pid = %d, n = %d, errno = %d, status = 0x%x\n", 69 "pid = %d, n = %d, errno = %d, status = 0x%x\n",
70 fname, pid, n, errno, status); 70 fname, pid, n, errno, status);
diff --git a/arch/um/kernel/skas/syscall_user.c b/arch/um/kernel/skas/syscall_user.c
index 2828e6e37721..6b0664970147 100644
--- a/arch/um/kernel/skas/syscall_user.c
+++ b/arch/um/kernel/skas/syscall_user.c
@@ -15,7 +15,7 @@
15void handle_syscall(union uml_pt_regs *regs) 15void handle_syscall(union uml_pt_regs *regs)
16{ 16{
17 long result; 17 long result;
18#if UML_CONFIG_SYSCALL_DEBUG 18#ifdef UML_CONFIG_SYSCALL_DEBUG
19 int index; 19 int index;
20 20
21 index = record_syscall_start(UPT_SYSCALL_NR(regs)); 21 index = record_syscall_start(UPT_SYSCALL_NR(regs));
@@ -27,7 +27,7 @@ void handle_syscall(union uml_pt_regs *regs)
27 REGS_SET_SYSCALL_RETURN(regs->skas.regs, result); 27 REGS_SET_SYSCALL_RETURN(regs->skas.regs, result);
28 28
29 syscall_trace(regs, 1); 29 syscall_trace(regs, 1);
30#if UML_CONFIG_SYSCALL_DEBUG 30#ifdef UML_CONFIG_SYSCALL_DEBUG
31 record_syscall_end(index, result); 31 record_syscall_end(index, result);
32#endif 32#endif
33} 33}
diff --git a/arch/um/kernel/skas/trap_user.c b/arch/um/kernel/skas/trap_user.c
index 0dee1d95c806..9950a6716fe5 100644
--- a/arch/um/kernel/skas/trap_user.c
+++ b/arch/um/kernel/skas/trap_user.c
@@ -58,7 +58,6 @@ void user_signal(int sig, union uml_pt_regs *regs, int pid)
58 int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) || 58 int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
59 (sig == SIGILL) || (sig == SIGTRAP)); 59 (sig == SIGILL) || (sig == SIGTRAP));
60 60
61 regs->skas.is_user = 1;
62 if (segv) 61 if (segv)
63 get_skas_faultinfo(pid, &regs->skas.faultinfo); 62 get_skas_faultinfo(pid, &regs->skas.faultinfo);
64 info = &sig_info[sig]; 63 info = &sig_info[sig];
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
index a8b4ef601f59..4e08f7545d63 100644
--- a/arch/um/kernel/time_kern.c
+++ b/arch/um/kernel/time_kern.c
@@ -137,7 +137,10 @@ long um_stime(int __user *tptr)
137void timer_handler(int sig, union uml_pt_regs *regs) 137void timer_handler(int sig, union uml_pt_regs *regs)
138{ 138{
139 local_irq_disable(); 139 local_irq_disable();
140 update_process_times(CHOOSE_MODE(user_context(UPT_SP(regs)), (regs)->skas.is_user)); 140 irq_enter();
141 update_process_times(CHOOSE_MODE(user_context(UPT_SP(regs)),
142 (regs)->skas.is_user));
143 irq_exit();
141 local_irq_enable(); 144 local_irq_enable();
142 if(current_thread->cpu == 0) 145 if(current_thread->cpu == 0)
143 timer_irq(regs); 146 timer_irq(regs);
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 8736d098f0ee..ca2bb6f09a7d 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -38,6 +38,9 @@
38#include "choose-mode.h" 38#include "choose-mode.h"
39#include "mode_kern.h" 39#include "mode_kern.h"
40#include "mode.h" 40#include "mode.h"
41#ifdef UML_CONFIG_MODE_SKAS
42#include "skas.h"
43#endif
41 44
42#define DEFAULT_COMMAND_LINE "root=98:0" 45#define DEFAULT_COMMAND_LINE "root=98:0"
43 46
@@ -318,6 +321,7 @@ int linux_main(int argc, char **argv)
318 unsigned long avail, diff; 321 unsigned long avail, diff;
319 unsigned long virtmem_size, max_physmem; 322 unsigned long virtmem_size, max_physmem;
320 unsigned int i, add; 323 unsigned int i, add;
324 char * mode;
321 325
322 for (i = 1; i < argc; i++){ 326 for (i = 1; i < argc; i++){
323 if((i == 1) && (argv[i][0] == ' ')) continue; 327 if((i == 1) && (argv[i][0] == ' ')) continue;
@@ -338,6 +342,21 @@ int linux_main(int argc, char **argv)
338 exit(1); 342 exit(1);
339 } 343 }
340#endif 344#endif
345
346#ifndef CONFIG_MODE_SKAS
347 mode = "TT";
348#else
349 /* Show to the user the result of selection */
350 if (mode_tt)
351 mode = "TT";
352 else if (proc_mm && ptrace_faultinfo)
353 mode = "SKAS3";
354 else
355 mode = "SKAS0";
356#endif
357
358 printf("UML running in %s mode\n", mode);
359
341 uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0, 360 uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
342 &host_task_size, &task_size); 361 &host_task_size, &task_size);
343 362
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index 163476a8cb1b..b03326d391c9 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -16,8 +16,8 @@ SECTIONS
16 __binary_start = .; 16 __binary_start = .;
17 17
18#ifdef MODE_TT 18#ifdef MODE_TT
19 .remap_data : { arch/um/sys-SUBARCH/unmap_fin.o (.data .bss) } 19 .remap_data : { UNMAP_PATH (.data .bss) }
20 .remap : { arch/um/sys-SUBARCH/unmap_fin.o (.text) } 20 .remap : { UNMAP_PATH (.text) }
21 21
22 . = ALIGN(4096); /* Init code and data */ 22 . = ALIGN(4096); /* Init code and data */
23#endif 23#endif
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c
index f0d6060e3e57..9416e1c29926 100644
--- a/arch/um/os-Linux/elf_aux.c
+++ b/arch/um/os-Linux/elf_aux.c
@@ -9,8 +9,10 @@
9 */ 9 */
10#include <elf.h> 10#include <elf.h>
11#include <stddef.h> 11#include <stddef.h>
12#include <asm/elf.h>
12#include "init.h" 13#include "init.h"
13#include "elf_user.h" 14#include "elf_user.h"
15#include "mem_user.h"
14 16
15#if ELF_CLASS == ELFCLASS32 17#if ELF_CLASS == ELFCLASS32
16typedef Elf32_auxv_t elf_auxv_t; 18typedef Elf32_auxv_t elf_auxv_t;
@@ -40,6 +42,9 @@ __init void scan_elf_aux( char **envp)
40 break; 42 break;
41 case AT_SYSINFO_EHDR: 43 case AT_SYSINFO_EHDR:
42 vsyscall_ehdr = auxv->a_un.a_val; 44 vsyscall_ehdr = auxv->a_un.a_val;
45 /* See if the page is under TASK_SIZE */
46 if (vsyscall_ehdr < (unsigned long) envp)
47 vsyscall_ehdr = 0;
43 break; 48 break;
44 case AT_HWCAP: 49 case AT_HWCAP:
45 elf_aux_hwcap = auxv->a_un.a_val; 50 elf_aux_hwcap = auxv->a_un.a_val;
diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c
index 75d7af9ae1d2..56d3f870926b 100644
--- a/arch/um/os-Linux/user_syms.c
+++ b/arch/um/os-Linux/user_syms.c
@@ -83,6 +83,9 @@ EXPORT_SYMBOL_PROTO(statfs64);
83 83
84EXPORT_SYMBOL_PROTO(getuid); 84EXPORT_SYMBOL_PROTO(getuid);
85 85
86EXPORT_SYMBOL_PROTO(fsync);
87EXPORT_SYMBOL_PROTO(fdatasync);
88
86/* 89/*
87 * Overrides for Emacs so that we follow Linus's tabbing style. 90 * Overrides for Emacs so that we follow Linus's tabbing style.
88 * Emacs will notice this stuff at the end of the file and automatically 91 * Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/scripts/Makefile.unmap b/arch/um/scripts/Makefile.unmap
index 37a8f9765295..802d027a1e13 100644
--- a/arch/um/scripts/Makefile.unmap
+++ b/arch/um/scripts/Makefile.unmap
@@ -12,8 +12,8 @@ $(obj)/unmap.o: _c_flags = $(call unprofile,$(CFLAGS))
12 12
13quiet_cmd_wrapld = LD $@ 13quiet_cmd_wrapld = LD $@
14define cmd_wrapld 14define cmd_wrapld
15 $(LD) -r -o $(obj)/unmap_tmp.o $< $(shell $(CC) -print-file-name=libc.a); \ 15 $(LD) $(LDFLAGS) -r -o $(obj)/unmap_tmp.o $< $(shell $(CC) $(CFLAGS) -print-file-name=libc.a); \
16 $(OBJCOPY) $(obj)/unmap_tmp.o $@ -G switcheroo 16 $(OBJCOPY) $(UML_OBJCOPYFLAGS) $(obj)/unmap_tmp.o $@ -G switcheroo
17endef 17endef
18 18
19$(obj)/unmap_fin.o : $(obj)/unmap.o FORCE 19$(obj)/unmap_fin.o : $(obj)/unmap.o FORCE
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index dc755b0b9db8..bd3c34aa52e5 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -4,96 +4,106 @@
4 */ 4 */
5 5
6#include "linux/config.h" 6#include "linux/config.h"
7#include "linux/sched.h"
7#include "linux/slab.h" 8#include "linux/slab.h"
9#include "linux/types.h"
8#include "asm/uaccess.h" 10#include "asm/uaccess.h"
9#include "asm/ptrace.h" 11#include "asm/ptrace.h"
12#include "asm/smp.h"
13#include "asm/ldt.h"
10#include "choose-mode.h" 14#include "choose-mode.h"
11#include "kern.h" 15#include "kern.h"
16#include "mode_kern.h"
12 17
13#ifdef CONFIG_MODE_TT 18#ifdef CONFIG_MODE_TT
14extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
15 19
16/* XXX this needs copy_to_user and copy_from_user */ 20extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
17 21
18int sys_modify_ldt_tt(int func, void __user *ptr, unsigned long bytecount) 22static int do_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
19{ 23{
20 if (!access_ok(VERIFY_READ, ptr, bytecount))
21 return -EFAULT;
22
23 return modify_ldt(func, ptr, bytecount); 24 return modify_ldt(func, ptr, bytecount);
24} 25}
26
25#endif 27#endif
26 28
27#ifdef CONFIG_MODE_SKAS 29#ifdef CONFIG_MODE_SKAS
28extern int userspace_pid[];
29 30
31#include "skas.h"
30#include "skas_ptrace.h" 32#include "skas_ptrace.h"
31 33
32int sys_modify_ldt_skas(int func, void __user *ptr, unsigned long bytecount) 34static int do_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
33{ 35{
34 struct ptrace_ldt ldt; 36 struct ptrace_ldt ldt;
35 void *buf; 37 u32 cpu;
36 int res, n; 38 int res;
37 39
38 buf = kmalloc(bytecount, GFP_KERNEL); 40 ldt = ((struct ptrace_ldt) { .func = func,
39 if(buf == NULL) 41 .ptr = ptr,
40 return(-ENOMEM); 42 .bytecount = bytecount });
41 43
42 res = 0; 44 cpu = get_cpu();
45 res = ptrace(PTRACE_LDT, userspace_pid[cpu], 0, (unsigned long) &ldt);
46 put_cpu();
47
48 return res;
49}
50#endif
51
52int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
53{
54 struct user_desc info;
55 int res = 0;
56 void *buf = NULL;
57 void *p = NULL; /* What we pass to host. */
43 58
44 switch(func){ 59 switch(func){
45 case 1: 60 case 1:
46 case 0x11: 61 case 0x11: /* write_ldt */
47 res = copy_from_user(buf, ptr, bytecount); 62 /* Do this check now to avoid overflows. */
48 break; 63 if (bytecount != sizeof(struct user_desc)) {
49 } 64 res = -EINVAL;
65 goto out;
66 }
67
68 if(copy_from_user(&info, ptr, sizeof(info))) {
69 res = -EFAULT;
70 goto out;
71 }
50 72
51 if(res != 0){ 73 p = &info;
52 res = -EFAULT; 74 break;
75 case 0:
76 case 2: /* read_ldt */
77
78 /* The use of info avoids kmalloc on the write case, not on the
79 * read one. */
80 buf = kmalloc(bytecount, GFP_KERNEL);
81 if (!buf) {
82 res = -ENOMEM;
83 goto out;
84 }
85 p = buf;
86 default:
87 res = -ENOSYS;
53 goto out; 88 goto out;
54 } 89 }
55 90
56 ldt = ((struct ptrace_ldt) { .func = func, 91 res = CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,
57 .ptr = buf, 92 p, bytecount);
58 .bytecount = bytecount });
59#warning Need to look up userspace_pid by cpu
60 res = ptrace(PTRACE_LDT, userspace_pid[0], 0, (unsigned long) &ldt);
61 if(res < 0) 93 if(res < 0)
62 goto out; 94 goto out;
63 95
64 switch(func){ 96 switch(func){
65 case 0: 97 case 0:
66 case 2: 98 case 2:
67 n = res; 99 /* Modify_ldt was for reading and returned the number of read
68 res = copy_to_user(ptr, buf, n); 100 * bytes.*/
69 if(res != 0) 101 if(copy_to_user(ptr, p, res))
70 res = -EFAULT; 102 res = -EFAULT;
71 else
72 res = n;
73 break; 103 break;
74 } 104 }
75 105
76 out: 106out:
77 kfree(buf); 107 kfree(buf);
78 return(res); 108 return res;
79}
80#endif
81
82int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
83{
84 return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func,
85 ptr, bytecount));
86} 109}
87
88
89
90/*
91 * Overrides for Emacs so that we follow Linus's tabbing style.
92 * Emacs will notice this stuff at the end of the file and automatically
93 * adjust the settings for this buffer only. This must remain at the end
94 * of the file.
95 * ---------------------------------------------------------------------------
96 * Local variables:
97 * c-file-style: "linux"
98 * End:
99 */
diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c
index b251442ad0b1..68aeabe3a654 100644
--- a/arch/um/sys-i386/stub_segv.c
+++ b/arch/um/sys-i386/stub_segv.c
@@ -21,10 +21,10 @@ stub_segv_handler(int sig)
21 __asm__("movl %0, %%eax ; int $0x80": : "g" (__NR_getpid)); 21 __asm__("movl %0, %%eax ; int $0x80": : "g" (__NR_getpid));
22 __asm__("movl %%eax, %%ebx ; movl %0, %%eax ; movl %1, %%ecx ;" 22 __asm__("movl %%eax, %%ebx ; movl %0, %%eax ; movl %1, %%ecx ;"
23 "int $0x80": : "g" (__NR_kill), "g" (SIGUSR1)); 23 "int $0x80": : "g" (__NR_kill), "g" (SIGUSR1));
24 /* Pop the frame pointer and return address since we need to leave 24 /* Load pointer to sigcontext into esp, since we need to leave
25 * the stack in its original form when we do the sigreturn here, by 25 * the stack in its original form when we do the sigreturn here, by
26 * hand. 26 * hand.
27 */ 27 */
28 __asm__("popl %%eax ; popl %%eax ; popl %%eax ; movl %0, %%eax ; " 28 __asm__("mov %0,%%esp ; movl %1, %%eax ; "
29 "int $0x80" : : "g" (__NR_sigreturn)); 29 "int $0x80" : : "a" (sc), "g" (__NR_sigreturn));
30} 30}
diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c
index 136875263d27..1b0ad0e4adcd 100644
--- a/arch/um/sys-i386/unmap.c
+++ b/arch/um/sys-i386/unmap.c
@@ -15,7 +15,7 @@ int switcheroo(int fd, int prot, void *from, void *to, int size)
15 if(munmap(to, size) < 0){ 15 if(munmap(to, size) < 0){
16 return(-1); 16 return(-1);
17 } 17 }
18 if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){ 18 if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
19 return(-1); 19 return(-1);
20 } 20 }
21 if(munmap(from, size) < 0){ 21 if(munmap(from, size) < 0){
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
index 73a7926f7370..8fdaed06c10d 100644
--- a/arch/um/sys-x86_64/signal.c
+++ b/arch/um/sys-x86_64/signal.c
@@ -168,7 +168,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
168 168
169 frame = (struct rt_sigframe __user *) 169 frame = (struct rt_sigframe __user *)
170 round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8; 170 round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8;
171 ((unsigned char *) frame) -= 128; 171 frame = (struct rt_sigframe *) ((unsigned long) frame - 128);
172 172
173 if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) 173 if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
174 goto out; 174 goto out;
diff --git a/arch/um/sys-x86_64/unmap.c b/arch/um/sys-x86_64/unmap.c
index bc7094cce47e..f4a4bffd8a18 100644
--- a/arch/um/sys-x86_64/unmap.c
+++ b/arch/um/sys-x86_64/unmap.c
@@ -15,7 +15,7 @@ int switcheroo(int fd, int prot, void *from, void *to, int size)
15 if(munmap(to, size) < 0){ 15 if(munmap(to, size) < 0){
16 return(-1); 16 return(-1);
17 } 17 }
18 if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){ 18 if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
19 return(-1); 19 return(-1);
20 } 20 }
21 if(munmap(from, size) < 0){ 21 if(munmap(from, size) < 0){