aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2007-10-16 04:26:50 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:43:05 -0400
commit42fda66387daa53538ae13a2c858396aaf037158 (patch)
tree77955a91a958fde7be47cb0ff23ac9e1248217db /arch/um
parenta1ff5878d2628bbe1e42821c024c96f48318f683 (diff)
uml: throw out CONFIG_MODE_TT
This patchset throws out tt mode, which has been non-functional for a while. This is done in phases, interspersed with code cleanups on the affected files. The removal is done as follows: remove all code, config options, and files which depend on CONFIG_MODE_TT get rid of the CHOOSE_MODE macro, which decided whether to call tt-mode or skas-mode code, and replace invocations with their skas portions replace all now-trivial procedures with their skas equivalents There are now a bunch of now-redundant pieces of data structures, including mode-specific pieces of the thread structure, pt_regs, and mm_context. These are all replaced with their skas-specific contents. As part of the ongoing style compliance project, I made a style pass over all files that were changed. There are three such patches, one for each phase, covering the files affected by that phase but no later ones. I noticed that we weren't freeing the LDT state associated with a process when it exited, so that's fixed in one of the later patches. The last patch is a tidying patch which I've had for a while, but which caused inexplicable crashes under tt mode. Since that is no longer a problem, this can now go in. This patch: Start getting rid of tt mode support. This patch throws out CONFIG_MODE_TT and all config options, code, and files which depend on it. CONFIG_MODE_SKAS is gone and everything that depends on it is included unconditionally. The few changed lines are in re-written Kconfig help, lines which needed something skas-related removed from them, and a few more which weren't strictly deletions. Signed-off-by: Jeff Dike <jdike@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/Kconfig64
-rw-r--r--arch/um/Kconfig.char2
-rw-r--r--arch/um/Kconfig.debug23
-rw-r--r--arch/um/Makefile24
-rw-r--r--arch/um/Makefile-i3866
-rw-r--r--arch/um/defconfig2
-rw-r--r--arch/um/drivers/mconsole_kern.c15
-rw-r--r--arch/um/include/as-layout.h1
-rw-r--r--arch/um/include/choose-mode.h18
-rw-r--r--arch/um/include/common-offsets.h3
-rw-r--r--arch/um/include/irq_user.h4
-rw-r--r--arch/um/include/kern_util.h6
-rw-r--r--arch/um/include/mode.h19
-rw-r--r--arch/um/include/mode_kern.h6
-rw-r--r--arch/um/include/os.h26
-rw-r--r--arch/um/include/sysdep-i386/ptrace.h23
-rw-r--r--arch/um/include/sysdep-i386/sigcontext.h4
-rw-r--r--arch/um/include/sysdep-i386/thread.h3
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace.h21
-rw-r--r--arch/um/include/sysdep-x86_64/thread.h4
-rw-r--r--arch/um/include/tt/debug.h18
-rw-r--r--arch/um/include/tt/mmu-tt.h12
-rw-r--r--arch/um/include/tt/mode-tt.h23
-rw-r--r--arch/um/include/tt/mode_kern_tt.h40
-rw-r--r--arch/um/include/tt/tt.h37
-rw-r--r--arch/um/include/tt/uaccess-tt.h46
-rw-r--r--arch/um/include/um_mmu.h23
-rw-r--r--arch/um/include/um_uaccess.h8
-rw-r--r--arch/um/kernel/Makefile5
-rw-r--r--arch/um/kernel/dyn.lds.S2
-rw-r--r--arch/um/kernel/exec.c1
-rw-r--r--arch/um/kernel/init_task.c7
-rw-r--r--arch/um/kernel/irq.c24
-rw-r--r--arch/um/kernel/ksyms.c10
-rw-r--r--arch/um/kernel/process.c7
-rw-r--r--arch/um/kernel/reboot.c19
-rw-r--r--arch/um/kernel/smp.c5
-rw-r--r--arch/um/kernel/trap.c2
-rw-r--r--arch/um/kernel/tt/Makefile14
-rw-r--r--arch/um/kernel/tt/exec_kern.c84
-rw-r--r--arch/um/kernel/tt/exec_user.c56
-rw-r--r--arch/um/kernel/tt/gdb.c280
-rw-r--r--arch/um/kernel/tt/gdb_kern.c40
-rw-r--r--arch/um/kernel/tt/include/mode-tt.h34
-rw-r--r--arch/um/kernel/tt/ksyms.c29
-rw-r--r--arch/um/kernel/tt/mem.c34
-rw-r--r--arch/um/kernel/tt/mem_user.c49
-rw-r--r--arch/um/kernel/tt/process_kern.c461
-rw-r--r--arch/um/kernel/tt/ptproxy/Makefile10
-rw-r--r--arch/um/kernel/tt/ptproxy/proxy.c377
-rw-r--r--arch/um/kernel/tt/ptproxy/ptproxy.h61
-rw-r--r--arch/um/kernel/tt/ptproxy/ptrace.c237
-rw-r--r--arch/um/kernel/tt/ptproxy/sysdep.c70
-rw-r--r--arch/um/kernel/tt/ptproxy/sysdep.h25
-rw-r--r--arch/um/kernel/tt/ptproxy/wait.c85
-rw-r--r--arch/um/kernel/tt/ptproxy/wait.h15
-rw-r--r--arch/um/kernel/tt/syscall_kern.c46
-rw-r--r--arch/um/kernel/tt/syscall_user.c60
-rw-r--r--arch/um/kernel/tt/tlb.c120
-rw-r--r--arch/um/kernel/tt/tracer.c461
-rw-r--r--arch/um/kernel/tt/trap_user.c70
-rw-r--r--arch/um/kernel/tt/uaccess.c73
-rw-r--r--arch/um/kernel/tt/uaccess_user.c105
-rw-r--r--arch/um/kernel/um_arch.c113
-rw-r--r--arch/um/kernel/uml.lds.S7
-rw-r--r--arch/um/os-Linux/Makefile7
-rw-r--r--arch/um/os-Linux/main.c32
-rw-r--r--arch/um/os-Linux/process.c31
-rw-r--r--arch/um/os-Linux/start_up.c10
-rw-r--r--arch/um/os-Linux/sys-i386/Makefile2
-rw-r--r--arch/um/os-Linux/sys-x86_64/Makefile2
-rw-r--r--arch/um/os-Linux/time.c19
-rw-r--r--arch/um/os-Linux/tls.c36
-rw-r--r--arch/um/scripts/Makefile.rules2
-rw-r--r--arch/um/sys-i386/Makefile10
-rw-r--r--arch/um/sys-i386/ldt.c67
-rw-r--r--arch/um/sys-i386/ptrace.c120
-rw-r--r--arch/um/sys-i386/ptrace_user.c86
-rw-r--r--arch/um/sys-i386/signal.c58
-rw-r--r--arch/um/sys-i386/tls.c16
-rw-r--r--arch/um/sys-i386/unmap.c25
-rw-r--r--arch/um/sys-x86_64/Makefile9
-rw-r--r--arch/um/sys-x86_64/signal.c50
-rw-r--r--arch/um/sys-x86_64/syscalls.c31
-rw-r--r--arch/um/sys-x86_64/unmap.c25
85 files changed, 34 insertions, 4183 deletions
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index e6ff30266542..a0e47e271156 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -62,55 +62,16 @@ config IRQ_RELEASE_METHOD
62 62
63menu "UML-specific options" 63menu "UML-specific options"
64 64
65config MODE_TT
66 bool "Tracing thread support (DEPRECATED)"
67 default n
68 depends on BROKEN
69 help
70 This option controls whether tracing thread support is compiled
71 into UML. This option is largely obsolete, given that skas0 provides
72 skas security and performance without needing to patch the host.
73 It is safe to say 'N' here; saying 'Y' may cause additional problems
74 with the resulting binary even if you run UML in SKAS mode, and running
75 in TT mode is strongly *NOT RECOMMENDED*.
76
77config STATIC_LINK 65config STATIC_LINK
78 bool "Force a static link" 66 bool "Force a static link"
79 default n 67 default n
80 depends on !MODE_TT
81 help 68 help
82 If CONFIG_MODE_TT is disabled, then this option gives you the ability 69 This option gives you the ability to force a static link of UML.
83 to force a static link of UML. Normally, if only skas mode is built 70 Normally, UML is linked as a shared binary. This is inconvenient for
84 in to UML, it will be linked as a shared binary. This is inconvenient 71 use in a chroot jail. So, if you intend to run UML inside a chroot,
85 for use in a chroot jail. So, if you intend to run UML inside a 72 you probably want to say Y here.
86 chroot, and you disable CONFIG_MODE_TT, you probably want to say Y
87 here.
88 Additionally, this option enables using higher memory spaces (up to 73 Additionally, this option enables using higher memory spaces (up to
89 2.75G) for UML - disabling CONFIG_MODE_TT and enabling this option leads 74 2.75G) for UML.
90 to best results for this.
91
92config KERNEL_HALF_GIGS
93 int "Kernel address space size (in .5G units)"
94 default "1"
95 depends on MODE_TT
96 help
97 This determines the amount of address space that UML will allocate for
98 its own, measured in half Gigabyte units. The default is 1.
99 Change this only if you need to boot UML with an unusually large amount
100 of physical memory.
101
102config MODE_SKAS
103 bool "Separate Kernel Address Space support" if MODE_TT
104 default y
105 help
106 This option controls whether skas (separate kernel address space)
107 support is compiled in.
108 Unless you have specific needs to use TT mode (which applies almost only
109 to developers), you should say Y here.
110 SKAS mode will make use of the SKAS3 patch if it is applied on the host
111 (and your UML will run in SKAS3 mode), but if no SKAS patch is applied
112 on the host it will run in SKAS0 mode, which is anyway faster than TT
113 mode.
114 75
115source "arch/um/Kconfig.arch" 76source "arch/um/Kconfig.arch"
116source "mm/Kconfig" 77source "mm/Kconfig"
@@ -118,7 +79,7 @@ source "mm/Kconfig"
118config LD_SCRIPT_STATIC 79config LD_SCRIPT_STATIC
119 bool 80 bool
120 default y 81 default y
121 depends on MODE_TT || STATIC_LINK 82 depends on STATIC_LINK
122 83
123config LD_SCRIPT_DYN 84config LD_SCRIPT_DYN
124 bool 85 bool
@@ -220,7 +181,7 @@ config SMP
220 bool "Symmetric multi-processing support (EXPERIMENTAL)" 181 bool "Symmetric multi-processing support (EXPERIMENTAL)"
221 default n 182 default n
222 #SMP_BROKEN is for x86_64. 183 #SMP_BROKEN is for x86_64.
223 depends on MODE_TT && EXPERIMENTAL && (!SMP_BROKEN || (BROKEN && SMP_BROKEN)) 184 depends on EXPERIMENTAL && (!SMP_BROKEN || (BROKEN && SMP_BROKEN))
224 help 185 help
225 This option enables UML SMP support. 186 This option enables UML SMP support.
226 It is NOT related to having a real SMP box. Not directly, at least. 187 It is NOT related to having a real SMP box. Not directly, at least.
@@ -258,11 +219,6 @@ config NEST_LEVEL
258 inside another UML, set CONFIG_NEST_LEVEL to one more than the host 219 inside another UML, set CONFIG_NEST_LEVEL to one more than the host
259 UML. 220 UML.
260 221
261 Note that if the hosting UML has its CONFIG_KERNEL_HALF_GIGS set to
262 greater than one, then the guest UML should have its CONFIG_NEST_LEVEL
263 set to the host's CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS.
264 Only change this if you are running nested UMLs.
265
266config HIGHMEM 222config HIGHMEM
267 bool "Highmem support (EXPERIMENTAL)" 223 bool "Highmem support (EXPERIMENTAL)"
268 depends on !64BIT && EXPERIMENTAL 224 depends on !64BIT && EXPERIMENTAL
@@ -271,9 +227,9 @@ config HIGHMEM
271 This was used to allow UML to run with big amounts of memory. 227 This was used to allow UML to run with big amounts of memory.
272 Currently it is unstable, so if unsure say N. 228 Currently it is unstable, so if unsure say N.
273 229
274 To use big amounts of memory, it is recommended to disable TT mode (i.e. 230 To use big amounts of memory, it is recommended enable static
275 CONFIG_MODE_TT) and enable static linking (i.e. CONFIG_STATIC_LINK) - 231 linking (i.e. CONFIG_STATIC_LINK) - this should allow the
276 this should allow the guest to use up to 2.75G of memory. 232 guest to use up to 2.75G of memory.
277 233
278config KERNEL_STACK_ORDER 234config KERNEL_STACK_ORDER
279 int "Kernel stack size order" 235 int "Kernel stack size order"
diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char
index a5b079d5e865..1168936fb153 100644
--- a/arch/um/Kconfig.char
+++ b/arch/um/Kconfig.char
@@ -65,8 +65,6 @@ config XTERM_CHAN
65 This option enables support for attaching UML consoles and serial 65 This option enables support for attaching UML consoles and serial
66 lines to xterms. Each UML device so assigned will be brought up in 66 lines to xterms. Each UML device so assigned will be brought up in
67 its own xterm. 67 its own xterm.
68 If you disable this option, then CONFIG_PT_PROXY will be disabled as
69 well, since UML's gdb currently requires an xterm.
70 It is safe to say 'Y' here. 68 It is safe to say 'Y' here.
71 69
72config NOCONFIG_CHAN 70config NOCONFIG_CHAN
diff --git a/arch/um/Kconfig.debug b/arch/um/Kconfig.debug
index c86f5eb29fd5..1eace4bd6616 100644
--- a/arch/um/Kconfig.debug
+++ b/arch/um/Kconfig.debug
@@ -2,28 +2,9 @@ menu "Kernel hacking"
2 2
3source "lib/Kconfig.debug" 3source "lib/Kconfig.debug"
4 4
5config CMDLINE_ON_HOST
6 bool "Show command line arguments on the host in TT mode"
7 depends on MODE_TT
8 default !DEBUG_INFO
9 help
10 This controls whether arguments in guest processes should be shown on
11 the host's ps output.
12 Enabling this option hinders debugging on some recent GDB versions
13 (because GDB gets "confused" when we do an execvp()). So probably you
14 should disable it.
15
16config PT_PROXY
17 bool "Enable ptrace proxy"
18 depends on XTERM_CHAN && DEBUG_INFO && MODE_TT
19 help
20 This option enables a debugging interface which allows gdb to debug
21 the kernel without needing to actually attach to kernel threads.
22 If you want to do kernel debugging, say Y here; otherwise say N.
23
24config GPROF 5config GPROF
25 bool "Enable gprof support" 6 bool "Enable gprof support"
26 depends on DEBUG_INFO && MODE_SKAS && !MODE_TT 7 depends on DEBUG_INFO
27 help 8 help
28 This allows profiling of a User-Mode Linux kernel with the gprof 9 This allows profiling of a User-Mode Linux kernel with the gprof
29 utility. 10 utility.
@@ -36,7 +17,7 @@ config GPROF
36 17
37config GCOV 18config GCOV
38 bool "Enable gcov support" 19 bool "Enable gcov support"
39 depends on DEBUG_INFO && MODE_SKAS 20 depends on DEBUG_INFO
40 help 21 help
41 This option allows developers to retrieve coverage data from a UML 22 This option allows developers to retrieve coverage data from a UML
42 session. 23 session.
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 3efc4ffb32a4..e7aa0535f5d9 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -31,18 +31,9 @@ SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
31ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \ 31ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
32 $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h 32 $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
33 33
34um-modes-$(CONFIG_MODE_TT) += tt 34MODE_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include/skas
35um-modes-$(CONFIG_MODE_SKAS) += skas
36 35
37MODE_INCLUDE += $(foreach mode,$(um-modes-y),\ 36include $(srctree)/$(ARCH_DIR)/Makefile-skas
38 -I$(srctree)/$(ARCH_DIR)/include/$(mode))
39
40MAKEFILES-INCL += $(foreach mode,$(um-modes-y),\
41 $(srctree)/$(ARCH_DIR)/Makefile-$(mode))
42
43ifneq ($(MAKEFILES-INCL),)
44 include $(MAKEFILES-INCL)
45endif
46 37
47ARCH_INCLUDE := -I$(ARCH_DIR)/include 38ARCH_INCLUDE := -I$(ARCH_DIR)/include
48ifneq ($(KBUILD_SRC),) 39ifneq ($(KBUILD_SRC),)
@@ -89,9 +80,8 @@ CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
89# included; the values here are meaningless 80# included; the values here are meaningless
90 81
91CONFIG_NEST_LEVEL ?= 0 82CONFIG_NEST_LEVEL ?= 0
92CONFIG_KERNEL_HALF_GIGS ?= 0
93 83
94SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000) 84SIZE = ($(CONFIG_NEST_LEVEL) * 0x20000000)
95 85
96PHONY += linux 86PHONY += linux
97 87
@@ -124,7 +114,6 @@ CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,)
124 $(call cc-option, -fno-stack-protector,) \ 114 $(call cc-option, -fno-stack-protector,) \
125 $(call cc-option, -fno-stack-protector-all,) 115 $(call cc-option, -fno-stack-protector-all,)
126 116
127CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT
128CONFIG_KERNEL_STACK_ORDER ?= 2 117CONFIG_KERNEL_STACK_ORDER ?= 2
129STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) 118STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
130 119
@@ -132,11 +121,8 @@ ifndef START
132 START = $(shell echo $$[ $(TOP_ADDR) - $(SIZE) ] ) 121 START = $(shell echo $$[ $(TOP_ADDR) - $(SIZE) ] )
133endif 122endif
134 123
135CPPFLAGS_vmlinux.lds = -U$(SUBARCH) \ 124CPPFLAGS_vmlinux.lds = -U$(SUBARCH) -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
136 -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \ 125 -DELF_FORMAT="$(ELF_FORMAT)" -DKERNEL_STACK_SIZE=$(STACK_SIZE)
137 -DELF_FORMAT="$(ELF_FORMAT)" $(CPP_MODE-y) \
138 -DKERNEL_STACK_SIZE=$(STACK_SIZE) \
139 -DUNMAP_PATH=arch/um/sys-$(SUBARCH)/unmap.o
140 126
141#The wrappers will select whether using "malloc" or the kernel allocator. 127#The wrappers will select whether using "malloc" or the kernel allocator.
142LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc 128LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index 60107ed4905b..ae61e3c271e2 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -2,11 +2,7 @@ core-y += arch/um/sys-i386/ arch/x86/crypto/
2 2
3TOP_ADDR := $(CONFIG_TOP_ADDR) 3TOP_ADDR := $(CONFIG_TOP_ADDR)
4 4
5ifeq ($(CONFIG_MODE_SKAS),y) 5START := 0x8048000
6 ifneq ($(CONFIG_MODE_TT),y)
7 START := 0x8048000
8 endif
9endif
10 6
11LDFLAGS += -m elf_i386 7LDFLAGS += -m elf_i386
12ELF_ARCH := $(SUBARCH) 8ELF_ARCH := $(SUBARCH)
diff --git a/arch/um/defconfig b/arch/um/defconfig
index 1e0f677c2f46..ed3196d8c908 100644
--- a/arch/um/defconfig
+++ b/arch/um/defconfig
@@ -12,9 +12,7 @@ CONFIG_IRQ_RELEASE_METHOD=y
12# 12#
13# UML-specific options 13# UML-specific options
14# 14#
15# CONFIG_MODE_TT is not set
16# CONFIG_STATIC_LINK is not set 15# CONFIG_STATIC_LINK is not set
17CONFIG_MODE_SKAS=y
18 16
19# 17#
20# Host processor type and features 18# Host processor type and features
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index d87090507401..4d563b9dde56 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -735,8 +735,6 @@ void mconsole_sysrq(struct mc_request *req)
735} 735}
736#endif 736#endif
737 737
738#ifdef CONFIG_MODE_SKAS
739
740static void stack_proc(void *arg) 738static void stack_proc(void *arg)
741{ 739{
742 struct task_struct *from = current, *to = arg; 740 struct task_struct *from = current, *to = arg;
@@ -750,7 +748,7 @@ static void stack_proc(void *arg)
750 * Dumps a stacks registers to the linux console. 748 * Dumps a stacks registers to the linux console.
751 * Usage stack <pid>. 749 * Usage stack <pid>.
752 */ 750 */
753static void do_stack_trace(struct mc_request *req) 751void mconsole_stack(struct mc_request *req)
754{ 752{
755 char *ptr = req->request.data; 753 char *ptr = req->request.data;
756 int pid_requested= -1; 754 int pid_requested= -1;
@@ -781,17 +779,6 @@ static void do_stack_trace(struct mc_request *req)
781 } 779 }
782 with_console(req, stack_proc, to); 780 with_console(req, stack_proc, to);
783} 781}
784#endif /* CONFIG_MODE_SKAS */
785
786void mconsole_stack(struct mc_request *req)
787{
788 /* This command doesn't work in TT mode, so let's check and then
789 * get out of here
790 */
791 CHOOSE_MODE(mconsole_reply(req, "Sorry, this doesn't work in TT mode",
792 1, 0),
793 do_stack_trace(req));
794}
795 782
796/* Changed by mconsole_setup, which is __setup, and called before SMP is 783/* Changed by mconsole_setup, which is __setup, and called before SMP is
797 * active. 784 * active.
diff --git a/arch/um/include/as-layout.h b/arch/um/include/as-layout.h
index fccf187bf4e1..e44f32940f8a 100644
--- a/arch/um/include/as-layout.h
+++ b/arch/um/include/as-layout.h
@@ -28,7 +28,6 @@ extern unsigned long _unprotected_end;
28extern unsigned long brk_start; 28extern unsigned long brk_start;
29 29
30extern int linux_main(int argc, char **argv); 30extern int linux_main(int argc, char **argv);
31extern void set_cmdline(char *cmd);
32 31
33extern void (*sig_info[])(int, union uml_pt_regs *); 32extern void (*sig_info[])(int, union uml_pt_regs *);
34 33
diff --git a/arch/um/include/choose-mode.h b/arch/um/include/choose-mode.h
index b87b36a87d91..51a387626da2 100644
--- a/arch/um/include/choose-mode.h
+++ b/arch/um/include/choose-mode.h
@@ -8,26 +8,8 @@
8 8
9#include "uml-config.h" 9#include "uml-config.h"
10 10
11#if defined(UML_CONFIG_MODE_TT) && defined(UML_CONFIG_MODE_SKAS)
12#define CHOOSE_MODE(tt, skas) (mode_tt ? (tt) : (skas))
13
14extern int mode_tt;
15static inline void *__choose_mode(void *tt, void *skas) {
16 return mode_tt ? tt : skas;
17}
18
19#define __CHOOSE_MODE(tt, skas) (*( (typeof(tt) *) __choose_mode(&(tt), &(skas))))
20
21#elif defined(UML_CONFIG_MODE_SKAS)
22#define CHOOSE_MODE(tt, skas) (skas) 11#define CHOOSE_MODE(tt, skas) (skas)
23 12
24#elif defined(UML_CONFIG_MODE_TT)
25#define CHOOSE_MODE(tt, skas) (tt)
26
27#else
28#error CONFIG_MODE_SKAS and CONFIG_MODE_TT are both disabled
29#endif
30
31#define CHOOSE_MODE_PROC(tt, skas, args...) \ 13#define CHOOSE_MODE_PROC(tt, skas, args...) \
32 CHOOSE_MODE(tt(args), skas(args)) 14 CHOOSE_MODE(tt(args), skas(args))
33 15
diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h
index 2378ff42e41c..439b91f141a5 100644
--- a/arch/um/include/common-offsets.h
+++ b/arch/um/include/common-offsets.h
@@ -1,9 +1,6 @@
1/* for use by sys-$SUBARCH/kernel-offsets.c */ 1/* for use by sys-$SUBARCH/kernel-offsets.c */
2 2
3DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); 3DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE);
4#ifdef CONFIG_MODE_TT
5OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
6#endif
7 4
8OFFSET(HOST_TASK_REGS, task_struct, thread.regs); 5OFFSET(HOST_TASK_REGS, task_struct, thread.regs);
9OFFSET(HOST_TASK_PID, task_struct, pid); 6OFFSET(HOST_TASK_PID, task_struct, pid);
diff --git a/arch/um/include/irq_user.h b/arch/um/include/irq_user.h
index 15d311b9be9e..741cb7d6f859 100644
--- a/arch/um/include/irq_user.h
+++ b/arch/um/include/irq_user.h
@@ -30,8 +30,4 @@ extern void deactivate_fd(int fd, int irqnum);
30extern int deactivate_all_fds(void); 30extern int deactivate_all_fds(void);
31extern int activate_ipi(int fd, int pid); 31extern int activate_ipi(int fd, int pid);
32 32
33#ifdef CONFIG_MODE_TT
34extern void forward_interrupts(int pid);
35#endif
36
37#endif 33#endif
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index b84b5dadb958..578156db3039 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -34,9 +34,6 @@ extern int nsyscalls;
34 UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1) 34 UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1)
35 35
36extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg); 36extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg);
37#ifdef UML_CONFIG_MODE_TT
38extern unsigned long stack_sp(unsigned long page);
39#endif
40extern int kernel_thread_proc(void *data); 37extern int kernel_thread_proc(void *data);
41extern void syscall_segv(int sig); 38extern void syscall_segv(int sig);
42extern int current_pid(void); 39extern int current_pid(void);
@@ -82,9 +79,6 @@ extern void check_stack_overflow(void *ptr);
82extern void relay_signal(int sig, union uml_pt_regs *regs); 79extern void relay_signal(int sig, union uml_pt_regs *regs);
83extern int user_context(unsigned long sp); 80extern int user_context(unsigned long sp);
84extern void timer_irq(union uml_pt_regs *regs); 81extern void timer_irq(union uml_pt_regs *regs);
85#ifdef CONFIG_MODE_TT
86extern void unprotect_stack(unsigned long stack);
87#endif
88extern void do_uml_exitcalls(void); 82extern void do_uml_exitcalls(void);
89extern int attach_debugger(int idle_pid, int pid, int stop); 83extern int attach_debugger(int idle_pid, int pid, int stop);
90extern int config_gdb(char *str); 84extern int config_gdb(char *str);
diff --git a/arch/um/include/mode.h b/arch/um/include/mode.h
index 786cf563eb05..fcce95cbc16a 100644
--- a/arch/um/include/mode.h
+++ b/arch/um/include/mode.h
@@ -6,25 +6,6 @@
6#ifndef __MODE_H__ 6#ifndef __MODE_H__
7#define __MODE_H__ 7#define __MODE_H__
8 8
9#include "uml-config.h"
10
11#ifdef UML_CONFIG_MODE_TT
12#include "mode-tt.h"
13#endif
14
15#ifdef UML_CONFIG_MODE_SKAS
16#include "mode-skas.h" 9#include "mode-skas.h"
17#endif
18 10
19#endif 11#endif
20
21/*
22 * Overrides for Emacs so that we follow Linus's tabbing style.
23 * Emacs will notice this stuff at the end of the file and automatically
24 * adjust the settings for this buffer only. This must remain at the end
25 * of the file.
26 * ---------------------------------------------------------------------------
27 * Local variables:
28 * c-file-style: "linux"
29 * End:
30 */
diff --git a/arch/um/include/mode_kern.h b/arch/um/include/mode_kern.h
index 88e5e77bf517..b2a44c0dcd00 100644
--- a/arch/um/include/mode_kern.h
+++ b/arch/um/include/mode_kern.h
@@ -6,12 +6,6 @@
6#ifndef __MODE_KERN_H__ 6#ifndef __MODE_KERN_H__
7#define __MODE_KERN_H__ 7#define __MODE_KERN_H__
8 8
9#ifdef CONFIG_MODE_TT
10#include "mode_kern_tt.h"
11#endif
12
13#ifdef CONFIG_MODE_SKAS
14#include "mode_kern_skas.h" 9#include "mode_kern_skas.h"
15#endif
16 10
17#endif 11#endif
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index c0803e67fc67..208d9b91fc93 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -178,11 +178,7 @@ extern void check_host_supports_tls(int *supports_tls, int *tls_min);
178 178
179/* Make sure they are clear when running in TT mode. Required by 179/* Make sure they are clear when running in TT mode. Required by
180 * SEGV_MAYBE_FIXABLE */ 180 * SEGV_MAYBE_FIXABLE */
181#ifdef UML_CONFIG_MODE_SKAS
182#define clear_can_do_skas() do { ptrace_faultinfo = proc_mm = 0; } while (0) 181#define clear_can_do_skas() do { ptrace_faultinfo = proc_mm = 0; } while (0)
183#else
184#define clear_can_do_skas() do {} while (0)
185#endif
186 182
187/* mem.c */ 183/* mem.c */
188extern int create_mem_file(unsigned long long len); 184extern int create_mem_file(unsigned long long len);
@@ -193,18 +189,11 @@ extern int os_process_parent(int pid);
193extern void os_stop_process(int pid); 189extern void os_stop_process(int pid);
194extern void os_kill_process(int pid, int reap_child); 190extern void os_kill_process(int pid, int reap_child);
195extern void os_kill_ptraced_process(int pid, int reap_child); 191extern void os_kill_ptraced_process(int pid, int reap_child);
196#ifdef UML_CONFIG_MODE_TT
197extern void os_usr1_process(int pid);
198#endif
199extern long os_ptrace_ldt(long pid, long addr, long data); 192extern long os_ptrace_ldt(long pid, long addr, long data);
200 193
201extern int os_getpid(void); 194extern int os_getpid(void);
202extern int os_getpgrp(void); 195extern int os_getpgrp(void);
203 196
204#ifdef UML_CONFIG_MODE_TT
205extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
206extern void stop(void);
207#endif
208extern void init_new_thread_signals(void); 197extern void init_new_thread_signals(void);
209extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr); 198extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
210 199
@@ -217,18 +206,6 @@ extern int os_drop_memory(void *addr, int length);
217extern int can_drop_memory(void); 206extern int can_drop_memory(void);
218extern void os_flush_stdout(void); 207extern void os_flush_stdout(void);
219 208
220/* tt.c
221 * for tt mode only (will be deleted in future...)
222 */
223extern void forward_ipi(int fd, int pid);
224extern void kill_child_dead(int pid);
225extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
226extern int protect_memory(unsigned long addr, unsigned long len,
227 int r, int w, int x, int must_succeed);
228extern void forward_pending_sigio(int target);
229extern int start_fork_tramp(void *arg, unsigned long temp_stack,
230 int clone_flags, int (*tramp)(void *));
231
232/* uaccess.c */ 209/* uaccess.c */
233extern unsigned long __do_user_copy(void *to, const void *from, int n, 210extern unsigned long __do_user_copy(void *to, const void *from, int n,
234 void **fault_addr, void **fault_catcher, 211 void **fault_addr, void **fault_catcher,
@@ -281,9 +258,6 @@ extern void os_dump_core(void);
281extern void switch_timers(int to_real); 258extern void switch_timers(int to_real);
282extern void idle_sleep(int secs); 259extern void idle_sleep(int secs);
283extern int set_interval(int is_virtual); 260extern int set_interval(int is_virtual);
284#ifdef CONFIG_MODE_TT
285extern void enable_timer(void);
286#endif
287extern void disable_timer(void); 261extern void disable_timer(void);
288extern void uml_idle_timer(void); 262extern void uml_idle_timer(void);
289extern unsigned long long os_nsecs(void); 263extern unsigned long long os_nsecs(void);
diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h
index b45a72feb08c..c0ea4dbd042b 100644
--- a/arch/um/include/sysdep-i386/ptrace.h
+++ b/arch/um/include/sysdep-i386/ptrace.h
@@ -14,12 +14,7 @@
14#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) 14#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long))
15#define MAX_REG_OFFSET (UM_FRAME_SIZE) 15#define MAX_REG_OFFSET (UM_FRAME_SIZE)
16 16
17#ifdef UML_CONFIG_PT_PROXY
18extern void update_debugregs(int seq);
19#else
20static inline void update_debugregs(int seq) {} 17static inline void update_debugregs(int seq) {}
21#endif
22
23 18
24/* syscall emulation path in ptrace */ 19/* syscall emulation path in ptrace */
25 20
@@ -31,12 +26,6 @@ void set_using_sysemu(int value);
31int get_using_sysemu(void); 26int get_using_sysemu(void);
32extern int sysemu_supported; 27extern int sysemu_supported;
33 28
34#ifdef UML_CONFIG_MODE_TT
35#include "sysdep/sc.h"
36#endif
37
38#ifdef UML_CONFIG_MODE_SKAS
39
40#include "skas_ptregs.h" 29#include "skas_ptregs.h"
41 30
42#define REGS_IP(r) ((r)[HOST_IP]) 31#define REGS_IP(r) ((r)[HOST_IP])
@@ -60,20 +49,11 @@ extern int sysemu_supported;
60 49
61#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) 50#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
62 51
63#endif
64#ifndef PTRACE_SYSEMU_SINGLESTEP 52#ifndef PTRACE_SYSEMU_SINGLESTEP
65#define PTRACE_SYSEMU_SINGLESTEP 32 53#define PTRACE_SYSEMU_SINGLESTEP 32
66#endif 54#endif
67 55
68union uml_pt_regs { 56union uml_pt_regs {
69#ifdef UML_CONFIG_MODE_TT
70 struct tt_regs {
71 long syscall;
72 void *sc;
73 struct faultinfo faultinfo;
74 } tt;
75#endif
76#ifdef UML_CONFIG_MODE_SKAS
77 struct skas_regs { 57 struct skas_regs {
78 unsigned long regs[MAX_REG_NR]; 58 unsigned long regs[MAX_REG_NR];
79 unsigned long fp[HOST_FP_SIZE]; 59 unsigned long fp[HOST_FP_SIZE];
@@ -82,13 +62,10 @@ union uml_pt_regs {
82 long syscall; 62 long syscall;
83 int is_user; 63 int is_user;
84 } skas; 64 } skas;
85#endif
86}; 65};
87 66
88#define EMPTY_UML_PT_REGS { } 67#define EMPTY_UML_PT_REGS { }
89 68
90extern int mode_tt;
91
92#define UPT_SC(r) ((r)->tt.sc) 69#define UPT_SC(r) ((r)->tt.sc)
93#define UPT_IP(r) \ 70#define UPT_IP(r) \
94 __CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs)) 71 __CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs))
diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
index 23fd2644d7ed..8658634ca4f4 100644
--- a/arch/um/include/sysdep-i386/sigcontext.h
+++ b/arch/um/include/sysdep-i386/sigcontext.h
@@ -30,11 +30,7 @@
30#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) 30#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
31 31
32/* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */ 32/* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */
33#ifdef UML_CONFIG_MODE_SKAS
34#define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo) 33#define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo)
35#else
36#define SEGV_MAYBE_FIXABLE(fi) 0
37#endif
38 34
39extern unsigned long *sc_sigmask(void *sc_ptr); 35extern unsigned long *sc_sigmask(void *sc_ptr);
40extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); 36extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
diff --git a/arch/um/include/sysdep-i386/thread.h b/arch/um/include/sysdep-i386/thread.h
index 243fed44d780..0cf7bf6e9e04 100644
--- a/arch/um/include/sysdep-i386/thread.h
+++ b/arch/um/include/sysdep-i386/thread.h
@@ -4,8 +4,5 @@
4#include <kern_constants.h> 4#include <kern_constants.h>
5 5
6#define TASK_DEBUGREGS(task) ((unsigned long *) &(((char *) (task))[HOST_TASK_DEBUGREGS])) 6#define TASK_DEBUGREGS(task) ((unsigned long *) &(((char *) (task))[HOST_TASK_DEBUGREGS]))
7#ifdef UML_CONFIG_MODE_TT
8#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[HOST_TASK_EXTERN_PID]))
9#endif
10 7
11#endif 8#endif
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
index 62403bd99661..ff525bda4c11 100644
--- a/arch/um/include/sysdep-x86_64/ptrace.h
+++ b/arch/um/include/sysdep-x86_64/ptrace.h
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright 2003 PathScale, Inc. 2 * Copyright 2003 PathScale, Inc.
3 * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * 4 *
4 * Licensed under the GPL 5 * Licensed under the GPL
5 */ 6 */
@@ -14,11 +15,6 @@
14#define MAX_REG_OFFSET (UM_FRAME_SIZE) 15#define MAX_REG_OFFSET (UM_FRAME_SIZE)
15#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long)) 16#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long))
16 17
17#ifdef UML_CONFIG_MODE_TT
18#include "sysdep/sc.h"
19#endif
20
21#ifdef UML_CONFIG_MODE_SKAS
22#include "skas_ptregs.h" 18#include "skas_ptregs.h"
23 19
24#define REGS_IP(r) ((r)[HOST_IP]) 20#define REGS_IP(r) ((r)[HOST_IP])
@@ -88,21 +84,10 @@
88 84
89#define REGS_ERR(r) ((r)->fault_type) 85#define REGS_ERR(r) ((r)->fault_type)
90 86
91#endif
92
93#include "choose-mode.h" 87#include "choose-mode.h"
94 88
95/* XXX */ 89/* XXX */
96union uml_pt_regs { 90union uml_pt_regs {
97#ifdef UML_CONFIG_MODE_TT
98 struct tt_regs {
99 long syscall;
100 unsigned long orig_rax;
101 void *sc;
102 struct faultinfo faultinfo;
103 } tt;
104#endif
105#ifdef UML_CONFIG_MODE_SKAS
106 struct skas_regs { 91 struct skas_regs {
107 unsigned long regs[MAX_REG_NR]; 92 unsigned long regs[MAX_REG_NR];
108 unsigned long fp[HOST_FP_SIZE]; 93 unsigned long fp[HOST_FP_SIZE];
@@ -110,14 +95,10 @@ union uml_pt_regs {
110 long syscall; 95 long syscall;
111 int is_user; 96 int is_user;
112 } skas; 97 } skas;
113#endif
114}; 98};
115 99
116#define EMPTY_UML_PT_REGS { } 100#define EMPTY_UML_PT_REGS { }
117 101
118/* XXX */
119extern int mode_tt;
120
121#define UPT_RBX(r) __CHOOSE_MODE(SC_RBX(UPT_SC(r)), REGS_RBX((r)->skas.regs)) 102#define UPT_RBX(r) __CHOOSE_MODE(SC_RBX(UPT_SC(r)), REGS_RBX((r)->skas.regs))
122#define UPT_RCX(r) __CHOOSE_MODE(SC_RCX(UPT_SC(r)), REGS_RCX((r)->skas.regs)) 103#define UPT_RCX(r) __CHOOSE_MODE(SC_RCX(UPT_SC(r)), REGS_RCX((r)->skas.regs))
123#define UPT_RDX(r) __CHOOSE_MODE(SC_RDX(UPT_SC(r)), REGS_RDX((r)->skas.regs)) 104#define UPT_RDX(r) __CHOOSE_MODE(SC_RDX(UPT_SC(r)), REGS_RDX((r)->skas.regs))
diff --git a/arch/um/include/sysdep-x86_64/thread.h b/arch/um/include/sysdep-x86_64/thread.h
index cbef3e1697f4..d73d0b0afdb7 100644
--- a/arch/um/include/sysdep-x86_64/thread.h
+++ b/arch/um/include/sysdep-x86_64/thread.h
@@ -3,8 +3,4 @@
3 3
4#include <kern_constants.h> 4#include <kern_constants.h>
5 5
6#ifdef UML_CONFIG_MODE_TT
7#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[HOST_TASK_EXTERN_PID]))
8#endif
9
10#endif 6#endif
diff --git a/arch/um/include/tt/debug.h b/arch/um/include/tt/debug.h
deleted file mode 100644
index 9778fa838296..000000000000
--- a/arch/um/include/tt/debug.h
+++ /dev/null
@@ -1,18 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) and
3 * Lars Brinkhoff.
4 * Licensed under the GPL
5 */
6
7#ifndef __UML_TT_DEBUG_H
8#define __UML_TT_DEBUG_H
9
10extern int debugger_proxy(int status, pid_t pid);
11extern void child_proxy(pid_t pid, int status);
12extern void init_proxy (pid_t pid, int waiting, int status);
13extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd);
14extern void fake_child_exit(void);
15extern int gdb_config(char *str);
16extern int gdb_remove(int unused);
17
18#endif
diff --git a/arch/um/include/tt/mmu-tt.h b/arch/um/include/tt/mmu-tt.h
deleted file mode 100644
index 572a78b22587..000000000000
--- a/arch/um/include/tt/mmu-tt.h
+++ /dev/null
@@ -1,12 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __TT_MMU_H
7#define __TT_MMU_H
8
9struct mmu_context_tt {
10};
11
12#endif
diff --git a/arch/um/include/tt/mode-tt.h b/arch/um/include/tt/mode-tt.h
deleted file mode 100644
index 2823cd56eea2..000000000000
--- a/arch/um/include/tt/mode-tt.h
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __MODE_TT_H__
7#define __MODE_TT_H__
8
9#include "sysdep/ptrace.h"
10
11enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
12
13extern int tracing_pid;
14
15extern int tracer(int (*init_proc)(void *), void *sp);
16extern void sig_handler_common_tt(int sig, void *sc);
17extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
18extern void reboot_tt(void);
19extern void halt_tt(void);
20extern int is_tracer_winch(int pid, int fd, void *data);
21extern void kill_off_processes_tt(void);
22
23#endif
diff --git a/arch/um/include/tt/mode_kern_tt.h b/arch/um/include/tt/mode_kern_tt.h
deleted file mode 100644
index a4fc63057195..000000000000
--- a/arch/um/include/tt/mode_kern_tt.h
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __TT_MODE_KERN_H__
7#define __TT_MODE_KERN_H__
8
9#include "linux/sched.h"
10#include "asm/page.h"
11#include "asm/ptrace.h"
12#include "asm/uaccess.h"
13
14extern void switch_to_tt(void *prev, void *next);
15extern void flush_thread_tt(void);
16extern void start_thread_tt(struct pt_regs *regs, unsigned long eip,
17 unsigned long esp);
18extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
19 unsigned long stack_top, struct task_struct *p,
20 struct pt_regs *regs);
21extern void release_thread_tt(struct task_struct *task);
22extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
23extern void init_idle_tt(void);
24extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end);
25extern void flush_tlb_kernel_vm_tt(void);
26extern void __flush_tlb_one_tt(unsigned long addr);
27extern void flush_tlb_range_tt(struct vm_area_struct *vma,
28 unsigned long start, unsigned long end);
29extern void flush_tlb_mm_tt(struct mm_struct *mm);
30extern void force_flush_all_tt(void);
31extern long execute_syscall_tt(void *r);
32extern void before_mem_tt(unsigned long brk_start);
33extern unsigned long set_task_sizes_tt(unsigned long *task_size_out);
34extern int start_uml_tt(void);
35extern int external_pid_tt(struct task_struct *task);
36extern int thread_pid_tt(struct task_struct *task);
37
38#define kmem_end_tt (host_task_size - ABOVE_KMEM)
39
40#endif
diff --git a/arch/um/include/tt/tt.h b/arch/um/include/tt/tt.h
deleted file mode 100644
index acb8356e1f98..000000000000
--- a/arch/um/include/tt/tt.h
+++ /dev/null
@@ -1,37 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __TT_H__
7#define __TT_H__
8
9#include "sysdep/ptrace.h"
10
11extern int gdb_pid;
12extern int debug;
13extern int debug_stop;
14extern int debug_trace;
15
16extern int honeypot;
17
18extern int fork_tramp(void *sig_stack);
19extern int do_proc_op(void *t, int proc_id);
20extern int tracer(int (*init_proc)(void *), void *sp);
21extern void attach_process(int pid);
22extern void tracer_panic(char *format, ...)
23 __attribute__ ((format (printf, 1, 2)));
24extern void set_init_pid(int pid);
25extern int set_user_mode(void *task);
26extern void set_tracing(void *t, int tracing);
27extern int is_tracing(void *task);
28extern void syscall_handler(int sig, union uml_pt_regs *regs);
29extern void exit_kernel(int pid, void *task);
30extern void do_syscall(void *task, int pid, int local_using_sysemu);
31extern void do_sigtrap(void *task);
32extern int is_valid_pid(int pid);
33extern void remap_data(void *segment_start, void *segment_end, int w);
34extern long execute_syscall_tt(void *r);
35
36#endif
37
diff --git a/arch/um/include/tt/uaccess-tt.h b/arch/um/include/tt/uaccess-tt.h
deleted file mode 100644
index 13a64f61fcf4..000000000000
--- a/arch/um/include/tt/uaccess-tt.h
+++ /dev/null
@@ -1,46 +0,0 @@
1/*
2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __TT_UACCESS_H
7#define __TT_UACCESS_H
8
9#include "linux/string.h"
10#include "linux/sched.h"
11#include "asm/processor.h"
12#include "asm/errno.h"
13#include "asm/current.h"
14#include "asm/a.out.h"
15#include "uml_uaccess.h"
16
17#define ABOVE_KMEM (16 * 1024 * 1024)
18
19extern unsigned long end_vm;
20extern unsigned long uml_physmem;
21
22#define is_stack(addr, size) \
23 (((unsigned long) (addr) < STACK_TOP) && \
24 ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \
25 (((unsigned long) (addr) + (size)) <= STACK_TOP))
26
27#define access_ok_tt(type, addr, size) \
28 (is_stack(addr, size))
29
30extern int __do_copy_from_user(void *to, const void *from, int n,
31 void **fault_addr, void **fault_catcher);
32extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
33 void **fault_addr, void **fault_catcher);
34extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
35 void **fault_catcher);
36extern int __do_strnlen_user(const char *str, unsigned long n,
37 void **fault_addr, void **fault_catcher);
38
39extern int copy_from_user_tt(void *to, const void __user *from, int n);
40extern int copy_to_user_tt(void __user *to, const void *from, int n);
41extern int strncpy_from_user_tt(char *dst, const char __user *src, int count);
42extern int __clear_user_tt(void __user *mem, int len);
43extern int clear_user_tt(void __user *mem, int len);
44extern int strnlen_user_tt(const void __user *str, int len);
45
46#endif
diff --git a/arch/um/include/um_mmu.h b/arch/um/include/um_mmu.h
index 0fa643238300..2461be6b0a60 100644
--- a/arch/um/include/um_mmu.h
+++ b/arch/um/include/um_mmu.h
@@ -8,33 +8,10 @@
8 8
9#include "uml-config.h" 9#include "uml-config.h"
10#include "choose-mode.h" 10#include "choose-mode.h"
11
12#ifdef UML_CONFIG_MODE_TT
13#include "mmu-tt.h"
14#endif
15
16#ifdef UML_CONFIG_MODE_SKAS
17#include "mmu-skas.h" 11#include "mmu-skas.h"
18#endif
19 12
20typedef union mm_context { 13typedef union mm_context {
21#ifdef UML_CONFIG_MODE_TT
22 struct mmu_context_tt tt;
23#endif
24#ifdef UML_CONFIG_MODE_SKAS
25 struct mmu_context_skas skas; 14 struct mmu_context_skas skas;
26#endif
27} mm_context_t; 15} mm_context_t;
28 16
29#endif 17#endif
30
31/*
32 * Overrides for Emacs so that we follow Linus's tabbing style.
33 * Emacs will notice this stuff at the end of the file and automatically
34 * adjust the settings for this buffer only. This must remain at the end
35 * of the file.
36 * ---------------------------------------------------------------------------
37 * Local variables:
38 * c-file-style: "linux"
39 * End:
40 */
diff --git a/arch/um/include/um_uaccess.h b/arch/um/include/um_uaccess.h
index 5126a99b5961..6757ee768ccb 100644
--- a/arch/um/include/um_uaccess.h
+++ b/arch/um/include/um_uaccess.h
@@ -7,15 +7,7 @@
7#define __ARCH_UM_UACCESS_H 7#define __ARCH_UM_UACCESS_H
8 8
9#include "choose-mode.h" 9#include "choose-mode.h"
10
11#ifdef CONFIG_MODE_TT
12#include "uaccess-tt.h"
13#endif
14
15#ifdef CONFIG_MODE_SKAS
16#include "uaccess-skas.h" 10#include "uaccess-skas.h"
17#endif
18
19#include "asm/fixmap.h" 11#include "asm/fixmap.h"
20 12
21#define __under_task_size(addr, size) \ 13#define __under_task_size(addr, size) \
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index c5cf4a0827b0..6651937a2d26 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -9,15 +9,12 @@ clean-files :=
9obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \ 9obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \
10 physmem.o process.o ptrace.o reboot.o sigio.o \ 10 physmem.o process.o ptrace.o reboot.o sigio.o \
11 signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o uaccess.o \ 11 signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o uaccess.o \
12 um_arch.o umid.o 12 um_arch.o umid.o skas/
13 13
14obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o 14obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
15obj-$(CONFIG_GPROF) += gprof_syms.o 15obj-$(CONFIG_GPROF) += gprof_syms.o
16obj-$(CONFIG_GCOV) += gmon_syms.o 16obj-$(CONFIG_GCOV) += gmon_syms.o
17 17
18obj-$(CONFIG_MODE_TT) += tt/
19obj-$(CONFIG_MODE_SKAS) += skas/
20
21USER_OBJS := config.o 18USER_OBJS := config.o
22 19
23include arch/um/scripts/Makefile.rules 20include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index 41850906116e..3866f4960f04 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -10,8 +10,6 @@ SECTIONS
10 PROVIDE (__executable_start = START); 10 PROVIDE (__executable_start = START);
11 . = START + SIZEOF_HEADERS; 11 . = START + SIZEOF_HEADERS;
12 .interp : { *(.interp) } 12 .interp : { *(.interp) }
13 /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start
14 * is remapped.*/
15 __binary_start = .; 13 __binary_start = .;
16 . = ALIGN(4096); /* Init code and data */ 14 . = ALIGN(4096); /* Init code and data */
17 _text = .; 15 _text = .;
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
index ce6828fd396f..84d77a0d138c 100644
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -57,7 +57,6 @@ static long execve1(char *file, char __user * __user *argv,
57 SUBARCH_EXECVE1(&current->thread.regs.regs); 57 SUBARCH_EXECVE1(&current->thread.regs.regs);
58#endif 58#endif
59 task_unlock(current); 59 task_unlock(current);
60 set_cmdline(current_cmd());
61 } 60 }
62 return(error); 61 return(error);
63} 62}
diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c
index fa90db964b28..33055082356e 100644
--- a/arch/um/kernel/init_task.c
+++ b/arch/um/kernel/init_task.c
@@ -46,10 +46,3 @@ union thread_union init_thread_union
46union thread_union cpu0_irqstack 46union thread_union cpu0_irqstack
47 __attribute__((__section__(".data.init_irqstack"))) = 47 __attribute__((__section__(".data.init_irqstack"))) =
48 { INIT_THREAD_INFO(init_task) }; 48 { INIT_THREAD_INFO(init_task) };
49
50#ifdef CONFIG_MODE_TT
51void unprotect_stack(unsigned long stack)
52{
53 os_protect_memory((void *) stack, THREAD_SIZE, 1, 1, 0);
54}
55#endif
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index cf0dd9cf8c43..ec1ed680032b 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -339,30 +339,6 @@ int deactivate_all_fds(void)
339 return 0; 339 return 0;
340} 340}
341 341
342#ifdef CONFIG_MODE_TT
343void forward_interrupts(int pid)
344{
345 struct irq_fd *irq;
346 unsigned long flags;
347 int err;
348
349 spin_lock_irqsave(&irq_lock, flags);
350 for (irq = active_fds; irq != NULL; irq = irq->next) {
351 err = os_set_owner(irq->fd, pid);
352 if (err < 0) {
353 /* XXX Just remove the irq rather than
354 * print out an infinite stream of these
355 */
356 printk("Failed to forward %d to pid %d, err = %d\n",
357 irq->fd, pid, -err);
358 }
359
360 irq->pid = pid;
361 }
362 spin_unlock_irqrestore(&irq_lock, flags);
363}
364#endif
365
366/* 342/*
367 * do_IRQ handles all normal device IRQ's (the special 343 * do_IRQ handles all normal device IRQ's (the special
368 * SMP cross-CPU interrupts have their own specific 344 * SMP cross-CPU interrupts have their own specific
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index 7b3e53fb8070..59e22d27b239 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -34,24 +34,14 @@ EXPORT_SYMBOL(get_kmem_end);
34EXPORT_SYMBOL(high_physmem); 34EXPORT_SYMBOL(high_physmem);
35EXPORT_SYMBOL(empty_zero_page); 35EXPORT_SYMBOL(empty_zero_page);
36EXPORT_SYMBOL(um_virt_to_phys); 36EXPORT_SYMBOL(um_virt_to_phys);
37EXPORT_SYMBOL(mode_tt);
38EXPORT_SYMBOL(handle_page_fault); 37EXPORT_SYMBOL(handle_page_fault);
39EXPORT_SYMBOL(find_iomem); 38EXPORT_SYMBOL(find_iomem);
40 39
41#ifdef CONFIG_MODE_TT
42EXPORT_SYMBOL(stop);
43EXPORT_SYMBOL(strncpy_from_user_tt);
44EXPORT_SYMBOL(copy_from_user_tt);
45EXPORT_SYMBOL(copy_to_user_tt);
46#endif
47
48#ifdef CONFIG_MODE_SKAS
49EXPORT_SYMBOL(strnlen_user_skas); 40EXPORT_SYMBOL(strnlen_user_skas);
50EXPORT_SYMBOL(strncpy_from_user_skas); 41EXPORT_SYMBOL(strncpy_from_user_skas);
51EXPORT_SYMBOL(copy_to_user_skas); 42EXPORT_SYMBOL(copy_to_user_skas);
52EXPORT_SYMBOL(copy_from_user_skas); 43EXPORT_SYMBOL(copy_from_user_skas);
53EXPORT_SYMBOL(clear_user_skas); 44EXPORT_SYMBOL(clear_user_skas);
54#endif
55EXPORT_SYMBOL(uml_strdup); 45EXPORT_SYMBOL(uml_strdup);
56 46
57EXPORT_SYMBOL(os_stat_fd); 47EXPORT_SYMBOL(os_stat_fd);
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index f083787410af..005ed44d4a8e 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -183,13 +183,6 @@ void initial_thread_cb(void (*proc)(void *), void *arg)
183 kmalloc_ok = save_kmalloc_ok; 183 kmalloc_ok = save_kmalloc_ok;
184} 184}
185 185
186#ifdef CONFIG_MODE_TT
187unsigned long stack_sp(unsigned long page)
188{
189 return page + PAGE_SIZE - sizeof(void *);
190}
191#endif
192
193void default_idle(void) 186void default_idle(void)
194{ 187{
195 CHOOSE_MODE(uml_idle_timer(), (void) 0); 188 CHOOSE_MODE(uml_idle_timer(), (void) 0);
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index 7e4305a1fd3c..93df0672d022 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -14,28 +14,9 @@
14 14
15void (*pm_power_off)(void); 15void (*pm_power_off)(void);
16 16
17#ifdef CONFIG_SMP
18static void kill_idlers(int me)
19{
20#ifdef CONFIG_MODE_TT
21 struct task_struct *p;
22 int i;
23
24 for(i = 0; i < ARRAY_SIZE(idle_threads); i++){
25 p = idle_threads[i];
26 if((p != NULL) && (p->thread.mode.tt.extern_pid != me))
27 os_kill_process(p->thread.mode.tt.extern_pid, 0);
28 }
29#endif
30}
31#endif
32
33static void kill_off_processes(void) 17static void kill_off_processes(void)
34{ 18{
35 CHOOSE_MODE(kill_off_processes_tt(), kill_off_processes_skas()); 19 CHOOSE_MODE(kill_off_processes_tt(), kill_off_processes_skas());
36#ifdef CONFIG_SMP
37 kill_idlers(os_getpid());
38#endif
39} 20}
40 21
41void uml_cleanup(void) 22void uml_cleanup(void)
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
index e6a7778006ad..15bb54365779 100644
--- a/arch/um/kernel/smp.c
+++ b/arch/um/kernel/smp.c
@@ -95,7 +95,6 @@ static int idle_proc(void *cpup)
95static struct task_struct *idle_thread(int cpu) 95static struct task_struct *idle_thread(int cpu)
96{ 96{
97 struct task_struct *new_task; 97 struct task_struct *new_task;
98 unsigned char c;
99 98
100 current->thread.request.u.thread.proc = idle_proc; 99 current->thread.request.u.thread.proc = idle_proc;
101 current->thread.request.u.thread.arg = (void *) cpu; 100 current->thread.request.u.thread.arg = (void *) cpu;
@@ -108,9 +107,7 @@ static struct task_struct *idle_thread(int cpu)
108 { .pid = new_task->thread.mode.tt.extern_pid, 107 { .pid = new_task->thread.mode.tt.extern_pid,
109 .task = new_task } ); 108 .task = new_task } );
110 idle_threads[cpu] = new_task; 109 idle_threads[cpu] = new_task;
111 CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c, 110 panic("skas mode doesn't support SMP");
112 sizeof(c)),
113 ({ panic("skas mode doesn't support SMP"); }));
114 return new_task; 111 return new_task;
115} 112}
116 113
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index 3850d53f79fd..c517c449d0dd 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -29,9 +29,7 @@
29#include "sysdep/sigcontext.h" 29#include "sysdep/sigcontext.h"
30#include "sysdep/ptrace.h" 30#include "sysdep/ptrace.h"
31#include "os.h" 31#include "os.h"
32#ifdef CONFIG_MODE_SKAS
33#include "skas.h" 32#include "skas.h"
34#endif
35#include "os.h" 33#include "os.h"
36 34
37/* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */ 35/* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */
diff --git a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile
deleted file mode 100644
index 6939e5af8472..000000000000
--- a/arch/um/kernel/tt/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
1#
2# Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
3# Licensed under the GPL
4#
5
6obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
7 syscall_kern.o syscall_user.o tlb.o tracer.o trap_user.o \
8 uaccess.o uaccess_user.o
9
10obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/
11
12USER_OBJS := gdb.o tracer.o
13
14include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c
deleted file mode 100644
index 40126cb51801..000000000000
--- a/arch/um/kernel/tt/exec_kern.c
+++ /dev/null
@@ -1,84 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/kernel.h"
7#include "linux/mm.h"
8#include "asm/signal.h"
9#include "asm/ptrace.h"
10#include "asm/uaccess.h"
11#include "asm/pgalloc.h"
12#include "asm/tlbflush.h"
13#include "kern_util.h"
14#include "irq_user.h"
15#include "mem_user.h"
16#include "os.h"
17#include "tlb.h"
18#include "mode.h"
19
20static int exec_tramp(void *sig_stack)
21{
22 init_new_thread_stack(sig_stack, NULL);
23 init_new_thread_signals();
24 os_stop_process(os_getpid());
25 return(0);
26}
27
28void flush_thread_tt(void)
29{
30 unsigned long stack;
31 int new_pid;
32
33 stack = alloc_stack(0, 0);
34 if(stack == 0){
35 printk(KERN_ERR
36 "flush_thread : failed to allocate temporary stack\n");
37 do_exit(SIGKILL);
38 }
39
40 new_pid = start_fork_tramp(task_stack_page(current), stack, 0, exec_tramp);
41 if(new_pid < 0){
42 printk(KERN_ERR
43 "flush_thread : new thread failed, errno = %d\n",
44 -new_pid);
45 do_exit(SIGKILL);
46 }
47
48 if(current_thread->cpu == 0)
49 forward_interrupts(new_pid);
50 current->thread.request.op = OP_EXEC;
51 current->thread.request.u.exec.pid = new_pid;
52 unprotect_stack((unsigned long) current_thread);
53 os_usr1_process(os_getpid());
54 change_sig(SIGUSR1, 1);
55
56 change_sig(SIGUSR1, 0);
57 enable_timer();
58 free_page(stack);
59 protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
60 stack_protections((unsigned long) current_thread);
61 force_flush_all();
62 unblock_signals();
63}
64
65void start_thread_tt(struct pt_regs *regs, unsigned long eip,
66 unsigned long esp)
67{
68 set_fs(USER_DS);
69 flush_tlb_mm(current->mm);
70 PT_REGS_IP(regs) = eip;
71 PT_REGS_SP(regs) = esp;
72 PT_FIX_EXEC_STACK(esp);
73}
74
75/*
76 * Overrides for Emacs so that we follow Linus's tabbing style.
77 * Emacs will notice this stuff at the end of the file and automatically
78 * adjust the settings for this buffer only. This must remain at the end
79 * of the file.
80 * ---------------------------------------------------------------------------
81 * Local variables:
82 * c-file-style: "linux"
83 * End:
84 */
diff --git a/arch/um/kernel/tt/exec_user.c b/arch/um/kernel/tt/exec_user.c
deleted file mode 100644
index 7b5f2181cf51..000000000000
--- a/arch/um/kernel/tt/exec_user.c
+++ /dev/null
@@ -1,56 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdio.h>
7#include <unistd.h>
8#include <stdlib.h>
9#include <sched.h>
10#include <errno.h>
11#include <sys/wait.h>
12#include <signal.h>
13#include "kern_util.h"
14#include "user.h"
15#include "ptrace_user.h"
16#include "os.h"
17
18void do_exec(int old_pid, int new_pid)
19{
20 unsigned long regs[FRAME_SIZE];
21 int err;
22
23 if((ptrace(PTRACE_ATTACH, new_pid, 0, 0) < 0) ||
24 (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0))
25 tracer_panic("do_exec failed to attach proc - errno = %d",
26 errno);
27
28 CATCH_EINTR(err = waitpid(new_pid, 0, WUNTRACED));
29 if (err < 0)
30 tracer_panic("do_exec failed to attach proc in waitpid - errno = %d",
31 errno);
32
33 if(ptrace_getregs(old_pid, regs) < 0)
34 tracer_panic("do_exec failed to get registers - errno = %d",
35 errno);
36
37 os_kill_ptraced_process(old_pid, 0);
38
39 if (ptrace(PTRACE_OLDSETOPTIONS, new_pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
40 tracer_panic("do_exec: PTRACE_SETOPTIONS failed, errno = %d", errno);
41
42 if(ptrace_setregs(new_pid, regs) < 0)
43 tracer_panic("do_exec failed to start new proc - errno = %d",
44 errno);
45}
46
47/*
48 * Overrides for Emacs so that we follow Linus's tabbing style.
49 * Emacs will notice this stuff at the end of the file and automatically
50 * adjust the settings for this buffer only. This must remain at the end
51 * of the file.
52 * ---------------------------------------------------------------------------
53 * Local variables:
54 * c-file-style: "linux"
55 * End:
56 */
diff --git a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c
deleted file mode 100644
index 030e4658f36b..000000000000
--- a/arch/um/kernel/tt/gdb.c
+++ /dev/null
@@ -1,280 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <errno.h>
9#include <string.h>
10#include <signal.h>
11#include <sys/types.h>
12#include "ptrace_user.h"
13#include "uml-config.h"
14#include "kern_constants.h"
15#include "chan_user.h"
16#include "init.h"
17#include "user.h"
18#include "debug.h"
19#include "kern_util.h"
20#include "tt.h"
21#include "sysdep/thread.h"
22#include "os.h"
23
24extern int debugger_pid;
25extern int debugger_fd;
26extern int debugger_parent;
27
28int detach(int pid, int sig)
29{
30 return(ptrace(PTRACE_DETACH, pid, 0, sig));
31}
32
33int attach(int pid)
34{
35 int err;
36
37 err = ptrace(PTRACE_ATTACH, pid, 0, 0);
38 if(err < 0) return(-errno);
39 else return(err);
40}
41
42int cont(int pid)
43{
44 return(ptrace(PTRACE_CONT, pid, 0, 0));
45}
46
47#ifdef UML_CONFIG_PT_PROXY
48
49int debugger_signal(int status, pid_t pid)
50{
51 return(debugger_proxy(status, pid));
52}
53
54void child_signal(pid_t pid, int status)
55{
56 child_proxy(pid, status);
57}
58
59static void gdb_announce(char *dev_name, int dev)
60{
61 printf("gdb assigned device '%s'\n", dev_name);
62}
63
64static struct chan_opts opts = {
65 .announce = gdb_announce,
66 .xterm_title = "UML kernel debugger",
67 .raw = 0,
68 .tramp_stack = 0,
69 .in_kernel = 0,
70};
71
72/* Accessed by the tracing thread, which automatically serializes access */
73static void *xterm_data;
74static int xterm_fd;
75
76extern void *xterm_init(char *, int, struct chan_opts *);
77extern int xterm_open(int, int, int, void *, char **);
78extern void xterm_close(int, void *);
79
80int open_gdb_chan(void)
81{
82 char stack[UM_KERN_PAGE_SIZE], *dummy;
83
84 opts.tramp_stack = (unsigned long) stack;
85 xterm_data = xterm_init("", 0, &opts);
86 xterm_fd = xterm_open(1, 1, 1, xterm_data, &dummy);
87 return(xterm_fd);
88}
89
90static void exit_debugger_cb(void *unused)
91{
92 if(debugger_pid != -1){
93 if(gdb_pid != -1){
94 fake_child_exit();
95 gdb_pid = -1;
96 }
97 else kill_child_dead(debugger_pid);
98 debugger_pid = -1;
99 if(debugger_parent != -1)
100 detach(debugger_parent, SIGINT);
101 }
102 if(xterm_data != NULL) xterm_close(xterm_fd, xterm_data);
103}
104
105static void exit_debugger(void)
106{
107 initial_thread_cb(exit_debugger_cb, NULL);
108}
109
110__uml_exitcall(exit_debugger);
111
112struct gdb_data {
113 char *str;
114 int err;
115};
116
117extern char *linux_prog;
118
119static void config_gdb_cb(void *arg)
120{
121 struct gdb_data *data = arg;
122 void *task;
123 int pid;
124
125 data->err = -1;
126 if(debugger_pid != -1) exit_debugger_cb(NULL);
127 if(!strncmp(data->str, "pid,", strlen("pid,"))){
128 data->str += strlen("pid,");
129 pid = strtoul(data->str, NULL, 0);
130 task = cpu_tasks[0].task;
131 debugger_pid = attach_debugger(TASK_EXTERN_PID(task), pid, 0);
132 if(debugger_pid != -1){
133 data->err = 0;
134 gdb_pid = pid;
135 }
136 return;
137 }
138 data->err = 0;
139 debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
140 init_proxy(debugger_pid, 0, 0);
141}
142
143int gdb_config(char *str, char **error_out)
144{
145 struct gdb_data data;
146
147 if(*str++ != '=') return(-1);
148 data.str = str;
149 initial_thread_cb(config_gdb_cb, &data);
150 return(data.err);
151}
152
153void remove_gdb_cb(void *unused)
154{
155 exit_debugger_cb(NULL);
156}
157
158int gdb_remove(int unused, char **error_out)
159{
160 initial_thread_cb(remove_gdb_cb, NULL);
161 return 0;
162}
163
164void signal_usr1(int sig)
165{
166 if(debugger_pid != -1){
167 printf("The debugger is already running\n");
168 return;
169 }
170 debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
171 init_proxy(debugger_pid, 0, 0);
172}
173
174int init_ptrace_proxy(int idle_pid, int startup, int stop)
175{
176 int pid, status;
177
178 pid = start_debugger(linux_prog, startup, stop, &debugger_fd);
179 status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
180 if(pid < 0){
181 cont(idle_pid);
182 return(-1);
183 }
184 init_proxy(pid, 1, status);
185 return(pid);
186}
187
188int attach_debugger(int idle_pid, int pid, int stop)
189{
190 int status = 0, err;
191
192 err = attach(pid);
193 if(err < 0){
194 printf("Failed to attach pid %d, errno = %d\n", pid, -err);
195 return(-1);
196 }
197 if(stop) status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
198 init_proxy(pid, 1, status);
199 return(pid);
200}
201
202#ifdef notdef /* Put this back in when it does something useful */
203static int __init uml_gdb_init_setup(char *line, int *add)
204{
205 gdb_init = uml_strdup(line);
206 return 0;
207}
208
209__uml_setup("gdb=", uml_gdb_init_setup,
210"gdb=<channel description>\n\n"
211);
212#endif
213
214static int __init uml_gdb_pid_setup(char *line, int *add)
215{
216 gdb_pid = strtoul(line, NULL, 0);
217 *add = 0;
218 return 0;
219}
220
221__uml_setup("gdb-pid=", uml_gdb_pid_setup,
222"gdb-pid=<pid>\n"
223" gdb-pid is used to attach an external debugger to UML. This may be\n"
224" an already-running gdb or a debugger-like process like strace.\n\n"
225);
226
227#else
228
229int debugger_signal(int status, pid_t pid){ return(0); }
230void child_signal(pid_t pid, int status){ }
231int init_ptrace_proxy(int idle_pid, int startup, int stop)
232{
233 printf("debug requested when CONFIG_PT_PROXY is off\n");
234 kill_child_dead(idle_pid);
235 exit(1);
236}
237
238void signal_usr1(int sig)
239{
240 printf("debug requested when CONFIG_PT_PROXY is off\n");
241}
242
243int attach_debugger(int idle_pid, int pid, int stop)
244{
245 printf("attach_debugger called when CONFIG_PT_PROXY "
246 "is off\n");
247 return(-1);
248}
249
250int config_gdb(char *str)
251{
252 return(-1);
253}
254
255int remove_gdb(void)
256{
257 return(-1);
258}
259
260int init_parent_proxy(int pid)
261{
262 return(-1);
263}
264
265void debugger_parent_signal(int status, int pid)
266{
267}
268
269#endif
270
271/*
272 * Overrides for Emacs so that we follow Linus's tabbing style.
273 * Emacs will notice this stuff at the end of the file and automatically
274 * adjust the settings for this buffer only. This must remain at the end
275 * of the file.
276 * ---------------------------------------------------------------------------
277 * Local variables:
278 * c-file-style: "linux"
279 * End:
280 */
diff --git a/arch/um/kernel/tt/gdb_kern.c b/arch/um/kernel/tt/gdb_kern.c
deleted file mode 100644
index 03b06bc00771..000000000000
--- a/arch/um/kernel/tt/gdb_kern.c
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/init.h"
7#include "mconsole_kern.h"
8
9#ifdef CONFIG_MCONSOLE
10
11extern int gdb_config(char *str, char **error_out);
12extern int gdb_remove(int n, char **error_out);
13
14static struct mc_device gdb_mc = {
15 .list = INIT_LIST_HEAD(gdb_mc.list),
16 .name = "gdb",
17 .config = gdb_config,
18 .remove = gdb_remove,
19};
20
21int gdb_mc_init(void)
22{
23 mconsole_register_dev(&gdb_mc);
24 return(0);
25}
26
27__initcall(gdb_mc_init);
28
29#endif
30
31/*
32 * Overrides for Emacs so that we follow Linus's tabbing style.
33 * Emacs will notice this stuff at the end of the file and automatically
34 * adjust the settings for this buffer only. This must remain at the end
35 * of the file.
36 * ---------------------------------------------------------------------------
37 * Local variables:
38 * c-file-style: "linux"
39 * End:
40 */
diff --git a/arch/um/kernel/tt/include/mode-tt.h b/arch/um/kernel/tt/include/mode-tt.h
deleted file mode 100644
index e171e15fead5..000000000000
--- a/arch/um/kernel/tt/include/mode-tt.h
+++ /dev/null
@@ -1,34 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __MODE_TT_H__
7#define __MODE_TT_H__
8
9#include "sysdep/ptrace.h"
10
11enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
12
13extern int tracing_pid;
14
15extern int tracer(int (*init_proc)(void *), void *sp);
16extern void sig_handler_common_tt(int sig, void *sc);
17extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
18extern void reboot_tt(void);
19extern void halt_tt(void);
20extern int is_tracer_winch(int pid, int fd, void *data);
21extern void kill_off_processes_tt(void);
22
23#endif
24
25/*
26 * Overrides for Emacs so that we follow Linus's tabbing style.
27 * Emacs will notice this stuff at the end of the file and automatically
28 * adjust the settings for this buffer only. This must remain at the end
29 * of the file.
30 * ---------------------------------------------------------------------------
31 * Local variables:
32 * c-file-style: "linux"
33 * End:
34 */
diff --git a/arch/um/kernel/tt/ksyms.c b/arch/um/kernel/tt/ksyms.c
deleted file mode 100644
index 84a9385a8fef..000000000000
--- a/arch/um/kernel/tt/ksyms.c
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/module.h"
7#include "asm/uaccess.h"
8#include "mode.h"
9
10EXPORT_SYMBOL(__do_copy_from_user);
11EXPORT_SYMBOL(__do_copy_to_user);
12EXPORT_SYMBOL(__do_strncpy_from_user);
13EXPORT_SYMBOL(__do_strnlen_user);
14EXPORT_SYMBOL(__do_clear_user);
15EXPORT_SYMBOL(clear_user_tt);
16
17EXPORT_SYMBOL(tracing_pid);
18EXPORT_SYMBOL(honeypot);
19
20/*
21 * Overrides for Emacs so that we follow Linus's tabbing style.
22 * Emacs will notice this stuff at the end of the file and automatically
23 * adjust the settings for this buffer only. This must remain at the end
24 * of the file.
25 * ---------------------------------------------------------------------------
26 * Local variables:
27 * c-file-style: "linux"
28 * End:
29 */
diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c
deleted file mode 100644
index d0c3c4975f28..000000000000
--- a/arch/um/kernel/tt/mem.c
+++ /dev/null
@@ -1,34 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/stddef.h"
7#include "linux/mm.h"
8#include "asm/uaccess.h"
9#include "mem_user.h"
10#include "kern_util.h"
11#include "kern.h"
12#include "tt.h"
13
14void before_mem_tt(unsigned long brk_start)
15{
16 if(debug)
17 remap_data(UML_ROUND_DOWN(&_stext), UML_ROUND_UP(&_etext), 1);
18 remap_data(UML_ROUND_DOWN(&_sdata), UML_ROUND_UP(&_edata), 1);
19 remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1);
20}
21
22#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
23#define START (CONFIG_TOP_ADDR - SIZE)
24
25unsigned long set_task_sizes_tt(unsigned long *task_size_out)
26{
27 unsigned long host_task_size;
28
29 /* Round up to the nearest 4M */
30 host_task_size = ROUND_4M((unsigned long) &host_task_size);
31 *task_size_out = START;
32
33 return host_task_size;
34}
diff --git a/arch/um/kernel/tt/mem_user.c b/arch/um/kernel/tt/mem_user.c
deleted file mode 100644
index 9774f6360c32..000000000000
--- a/arch/um/kernel/tt/mem_user.c
+++ /dev/null
@@ -1,49 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdlib.h>
7#include <stdio.h>
8#include <unistd.h>
9#include <string.h>
10#include <errno.h>
11#include <sys/mman.h>
12#include "tt.h"
13#include "mem_user.h"
14#include "os.h"
15
16void remap_data(void *segment_start, void *segment_end, int w)
17{
18 void *addr;
19 unsigned long size;
20 int data, prot;
21
22 if(w) prot = PROT_WRITE;
23 else prot = 0;
24 prot |= PROT_READ | PROT_EXEC;
25 size = (unsigned long) segment_end -
26 (unsigned long) segment_start;
27 data = create_mem_file(size);
28 addr = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, data, 0);
29 if(addr == MAP_FAILED){
30 perror("mapping new data segment");
31 exit(1);
32 }
33 memcpy(addr, segment_start, size);
34 if(switcheroo(data, prot, addr, segment_start, size) < 0){
35 printf("switcheroo failed\n");
36 exit(1);
37 }
38}
39
40/*
41 * Overrides for Emacs so that we follow Linus's tabbing style.
42 * Emacs will notice this stuff at the end of the file and automatically
43 * adjust the settings for this buffer only. This must remain at the end
44 * of the file.
45 * ---------------------------------------------------------------------------
46 * Local variables:
47 * c-file-style: "linux"
48 * End:
49 */
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
deleted file mode 100644
index 74347adf81bf..000000000000
--- a/arch/um/kernel/tt/process_kern.c
+++ /dev/null
@@ -1,461 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/sched.h"
7#include "linux/signal.h"
8#include "linux/kernel.h"
9#include "linux/interrupt.h"
10#include "linux/ptrace.h"
11#include "asm/system.h"
12#include "asm/pgalloc.h"
13#include "asm/ptrace.h"
14#include "asm/tlbflush.h"
15#include "irq_user.h"
16#include "kern_util.h"
17#include "os.h"
18#include "kern.h"
19#include "sigcontext.h"
20#include "mem_user.h"
21#include "tlb.h"
22#include "mode.h"
23#include "mode_kern.h"
24#include "init.h"
25#include "tt.h"
26
27void switch_to_tt(void *prev, void *next)
28{
29 struct task_struct *from, *to, *prev_sched;
30 unsigned long flags;
31 int err, vtalrm, alrm, prof, cpu;
32 char c;
33
34 from = prev;
35 to = next;
36
37 cpu = task_thread_info(from)->cpu;
38 if(cpu == 0)
39 forward_interrupts(to->thread.mode.tt.extern_pid);
40#ifdef CONFIG_SMP
41 forward_ipi(cpu_data[cpu].ipi_pipe[0], to->thread.mode.tt.extern_pid);
42#endif
43 local_irq_save(flags);
44
45 vtalrm = change_sig(SIGVTALRM, 0);
46 alrm = change_sig(SIGALRM, 0);
47 prof = change_sig(SIGPROF, 0);
48
49 forward_pending_sigio(to->thread.mode.tt.extern_pid);
50
51 c = 0;
52
53 /* Notice that here we "up" the semaphore on which "to" is waiting, and
54 * below (the read) we wait on this semaphore (which is implemented by
55 * switch_pipe) and go sleeping. Thus, after that, we have resumed in
56 * "to", and can't use any more the value of "from" (which is outdated),
57 * nor the value in "to" (since it was the task which stole us the CPU,
58 * which we don't care about). */
59
60 err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
61 if(err != sizeof(c))
62 panic("write of switch_pipe failed, err = %d", -err);
63
64 if(from->thread.mode.tt.switch_pipe[0] == -1)
65 os_kill_process(os_getpid(), 0);
66
67 err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c,
68 sizeof(c));
69 if(err != sizeof(c))
70 panic("read of switch_pipe failed, errno = %d", -err);
71
72 /* If the process that we have just scheduled away from has exited,
73 * then it needs to be killed here. The reason is that, even though
74 * it will kill itself when it next runs, that may be too late. Its
75 * stack will be freed, possibly before then, and if that happens,
76 * we have a use-after-free situation. So, it gets killed here
77 * in case it has not already killed itself.
78 */
79 prev_sched = current->thread.prev_sched;
80 if(prev_sched->thread.mode.tt.switch_pipe[0] == -1)
81 os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1);
82
83 change_sig(SIGVTALRM, vtalrm);
84 change_sig(SIGALRM, alrm);
85 change_sig(SIGPROF, prof);
86
87 arch_switch_to_tt(prev_sched, current);
88
89 flush_tlb_all();
90 local_irq_restore(flags);
91}
92
93void release_thread_tt(struct task_struct *task)
94{
95 int pid = task->thread.mode.tt.extern_pid;
96
97 /*
98 * We first have to kill the other process, before
99 * closing its switch_pipe. Else it might wake up
100 * and receive "EOF" before we could kill it.
101 */
102 if(os_getpid() != pid)
103 os_kill_process(pid, 0);
104
105 os_close_file(task->thread.mode.tt.switch_pipe[0]);
106 os_close_file(task->thread.mode.tt.switch_pipe[1]);
107 /* use switch_pipe as flag: thread is released */
108 task->thread.mode.tt.switch_pipe[0] = -1;
109}
110
111void suspend_new_thread(int fd)
112{
113 int err;
114 char c;
115
116 os_stop_process(os_getpid());
117 err = os_read_file(fd, &c, sizeof(c));
118 if(err != sizeof(c))
119 panic("read failed in suspend_new_thread, err = %d", -err);
120}
121
122void schedule_tail(struct task_struct *prev);
123
124static void new_thread_handler(int sig)
125{
126 unsigned long disable;
127 int (*fn)(void *);
128 void *arg;
129
130 fn = current->thread.request.u.thread.proc;
131 arg = current->thread.request.u.thread.arg;
132
133 UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
134 disable = (1 << (SIGVTALRM - 1)) | (1 << (SIGALRM - 1)) |
135 (1 << (SIGIO - 1)) | (1 << (SIGPROF - 1));
136 SC_SIGMASK(UPT_SC(&current->thread.regs.regs)) &= ~disable;
137
138 suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
139
140 force_flush_all();
141 if(current->thread.prev_sched != NULL)
142 schedule_tail(current->thread.prev_sched);
143 current->thread.prev_sched = NULL;
144
145 init_new_thread_signals();
146 enable_timer();
147 free_page(current->thread.temp_stack);
148 set_cmdline("(kernel thread)");
149
150 change_sig(SIGUSR1, 1);
151 change_sig(SIGPROF, 1);
152 local_irq_enable();
153 if(!run_kernel_thread(fn, arg, &current->thread.exec_buf))
154 do_exit(0);
155
156 /* XXX No set_user_mode here because a newly execed process will
157 * immediately segfault on its non-existent IP, coming straight back
158 * to the signal handler, which will call set_user_mode on its way
159 * out. This should probably change since it's confusing.
160 */
161}
162
163static int new_thread_proc(void *stack)
164{
165 /* local_irq_disable is needed to block out signals until this thread is
166 * properly scheduled. Otherwise, the tracing thread will get mighty
167 * upset about any signals that arrive before that.
168 * This has the complication that it sets the saved signal mask in
169 * the sigcontext to block signals. This gets restored when this
170 * thread (or a descendant, since they get a copy of this sigcontext)
171 * returns to userspace.
172 * So, this is compensated for elsewhere.
173 * XXX There is still a small window until local_irq_disable() actually
174 * finishes where signals are possible - shouldn't be a problem in
175 * practice since SIGIO hasn't been forwarded here yet, and the
176 * local_irq_disable should finish before a SIGVTALRM has time to be
177 * delivered.
178 */
179
180 local_irq_disable();
181 init_new_thread_stack(stack, new_thread_handler);
182 os_usr1_process(os_getpid());
183 change_sig(SIGUSR1, 1);
184 return(0);
185}
186
187/* Signal masking - signals are blocked at the start of fork_tramp. They
188 * are re-enabled when finish_fork_handler is entered by fork_tramp hitting
189 * itself with a SIGUSR1. set_user_mode has to be run with SIGUSR1 off,
190 * so it is blocked before it's called. They are re-enabled on sigreturn
191 * despite the fact that they were blocked when the SIGUSR1 was issued because
192 * copy_thread copies the parent's sigcontext, including the signal mask
193 * onto the signal frame.
194 */
195
196void finish_fork_handler(int sig)
197{
198 UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
199 suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
200
201 force_flush_all();
202 if(current->thread.prev_sched != NULL)
203 schedule_tail(current->thread.prev_sched);
204 current->thread.prev_sched = NULL;
205
206 enable_timer();
207 change_sig(SIGVTALRM, 1);
208 local_irq_enable();
209 if(current->mm != current->parent->mm)
210 protect_memory(uml_reserved, high_physmem - uml_reserved, 1,
211 1, 0, 1);
212 stack_protections((unsigned long) current_thread);
213
214 free_page(current->thread.temp_stack);
215 local_irq_disable();
216 change_sig(SIGUSR1, 0);
217 set_user_mode(current);
218}
219
220int fork_tramp(void *stack)
221{
222 local_irq_disable();
223 arch_init_thread();
224 init_new_thread_stack(stack, finish_fork_handler);
225
226 os_usr1_process(os_getpid());
227 change_sig(SIGUSR1, 1);
228 return(0);
229}
230
231int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
232 unsigned long stack_top, struct task_struct * p,
233 struct pt_regs *regs)
234{
235 int (*tramp)(void *);
236 int new_pid, err;
237 unsigned long stack;
238
239 if(current->thread.forking)
240 tramp = fork_tramp;
241 else {
242 tramp = new_thread_proc;
243 p->thread.request.u.thread = current->thread.request.u.thread;
244 }
245
246 err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1);
247 if(err < 0){
248 printk("copy_thread : pipe failed, err = %d\n", -err);
249 return(err);
250 }
251
252 stack = alloc_stack(0, 0);
253 if(stack == 0){
254 printk(KERN_ERR "copy_thread : failed to allocate "
255 "temporary stack\n");
256 return(-ENOMEM);
257 }
258
259 clone_flags &= CLONE_VM;
260 p->thread.temp_stack = stack;
261 new_pid = start_fork_tramp(task_stack_page(p), stack, clone_flags, tramp);
262 if(new_pid < 0){
263 printk(KERN_ERR "copy_thread : clone failed - errno = %d\n",
264 -new_pid);
265 return(new_pid);
266 }
267
268 if(current->thread.forking){
269 sc_to_sc(UPT_SC(&p->thread.regs.regs), UPT_SC(&regs->regs));
270 SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0);
271 if(sp != 0)
272 SC_SP(UPT_SC(&p->thread.regs.regs)) = sp;
273 }
274 p->thread.mode.tt.extern_pid = new_pid;
275
276 current->thread.request.op = OP_FORK;
277 current->thread.request.u.fork.pid = new_pid;
278 os_usr1_process(os_getpid());
279
280 /* Enable the signal and then disable it to ensure that it is handled
281 * here, and nowhere else.
282 */
283 change_sig(SIGUSR1, 1);
284
285 change_sig(SIGUSR1, 0);
286 err = 0;
287 return(err);
288}
289
290void reboot_tt(void)
291{
292 current->thread.request.op = OP_REBOOT;
293 os_usr1_process(os_getpid());
294 change_sig(SIGUSR1, 1);
295}
296
297void halt_tt(void)
298{
299 current->thread.request.op = OP_HALT;
300 os_usr1_process(os_getpid());
301 change_sig(SIGUSR1, 1);
302}
303
304void kill_off_processes_tt(void)
305{
306 struct task_struct *p;
307 int me;
308
309 me = os_getpid();
310 for_each_process(p){
311 if(p->thread.mode.tt.extern_pid != me)
312 os_kill_process(p->thread.mode.tt.extern_pid, 0);
313 }
314 if(init_task.thread.mode.tt.extern_pid != me)
315 os_kill_process(init_task.thread.mode.tt.extern_pid, 0);
316}
317
318void initial_thread_cb_tt(void (*proc)(void *), void *arg)
319{
320 if(os_getpid() == tracing_pid){
321 (*proc)(arg);
322 }
323 else {
324 current->thread.request.op = OP_CB;
325 current->thread.request.u.cb.proc = proc;
326 current->thread.request.u.cb.arg = arg;
327 os_usr1_process(os_getpid());
328 change_sig(SIGUSR1, 1);
329
330 change_sig(SIGUSR1, 0);
331 }
332}
333
334int do_proc_op(void *t, int proc_id)
335{
336 struct task_struct *task;
337 struct thread_struct *thread;
338 int op, pid;
339
340 task = t;
341 thread = &task->thread;
342 op = thread->request.op;
343 switch(op){
344 case OP_NONE:
345 case OP_TRACE_ON:
346 break;
347 case OP_EXEC:
348 pid = thread->request.u.exec.pid;
349 do_exec(thread->mode.tt.extern_pid, pid);
350 thread->mode.tt.extern_pid = pid;
351 cpu_tasks[task_thread_info(task)->cpu].pid = pid;
352 break;
353 case OP_FORK:
354 attach_process(thread->request.u.fork.pid);
355 break;
356 case OP_CB:
357 (*thread->request.u.cb.proc)(thread->request.u.cb.arg);
358 break;
359 case OP_REBOOT:
360 case OP_HALT:
361 break;
362 default:
363 tracer_panic("Bad op in do_proc_op");
364 break;
365 }
366 thread->request.op = OP_NONE;
367 return(op);
368}
369
370void init_idle_tt(void)
371{
372 default_idle();
373}
374
375extern void start_kernel(void);
376
377static int start_kernel_proc(void *unused)
378{
379 int pid;
380
381 block_signals();
382 pid = os_getpid();
383
384 cpu_tasks[0].pid = pid;
385 cpu_tasks[0].task = current;
386#ifdef CONFIG_SMP
387 cpu_online_map = cpumask_of_cpu(0);
388#endif
389 if(debug) os_stop_process(pid);
390 start_kernel();
391 return(0);
392}
393
394void set_tracing(void *task, int tracing)
395{
396 ((struct task_struct *) task)->thread.mode.tt.tracing = tracing;
397}
398
399int is_tracing(void *t)
400{
401 return (((struct task_struct *) t)->thread.mode.tt.tracing);
402}
403
404int set_user_mode(void *t)
405{
406 struct task_struct *task;
407
408 task = t ? t : current;
409 if(task->thread.mode.tt.tracing)
410 return(1);
411 task->thread.request.op = OP_TRACE_ON;
412 os_usr1_process(os_getpid());
413 return(0);
414}
415
416void set_init_pid(int pid)
417{
418 int err;
419
420 init_task.thread.mode.tt.extern_pid = pid;
421 err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1);
422 if(err)
423 panic("Can't create switch pipe for init_task, errno = %d",
424 -err);
425}
426
427int start_uml_tt(void)
428{
429 void *sp;
430 int pages;
431
432 pages = (1 << CONFIG_KERNEL_STACK_ORDER);
433 sp = task_stack_page(&init_task) +
434 pages * PAGE_SIZE - sizeof(unsigned long);
435 return(tracer(start_kernel_proc, sp));
436}
437
438int external_pid_tt(struct task_struct *task)
439{
440 return(task->thread.mode.tt.extern_pid);
441}
442
443int thread_pid_tt(struct task_struct *task)
444{
445 return(task->thread.mode.tt.extern_pid);
446}
447
448int is_valid_pid(int pid)
449{
450 struct task_struct *task;
451
452 read_lock(&tasklist_lock);
453 for_each_process(task){
454 if(task->thread.mode.tt.extern_pid == pid){
455 read_unlock(&tasklist_lock);
456 return(1);
457 }
458 }
459 read_unlock(&tasklist_lock);
460 return(0);
461}
diff --git a/arch/um/kernel/tt/ptproxy/Makefile b/arch/um/kernel/tt/ptproxy/Makefile
deleted file mode 100644
index 3ad5b774de59..000000000000
--- a/arch/um/kernel/tt/ptproxy/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
1#
2# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3# Licensed under the GPL
4#
5
6obj-y = proxy.o ptrace.o sysdep.o wait.o
7
8USER_OBJS := $(obj-y)
9
10include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c
deleted file mode 100644
index 420c23f311f3..000000000000
--- a/arch/um/kernel/tt/ptproxy/proxy.c
+++ /dev/null
@@ -1,377 +0,0 @@
1/**********************************************************************
2proxy.c
3
4Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
5terms and conditions.
6
7Jeff Dike (jdike@karaya.com) : Modified for integration into uml
8**********************************************************************/
9
10/* XXX This file shouldn't refer to CONFIG_* */
11
12#include <errno.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <unistd.h>
16#include <signal.h>
17#include <string.h>
18#include <termios.h>
19#include <sys/wait.h>
20#include <sys/types.h>
21#include <sys/ioctl.h>
22#include <asm/unistd.h>
23#include "ptrace_user.h"
24
25#include "ptproxy.h"
26#include "sysdep.h"
27#include "wait.h"
28
29#include "user.h"
30#include "os.h"
31#include "tempfile.h"
32
33static int debugger_wait(debugger_state *debugger, int *status, int options,
34 int (*syscall)(debugger_state *debugger, pid_t child),
35 int (*normal_return)(debugger_state *debugger,
36 pid_t unused),
37 int (*wait_return)(debugger_state *debugger,
38 pid_t unused))
39{
40 if(debugger->real_wait){
41 debugger->handle_trace = normal_return;
42 syscall_continue(debugger->pid);
43 debugger->real_wait = 0;
44 return(1);
45 }
46 debugger->wait_status_ptr = status;
47 debugger->wait_options = options;
48 if((debugger->debugee != NULL) && debugger->debugee->event){
49 syscall_continue(debugger->pid);
50 wait_for_stop(debugger->pid, SIGTRAP, PTRACE_SYSCALL,
51 NULL);
52 (*wait_return)(debugger, -1);
53 return(0);
54 }
55 else if(debugger->wait_options & WNOHANG){
56 syscall_cancel(debugger->pid, 0);
57 debugger->handle_trace = syscall;
58 return(0);
59 }
60 else {
61 syscall_pause(debugger->pid);
62 debugger->handle_trace = wait_return;
63 debugger->waiting = 1;
64 }
65 return(1);
66}
67
68/*
69 * Handle debugger trap, i.e. syscall.
70 */
71
72int debugger_syscall(debugger_state *debugger, pid_t child)
73{
74 long arg1, arg2, arg3, arg4, arg5, result;
75 int syscall, ret = 0;
76
77 syscall = get_syscall(debugger->pid, &arg1, &arg2, &arg3, &arg4,
78 &arg5);
79
80 switch(syscall){
81 case __NR_execve:
82 /* execve never returns */
83 debugger->handle_trace = debugger_syscall;
84 break;
85
86 case __NR_ptrace:
87 if(debugger->debugee->pid != 0) arg2 = debugger->debugee->pid;
88 if(!debugger->debugee->in_context)
89 child = debugger->debugee->pid;
90 result = proxy_ptrace(debugger, arg1, arg2, arg3, arg4, child,
91 &ret);
92 syscall_cancel(debugger->pid, result);
93 debugger->handle_trace = debugger_syscall;
94 return(ret);
95
96#ifdef __NR_waitpid
97 case __NR_waitpid:
98#endif
99 case __NR_wait4:
100 if(!debugger_wait(debugger, (int *) arg2, arg3,
101 debugger_syscall, debugger_normal_return,
102 proxy_wait_return))
103 return(0);
104 break;
105
106 case __NR_kill:
107 if(!debugger->debugee->in_context)
108 child = debugger->debugee->pid;
109 if(arg1 == debugger->debugee->pid){
110 result = kill(child, arg2);
111 syscall_cancel(debugger->pid, result);
112 debugger->handle_trace = debugger_syscall;
113 return(0);
114 }
115 else debugger->handle_trace = debugger_normal_return;
116 break;
117
118 default:
119 debugger->handle_trace = debugger_normal_return;
120 }
121
122 syscall_continue(debugger->pid);
123 return(0);
124}
125
126/* Used by the tracing thread */
127static debugger_state parent;
128static int parent_syscall(debugger_state *debugger, int pid);
129
130int init_parent_proxy(int pid)
131{
132 parent = ((debugger_state) { .pid = pid,
133 .wait_options = 0,
134 .wait_status_ptr = NULL,
135 .waiting = 0,
136 .real_wait = 0,
137 .expecting_child = 0,
138 .handle_trace = parent_syscall,
139 .debugee = NULL } );
140 return(0);
141}
142
143int parent_normal_return(debugger_state *debugger, pid_t unused)
144{
145 debugger->handle_trace = parent_syscall;
146 syscall_continue(debugger->pid);
147 return(0);
148}
149
150static int parent_syscall(debugger_state *debugger, int pid)
151{
152 long arg1, arg2, arg3, arg4, arg5;
153 int syscall;
154
155 syscall = get_syscall(pid, &arg1, &arg2, &arg3, &arg4, &arg5);
156
157 if((syscall == __NR_wait4)
158#ifdef __NR_waitpid
159 || (syscall == __NR_waitpid)
160#endif
161 ){
162 debugger_wait(&parent, (int *) arg2, arg3, parent_syscall,
163 parent_normal_return, parent_wait_return);
164 }
165 else ptrace(PTRACE_SYSCALL, pid, 0, 0);
166 return(0);
167}
168
169int debugger_normal_return(debugger_state *debugger, pid_t unused)
170{
171 debugger->handle_trace = debugger_syscall;
172 syscall_continue(debugger->pid);
173 return(0);
174}
175
176void debugger_cancelled_return(debugger_state *debugger, int result)
177{
178 debugger->handle_trace = debugger_syscall;
179 syscall_set_result(debugger->pid, result);
180 syscall_continue(debugger->pid);
181}
182
183/* Used by the tracing thread */
184static debugger_state debugger;
185static debugee_state debugee;
186
187void init_proxy (pid_t debugger_pid, int stopped, int status)
188{
189 debugger.pid = debugger_pid;
190 debugger.handle_trace = debugger_syscall;
191 debugger.debugee = &debugee;
192 debugger.waiting = 0;
193 debugger.real_wait = 0;
194 debugger.expecting_child = 0;
195
196 debugee.pid = 0;
197 debugee.traced = 0;
198 debugee.stopped = stopped;
199 debugee.event = 0;
200 debugee.zombie = 0;
201 debugee.died = 0;
202 debugee.wait_status = status;
203 debugee.in_context = 1;
204}
205
206int debugger_proxy(int status, int pid)
207{
208 int ret = 0, sig;
209
210 if(WIFSTOPPED(status)){
211 sig = WSTOPSIG(status);
212 if (sig == SIGTRAP)
213 ret = (*debugger.handle_trace)(&debugger, pid);
214
215 else if(sig == SIGCHLD){
216 if(debugger.expecting_child){
217 ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
218 debugger.expecting_child = 0;
219 }
220 else if(debugger.waiting)
221 real_wait_return(&debugger);
222 else {
223 ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
224 debugger.real_wait = 1;
225 }
226 }
227 else ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
228 }
229 else if(WIFEXITED(status)){
230 tracer_panic("debugger (pid %d) exited with status %d",
231 debugger.pid, WEXITSTATUS(status));
232 }
233 else if(WIFSIGNALED(status)){
234 tracer_panic("debugger (pid %d) exited with signal %d",
235 debugger.pid, WTERMSIG(status));
236 }
237 else {
238 tracer_panic("proxy got unknown status (0x%x) on debugger "
239 "(pid %d)", status, debugger.pid);
240 }
241 return(ret);
242}
243
244void child_proxy(pid_t pid, int status)
245{
246 debugee.event = 1;
247 debugee.wait_status = status;
248
249 if(WIFSTOPPED(status)){
250 debugee.stopped = 1;
251 debugger.expecting_child = 1;
252 kill(debugger.pid, SIGCHLD);
253 }
254 else if(WIFEXITED(status) || WIFSIGNALED(status)){
255 debugee.zombie = 1;
256 debugger.expecting_child = 1;
257 kill(debugger.pid, SIGCHLD);
258 }
259 else panic("proxy got unknown status (0x%x) on child (pid %d)",
260 status, pid);
261}
262
263void debugger_parent_signal(int status, int pid)
264{
265 int sig;
266
267 if(WIFSTOPPED(status)){
268 sig = WSTOPSIG(status);
269 if(sig == SIGTRAP) (*parent.handle_trace)(&parent, pid);
270 else ptrace(PTRACE_SYSCALL, pid, 0, sig);
271 }
272}
273
274void fake_child_exit(void)
275{
276 int status, pid;
277
278 child_proxy(1, W_EXITCODE(0, 0));
279 while(debugger.waiting == 1){
280 CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED));
281 if(pid != debugger.pid){
282 printk("fake_child_exit - waitpid failed, "
283 "errno = %d\n", errno);
284 return;
285 }
286 debugger_proxy(status, debugger.pid);
287 }
288 CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED));
289 if(pid != debugger.pid){
290 printk("fake_child_exit - waitpid failed, "
291 "errno = %d\n", errno);
292 return;
293 }
294 if(ptrace(PTRACE_DETACH, debugger.pid, 0, SIGCONT) < 0)
295 printk("fake_child_exit - PTRACE_DETACH failed, errno = %d\n",
296 errno);
297}
298
299char gdb_init_string[] =
300"att 1 \n\
301b panic \n\
302b stop \n\
303handle SIGWINCH nostop noprint pass \n\
304";
305
306int start_debugger(char *prog, int startup, int stop, int *fd_out)
307{
308 int slave, child;
309
310 slave = open_gdb_chan();
311 child = fork();
312 if(child == 0){
313 char *tempname = NULL;
314 int fd;
315
316 if(setsid() < 0) perror("setsid");
317 if((dup2(slave, 0) < 0) || (dup2(slave, 1) < 0) ||
318 (dup2(slave, 2) < 0)){
319 printk("start_debugger : dup2 failed, errno = %d\n",
320 errno);
321 exit(1);
322 }
323 if(ioctl(0, TIOCSCTTY, 0) < 0){
324 printk("start_debugger : TIOCSCTTY failed, "
325 "errno = %d\n", errno);
326 exit(1);
327 }
328 if(tcsetpgrp (1, os_getpid()) < 0){
329 printk("start_debugger : tcsetpgrp failed, "
330 "errno = %d\n", errno);
331#ifdef notdef
332 exit(1);
333#endif
334 }
335 fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0);
336 if(fd < 0){
337 printk("start_debugger : make_tempfile failed,"
338 "err = %d\n", -fd);
339 exit(1);
340 }
341 os_write_file(fd, gdb_init_string,
342 sizeof(gdb_init_string) - 1);
343 if(startup){
344 if(stop){
345 os_write_file(fd, "b start_kernel\n",
346 strlen("b start_kernel\n"));
347 }
348 os_write_file(fd, "c\n", strlen("c\n"));
349 }
350 if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
351 printk("start_debugger : PTRACE_TRACEME failed, "
352 "errno = %d\n", errno);
353 exit(1);
354 }
355 execlp("gdb", "gdb", "--command", tempname, prog, NULL);
356 printk("start_debugger : exec of gdb failed, errno = %d\n",
357 errno);
358 }
359 if(child < 0){
360 printk("start_debugger : fork for gdb failed, errno = %d\n",
361 errno);
362 return(-1);
363 }
364 *fd_out = slave;
365 return(child);
366}
367
368/*
369 * Overrides for Emacs so that we follow Linus's tabbing style.
370 * Emacs will notice this stuff at the end of the file and automatically
371 * adjust the settings for this buffer only. This must remain at the end
372 * of the file.
373 * ---------------------------------------------------------------------------
374 * Local variables:
375 * c-file-style: "linux"
376 * End:
377 */
diff --git a/arch/um/kernel/tt/ptproxy/ptproxy.h b/arch/um/kernel/tt/ptproxy/ptproxy.h
deleted file mode 100644
index 5eb0285b1968..000000000000
--- a/arch/um/kernel/tt/ptproxy/ptproxy.h
+++ /dev/null
@@ -1,61 +0,0 @@
1/**********************************************************************
2ptproxy.h
3
4Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
5terms and conditions.
6**********************************************************************/
7
8#ifndef __PTPROXY_H
9#define __PTPROXY_H
10
11#include <sys/types.h>
12
13typedef struct debugger debugger_state;
14typedef struct debugee debugee_state;
15
16struct debugger
17{
18 pid_t pid;
19 int wait_options;
20 int *wait_status_ptr;
21 unsigned int waiting : 1;
22 unsigned int real_wait : 1;
23 unsigned int expecting_child : 1;
24 int (*handle_trace) (debugger_state *, pid_t);
25
26 debugee_state *debugee;
27};
28
29struct debugee
30{
31 pid_t pid;
32 int wait_status;
33 unsigned int died : 1;
34 unsigned int event : 1;
35 unsigned int stopped : 1;
36 unsigned int trace_singlestep : 1;
37 unsigned int trace_syscall : 1;
38 unsigned int traced : 1;
39 unsigned int zombie : 1;
40 unsigned int in_context : 1;
41};
42
43extern int debugger_syscall(debugger_state *debugger, pid_t pid);
44extern int debugger_normal_return (debugger_state *debugger, pid_t unused);
45
46extern long proxy_ptrace (struct debugger *, int, pid_t, long, long, pid_t,
47 int *strace_out);
48extern void debugger_cancelled_return(debugger_state *debugger, int result);
49
50#endif
51
52/*
53 * Overrides for Emacs so that we follow Linus's tabbing style.
54 * Emacs will notice this stuff at the end of the file and automatically
55 * adjust the settings for this buffer only. This must remain at the end
56 * of the file.
57 * ---------------------------------------------------------------------------
58 * Local variables:
59 * c-file-style: "linux"
60 * End:
61 */
diff --git a/arch/um/kernel/tt/ptproxy/ptrace.c b/arch/um/kernel/tt/ptproxy/ptrace.c
deleted file mode 100644
index 4b4f6179b212..000000000000
--- a/arch/um/kernel/tt/ptproxy/ptrace.c
+++ /dev/null
@@ -1,237 +0,0 @@
1/**********************************************************************
2ptrace.c
3
4Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
5terms and conditions.
6
7Jeff Dike (jdike@karaya.com) : Modified for integration into uml
8**********************************************************************/
9
10#include <errno.h>
11#include <unistd.h>
12#include <signal.h>
13#include <sys/types.h>
14#include <sys/time.h>
15#include <sys/wait.h>
16
17#include "ptproxy.h"
18#include "debug.h"
19#include "kern_util.h"
20#include "ptrace_user.h"
21#include "tt.h"
22#include "os.h"
23
24long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2,
25 long arg3, long arg4, pid_t child, int *ret)
26{
27 sigset_t relay;
28 long result;
29 int status;
30
31 *ret = 0;
32 if(debugger->debugee->died) return(-ESRCH);
33
34 switch(arg1){
35 case PTRACE_ATTACH:
36 if(debugger->debugee->traced) return(-EPERM);
37
38 debugger->debugee->pid = arg2;
39 debugger->debugee->traced = 1;
40
41 if(is_valid_pid(arg2) && (arg2 != child)){
42 debugger->debugee->in_context = 0;
43 kill(arg2, SIGSTOP);
44 debugger->debugee->event = 1;
45 debugger->debugee->wait_status = W_STOPCODE(SIGSTOP);
46 }
47 else {
48 debugger->debugee->in_context = 1;
49 if(debugger->debugee->stopped)
50 child_proxy(child, W_STOPCODE(SIGSTOP));
51 else kill(child, SIGSTOP);
52 }
53
54 return(0);
55
56 case PTRACE_DETACH:
57 if(!debugger->debugee->traced) return(-EPERM);
58
59 debugger->debugee->traced = 0;
60 debugger->debugee->pid = 0;
61 if(!debugger->debugee->in_context)
62 kill(child, SIGCONT);
63
64 return(0);
65
66 case PTRACE_CONT:
67 if(!debugger->debugee->in_context) return(-EPERM);
68 *ret = PTRACE_CONT;
69 return(ptrace(PTRACE_CONT, child, arg3, arg4));
70
71#ifdef UM_HAVE_GETFPREGS
72 case PTRACE_GETFPREGS:
73 {
74 long regs[FP_FRAME_SIZE];
75 int i, result;
76
77 result = ptrace(PTRACE_GETFPREGS, child, 0, regs);
78 if(result == -1) return(-errno);
79
80 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
81 ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
82 regs[i]);
83 return(result);
84 }
85#endif
86
87#ifdef UM_HAVE_GETFPXREGS
88 case PTRACE_GETFPXREGS:
89 {
90 long regs[FPX_FRAME_SIZE];
91 int i, result;
92
93 result = ptrace(PTRACE_GETFPXREGS, child, 0, regs);
94 if(result == -1) return(-errno);
95
96 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
97 ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
98 regs[i]);
99 return(result);
100 }
101#endif
102
103#ifdef UM_HAVE_GETREGS
104 case PTRACE_GETREGS:
105 {
106 long regs[FRAME_SIZE];
107 int i, result;
108
109 result = ptrace(PTRACE_GETREGS, child, 0, regs);
110 if(result == -1) return(-errno);
111
112 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
113 ptrace (PTRACE_POKEDATA, debugger->pid,
114 arg4 + 4 * i, regs[i]);
115 return(result);
116 }
117 break;
118#endif
119
120 case PTRACE_KILL:
121 result = ptrace(PTRACE_KILL, child, arg3, arg4);
122 if(result == -1) return(-errno);
123
124 return(result);
125
126 case PTRACE_PEEKDATA:
127 case PTRACE_PEEKTEXT:
128 case PTRACE_PEEKUSR:
129 /* The value being read out could be -1, so we have to
130 * check errno to see if there's an error, and zero it
131 * beforehand so we're not faked out by an old error
132 */
133
134 errno = 0;
135 result = ptrace(arg1, child, arg3, 0);
136 if((result == -1) && (errno != 0)) return(-errno);
137
138 result = ptrace(PTRACE_POKEDATA, debugger->pid, arg4, result);
139 if(result == -1) return(-errno);
140
141 return(result);
142
143 case PTRACE_POKEDATA:
144 case PTRACE_POKETEXT:
145 case PTRACE_POKEUSR:
146 result = ptrace(arg1, child, arg3, arg4);
147 if(result == -1) return(-errno);
148
149 if(arg1 == PTRACE_POKEUSR) ptrace_pokeuser(arg3, arg4);
150 return(result);
151
152#ifdef UM_HAVE_SETFPREGS
153 case PTRACE_SETFPREGS:
154 {
155 long regs[FP_FRAME_SIZE];
156 int i;
157
158 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
159 regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
160 arg4 + 4 * i, 0);
161 result = ptrace(PTRACE_SETFPREGS, child, 0, regs);
162 if(result == -1) return(-errno);
163
164 return(result);
165 }
166#endif
167
168#ifdef UM_HAVE_SETFPXREGS
169 case PTRACE_SETFPXREGS:
170 {
171 long regs[FPX_FRAME_SIZE];
172 int i;
173
174 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
175 regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
176 arg4 + 4 * i, 0);
177 result = ptrace(PTRACE_SETFPXREGS, child, 0, regs);
178 if(result == -1) return(-errno);
179
180 return(result);
181 }
182#endif
183
184#ifdef UM_HAVE_SETREGS
185 case PTRACE_SETREGS:
186 {
187 long regs[FRAME_SIZE];
188 int i;
189
190 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
191 regs[i] = ptrace(PTRACE_PEEKDATA, debugger->pid,
192 arg4 + 4 * i, 0);
193 result = ptrace(PTRACE_SETREGS, child, 0, regs);
194 if(result == -1) return(-errno);
195
196 return(result);
197 }
198#endif
199
200 case PTRACE_SINGLESTEP:
201 if(!debugger->debugee->in_context) return(-EPERM);
202 sigemptyset(&relay);
203 sigaddset(&relay, SIGSEGV);
204 sigaddset(&relay, SIGILL);
205 sigaddset(&relay, SIGBUS);
206 result = ptrace(PTRACE_SINGLESTEP, child, arg3, arg4);
207 if(result == -1) return(-errno);
208
209 status = wait_for_stop(child, SIGTRAP, PTRACE_SINGLESTEP,
210 &relay);
211 child_proxy(child, status);
212 return(result);
213
214 case PTRACE_SYSCALL:
215 if(!debugger->debugee->in_context) return(-EPERM);
216 result = ptrace(PTRACE_SYSCALL, child, arg3, arg4);
217 if(result == -1) return(-errno);
218
219 *ret = PTRACE_SYSCALL;
220 return(result);
221
222 case PTRACE_TRACEME:
223 default:
224 return(-EINVAL);
225 }
226}
227
228/*
229 * Overrides for Emacs so that we follow Linus's tabbing style.
230 * Emacs will notice this stuff at the end of the file and automatically
231 * adjust the settings for this buffer only. This must remain at the end
232 * of the file.
233 * ---------------------------------------------------------------------------
234 * Local variables:
235 * c-file-style: "linux"
236 * End:
237 */
diff --git a/arch/um/kernel/tt/ptproxy/sysdep.c b/arch/um/kernel/tt/ptproxy/sysdep.c
deleted file mode 100644
index e0e1ab0588ad..000000000000
--- a/arch/um/kernel/tt/ptproxy/sysdep.c
+++ /dev/null
@@ -1,70 +0,0 @@
1/**********************************************************************
2sysdep.c
3
4Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
5terms and conditions.
6**********************************************************************/
7
8#include <stdio.h>
9#include <string.h>
10#include <stdlib.h>
11#include <signal.h>
12#include <errno.h>
13#include <sys/types.h>
14#include <linux/unistd.h>
15#include "ptrace_user.h"
16#include "user.h"
17#include "os.h"
18
19int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, long *arg4,
20 long *arg5)
21{
22 *arg1 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG1_OFFSET, 0);
23 *arg2 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG2_OFFSET, 0);
24 *arg3 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG3_OFFSET, 0);
25 *arg4 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG4_OFFSET, 0);
26 *arg5 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG5_OFFSET, 0);
27 return(ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET, 0));
28}
29
30void syscall_cancel(pid_t pid, int result)
31{
32 if((ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
33 __NR_getpid) < 0) ||
34 (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) ||
35 (wait_for_stop(pid, SIGTRAP, PTRACE_SYSCALL, NULL) < 0) ||
36 (ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, result) < 0) ||
37 (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0))
38 printk("ptproxy: couldn't cancel syscall: errno = %d\n",
39 errno);
40}
41
42void syscall_set_result(pid_t pid, long result)
43{
44 ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, result);
45}
46
47void syscall_continue(pid_t pid)
48{
49 ptrace(PTRACE_SYSCALL, pid, 0, 0);
50}
51
52int syscall_pause(pid_t pid)
53{
54 if(ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, __NR_pause) < 0){
55 printk("syscall_change - ptrace failed, errno = %d\n", errno);
56 return(-1);
57 }
58 return(0);
59}
60
61/*
62 * Overrides for Emacs so that we follow Linus's tabbing style.
63 * Emacs will notice this stuff at the end of the file and automatically
64 * adjust the settings for this buffer only. This must remain at the end
65 * of the file.
66 * ---------------------------------------------------------------------------
67 * Local variables:
68 * c-file-style: "linux"
69 * End:
70 */
diff --git a/arch/um/kernel/tt/ptproxy/sysdep.h b/arch/um/kernel/tt/ptproxy/sysdep.h
deleted file mode 100644
index 735f488049aa..000000000000
--- a/arch/um/kernel/tt/ptproxy/sysdep.h
+++ /dev/null
@@ -1,25 +0,0 @@
1/**********************************************************************
2sysdep.h
3
4Copyright (C) 1999 Lars Brinkhoff.
5Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
6See the file COPYING for licensing terms and conditions.
7**********************************************************************/
8
9extern int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3,
10 long *arg4, long *arg5);
11extern void syscall_cancel (pid_t pid, long result);
12extern void syscall_set_result (pid_t pid, long result);
13extern void syscall_continue (pid_t pid);
14extern int syscall_pause(pid_t pid);
15
16/*
17 * Overrides for Emacs so that we follow Linus's tabbing style.
18 * Emacs will notice this stuff at the end of the file and automatically
19 * adjust the settings for this buffer only. This must remain at the end
20 * of the file.
21 * ---------------------------------------------------------------------------
22 * Local variables:
23 * c-file-style: "linux"
24 * End:
25 */
diff --git a/arch/um/kernel/tt/ptproxy/wait.c b/arch/um/kernel/tt/ptproxy/wait.c
deleted file mode 100644
index bdd4af4b65fc..000000000000
--- a/arch/um/kernel/tt/ptproxy/wait.c
+++ /dev/null
@@ -1,85 +0,0 @@
1/**********************************************************************
2wait.c
3
4Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
5terms and conditions.
6
7**********************************************************************/
8
9#include <errno.h>
10#include <signal.h>
11#include <sys/wait.h>
12
13#include "ptproxy.h"
14#include "sysdep.h"
15#include "wait.h"
16#include "ptrace_user.h"
17#include "sysdep/ptrace.h"
18#include "sysdep/sigcontext.h"
19
20int proxy_wait_return(struct debugger *debugger, pid_t unused)
21{
22 debugger->waiting = 0;
23
24 if(debugger->debugee->died || (debugger->wait_options & __WCLONE)){
25 debugger_cancelled_return(debugger, -ECHILD);
26 return(0);
27 }
28
29 if(debugger->debugee->zombie && debugger->debugee->event)
30 debugger->debugee->died = 1;
31
32 if(debugger->debugee->event){
33 debugger->debugee->event = 0;
34 ptrace(PTRACE_POKEDATA, debugger->pid,
35 debugger->wait_status_ptr,
36 debugger->debugee->wait_status);
37 /* if (wait4)
38 ptrace (PTRACE_POKEDATA, pid, rusage_ptr, ...); */
39 debugger_cancelled_return(debugger, debugger->debugee->pid);
40 return(0);
41 }
42
43 /* pause will return -EINTR, which happens to be right for wait */
44 debugger_normal_return(debugger, -1);
45 return(0);
46}
47
48int parent_wait_return(struct debugger *debugger, pid_t unused)
49{
50 return(debugger_normal_return(debugger, -1));
51}
52
53int real_wait_return(struct debugger *debugger)
54{
55 unsigned long ip;
56 int pid;
57
58 pid = debugger->pid;
59
60 ip = ptrace(PTRACE_PEEKUSR, pid, PT_IP_OFFSET, 0);
61 IP_RESTART_SYSCALL(ip);
62
63 if(ptrace(PTRACE_POKEUSR, pid, PT_IP_OFFSET, ip) < 0)
64 tracer_panic("real_wait_return : Failed to restart system "
65 "call, errno = %d\n", errno);
66
67 if((ptrace(PTRACE_SYSCALL, debugger->pid, 0, SIGCHLD) < 0) ||
68 (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
69 (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
70 debugger_normal_return(debugger, -1))
71 tracer_panic("real_wait_return : gdb failed to wait, "
72 "errno = %d\n", errno);
73 return(0);
74}
75
76/*
77 * Overrides for Emacs so that we follow Linus's tabbing style.
78 * Emacs will notice this stuff at the end of the file and automatically
79 * adjust the settings for this buffer only. This must remain at the end
80 * of the file.
81 * ---------------------------------------------------------------------------
82 * Local variables:
83 * c-file-style: "linux"
84 * End:
85 */
diff --git a/arch/um/kernel/tt/ptproxy/wait.h b/arch/um/kernel/tt/ptproxy/wait.h
deleted file mode 100644
index 542e73ee2cee..000000000000
--- a/arch/um/kernel/tt/ptproxy/wait.h
+++ /dev/null
@@ -1,15 +0,0 @@
1/**********************************************************************
2wait.h
3
4Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
5terms and conditions.
6**********************************************************************/
7
8#ifndef __PTPROXY_WAIT_H
9#define __PTPROXY_WAIT_H
10
11extern int proxy_wait_return(struct debugger *debugger, pid_t unused);
12extern int real_wait_return(struct debugger *debugger);
13extern int parent_wait_return(struct debugger *debugger, pid_t unused);
14
15#endif
diff --git a/arch/um/kernel/tt/syscall_kern.c b/arch/um/kernel/tt/syscall_kern.c
deleted file mode 100644
index 293caa6d0c2d..000000000000
--- a/arch/um/kernel/tt/syscall_kern.c
+++ /dev/null
@@ -1,46 +0,0 @@
1/*
2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/types.h"
7#include "linux/utime.h"
8#include "linux/sys.h"
9#include "linux/ptrace.h"
10#include "asm/unistd.h"
11#include "asm/ptrace.h"
12#include "asm/uaccess.h"
13#include "asm/stat.h"
14#include "sysdep/syscalls.h"
15#include "sysdep/sigcontext.h"
16#include "kern_util.h"
17#include "syscall.h"
18
19void syscall_handler_tt(int sig, struct pt_regs *regs)
20{
21 void *sc;
22 long result;
23 int syscall;
24
25 sc = UPT_SC(&regs->regs);
26 SC_START_SYSCALL(sc);
27
28 syscall = UPT_SYSCALL_NR(&regs->regs);
29 syscall_trace(&regs->regs, 0);
30
31 current->thread.nsyscalls++;
32 nsyscalls++;
33
34 if((syscall >= NR_syscalls) || (syscall < 0))
35 result = -ENOSYS;
36 else result = EXECUTE_SYSCALL(syscall, regs);
37
38 /* regs->sc may have changed while the system call ran (there may
39 * have been an interrupt or segfault), so it needs to be refreshed.
40 */
41 UPT_SC(&regs->regs) = sc;
42
43 SC_SET_SYSCALL_RETURN(sc, result);
44
45 syscall_trace(&regs->regs, 1);
46}
diff --git a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c
deleted file mode 100644
index f52b47aff1d2..000000000000
--- a/arch/um/kernel/tt/syscall_user.c
+++ /dev/null
@@ -1,60 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <unistd.h>
7#include <signal.h>
8#include <errno.h>
9#include <asm/unistd.h>
10#include "sysdep/ptrace.h"
11#include "sigcontext.h"
12#include "ptrace_user.h"
13#include "task.h"
14#include "kern_util.h"
15#include "syscall.h"
16#include "tt.h"
17
18void do_sigtrap(void *task)
19{
20 UPT_SYSCALL_NR(TASK_REGS(task)) = -1;
21}
22
23void do_syscall(void *task, int pid, int local_using_sysemu)
24{
25 unsigned long proc_regs[FRAME_SIZE];
26
27 if(ptrace_getregs(pid, proc_regs) < 0)
28 tracer_panic("Couldn't read registers");
29
30 UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs);
31
32#ifdef UPT_ORIGGPR2
33 UPT_ORIGGPR2(TASK_REGS(task)) = REGS_ORIGGPR2(proc_regs);
34#endif
35
36 if(((unsigned long *) PT_IP(proc_regs) >= &_stext) &&
37 ((unsigned long *) PT_IP(proc_regs) <= &_etext))
38 tracer_panic("I'm tracing myself and I can't get out");
39
40 /* advanced sysemu mode set syscall number to -1 automatically */
41 if (local_using_sysemu==2)
42 return;
43
44 /* syscall number -1 in sysemu skips syscall restarting in host */
45 if(ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
46 local_using_sysemu ? -1 : __NR_getpid) < 0)
47 tracer_panic("do_syscall : Nullifying syscall failed, "
48 "errno = %d", errno);
49}
50
51/*
52 * Overrides for Emacs so that we follow Linus's tabbing style.
53 * Emacs will notice this stuff at the end of the file and automatically
54 * adjust the settings for this buffer only. This must remain at the end
55 * of the file.
56 * ---------------------------------------------------------------------------
57 * Local variables:
58 * c-file-style: "linux"
59 * End:
60 */
diff --git a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c
deleted file mode 100644
index 7caa24fe05df..000000000000
--- a/arch/um/kernel/tt/tlb.c
+++ /dev/null
@@ -1,120 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Copyright 2003 PathScale, Inc.
4 * Licensed under the GPL
5 */
6
7#include "linux/stddef.h"
8#include "linux/kernel.h"
9#include "linux/sched.h"
10#include "linux/mm.h"
11#include "asm/page.h"
12#include "asm/pgtable.h"
13#include "asm/uaccess.h"
14#include "asm/tlbflush.h"
15#include "mem_user.h"
16#include "os.h"
17#include "tlb.h"
18
19static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last,
20 int finished, void **flush)
21{
22 struct host_vm_op *op;
23 int i, ret=0;
24
25 for(i = 0; i <= last && !ret; i++){
26 op = &ops[i];
27 switch(op->type){
28 case MMAP:
29 ret = os_map_memory((void *) op->u.mmap.addr,
30 op->u.mmap.fd, op->u.mmap.offset,
31 op->u.mmap.len, op->u.mmap.r,
32 op->u.mmap.w, op->u.mmap.x);
33 break;
34 case MUNMAP:
35 ret = os_unmap_memory((void *) op->u.munmap.addr,
36 op->u.munmap.len);
37 break;
38 case MPROTECT:
39 ret = protect_memory(op->u.mprotect.addr,
40 op->u.munmap.len,
41 op->u.mprotect.r,
42 op->u.mprotect.w,
43 op->u.mprotect.x, 1);
44 protect_memory(op->u.mprotect.addr, op->u.munmap.len,
45 op->u.mprotect.r, op->u.mprotect.w,
46 op->u.mprotect.x, 1);
47 break;
48 default:
49 printk("Unknown op type %d in do_ops\n", op->type);
50 break;
51 }
52 }
53
54 return ret;
55}
56
57static void fix_range(struct mm_struct *mm, unsigned long start_addr,
58 unsigned long end_addr, int force)
59{
60 if((current->thread.mode.tt.extern_pid != -1) &&
61 (current->thread.mode.tt.extern_pid != os_getpid()))
62 panic("fix_range fixing wrong address space, current = 0x%p",
63 current);
64
65 fix_range_common(mm, start_addr, end_addr, force, do_ops);
66}
67
68atomic_t vmchange_seq = ATOMIC_INIT(1);
69
70void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end)
71{
72 if(flush_tlb_kernel_range_common(start, end))
73 atomic_inc(&vmchange_seq);
74}
75
76void flush_tlb_kernel_vm_tt(void)
77{
78 flush_tlb_kernel_range(start_vm, end_vm);
79}
80
81void __flush_tlb_one_tt(unsigned long addr)
82{
83 flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
84}
85
86void flush_tlb_range_tt(struct vm_area_struct *vma, unsigned long start,
87 unsigned long end)
88{
89 if(vma->vm_mm != current->mm) return;
90
91 /* Assumes that the range start ... end is entirely within
92 * either process memory or kernel vm
93 */
94 if((start >= start_vm) && (start < end_vm)){
95 if(flush_tlb_kernel_range_common(start, end))
96 atomic_inc(&vmchange_seq);
97 }
98 else fix_range(vma->vm_mm, start, end, 0);
99}
100
101void flush_tlb_mm_tt(struct mm_struct *mm)
102{
103 unsigned long seq;
104
105 if(mm != current->mm) return;
106
107 fix_range(mm, 0, STACK_TOP, 0);
108
109 seq = atomic_read(&vmchange_seq);
110 if(current->thread.mode.tt.vm_seq == seq)
111 return;
112 current->thread.mode.tt.vm_seq = seq;
113 flush_tlb_kernel_range_common(start_vm, end_vm);
114}
115
116void force_flush_all_tt(void)
117{
118 fix_range(current->mm, 0, STACK_TOP, 1);
119 flush_tlb_kernel_range_common(start_vm, end_vm);
120}
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
deleted file mode 100644
index c23588393f6e..000000000000
--- a/arch/um/kernel/tt/tracer.c
+++ /dev/null
@@ -1,461 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <stdarg.h>
9#include <unistd.h>
10#include <signal.h>
11#include <errno.h>
12#include <sched.h>
13#include <string.h>
14#include <sys/mman.h>
15#include <sys/time.h>
16#include <sys/wait.h>
17#include "user.h"
18#include "sysdep/ptrace.h"
19#include "sigcontext.h"
20#include "sysdep/sigcontext.h"
21#include "os.h"
22#include "mem_user.h"
23#include "process.h"
24#include "kern_util.h"
25#include "chan_user.h"
26#include "ptrace_user.h"
27#include "irq_user.h"
28#include "mode.h"
29#include "tt.h"
30
31static int tracer_winch[2];
32
33int is_tracer_winch(int pid, int fd, void *data)
34{
35 if(pid != os_getpgrp())
36 return(0);
37
38 register_winch_irq(tracer_winch[0], fd, -1, data);
39 return(1);
40}
41
42static void tracer_winch_handler(int sig)
43{
44 int n;
45 char c = 1;
46
47 n = os_write_file(tracer_winch[1], &c, sizeof(c));
48 if(n != sizeof(c))
49 printk("tracer_winch_handler - write failed, err = %d\n", -n);
50}
51
52/* Called only by the tracing thread during initialization */
53
54static void setup_tracer_winch(void)
55{
56 int err;
57
58 err = os_pipe(tracer_winch, 1, 1);
59 if(err < 0){
60 printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err);
61 return;
62 }
63 signal(SIGWINCH, tracer_winch_handler);
64}
65
66void attach_process(int pid)
67{
68 if((ptrace(PTRACE_ATTACH, pid, 0, 0) < 0) ||
69 (ptrace(PTRACE_CONT, pid, 0, 0) < 0))
70 tracer_panic("OP_FORK failed to attach pid");
71 wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
72 if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
73 tracer_panic("OP_FORK: PTRACE_SETOPTIONS failed, errno = %d", errno);
74 if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
75 tracer_panic("OP_FORK failed to continue process");
76}
77
78void tracer_panic(char *format, ...)
79{
80 va_list ap;
81
82 va_start(ap, format);
83 vprintf(format, ap);
84 va_end(ap);
85 printf("\n");
86 while(1) pause();
87}
88
89static void tracer_segv(int sig, struct sigcontext sc)
90{
91 struct faultinfo fi;
92 GET_FAULTINFO_FROM_SC(fi, &sc);
93 printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n",
94 FAULT_ADDRESS(fi), SC_IP(&sc));
95 while(1)
96 pause();
97}
98
99/* Changed early in boot, and then only read */
100int debug = 0;
101int debug_stop = 1;
102int debug_parent = 0;
103int honeypot = 0;
104
105static int signal_tramp(void *arg)
106{
107 int (*proc)(void *);
108
109 if(honeypot && munmap((void *) (host_task_size - 0x10000000),
110 0x10000000))
111 panic("Unmapping stack failed");
112 if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
113 panic("ptrace PTRACE_TRACEME failed");
114 os_stop_process(os_getpid());
115 change_sig(SIGWINCH, 0);
116 signal(SIGUSR1, SIG_IGN);
117 change_sig(SIGCHLD, 0);
118 signal(SIGSEGV, (__sighandler_t) sig_handler);
119 set_cmdline("(idle thread)");
120 set_init_pid(os_getpid());
121 init_irq_signals(0);
122 proc = arg;
123 return((*proc)(NULL));
124}
125
126static void sleeping_process_signal(int pid, int sig)
127{
128 switch(sig){
129 /* These two result from UML being ^Z-ed and bg-ed. PTRACE_CONT is
130 * right because the process must be in the kernel already.
131 */
132 case SIGCONT:
133 case SIGTSTP:
134 if(ptrace(PTRACE_CONT, pid, 0, sig) < 0)
135 tracer_panic("sleeping_process_signal : Failed to "
136 "continue pid %d, signal = %d, "
137 "errno = %d\n", pid, sig, errno);
138 break;
139
140 /* This happens when the debugger (e.g. strace) is doing system call
141 * tracing on the kernel. During a context switch, the current task
142 * will be set to the incoming process and the outgoing process will
143 * hop into write and then read. Since it's not the current process
144 * any more, the trace of those will land here. So, we need to just
145 * PTRACE_SYSCALL it.
146 */
147 case (SIGTRAP + 0x80):
148 if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
149 tracer_panic("sleeping_process_signal : Failed to "
150 "PTRACE_SYSCALL pid %d, errno = %d\n",
151 pid, errno);
152 break;
153 case SIGSTOP:
154 break;
155 default:
156 tracer_panic("sleeping process %d got unexpected "
157 "signal : %d\n", pid, sig);
158 break;
159 }
160}
161
162/* Accessed only by the tracing thread */
163int debugger_pid = -1;
164int debugger_parent = -1;
165int debugger_fd = -1;
166int gdb_pid = -1;
167
168struct {
169 int pid;
170 int signal;
171 unsigned long addr;
172 struct timeval time;
173} signal_record[1024][32];
174
175int signal_index[32];
176int nsignals = 0;
177int debug_trace = 0;
178
179extern void signal_usr1(int sig);
180
181int tracing_pid = -1;
182
183int tracer(int (*init_proc)(void *), void *sp)
184{
185 void *task = NULL;
186 int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0;
187 int proc_id = 0, n, err, old_tracing = 0, strace = 0;
188 int local_using_sysemu = 0;
189
190 signal(SIGPIPE, SIG_IGN);
191 setup_tracer_winch();
192 tracing_pid = os_getpid();
193 printf("tracing thread pid = %d\n", tracing_pid);
194
195 pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc);
196 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
197 if(n < 0){
198 printf("waitpid on idle thread failed, errno = %d\n", errno);
199 exit(1);
200 }
201 if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) {
202 printf("Failed to PTRACE_SETOPTIONS for idle thread, errno = %d\n", errno);
203 exit(1);
204 }
205 if((ptrace(PTRACE_CONT, pid, 0, 0) < 0)){
206 printf("Failed to continue idle thread, errno = %d\n", errno);
207 exit(1);
208 }
209
210 signal(SIGSEGV, (sighandler_t) tracer_segv);
211 signal(SIGUSR1, signal_usr1);
212 if(debug_trace){
213 printf("Tracing thread pausing to be attached\n");
214 stop();
215 }
216 if(debug){
217 if(gdb_pid != -1)
218 debugger_pid = attach_debugger(pid, gdb_pid, 1);
219 else debugger_pid = init_ptrace_proxy(pid, 1, debug_stop);
220 if(debug_parent){
221 debugger_parent = os_process_parent(debugger_pid);
222 init_parent_proxy(debugger_parent);
223 err = attach(debugger_parent);
224 if(err){
225 printf("Failed to attach debugger parent %d, "
226 "errno = %d\n", debugger_parent, -err);
227 debugger_parent = -1;
228 }
229 else {
230 if(ptrace(PTRACE_SYSCALL, debugger_parent,
231 0, 0) < 0){
232 printf("Failed to continue debugger "
233 "parent, errno = %d\n", errno);
234 debugger_parent = -1;
235 }
236 }
237 }
238 }
239 set_cmdline("(tracing thread)");
240 while(1){
241 CATCH_EINTR(pid = waitpid(-1, &status, WUNTRACED));
242 if(pid <= 0){
243 if(errno != ECHILD){
244 printf("wait failed - errno = %d\n", errno);
245 }
246 continue;
247 }
248 if(pid == debugger_pid){
249 int cont = 0;
250
251 if(WIFEXITED(status) || WIFSIGNALED(status))
252 debugger_pid = -1;
253 /* XXX Figure out how to deal with gdb and SMP */
254 else cont = debugger_signal(status, cpu_tasks[0].pid);
255 if(cont == PTRACE_SYSCALL) strace = 1;
256 continue;
257 }
258 else if(pid == debugger_parent){
259 debugger_parent_signal(status, pid);
260 continue;
261 }
262 nsignals++;
263 if(WIFEXITED(status)) ;
264#ifdef notdef
265 {
266 printf("Child %d exited with status %d\n", pid,
267 WEXITSTATUS(status));
268 }
269#endif
270 else if(WIFSIGNALED(status)){
271 sig = WTERMSIG(status);
272 if(sig != 9){
273 printf("Child %d exited with signal %d\n", pid,
274 sig);
275 }
276 }
277 else if(WIFSTOPPED(status)){
278 proc_id = pid_to_processor_id(pid);
279 sig = WSTOPSIG(status);
280 if(proc_id == -1){
281 sleeping_process_signal(pid, sig);
282 continue;
283 }
284
285 task = cpu_tasks[proc_id].task;
286 tracing = is_tracing(task);
287 old_tracing = tracing;
288
289 /* Assume: no syscall, when coming from user */
290 if ( tracing )
291 do_sigtrap(task);
292
293 switch(sig){
294 case SIGUSR1:
295 sig = 0;
296 op = do_proc_op(task, proc_id);
297 switch(op){
298 /*
299 * This is called when entering user mode; after
300 * this, we start intercepting syscalls.
301 *
302 * In fact, a process is started in kernel mode,
303 * so with is_tracing() == 0 (and that is reset
304 * when executing syscalls, since UML kernel has
305 * the right to do syscalls);
306 */
307 case OP_TRACE_ON:
308 arch_leave_kernel(task, pid);
309 tracing = 1;
310 break;
311 case OP_REBOOT:
312 case OP_HALT:
313 unmap_physmem();
314 kmalloc_ok = 0;
315 os_kill_ptraced_process(pid, 0);
316 /* Now let's reap remaining zombies */
317 errno = 0;
318 do {
319 waitpid(-1, &status,
320 WUNTRACED);
321 } while (errno != ECHILD);
322 return(op == OP_REBOOT);
323 case OP_NONE:
324 printf("Detaching pid %d\n", pid);
325 detach(pid, SIGSTOP);
326 continue;
327 default:
328 break;
329 }
330 /* OP_EXEC switches host processes on us,
331 * we want to continue the new one.
332 */
333 pid = cpu_tasks[proc_id].pid;
334 break;
335 case (SIGTRAP + 0x80):
336 if(!tracing && (debugger_pid != -1)){
337 child_signal(pid, status & 0x7fff);
338 continue;
339 }
340 tracing = 0;
341 /* local_using_sysemu has been already set
342 * below, since if we are here, is_tracing() on
343 * the traced task was 1, i.e. the process had
344 * already run through one iteration of the
345 * loop which executed a OP_TRACE_ON request.*/
346 do_syscall(task, pid, local_using_sysemu);
347 sig = SIGUSR2;
348 break;
349 case SIGTRAP:
350 if(!tracing && (debugger_pid != -1)){
351 child_signal(pid, status);
352 continue;
353 }
354 tracing = 0;
355 break;
356 case SIGPROF:
357 if(tracing) sig = 0;
358 break;
359 case SIGCHLD:
360 case SIGHUP:
361 sig = 0;
362 break;
363 case SIGSEGV:
364 case SIGIO:
365 case SIGALRM:
366 case SIGVTALRM:
367 case SIGFPE:
368 case SIGBUS:
369 case SIGILL:
370 case SIGWINCH:
371
372 default:
373 tracing = 0;
374 break;
375 }
376 set_tracing(task, tracing);
377
378 if(!tracing && old_tracing)
379 arch_enter_kernel(task, pid);
380
381 if(!tracing && (debugger_pid != -1) && (sig != 0) &&
382 (sig != SIGALRM) && (sig != SIGVTALRM) &&
383 (sig != SIGSEGV) && (sig != SIGTRAP) &&
384 (sig != SIGUSR2) && (sig != SIGIO) &&
385 (sig != SIGFPE)){
386 child_signal(pid, status);
387 continue;
388 }
389
390 local_using_sysemu = get_using_sysemu();
391
392 if(tracing)
393 cont_type = SELECT_PTRACE_OPERATION(local_using_sysemu,
394 singlestepping(task));
395 else if((debugger_pid != -1) && strace)
396 cont_type = PTRACE_SYSCALL;
397 else
398 cont_type = PTRACE_CONT;
399
400 if(ptrace(cont_type, pid, 0, sig) != 0){
401 tracer_panic("ptrace failed to continue "
402 "process - errno = %d\n",
403 errno);
404 }
405 }
406 }
407 return(0);
408}
409
410static int __init uml_debug_setup(char *line, int *add)
411{
412 char *next;
413
414 debug = 1;
415 *add = 0;
416 if(*line != '=') return(0);
417 line++;
418
419 while(line != NULL){
420 next = strchr(line, ',');
421 if(next) *next++ = '\0';
422
423 if(!strcmp(line, "go")) debug_stop = 0;
424 else if(!strcmp(line, "parent")) debug_parent = 1;
425 else printf("Unknown debug option : '%s'\n", line);
426
427 line = next;
428 }
429 return(0);
430}
431
432__uml_setup("debug", uml_debug_setup,
433"debug\n"
434" Starts up the kernel under the control of gdb. See the \n"
435" kernel debugging tutorial and the debugging session pages\n"
436" at http://user-mode-linux.sourceforge.net/ for more information.\n\n"
437);
438
439static int __init uml_debugtrace_setup(char *line, int *add)
440{
441 debug_trace = 1;
442 return 0;
443}
444__uml_setup("debugtrace", uml_debugtrace_setup,
445"debugtrace\n"
446" Causes the tracing thread to pause until it is attached by a\n"
447" debugger and continued. This is mostly for debugging crashes\n"
448" early during boot, and should be pretty much obsoleted by\n"
449" the debug switch.\n\n"
450);
451
452/*
453 * Overrides for Emacs so that we follow Linus's tabbing style.
454 * Emacs will notice this stuff at the end of the file and automatically
455 * adjust the settings for this buffer only. This must remain at the end
456 * of the file.
457 * ---------------------------------------------------------------------------
458 * Local variables:
459 * c-file-style: "linux"
460 * End:
461 */
diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c
deleted file mode 100644
index 3032eb5e2467..000000000000
--- a/arch/um/kernel/tt/trap_user.c
+++ /dev/null
@@ -1,70 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdlib.h>
7#include <errno.h>
8#include <signal.h>
9#include "sysdep/ptrace.h"
10#include "sysdep/sigcontext.h"
11#include "kern_util.h"
12#include "task.h"
13#include "tt.h"
14#include "os.h"
15
16void sig_handler_common_tt(int sig, void *sc_ptr)
17{
18 struct sigcontext *sc = sc_ptr;
19 struct tt_regs save_regs, *r;
20 int save_errno = errno, is_user = 0;
21 void (*handler)(int, union uml_pt_regs *);
22
23 /* This is done because to allow SIGSEGV to be delivered inside a SEGV
24 * handler. This can happen in copy_user, and if SEGV is disabled,
25 * the process will die.
26 */
27 if(sig == SIGSEGV)
28 change_sig(SIGSEGV, 1);
29
30 r = &TASK_REGS(get_current())->tt;
31 if ( sig == SIGFPE || sig == SIGSEGV ||
32 sig == SIGBUS || sig == SIGILL ||
33 sig == SIGTRAP ) {
34 GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
35 }
36 save_regs = *r;
37 if (sc)
38 is_user = user_context(SC_SP(sc));
39 r->sc = sc;
40 if(sig != SIGUSR2)
41 r->syscall = -1;
42
43 handler = sig_info[sig];
44
45 /* unblock SIGALRM, SIGVTALRM, SIGIO if sig isn't IRQ signal */
46 if (sig != SIGIO && sig != SIGWINCH &&
47 sig != SIGVTALRM && sig != SIGALRM)
48 unblock_signals();
49
50 handler(sig, (union uml_pt_regs *) r);
51
52 if(is_user){
53 interrupt_end();
54 block_signals();
55 set_user_mode(NULL);
56 }
57 *r = save_regs;
58 errno = save_errno;
59}
60
61/*
62 * Overrides for Emacs so that we follow Linus's tabbing style.
63 * Emacs will notice this stuff at the end of the file and automatically
64 * adjust the settings for this buffer only. This must remain at the end
65 * of the file.
66 * ---------------------------------------------------------------------------
67 * Local variables:
68 * c-file-style: "linux"
69 * End:
70 */
diff --git a/arch/um/kernel/tt/uaccess.c b/arch/um/kernel/tt/uaccess.c
deleted file mode 100644
index 1cb60726567e..000000000000
--- a/arch/um/kernel/tt/uaccess.c
+++ /dev/null
@@ -1,73 +0,0 @@
1/*
2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/sched.h"
7#include "asm/uaccess.h"
8
9int copy_from_user_tt(void *to, const void __user *from, int n)
10{
11 if(!access_ok(VERIFY_READ, from, n))
12 return(n);
13
14 return(__do_copy_from_user(to, from, n, &current->thread.fault_addr,
15 &current->thread.fault_catcher));
16}
17
18int copy_to_user_tt(void __user *to, const void *from, int n)
19{
20 if(!access_ok(VERIFY_WRITE, to, n))
21 return(n);
22
23 return(__do_copy_to_user(to, from, n, &current->thread.fault_addr,
24 &current->thread.fault_catcher));
25}
26
27int strncpy_from_user_tt(char *dst, const char __user *src, int count)
28{
29 int n;
30
31 if(!access_ok(VERIFY_READ, src, 1))
32 return(-EFAULT);
33
34 n = __do_strncpy_from_user(dst, src, count,
35 &current->thread.fault_addr,
36 &current->thread.fault_catcher);
37 if(n < 0) return(-EFAULT);
38 return(n);
39}
40
41int __clear_user_tt(void __user *mem, int len)
42{
43 return(__do_clear_user(mem, len,
44 &current->thread.fault_addr,
45 &current->thread.fault_catcher));
46}
47
48int clear_user_tt(void __user *mem, int len)
49{
50 if(!access_ok(VERIFY_WRITE, mem, len))
51 return(len);
52
53 return(__do_clear_user(mem, len, &current->thread.fault_addr,
54 &current->thread.fault_catcher));
55}
56
57int strnlen_user_tt(const void __user *str, int len)
58{
59 return(__do_strnlen_user(str, len,
60 &current->thread.fault_addr,
61 &current->thread.fault_catcher));
62}
63
64/*
65 * Overrides for Emacs so that we follow Linus's tabbing style.
66 * Emacs will notice this stuff at the end of the file and automatically
67 * adjust the settings for this buffer only. This must remain at the end
68 * of the file.
69 * ---------------------------------------------------------------------------
70 * Local variables:
71 * c-file-style: "linux"
72 * End:
73 */
diff --git a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c
deleted file mode 100644
index 0e5c82c5e5b7..000000000000
--- a/arch/um/kernel/tt/uaccess_user.c
+++ /dev/null
@@ -1,105 +0,0 @@
1/*
2 * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
3 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
4 * Licensed under the GPL
5 */
6
7#include <string.h>
8#include "uml_uaccess.h"
9#include "task.h"
10#include "kern_util.h"
11#include "os.h"
12#include "longjmp.h"
13
14int __do_copy_from_user(void *to, const void *from, int n,
15 void **fault_addr, void **fault_catcher)
16{
17 struct tt_regs save = TASK_REGS(get_current())->tt;
18 unsigned long fault;
19 int faulted;
20
21 fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
22 __do_copy, &faulted);
23 TASK_REGS(get_current())->tt = save;
24
25 if(!faulted)
26 return 0;
27 else if (fault)
28 return n - (fault - (unsigned long) from);
29 else
30 /* In case of a general protection fault, we don't have the
31 * fault address, so NULL is used instead. Pretend we didn't
32 * copy anything. */
33 return n;
34}
35
36static void __do_strncpy(void *dst, const void *src, int count)
37{
38 strncpy(dst, src, count);
39}
40
41int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
42 void **fault_addr, void **fault_catcher)
43{
44 struct tt_regs save = TASK_REGS(get_current())->tt;
45 unsigned long fault;
46 int faulted;
47
48 fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
49 __do_strncpy, &faulted);
50 TASK_REGS(get_current())->tt = save;
51
52 if(!faulted) return(strlen(dst));
53 else return(-1);
54}
55
56static void __do_clear(void *to, const void *from, int n)
57{
58 memset(to, 0, n);
59}
60
61int __do_clear_user(void *mem, unsigned long len,
62 void **fault_addr, void **fault_catcher)
63{
64 struct tt_regs save = TASK_REGS(get_current())->tt;
65 unsigned long fault;
66 int faulted;
67
68 fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
69 __do_clear, &faulted);
70 TASK_REGS(get_current())->tt = save;
71
72 if(!faulted) return(0);
73 else return(len - (fault - (unsigned long) mem));
74}
75
76int __do_strnlen_user(const char *str, unsigned long n,
77 void **fault_addr, void **fault_catcher)
78{
79 struct tt_regs save = TASK_REGS(get_current())->tt;
80 int ret;
81 unsigned long *faddrp = (unsigned long *)fault_addr;
82 jmp_buf jbuf;
83
84 *fault_catcher = &jbuf;
85 if(UML_SETJMP(&jbuf) == 0)
86 ret = strlen(str) + 1;
87 else ret = *faddrp - (unsigned long) str;
88
89 *fault_addr = NULL;
90 *fault_catcher = NULL;
91
92 TASK_REGS(get_current())->tt = save;
93 return ret;
94}
95
96/*
97 * Overrides for Emacs so that we follow Linus's tabbing style.
98 * Emacs will notice this stuff at the end of the file and automatically
99 * adjust the settings for this buffer only. This must remain at the end
100 * of the file.
101 * ---------------------------------------------------------------------------
102 * Local variables:
103 * c-file-style: "linux"
104 * End:
105 */
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index ecc458fe51b9..aa7b067565d9 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -38,9 +38,7 @@
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" 41#include "skas.h"
43#endif
44 42
45#define DEFAULT_COMMAND_LINE "root=98:0" 43#define DEFAULT_COMMAND_LINE "root=98:0"
46 44
@@ -132,43 +130,12 @@ unsigned long end_vm;
132/* Set in uml_ncpus_setup */ 130/* Set in uml_ncpus_setup */
133int ncpus = 1; 131int ncpus = 1;
134 132
135#ifdef CONFIG_CMDLINE_ON_HOST
136/* Pointer set in linux_main, the array itself is private to each thread,
137 * and changed at address space creation time so this poses no concurrency
138 * problems.
139 */
140static char *argv1_begin = NULL;
141static char *argv1_end = NULL;
142#endif
143
144/* Set in early boot */ 133/* Set in early boot */
145static int have_root __initdata = 0; 134static int have_root __initdata = 0;
146 135
147/* Set in uml_mem_setup and modified in linux_main */ 136/* Set in uml_mem_setup and modified in linux_main */
148long long physmem_size = 32 * 1024 * 1024; 137long long physmem_size = 32 * 1024 * 1024;
149 138
150void set_cmdline(char *cmd)
151{
152#ifdef CONFIG_CMDLINE_ON_HOST
153 char *umid, *ptr;
154
155 if(CHOOSE_MODE(honeypot, 0)) return;
156
157 umid = get_umid();
158 if(*umid != '\0'){
159 snprintf(argv1_begin,
160 (argv1_end - argv1_begin) * sizeof(*ptr),
161 "(%s) ", umid);
162 ptr = &argv1_begin[strlen(argv1_begin)];
163 }
164 else ptr = argv1_begin;
165
166 snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
167 memset(argv1_begin + strlen(argv1_begin), '\0',
168 argv1_end - argv1_begin - strlen(argv1_begin));
169#endif
170}
171
172static char *usage_string = 139static char *usage_string =
173"User Mode Linux v%s\n" 140"User Mode Linux v%s\n"
174" available at http://user-mode-linux.sourceforge.net/\n\n"; 141" available at http://user-mode-linux.sourceforge.net/\n\n";
@@ -201,13 +168,10 @@ __uml_setup("root=", uml_root_setup,
201" root=/dev/ubd5\n\n" 168" root=/dev/ubd5\n\n"
202); 169);
203 170
204#ifndef CONFIG_MODE_TT
205
206static int __init no_skas_debug_setup(char *line, int *add) 171static int __init no_skas_debug_setup(char *line, int *add)
207{ 172{
208 printf("'debug' is not necessary to gdb UML in skas mode - run \n"); 173 printf("'debug' is not necessary to gdb UML in skas mode - run \n");
209 printf("'gdb linux' and disable CONFIG_CMDLINE_ON_HOST if gdb \n"); 174 printf("'gdb linux'");
210 printf("doesn't work as expected\n");
211 175
212 return 0; 176 return 0;
213} 177}
@@ -217,8 +181,6 @@ __uml_setup("debug", no_skas_debug_setup,
217" this flag is not needed to run gdb on UML in skas mode\n\n" 181" this flag is not needed to run gdb on UML in skas mode\n\n"
218); 182);
219 183
220#endif
221
222#ifdef CONFIG_SMP 184#ifdef CONFIG_SMP
223static int __init uml_ncpus_setup(char *line, int *add) 185static int __init uml_ncpus_setup(char *line, int *add)
224{ 186{
@@ -236,52 +198,6 @@ __uml_setup("ncpus=", uml_ncpus_setup,
236); 198);
237#endif 199#endif
238 200
239static int force_tt = 0;
240
241#if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS)
242#define DEFAULT_TT 0
243
244static int __init mode_tt_setup(char *line, int *add)
245{
246 force_tt = 1;
247 return 0;
248}
249
250#else
251#ifdef CONFIG_MODE_SKAS
252
253#define DEFAULT_TT 0
254
255static int __init mode_tt_setup(char *line, int *add)
256{
257 printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
258 return 0;
259}
260
261#else
262#ifdef CONFIG_MODE_TT
263
264#define DEFAULT_TT 1
265
266static int __init mode_tt_setup(char *line, int *add)
267{
268 printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
269 return 0;
270}
271
272#endif
273#endif
274#endif
275
276__uml_setup("mode=tt", mode_tt_setup,
277"mode=tt\n"
278" When both CONFIG_MODE_TT and CONFIG_MODE_SKAS are enabled, this option\n"
279" forces UML to run in tt (tracing thread) mode. It is not the default\n"
280" because it's slower and less secure than skas mode.\n\n"
281);
282
283int mode_tt = DEFAULT_TT;
284
285static int __init Usage(char *line, int *add) 201static int __init Usage(char *line, int *add)
286{ 202{
287 const char **p; 203 const char **p;
@@ -357,29 +273,13 @@ int __init linux_main(int argc, char **argv)
357 add_arg(DEFAULT_COMMAND_LINE); 273 add_arg(DEFAULT_COMMAND_LINE);
358 274
359 os_early_checks(); 275 os_early_checks();
360 if (force_tt)
361 clear_can_do_skas();
362 mode_tt = force_tt ? 1 : !can_do_skas();
363#ifndef CONFIG_MODE_TT
364 if (mode_tt) {
365 /*Since CONFIG_MODE_TT is #undef'ed, force_tt cannot be 1. So,
366 * can_do_skas() returned 0, and the message is correct. */
367 printf("Support for TT mode is disabled, and no SKAS support is present on the host.\n");
368 exit(1);
369 }
370#endif
371 276
372#ifndef CONFIG_MODE_SKAS 277 can_do_skas();
373 mode = "TT"; 278
374#else 279 if (proc_mm && ptrace_faultinfo)
375 /* Show to the user the result of selection */
376 if (mode_tt)
377 mode = "TT";
378 else if (proc_mm && ptrace_faultinfo)
379 mode = "SKAS3"; 280 mode = "SKAS3";
380 else 281 else
381 mode = "SKAS0"; 282 mode = "SKAS0";
382#endif
383 283
384 printf("UML running in %s mode\n", mode); 284 printf("UML running in %s mode\n", mode);
385 285
@@ -411,11 +311,6 @@ int __init linux_main(int argc, char **argv)
411 311
412 setup_machinename(init_utsname()->machine); 312 setup_machinename(init_utsname()->machine);
413 313
414#ifdef CONFIG_CMDLINE_ON_HOST
415 argv1_begin = argv[1];
416 argv1_end = &argv[1][strlen(argv[1])];
417#endif
418
419 highmem = 0; 314 highmem = 0;
420 iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK; 315 iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
421 max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC; 316 max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC;
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index 81acdc24348e..13df191e2b41 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -18,13 +18,6 @@ SECTIONS
18 18
19 . = START + SIZEOF_HEADERS; 19 . = START + SIZEOF_HEADERS;
20 20
21#ifdef MODE_TT
22 .remap_data : { UNMAP_PATH (.data .bss) }
23 .remap : { UNMAP_PATH (.text) }
24
25 . = ALIGN(4096); /* Init code and data */
26#endif
27
28 _text = .; 21 _text = .;
29 _stext = .; 22 _stext = .;
30 __init_begin = .; 23 __init_begin = .;
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index f1bb58fe3207..1dbb45dfc49b 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -5,12 +5,7 @@
5 5
6obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ 6obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \
7 registers.o sigio.o signal.o start_up.o time.o trap.o tty.o uaccess.o \ 7 registers.o sigio.o signal.o start_up.o time.o trap.o tty.o uaccess.o \
8 umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ 8 umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ skas/
9
10obj-$(CONFIG_MODE_SKAS) += skas/
11
12obj-$(CONFIG_MODE_TT) += tt.o
13user-objs-$(CONFIG_MODE_TT) += tt.o
14 9
15obj-$(CONFIG_TTY_LOG) += tty_log.o 10obj-$(CONFIG_TTY_LOG) += tty_log.o
16user-objs-$(CONFIG_TTY_LOG) += tty_log.o 11user-objs-$(CONFIG_TTY_LOG) += tty_log.o
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index 919c25be254a..425aa8960649 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -25,9 +25,6 @@
25#include "um_malloc.h" 25#include "um_malloc.h"
26#include "kern_constants.h" 26#include "kern_constants.h"
27 27
28/* Set in main, unchanged thereafter */
29char *linux_prog;
30
31#define PGD_BOUND (4 * 1024 * 1024) 28#define PGD_BOUND (4 * 1024 * 1024)
32#define STACKSIZE (8 * 1024 * 1024) 29#define STACKSIZE (8 * 1024 * 1024)
33#define THREAD_NAME_LEN (256) 30#define THREAD_NAME_LEN (256)
@@ -125,35 +122,6 @@ int __init main(int argc, char **argv, char **envp)
125 char **new_argv; 122 char **new_argv;
126 int ret, i, err; 123 int ret, i, err;
127 124
128#ifdef UML_CONFIG_CMDLINE_ON_HOST
129 /* Allocate memory for thread command lines */
130 if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){
131
132 char padding[THREAD_NAME_LEN] = {
133 [ 0 ... THREAD_NAME_LEN - 2] = ' ', '\0'
134 };
135
136 new_argv = malloc((argc + 2) * sizeof(char*));
137 if(!new_argv) {
138 perror("Allocating extended argv");
139 exit(1);
140 }
141
142 new_argv[0] = argv[0];
143 new_argv[1] = padding;
144
145 for(i = 2; i <= argc; i++)
146 new_argv[i] = argv[i - 1];
147 new_argv[argc + 1] = NULL;
148
149 execvp(new_argv[0], new_argv);
150 perror("execing with extended args");
151 exit(1);
152 }
153#endif
154
155 linux_prog = argv[0];
156
157 set_stklim(); 125 set_stklim();
158 126
159 setup_env_path(); 127 setup_env_path();
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index e9c143297512..d5fef4ce0112 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -133,13 +133,6 @@ void os_kill_ptraced_process(int pid, int reap_child)
133 CATCH_EINTR(waitpid(pid, NULL, 0)); 133 CATCH_EINTR(waitpid(pid, NULL, 0));
134} 134}
135 135
136#ifdef UML_CONFIG_MODE_TT
137void os_usr1_process(int pid)
138{
139 kill(pid, SIGUSR1);
140}
141#endif
142
143/* Don't use the glibc version, which caches the result in TLS. It misses some 136/* Don't use the glibc version, which caches the result in TLS. It misses some
144 * syscalls, and also breaks with clone(), which does not unshare the TLS. 137 * syscalls, and also breaks with clone(), which does not unshare the TLS.
145 */ 138 */
@@ -239,30 +232,6 @@ out:
239 return ok; 232 return ok;
240} 233}
241 234
242#ifdef UML_CONFIG_MODE_TT
243void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
244{
245 int flags = 0, pages;
246
247 if(sig_stack != NULL){
248 pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER);
249 set_sigstack(sig_stack, pages * UM_KERN_PAGE_SIZE);
250 flags = SA_ONSTACK;
251 }
252 if(usr1_handler){
253 struct sigaction sa;
254
255 sa.sa_handler = usr1_handler;
256 sigemptyset(&sa.sa_mask);
257 sa.sa_flags = flags;
258 sa.sa_restorer = NULL;
259 if(sigaction(SIGUSR1, &sa, NULL) < 0)
260 panic("init_new_thread_stack - sigaction failed - "
261 "errno = %d\n", errno);
262 }
263}
264#endif
265
266void init_new_thread_signals(void) 235void init_new_thread_signals(void)
267{ 236{
268 set_handler(SIGSEGV, (__sighandler_t) sig_handler, SA_ONSTACK, 237 set_handler(SIGSEGV, (__sighandler_t) sig_handler, SA_ONSTACK,
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index f4f2981f74b9..acf52ea4ff52 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -35,12 +35,9 @@
35#include "mode.h" 35#include "mode.h"
36#include "tempfile.h" 36#include "tempfile.h"
37#include "kern_constants.h" 37#include "kern_constants.h"
38
39#ifdef UML_CONFIG_MODE_SKAS
40#include "skas.h" 38#include "skas.h"
41#include "skas_ptrace.h" 39#include "skas_ptrace.h"
42#include "registers.h" 40#include "registers.h"
43#endif
44 41
45static int ptrace_child(void *arg) 42static int ptrace_child(void *arg)
46{ 43{
@@ -407,7 +404,6 @@ __uml_setup("noptraceldt", noptraceldt_cmd_param,
407" To support PTRACE_LDT, the host needs to be patched using\n" 404" To support PTRACE_LDT, the host needs to be patched using\n"
408" the current skas3 patch.\n\n"); 405" the current skas3 patch.\n\n");
409 406
410#ifdef UML_CONFIG_MODE_SKAS
411static inline void check_skas3_ptrace_faultinfo(void) 407static inline void check_skas3_ptrace_faultinfo(void)
412{ 408{
413 struct ptrace_faultinfo fi; 409 struct ptrace_faultinfo fi;
@@ -504,12 +500,6 @@ int can_do_skas(void)
504 500
505 return 1; 501 return 1;
506} 502}
507#else
508int can_do_skas(void)
509{
510 return 0;
511}
512#endif
513 503
514int __init parse_iomem(char *str, int *add) 504int __init parse_iomem(char *str, int *add)
515{ 505{
diff --git a/arch/um/os-Linux/sys-i386/Makefile b/arch/um/os-Linux/sys-i386/Makefile
index 37806621b25d..dc7208f0b741 100644
--- a/arch/um/os-Linux/sys-i386/Makefile
+++ b/arch/um/os-Linux/sys-i386/Makefile
@@ -3,7 +3,7 @@
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-$(CONFIG_MODE_SKAS) = registers.o signal.o tls.o 6obj-y = registers.o signal.o tls.o
7 7
8USER_OBJS := $(obj-y) 8USER_OBJS := $(obj-y)
9 9
diff --git a/arch/um/os-Linux/sys-x86_64/Makefile b/arch/um/os-Linux/sys-x86_64/Makefile
index eac8c0db3001..a42a4ef02e1e 100644
--- a/arch/um/os-Linux/sys-x86_64/Makefile
+++ b/arch/um/os-Linux/sys-x86_64/Makefile
@@ -3,7 +3,7 @@
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-$(CONFIG_MODE_SKAS) = registers.o prctl.o signal.o 6obj-y = registers.o prctl.o signal.o
7 7
8USER_OBJS := $(obj-y) 8USER_OBJS := $(obj-y)
9 9
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index 5de169b168f6..5eb32d24ba58 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -30,13 +30,6 @@ int set_interval(int is_virtual)
30 return 0; 30 return 0;
31} 31}
32 32
33#ifdef UML_CONFIG_MODE_TT
34void enable_timer(void)
35{
36 set_interval(1);
37}
38#endif
39
40void disable_timer(void) 33void disable_timer(void)
41{ 34{
42 struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }}); 35 struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
@@ -71,18 +64,6 @@ void switch_timers(int to_real)
71 errno); 64 errno);
72} 65}
73 66
74#ifdef UML_CONFIG_MODE_TT
75void uml_idle_timer(void)
76{
77 if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
78 panic("Couldn't unset SIGVTALRM handler");
79
80 set_handler(SIGALRM, (__sighandler_t) alarm_handler,
81 SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
82 set_interval(0);
83}
84#endif
85
86unsigned long long os_nsecs(void) 67unsigned long long os_nsecs(void)
87{ 68{
88 struct timeval tv; 69 struct timeval tv;
diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c
index 16215b990804..282bd25e19ef 100644
--- a/arch/um/os-Linux/tls.c
+++ b/arch/um/os-Linux/tls.c
@@ -8,11 +8,6 @@
8 8
9/* TLS support - we basically rely on the host's one.*/ 9/* TLS support - we basically rely on the host's one.*/
10 10
11/* In TT mode, this should be called only by the tracing thread, and makes sense
12 * only for PTRACE_SET_THREAD_AREA. In SKAS mode, it's used normally.
13 *
14 */
15
16#ifndef PTRACE_GET_THREAD_AREA 11#ifndef PTRACE_GET_THREAD_AREA
17#define PTRACE_GET_THREAD_AREA 25 12#define PTRACE_GET_THREAD_AREA 25
18#endif 13#endif
@@ -32,8 +27,6 @@ int os_set_thread_area(user_desc_t *info, int pid)
32 return ret; 27 return ret;
33} 28}
34 29
35#ifdef UML_CONFIG_MODE_SKAS
36
37int os_get_thread_area(user_desc_t *info, int pid) 30int os_get_thread_area(user_desc_t *info, int pid)
38{ 31{
39 int ret; 32 int ret;
@@ -44,32 +37,3 @@ int os_get_thread_area(user_desc_t *info, int pid)
44 ret = -errno; 37 ret = -errno;
45 return ret; 38 return ret;
46} 39}
47
48#endif
49
50#ifdef UML_CONFIG_MODE_TT
51#include "linux/unistd.h"
52
53int do_set_thread_area_tt(user_desc_t *info)
54{
55 int ret;
56
57 ret = syscall(__NR_set_thread_area,info);
58 if (ret < 0) {
59 ret = -errno;
60 }
61 return ret;
62}
63
64int do_get_thread_area_tt(user_desc_t *info)
65{
66 int ret;
67
68 ret = syscall(__NR_get_thread_area,info);
69 if (ret < 0) {
70 ret = -errno;
71 }
72 return ret;
73}
74
75#endif /* UML_CONFIG_MODE_TT */
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index bf23dd3e24d0..61107b68e05b 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -21,7 +21,7 @@ $(UNPROFILE_OBJS:.o=.%): \
21$(UNPROFILE_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ 21$(UNPROFILE_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \
22 -Dunix -D__unix__ -D__$(SUBARCH)__ $(CF) 22 -Dunix -D__unix__ -D__$(SUBARCH)__ $(CF)
23 23
24# The stubs and unmap.o can't try to call mcount or update basic block data 24# The stubs can't try to call mcount or update basic block data
25define unprofile 25define unprofile
26 $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1))) 26 $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1)))
27endef 27endef
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index a4618b6b85b9..94b6ede5ef6c 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -1,8 +1,6 @@
1obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ 1obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
2 ptrace_user.o setjmp.o signal.o sigcontext.o syscalls.o sysrq.o \ 2 ptrace_user.o setjmp.o signal.o sigcontext.o stub.o stub_segv.o \
3 sys_call_table.o tls.o 3 syscalls.o sysrq.o sys_call_table.o tls.o
4
5obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o
6 4
7subarch-obj-y = lib/bitops_32.o lib/semaphore_32.o lib/string_32.o 5subarch-obj-y = lib/bitops_32.o lib/semaphore_32.o lib/string_32.o
8subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o 6subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o
@@ -13,11 +11,7 @@ USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
13USER_OBJS += user-offsets.s 11USER_OBJS += user-offsets.s
14extra-y += user-offsets.s 12extra-y += user-offsets.s
15 13
16extra-$(CONFIG_MODE_TT) += unmap.o
17
18UNPROFILE_OBJS := stub_segv.o 14UNPROFILE_OBJS := stub_segv.o
19CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) 15CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING)
20 16
21include arch/um/scripts/Makefile.rules 17include arch/um/scripts/Makefile.rules
22
23$(obj)/unmap.%: _c_flags = $(call unprofile,$(CFLAGS))
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index a939a7ef0227..762a12aec757 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -19,72 +19,6 @@
19 19
20extern int modify_ldt(int func, void *ptr, unsigned long bytecount); 20extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
21 21
22#ifdef CONFIG_MODE_TT
23
24static long do_modify_ldt_tt(int func, void __user *ptr,
25 unsigned long bytecount)
26{
27 struct user_desc info;
28 int res = 0;
29 void *buf = NULL;
30 void *p = NULL; /* What we pass to host. */
31
32 switch(func){
33 case 1:
34 case 0x11: /* write_ldt */
35 /* Do this check now to avoid overflows. */
36 if (bytecount != sizeof(struct user_desc)) {
37 res = -EINVAL;
38 goto out;
39 }
40
41 if(copy_from_user(&info, ptr, sizeof(info))) {
42 res = -EFAULT;
43 goto out;
44 }
45
46 p = &info;
47 break;
48 case 0:
49 case 2: /* read_ldt */
50
51 /* The use of info avoids kmalloc on the write case, not on the
52 * read one. */
53 buf = kmalloc(bytecount, GFP_KERNEL);
54 if (!buf) {
55 res = -ENOMEM;
56 goto out;
57 }
58 p = buf;
59 break;
60 default:
61 res = -ENOSYS;
62 goto out;
63 }
64
65 res = modify_ldt(func, p, bytecount);
66 if(res < 0)
67 goto out;
68
69 switch(func){
70 case 0:
71 case 2:
72 /* Modify_ldt was for reading and returned the number of read
73 * bytes.*/
74 if(copy_to_user(ptr, p, res))
75 res = -EFAULT;
76 break;
77 }
78
79out:
80 kfree(buf);
81 return res;
82}
83
84#endif
85
86#ifdef CONFIG_MODE_SKAS
87
88#include "skas.h" 22#include "skas.h"
89#include "skas_ptrace.h" 23#include "skas_ptrace.h"
90#include "asm/mmu_context.h" 24#include "asm/mmu_context.h"
@@ -569,7 +503,6 @@ void free_ldt(struct mmu_context_skas * mm)
569 } 503 }
570 mm->ldt.entry_count = 0; 504 mm->ldt.entry_count = 0;
571} 505}
572#endif
573 506
574int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) 507int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
575{ 508{
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index 28bf01150323..572fd504b94b 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -14,12 +14,6 @@
14#include "sysdep/sigcontext.h" 14#include "sysdep/sigcontext.h"
15#include "sysdep/sc.h" 15#include "sysdep/sc.h"
16 16
17void arch_switch_to_tt(struct task_struct *from, struct task_struct *to)
18{
19 update_debugregs(to->thread.arch.debugregs_seq);
20 arch_switch_tls_tt(from, to);
21}
22
23void arch_switch_to_skas(struct task_struct *from, struct task_struct *to) 17void arch_switch_to_skas(struct task_struct *from, struct task_struct *to)
24{ 18{
25 int err = arch_switch_tls_skas(from, to); 19 int err = arch_switch_tls_skas(from, to);
@@ -233,79 +227,12 @@ static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave
233 return ret; 227 return ret;
234} 228}
235 229
236/*
237 * FXSR floating point environment conversions.
238 */
239
240#ifdef CONFIG_MODE_TT
241static inline int convert_fxsr_to_user_tt(struct _fpstate __user *buf,
242 struct pt_regs *regs)
243{
244 struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
245 unsigned long env[7];
246 struct _fpreg __user *to;
247 struct _fpxreg *from;
248 int i;
249
250 env[0] = (unsigned long)fxsave->cwd | 0xffff0000;
251 env[1] = (unsigned long)fxsave->swd | 0xffff0000;
252 env[2] = twd_fxsr_to_i387(fxsave);
253 env[3] = fxsave->fip;
254 env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
255 env[5] = fxsave->foo;
256 env[6] = fxsave->fos;
257
258 if ( __copy_to_user( buf, env, 7 * sizeof(unsigned long) ) )
259 return 1;
260
261 to = &buf->_st[0];
262 from = (struct _fpxreg *) &fxsave->st_space[0];
263 for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
264 if ( __copy_to_user( to, from, sizeof(*to) ) )
265 return 1;
266 }
267 return 0;
268}
269#endif
270
271static inline int convert_fxsr_to_user(struct _fpstate __user *buf, 230static inline int convert_fxsr_to_user(struct _fpstate __user *buf,
272 struct pt_regs *regs) 231 struct pt_regs *regs)
273{ 232{
274 return(CHOOSE_MODE(convert_fxsr_to_user_tt(buf, regs), 0)); 233 return(CHOOSE_MODE(convert_fxsr_to_user_tt(buf, regs), 0));
275} 234}
276 235
277#ifdef CONFIG_MODE_TT
278static inline int convert_fxsr_from_user_tt(struct pt_regs *regs,
279 struct _fpstate __user *buf)
280{
281 struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
282 unsigned long env[7];
283 struct _fpxreg *to;
284 struct _fpreg __user *from;
285 int i;
286
287 if ( __copy_from_user( env, buf, 7 * sizeof(long) ) )
288 return 1;
289
290 fxsave->cwd = (unsigned short)(env[0] & 0xffff);
291 fxsave->swd = (unsigned short)(env[1] & 0xffff);
292 fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
293 fxsave->fip = env[3];
294 fxsave->fop = (unsigned short)((env[4] & 0xffff0000) >> 16);
295 fxsave->fcs = (env[4] & 0xffff);
296 fxsave->foo = env[5];
297 fxsave->fos = env[6];
298
299 to = (struct _fpxreg *) &fxsave->st_space[0];
300 from = &buf->_st[0];
301 for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
302 if ( __copy_from_user( to, from, sizeof(*from) ) )
303 return 1;
304 }
305 return 0;
306}
307#endif
308
309static inline int convert_fxsr_from_user(struct pt_regs *regs, 236static inline int convert_fxsr_from_user(struct pt_regs *regs,
310 struct _fpstate __user *buf) 237 struct _fpstate __user *buf)
311{ 238{
@@ -332,39 +259,11 @@ int set_fpregs(unsigned long buf, struct task_struct *child)
332 else return(0); 259 else return(0);
333} 260}
334 261
335#ifdef CONFIG_MODE_TT
336int get_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
337{
338 struct pt_regs *regs = &tsk->thread.regs;
339 struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
340 int err;
341
342 err = __copy_to_user((void __user *) buf, fxsave,
343 sizeof(struct user_fxsr_struct));
344 if(err) return -EFAULT;
345 else return 0;
346}
347#endif
348
349int get_fpxregs(unsigned long buf, struct task_struct *tsk) 262int get_fpxregs(unsigned long buf, struct task_struct *tsk)
350{ 263{
351 return(CHOOSE_MODE(get_fpxregs_tt(buf, tsk), 0)); 264 return(CHOOSE_MODE(get_fpxregs_tt(buf, tsk), 0));
352} 265}
353 266
354#ifdef CONFIG_MODE_TT
355int set_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
356{
357 struct pt_regs *regs = &tsk->thread.regs;
358 struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
359 int err;
360
361 err = __copy_from_user(fxsave, (void __user *) buf,
362 sizeof(struct user_fxsr_struct) );
363 if(err) return -EFAULT;
364 else return 0;
365}
366#endif
367
368int set_fpxregs(unsigned long buf, struct task_struct *tsk) 267int set_fpxregs(unsigned long buf, struct task_struct *tsk)
369{ 268{
370 return(CHOOSE_MODE(set_fpxregs_tt(buf, tsk), 0)); 269 return(CHOOSE_MODE(set_fpxregs_tt(buf, tsk), 0));
@@ -387,25 +286,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
387} 286}
388#endif 287#endif
389 288
390#ifdef CONFIG_MODE_TT
391static inline void copy_fpu_fxsave_tt(struct pt_regs *regs,
392 struct user_i387_struct *buf)
393{
394 struct i387_fxsave_struct *fpu = SC_FXSR_ENV(PT_REGS_SC(regs));
395 unsigned short *to;
396 unsigned short *from;
397 int i;
398
399 memcpy( buf, fpu, 7 * sizeof(long) );
400
401 to = (unsigned short *) &buf->st_space[0];
402 from = (unsigned short *) &fpu->st_space[0];
403 for ( i = 0 ; i < 8 ; i++, to += 5, from += 8 ) {
404 memcpy( to, from, 5 * sizeof(unsigned short) );
405 }
406}
407#endif
408
409static inline void copy_fpu_fxsave(struct pt_regs *regs, 289static inline void copy_fpu_fxsave(struct pt_regs *regs,
410 struct user_i387_struct *buf) 290 struct user_i387_struct *buf)
411{ 291{
diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c
index 40ff0c831bd0..b68dd230e646 100644
--- a/arch/um/sys-i386/ptrace_user.c
+++ b/arch/um/sys-i386/ptrace_user.c
@@ -43,89 +43,3 @@ int ptrace_setfpregs(long pid, unsigned long *regs)
43 return -errno; 43 return -errno;
44 return 0; 44 return 0;
45} 45}
46
47#ifdef UML_CONFIG_MODE_TT
48
49static void write_debugregs(int pid, unsigned long *regs)
50{
51 struct user *dummy;
52 int nregs, i;
53
54 dummy = NULL;
55 nregs = ARRAY_SIZE(dummy->u_debugreg);
56 for(i = 0; i < nregs; i++){
57 if((i == 4) || (i == 5)) continue;
58 if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i],
59 regs[i]) < 0)
60 printk("write_debugregs - ptrace failed on "
61 "register %d, value = 0x%lx, errno = %d\n", i,
62 regs[i], errno);
63 }
64}
65
66static void read_debugregs(int pid, unsigned long *regs)
67{
68 struct user *dummy;
69 int nregs, i;
70
71 dummy = NULL;
72 nregs = ARRAY_SIZE(dummy->u_debugreg);
73 for(i = 0; i < nregs; i++){
74 regs[i] = ptrace(PTRACE_PEEKUSR, pid,
75 &dummy->u_debugreg[i], 0);
76 }
77}
78
79/* Accessed only by the tracing thread */
80static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 };
81
82void arch_enter_kernel(void *task, int pid)
83{
84 read_debugregs(pid, TASK_DEBUGREGS(task));
85 write_debugregs(pid, kernel_debugregs);
86}
87
88void arch_leave_kernel(void *task, int pid)
89{
90 read_debugregs(pid, kernel_debugregs);
91 write_debugregs(pid, TASK_DEBUGREGS(task));
92}
93
94#ifdef UML_CONFIG_PT_PROXY
95/* Accessed only by the tracing thread */
96static int debugregs_seq;
97
98/* Only called by the ptrace proxy */
99void ptrace_pokeuser(unsigned long addr, unsigned long data)
100{
101 if((addr < offsetof(struct user, u_debugreg[0])) ||
102 (addr > offsetof(struct user, u_debugreg[7])))
103 return;
104 addr -= offsetof(struct user, u_debugreg[0]);
105 addr = addr >> 2;
106 if(kernel_debugregs[addr] == data) return;
107
108 kernel_debugregs[addr] = data;
109 debugregs_seq++;
110}
111
112static void update_debugregs_cb(void *arg)
113{
114 int pid = *((int *) arg);
115
116 write_debugregs(pid, kernel_debugregs);
117}
118
119/* Optimized out in its header when not defined */
120void update_debugregs(int seq)
121{
122 int me;
123
124 if(seq == debugregs_seq) return;
125
126 me = os_getpid();
127 initial_thread_cb(update_debugregs_cb, &me);
128}
129#endif
130
131#endif
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 1cbf95f6858a..187ea27536bd 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -13,9 +13,6 @@
13#include "sigcontext.h" 13#include "sigcontext.h"
14#include "registers.h" 14#include "registers.h"
15#include "mode.h" 15#include "mode.h"
16
17#ifdef CONFIG_MODE_SKAS
18
19#include "skas.h" 16#include "skas.h"
20 17
21void copy_sc(union uml_pt_regs *regs, void *from) 18void copy_sc(union uml_pt_regs *regs, void *from)
@@ -108,61 +105,6 @@ int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *t
108 return copy_to_user(to, &sc, sizeof(sc)) || 105 return copy_to_user(to, &sc, sizeof(sc)) ||
109 copy_to_user(to_fp, fpregs, sizeof(fpregs)); 106 copy_to_user(to_fp, fpregs, sizeof(fpregs));
110} 107}
111#endif
112
113#ifdef CONFIG_MODE_TT
114
115/* These copy a sigcontext to/from userspace. They copy the fpstate pointer,
116 * blowing away the old, good one. So, that value is saved, and then restored
117 * after the sigcontext copy. In copy_from, the variable holding the saved
118 * fpstate pointer, and the sigcontext that it should be restored to are both
119 * in the kernel, so we can just restore using an assignment. In copy_to, the
120 * saved pointer is in the kernel, but the sigcontext is in userspace, so we
121 * copy_to_user it.
122 */
123int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from,
124 int fpsize)
125{
126 struct _fpstate *to_fp;
127 struct _fpstate __user *from_fp;
128 unsigned long sigs;
129 int err;
130
131 to_fp = to->fpstate;
132 sigs = to->oldmask;
133 err = copy_from_user(to, from, sizeof(*to));
134 from_fp = to->fpstate;
135 to->oldmask = sigs;
136 to->fpstate = to_fp;
137 if(to_fp != NULL)
138 err |= copy_from_user(to_fp, from_fp, fpsize);
139 return err;
140}
141
142int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp,
143 struct sigcontext *from, int fpsize, unsigned long sp)
144{
145 struct _fpstate __user *to_fp;
146 struct _fpstate *from_fp;
147 int err;
148
149 to_fp = (fp ? fp : (struct _fpstate __user *) (to + 1));
150 from_fp = from->fpstate;
151 err = copy_to_user(to, from, sizeof(*to));
152
153 /* The SP in the sigcontext is the updated one for the signal
154 * delivery. The sp passed in is the original, and this needs
155 * to be restored, so we stick it in separately.
156 */
157 err |= copy_to_user(&SC_SP(to), &sp, sizeof(sp));
158
159 if(from_fp != NULL){
160 err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate));
161 err |= copy_to_user(to_fp, from_fp, fpsize);
162 }
163 return err;
164}
165#endif
166 108
167static int copy_sc_from_user(struct pt_regs *to, void __user *from) 109static int copy_sc_from_user(struct pt_regs *to, void __user *from)
168{ 110{
diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c
index fea8e5e15cc4..0340b96d101b 100644
--- a/arch/um/sys-i386/tls.c
+++ b/arch/um/sys-i386/tls.c
@@ -18,10 +18,7 @@
18#include "mode_kern.h" 18#include "mode_kern.h"
19#include "os.h" 19#include "os.h"
20#include "mode.h" 20#include "mode.h"
21
22#ifdef CONFIG_MODE_SKAS
23#include "skas.h" 21#include "skas.h"
24#endif
25 22
26/* 23/*
27 * If needed we can detect when it's uninitialized. 24 * If needed we can detect when it's uninitialized.
@@ -31,7 +28,6 @@
31static int host_supports_tls = -1; 28static int host_supports_tls = -1;
32int host_gdt_entry_tls_min; 29int host_gdt_entry_tls_min;
33 30
34#ifdef CONFIG_MODE_SKAS
35int do_set_thread_area_skas(struct user_desc *info) 31int do_set_thread_area_skas(struct user_desc *info)
36{ 32{
37 int ret; 33 int ret;
@@ -53,7 +49,6 @@ int do_get_thread_area_skas(struct user_desc *info)
53 put_cpu(); 49 put_cpu();
54 return ret; 50 return ret;
55} 51}
56#endif
57 52
58/* 53/*
59 * sys_get_thread_area: get a yet unused TLS descriptor index. 54 * sys_get_thread_area: get a yet unused TLS descriptor index.
@@ -187,17 +182,6 @@ int arch_switch_tls_skas(struct task_struct *from, struct task_struct *to)
187 return 0; 182 return 0;
188} 183}
189 184
190int arch_switch_tls_tt(struct task_struct *from, struct task_struct *to)
191{
192 if (!host_supports_tls)
193 return 0;
194
195 if (needs_TLS_update(to))
196 return load_TLS(0, to);
197
198 return 0;
199}
200
201static int set_tls_entry(struct task_struct* task, struct user_desc *info, 185static int set_tls_entry(struct task_struct* task, struct user_desc *info,
202 int idx, int flushed) 186 int idx, int flushed)
203{ 187{
diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c
deleted file mode 100644
index 1b0ad0e4adcd..000000000000
--- a/arch/um/sys-i386/unmap.c
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <linux/mman.h>
7#include <asm/unistd.h>
8
9static int errno;
10
11static inline _syscall2(int,munmap,void *,start,size_t,len)
12static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
13int switcheroo(int fd, int prot, void *from, void *to, int size)
14{
15 if(munmap(to, size) < 0){
16 return(-1);
17 }
18 if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
19 return(-1);
20 }
21 if(munmap(from, size) < 0){
22 return(-1);
23 }
24 return(0);
25}
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index ea8185d85404..002bb020f96a 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -5,10 +5,9 @@
5# 5#
6 6
7obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \ 7obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \
8 setjmp.o sigcontext.o signal.o syscalls.o syscall_table.o sysrq.o \ 8 setjmp.o sigcontext.o signal.o stub.o stub_segv.o syscalls.o \
9 ksyms.o tls.o 9 syscall_table.o sysrq.o ksyms.o tls.o
10 10
11obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o
12obj-$(CONFIG_MODULES) += um_module.o 11obj-$(CONFIG_MODULES) += um_module.o
13 12
14subarch-obj-y = lib/bitops_64.o lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o 13subarch-obj-y = lib/bitops_64.o lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o
@@ -21,11 +20,7 @@ USER_OBJS := ptrace_user.o sigcontext.o
21USER_OBJS += user-offsets.s 20USER_OBJS += user-offsets.s
22extra-y += user-offsets.s 21extra-y += user-offsets.s
23 22
24extra-$(CONFIG_MODE_TT) += unmap.o
25
26UNPROFILE_OBJS := stub_segv.o 23UNPROFILE_OBJS := stub_segv.o
27CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) 24CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING)
28 25
29include arch/um/scripts/Makefile.rules 26include arch/um/scripts/Makefile.rules
30
31$(obj)/unmap.%: _c_flags = $(call unprofile,$(CFLAGS))
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
index fe8ec04d35bb..c18d929e69bc 100644
--- a/arch/um/sys-x86_64/signal.c
+++ b/arch/um/sys-x86_64/signal.c
@@ -15,9 +15,6 @@
15#include "choose-mode.h" 15#include "choose-mode.h"
16#include "sysdep/ptrace.h" 16#include "sysdep/ptrace.h"
17#include "frame_kern.h" 17#include "frame_kern.h"
18
19#ifdef CONFIG_MODE_SKAS
20
21#include "skas.h" 18#include "skas.h"
22 19
23void copy_sc(union uml_pt_regs *regs, void *from) 20void copy_sc(union uml_pt_regs *regs, void *from)
@@ -134,53 +131,6 @@ int copy_sc_to_user_skas(struct sigcontext __user *to,
134 return(err); 131 return(err);
135} 132}
136 133
137#endif
138
139#ifdef CONFIG_MODE_TT
140int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from,
141 int fpsize)
142{
143 struct _fpstate *to_fp;
144 struct _fpstate __user *from_fp;
145 unsigned long sigs;
146 int err;
147
148 to_fp = to->fpstate;
149 sigs = to->oldmask;
150 err = copy_from_user(to, from, sizeof(*to));
151 from_fp = to->fpstate;
152 to->fpstate = to_fp;
153 to->oldmask = sigs;
154 if(to_fp != NULL)
155 err |= copy_from_user(to_fp, from_fp, fpsize);
156 return(err);
157}
158
159int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp,
160 struct sigcontext *from, int fpsize, unsigned long sp)
161{
162 struct _fpstate __user *to_fp;
163 struct _fpstate *from_fp;
164 int err;
165
166 to_fp = (fp ? fp : (struct _fpstate __user *) (to + 1));
167 from_fp = from->fpstate;
168 err = copy_to_user(to, from, sizeof(*to));
169 /* The SP in the sigcontext is the updated one for the signal
170 * delivery. The sp passed in is the original, and this needs
171 * to be restored, so we stick it in separately.
172 */
173 err |= copy_to_user(&SC_SP(to), &sp, sizeof(sp));
174
175 if(from_fp != NULL){
176 err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate));
177 err |= copy_to_user(to_fp, from_fp, fpsize);
178 }
179 return err;
180}
181
182#endif
183
184static int copy_sc_from_user(struct pt_regs *to, void __user *from) 134static int copy_sc_from_user(struct pt_regs *to, void __user *from)
185{ 135{
186 int ret; 136 int ret;
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index b3f6350cac44..d0ff832c9eaf 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -29,36 +29,6 @@ asmlinkage long sys_uname64(struct new_utsname __user * name)
29 return err ? -EFAULT : 0; 29 return err ? -EFAULT : 0;
30} 30}
31 31
32#ifdef CONFIG_MODE_TT
33extern long arch_prctl(int code, unsigned long addr);
34
35static long arch_prctl_tt(int code, unsigned long addr)
36{
37 unsigned long tmp;
38 long ret;
39
40 switch(code){
41 case ARCH_SET_GS:
42 case ARCH_SET_FS:
43 ret = arch_prctl(code, addr);
44 break;
45 case ARCH_GET_FS:
46 case ARCH_GET_GS:
47 ret = arch_prctl(code, (unsigned long) &tmp);
48 if(!ret)
49 ret = put_user(tmp, (long __user *)addr);
50 break;
51 default:
52 ret = -EINVAL;
53 break;
54 }
55
56 return(ret);
57}
58#endif
59
60#ifdef CONFIG_MODE_SKAS
61
62long arch_prctl_skas(struct task_struct *task, int code, 32long arch_prctl_skas(struct task_struct *task, int code,
63 unsigned long __user *addr) 33 unsigned long __user *addr)
64{ 34{
@@ -119,7 +89,6 @@ long arch_prctl_skas(struct task_struct *task, int code,
119 89
120 return ret; 90 return ret;
121} 91}
122#endif
123 92
124long sys_arch_prctl(int code, unsigned long addr) 93long sys_arch_prctl(int code, unsigned long addr)
125{ 94{
diff --git a/arch/um/sys-x86_64/unmap.c b/arch/um/sys-x86_64/unmap.c
deleted file mode 100644
index f4a4bffd8a18..000000000000
--- a/arch/um/sys-x86_64/unmap.c
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <linux/mman.h>
7#include <asm/unistd.h>
8
9static int errno;
10
11static inline _syscall2(int,munmap,void *,start,size_t,len)
12static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
13int switcheroo(int fd, int prot, void *from, void *to, int size)
14{
15 if(munmap(to, size) < 0){
16 return(-1);
17 }
18 if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
19 return(-1);
20 }
21 if(munmap(from, size) < 0){
22 return(-1);
23 }
24 return(0);
25}