diff options
Diffstat (limited to 'arch/um')
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 | ||
63 | menu "UML-specific options" | 63 | menu "UML-specific options" |
64 | 64 | ||
65 | config 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 | |||
77 | config STATIC_LINK | 65 | config 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 | |||
92 | config 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 | |||
102 | config 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 | ||
115 | source "arch/um/Kconfig.arch" | 76 | source "arch/um/Kconfig.arch" |
116 | source "mm/Kconfig" | 77 | source "mm/Kconfig" |
@@ -118,7 +79,7 @@ source "mm/Kconfig" | |||
118 | config LD_SCRIPT_STATIC | 79 | config 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 | ||
123 | config LD_SCRIPT_DYN | 84 | config 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 | |||
266 | config HIGHMEM | 222 | config 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 | ||
278 | config KERNEL_STACK_ORDER | 234 | config 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 | ||
72 | config NOCONFIG_CHAN | 70 | config 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 | ||
3 | source "lib/Kconfig.debug" | 3 | source "lib/Kconfig.debug" |
4 | 4 | ||
5 | config 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 | |||
16 | config 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 | |||
24 | config GPROF | 5 | config 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 | ||
37 | config GCOV | 18 | config 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)) | |||
31 | ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \ | 31 | ARCH_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 | ||
34 | um-modes-$(CONFIG_MODE_TT) += tt | 34 | MODE_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include/skas |
35 | um-modes-$(CONFIG_MODE_SKAS) += skas | ||
36 | 35 | ||
37 | MODE_INCLUDE += $(foreach mode,$(um-modes-y),\ | 36 | include $(srctree)/$(ARCH_DIR)/Makefile-skas |
38 | -I$(srctree)/$(ARCH_DIR)/include/$(mode)) | ||
39 | |||
40 | MAKEFILES-INCL += $(foreach mode,$(um-modes-y),\ | ||
41 | $(srctree)/$(ARCH_DIR)/Makefile-$(mode)) | ||
42 | |||
43 | ifneq ($(MAKEFILES-INCL),) | ||
44 | include $(MAKEFILES-INCL) | ||
45 | endif | ||
46 | 37 | ||
47 | ARCH_INCLUDE := -I$(ARCH_DIR)/include | 38 | ARCH_INCLUDE := -I$(ARCH_DIR)/include |
48 | ifneq ($(KBUILD_SRC),) | 39 | ifneq ($(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 | ||
91 | CONFIG_NEST_LEVEL ?= 0 | 82 | CONFIG_NEST_LEVEL ?= 0 |
92 | CONFIG_KERNEL_HALF_GIGS ?= 0 | ||
93 | 83 | ||
94 | SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000) | 84 | SIZE = ($(CONFIG_NEST_LEVEL) * 0x20000000) |
95 | 85 | ||
96 | PHONY += linux | 86 | PHONY += 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 | ||
127 | CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT | ||
128 | CONFIG_KERNEL_STACK_ORDER ?= 2 | 117 | CONFIG_KERNEL_STACK_ORDER ?= 2 |
129 | STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) | 118 | STACK_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) ] ) |
133 | endif | 122 | endif |
134 | 123 | ||
135 | CPPFLAGS_vmlinux.lds = -U$(SUBARCH) \ | 124 | CPPFLAGS_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. |
142 | LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc | 128 | LINK_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 | ||
3 | TOP_ADDR := $(CONFIG_TOP_ADDR) | 3 | TOP_ADDR := $(CONFIG_TOP_ADDR) |
4 | 4 | ||
5 | ifeq ($(CONFIG_MODE_SKAS),y) | 5 | START := 0x8048000 |
6 | ifneq ($(CONFIG_MODE_TT),y) | ||
7 | START := 0x8048000 | ||
8 | endif | ||
9 | endif | ||
10 | 6 | ||
11 | LDFLAGS += -m elf_i386 | 7 | LDFLAGS += -m elf_i386 |
12 | ELF_ARCH := $(SUBARCH) | 8 | ELF_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 |
17 | CONFIG_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 | |||
740 | static void stack_proc(void *arg) | 738 | static 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 | */ |
753 | static void do_stack_trace(struct mc_request *req) | 751 | void 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 | |||
786 | void 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; | |||
28 | extern unsigned long brk_start; | 28 | extern unsigned long brk_start; |
29 | 29 | ||
30 | extern int linux_main(int argc, char **argv); | 30 | extern int linux_main(int argc, char **argv); |
31 | extern void set_cmdline(char *cmd); | ||
32 | 31 | ||
33 | extern void (*sig_info[])(int, union uml_pt_regs *); | 32 | extern 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 | |||
14 | extern int mode_tt; | ||
15 | static 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 | ||
3 | DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); | 3 | DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); |
4 | #ifdef CONFIG_MODE_TT | ||
5 | OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); | ||
6 | #endif | ||
7 | 4 | ||
8 | OFFSET(HOST_TASK_REGS, task_struct, thread.regs); | 5 | OFFSET(HOST_TASK_REGS, task_struct, thread.regs); |
9 | OFFSET(HOST_TASK_PID, task_struct, pid); | 6 | OFFSET(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); | |||
30 | extern int deactivate_all_fds(void); | 30 | extern int deactivate_all_fds(void); |
31 | extern int activate_ipi(int fd, int pid); | 31 | extern int activate_ipi(int fd, int pid); |
32 | 32 | ||
33 | #ifdef CONFIG_MODE_TT | ||
34 | extern 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 | ||
36 | extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg); | 36 | extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg); |
37 | #ifdef UML_CONFIG_MODE_TT | ||
38 | extern unsigned long stack_sp(unsigned long page); | ||
39 | #endif | ||
40 | extern int kernel_thread_proc(void *data); | 37 | extern int kernel_thread_proc(void *data); |
41 | extern void syscall_segv(int sig); | 38 | extern void syscall_segv(int sig); |
42 | extern int current_pid(void); | 39 | extern int current_pid(void); |
@@ -82,9 +79,6 @@ extern void check_stack_overflow(void *ptr); | |||
82 | extern void relay_signal(int sig, union uml_pt_regs *regs); | 79 | extern void relay_signal(int sig, union uml_pt_regs *regs); |
83 | extern int user_context(unsigned long sp); | 80 | extern int user_context(unsigned long sp); |
84 | extern void timer_irq(union uml_pt_regs *regs); | 81 | extern void timer_irq(union uml_pt_regs *regs); |
85 | #ifdef CONFIG_MODE_TT | ||
86 | extern void unprotect_stack(unsigned long stack); | ||
87 | #endif | ||
88 | extern void do_uml_exitcalls(void); | 82 | extern void do_uml_exitcalls(void); |
89 | extern int attach_debugger(int idle_pid, int pid, int stop); | 83 | extern int attach_debugger(int idle_pid, int pid, int stop); |
90 | extern int config_gdb(char *str); | 84 | extern 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 */ |
188 | extern int create_mem_file(unsigned long long len); | 184 | extern int create_mem_file(unsigned long long len); |
@@ -193,18 +189,11 @@ extern int os_process_parent(int pid); | |||
193 | extern void os_stop_process(int pid); | 189 | extern void os_stop_process(int pid); |
194 | extern void os_kill_process(int pid, int reap_child); | 190 | extern void os_kill_process(int pid, int reap_child); |
195 | extern void os_kill_ptraced_process(int pid, int reap_child); | 191 | extern void os_kill_ptraced_process(int pid, int reap_child); |
196 | #ifdef UML_CONFIG_MODE_TT | ||
197 | extern void os_usr1_process(int pid); | ||
198 | #endif | ||
199 | extern long os_ptrace_ldt(long pid, long addr, long data); | 192 | extern long os_ptrace_ldt(long pid, long addr, long data); |
200 | 193 | ||
201 | extern int os_getpid(void); | 194 | extern int os_getpid(void); |
202 | extern int os_getpgrp(void); | 195 | extern int os_getpgrp(void); |
203 | 196 | ||
204 | #ifdef UML_CONFIG_MODE_TT | ||
205 | extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); | ||
206 | extern void stop(void); | ||
207 | #endif | ||
208 | extern void init_new_thread_signals(void); | 197 | extern void init_new_thread_signals(void); |
209 | extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr); | 198 | extern 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); | |||
217 | extern int can_drop_memory(void); | 206 | extern int can_drop_memory(void); |
218 | extern void os_flush_stdout(void); | 207 | extern void os_flush_stdout(void); |
219 | 208 | ||
220 | /* tt.c | ||
221 | * for tt mode only (will be deleted in future...) | ||
222 | */ | ||
223 | extern void forward_ipi(int fd, int pid); | ||
224 | extern void kill_child_dead(int pid); | ||
225 | extern int wait_for_stop(int pid, int sig, int cont_type, void *relay); | ||
226 | extern int protect_memory(unsigned long addr, unsigned long len, | ||
227 | int r, int w, int x, int must_succeed); | ||
228 | extern void forward_pending_sigio(int target); | ||
229 | extern int start_fork_tramp(void *arg, unsigned long temp_stack, | ||
230 | int clone_flags, int (*tramp)(void *)); | ||
231 | |||
232 | /* uaccess.c */ | 209 | /* uaccess.c */ |
233 | extern unsigned long __do_user_copy(void *to, const void *from, int n, | 210 | extern 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); | |||
281 | extern void switch_timers(int to_real); | 258 | extern void switch_timers(int to_real); |
282 | extern void idle_sleep(int secs); | 259 | extern void idle_sleep(int secs); |
283 | extern int set_interval(int is_virtual); | 260 | extern int set_interval(int is_virtual); |
284 | #ifdef CONFIG_MODE_TT | ||
285 | extern void enable_timer(void); | ||
286 | #endif | ||
287 | extern void disable_timer(void); | 261 | extern void disable_timer(void); |
288 | extern void uml_idle_timer(void); | 262 | extern void uml_idle_timer(void); |
289 | extern unsigned long long os_nsecs(void); | 263 | extern 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 | ||
18 | extern void update_debugregs(int seq); | ||
19 | #else | ||
20 | static inline void update_debugregs(int seq) {} | 17 | static 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); | |||
31 | int get_using_sysemu(void); | 26 | int get_using_sysemu(void); |
32 | extern int sysemu_supported; | 27 | extern 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 | ||
68 | union uml_pt_regs { | 56 | union 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 | ||
90 | extern 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 | ||
39 | extern unsigned long *sc_sigmask(void *sc_ptr); | 35 | extern unsigned long *sc_sigmask(void *sc_ptr); |
40 | extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); | 36 | extern 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 */ |
96 | union uml_pt_regs { | 90 | union 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 */ | ||
119 | extern 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 | |||
10 | extern int debugger_proxy(int status, pid_t pid); | ||
11 | extern void child_proxy(pid_t pid, int status); | ||
12 | extern void init_proxy (pid_t pid, int waiting, int status); | ||
13 | extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd); | ||
14 | extern void fake_child_exit(void); | ||
15 | extern int gdb_config(char *str); | ||
16 | extern 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 | |||
9 | struct 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 | |||
11 | enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB }; | ||
12 | |||
13 | extern int tracing_pid; | ||
14 | |||
15 | extern int tracer(int (*init_proc)(void *), void *sp); | ||
16 | extern void sig_handler_common_tt(int sig, void *sc); | ||
17 | extern void syscall_handler_tt(int sig, union uml_pt_regs *regs); | ||
18 | extern void reboot_tt(void); | ||
19 | extern void halt_tt(void); | ||
20 | extern int is_tracer_winch(int pid, int fd, void *data); | ||
21 | extern 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 | |||
14 | extern void switch_to_tt(void *prev, void *next); | ||
15 | extern void flush_thread_tt(void); | ||
16 | extern void start_thread_tt(struct pt_regs *regs, unsigned long eip, | ||
17 | unsigned long esp); | ||
18 | extern 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); | ||
21 | extern void release_thread_tt(struct task_struct *task); | ||
22 | extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); | ||
23 | extern void init_idle_tt(void); | ||
24 | extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end); | ||
25 | extern void flush_tlb_kernel_vm_tt(void); | ||
26 | extern void __flush_tlb_one_tt(unsigned long addr); | ||
27 | extern void flush_tlb_range_tt(struct vm_area_struct *vma, | ||
28 | unsigned long start, unsigned long end); | ||
29 | extern void flush_tlb_mm_tt(struct mm_struct *mm); | ||
30 | extern void force_flush_all_tt(void); | ||
31 | extern long execute_syscall_tt(void *r); | ||
32 | extern void before_mem_tt(unsigned long brk_start); | ||
33 | extern unsigned long set_task_sizes_tt(unsigned long *task_size_out); | ||
34 | extern int start_uml_tt(void); | ||
35 | extern int external_pid_tt(struct task_struct *task); | ||
36 | extern 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 | |||
11 | extern int gdb_pid; | ||
12 | extern int debug; | ||
13 | extern int debug_stop; | ||
14 | extern int debug_trace; | ||
15 | |||
16 | extern int honeypot; | ||
17 | |||
18 | extern int fork_tramp(void *sig_stack); | ||
19 | extern int do_proc_op(void *t, int proc_id); | ||
20 | extern int tracer(int (*init_proc)(void *), void *sp); | ||
21 | extern void attach_process(int pid); | ||
22 | extern void tracer_panic(char *format, ...) | ||
23 | __attribute__ ((format (printf, 1, 2))); | ||
24 | extern void set_init_pid(int pid); | ||
25 | extern int set_user_mode(void *task); | ||
26 | extern void set_tracing(void *t, int tracing); | ||
27 | extern int is_tracing(void *task); | ||
28 | extern void syscall_handler(int sig, union uml_pt_regs *regs); | ||
29 | extern void exit_kernel(int pid, void *task); | ||
30 | extern void do_syscall(void *task, int pid, int local_using_sysemu); | ||
31 | extern void do_sigtrap(void *task); | ||
32 | extern int is_valid_pid(int pid); | ||
33 | extern void remap_data(void *segment_start, void *segment_end, int w); | ||
34 | extern 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 | |||
19 | extern unsigned long end_vm; | ||
20 | extern 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 | |||
30 | extern int __do_copy_from_user(void *to, const void *from, int n, | ||
31 | void **fault_addr, void **fault_catcher); | ||
32 | extern int __do_strncpy_from_user(char *dst, const char *src, size_t n, | ||
33 | void **fault_addr, void **fault_catcher); | ||
34 | extern int __do_clear_user(void *mem, size_t len, void **fault_addr, | ||
35 | void **fault_catcher); | ||
36 | extern int __do_strnlen_user(const char *str, unsigned long n, | ||
37 | void **fault_addr, void **fault_catcher); | ||
38 | |||
39 | extern int copy_from_user_tt(void *to, const void __user *from, int n); | ||
40 | extern int copy_to_user_tt(void __user *to, const void *from, int n); | ||
41 | extern int strncpy_from_user_tt(char *dst, const char __user *src, int count); | ||
42 | extern int __clear_user_tt(void __user *mem, int len); | ||
43 | extern int clear_user_tt(void __user *mem, int len); | ||
44 | extern 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 | ||
20 | typedef union mm_context { | 13 | typedef 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 := | |||
9 | obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \ | 9 | obj-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 | ||
14 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o | 14 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o |
15 | obj-$(CONFIG_GPROF) += gprof_syms.o | 15 | obj-$(CONFIG_GPROF) += gprof_syms.o |
16 | obj-$(CONFIG_GCOV) += gmon_syms.o | 16 | obj-$(CONFIG_GCOV) += gmon_syms.o |
17 | 17 | ||
18 | obj-$(CONFIG_MODE_TT) += tt/ | ||
19 | obj-$(CONFIG_MODE_SKAS) += skas/ | ||
20 | |||
21 | USER_OBJS := config.o | 18 | USER_OBJS := config.o |
22 | 19 | ||
23 | include arch/um/scripts/Makefile.rules | 20 | include 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(¤t->thread.regs.regs); | 57 | SUBARCH_EXECVE1(¤t->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 | |||
46 | union thread_union cpu0_irqstack | 46 | union 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 | ||
51 | void 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 | ||
343 | void 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); | |||
34 | EXPORT_SYMBOL(high_physmem); | 34 | EXPORT_SYMBOL(high_physmem); |
35 | EXPORT_SYMBOL(empty_zero_page); | 35 | EXPORT_SYMBOL(empty_zero_page); |
36 | EXPORT_SYMBOL(um_virt_to_phys); | 36 | EXPORT_SYMBOL(um_virt_to_phys); |
37 | EXPORT_SYMBOL(mode_tt); | ||
38 | EXPORT_SYMBOL(handle_page_fault); | 37 | EXPORT_SYMBOL(handle_page_fault); |
39 | EXPORT_SYMBOL(find_iomem); | 38 | EXPORT_SYMBOL(find_iomem); |
40 | 39 | ||
41 | #ifdef CONFIG_MODE_TT | ||
42 | EXPORT_SYMBOL(stop); | ||
43 | EXPORT_SYMBOL(strncpy_from_user_tt); | ||
44 | EXPORT_SYMBOL(copy_from_user_tt); | ||
45 | EXPORT_SYMBOL(copy_to_user_tt); | ||
46 | #endif | ||
47 | |||
48 | #ifdef CONFIG_MODE_SKAS | ||
49 | EXPORT_SYMBOL(strnlen_user_skas); | 40 | EXPORT_SYMBOL(strnlen_user_skas); |
50 | EXPORT_SYMBOL(strncpy_from_user_skas); | 41 | EXPORT_SYMBOL(strncpy_from_user_skas); |
51 | EXPORT_SYMBOL(copy_to_user_skas); | 42 | EXPORT_SYMBOL(copy_to_user_skas); |
52 | EXPORT_SYMBOL(copy_from_user_skas); | 43 | EXPORT_SYMBOL(copy_from_user_skas); |
53 | EXPORT_SYMBOL(clear_user_skas); | 44 | EXPORT_SYMBOL(clear_user_skas); |
54 | #endif | ||
55 | EXPORT_SYMBOL(uml_strdup); | 45 | EXPORT_SYMBOL(uml_strdup); |
56 | 46 | ||
57 | EXPORT_SYMBOL(os_stat_fd); | 47 | EXPORT_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 | ||
187 | unsigned long stack_sp(unsigned long page) | ||
188 | { | ||
189 | return page + PAGE_SIZE - sizeof(void *); | ||
190 | } | ||
191 | #endif | ||
192 | |||
193 | void default_idle(void) | 186 | void 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 | ||
15 | void (*pm_power_off)(void); | 15 | void (*pm_power_off)(void); |
16 | 16 | ||
17 | #ifdef CONFIG_SMP | ||
18 | static 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 | |||
33 | static void kill_off_processes(void) | 17 | static 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 | ||
41 | void uml_cleanup(void) | 22 | void 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) | |||
95 | static struct task_struct *idle_thread(int cpu) | 95 | static 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 | |||
6 | obj-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 | |||
10 | obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/ | ||
11 | |||
12 | USER_OBJS := gdb.o tracer.o | ||
13 | |||
14 | include 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 | |||
20 | static 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 | |||
28 | void 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 | |||
65 | void 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 | |||
18 | void 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 | |||
24 | extern int debugger_pid; | ||
25 | extern int debugger_fd; | ||
26 | extern int debugger_parent; | ||
27 | |||
28 | int detach(int pid, int sig) | ||
29 | { | ||
30 | return(ptrace(PTRACE_DETACH, pid, 0, sig)); | ||
31 | } | ||
32 | |||
33 | int 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 | |||
42 | int cont(int pid) | ||
43 | { | ||
44 | return(ptrace(PTRACE_CONT, pid, 0, 0)); | ||
45 | } | ||
46 | |||
47 | #ifdef UML_CONFIG_PT_PROXY | ||
48 | |||
49 | int debugger_signal(int status, pid_t pid) | ||
50 | { | ||
51 | return(debugger_proxy(status, pid)); | ||
52 | } | ||
53 | |||
54 | void child_signal(pid_t pid, int status) | ||
55 | { | ||
56 | child_proxy(pid, status); | ||
57 | } | ||
58 | |||
59 | static void gdb_announce(char *dev_name, int dev) | ||
60 | { | ||
61 | printf("gdb assigned device '%s'\n", dev_name); | ||
62 | } | ||
63 | |||
64 | static 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 */ | ||
73 | static void *xterm_data; | ||
74 | static int xterm_fd; | ||
75 | |||
76 | extern void *xterm_init(char *, int, struct chan_opts *); | ||
77 | extern int xterm_open(int, int, int, void *, char **); | ||
78 | extern void xterm_close(int, void *); | ||
79 | |||
80 | int 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 | |||
90 | static 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 | |||
105 | static void exit_debugger(void) | ||
106 | { | ||
107 | initial_thread_cb(exit_debugger_cb, NULL); | ||
108 | } | ||
109 | |||
110 | __uml_exitcall(exit_debugger); | ||
111 | |||
112 | struct gdb_data { | ||
113 | char *str; | ||
114 | int err; | ||
115 | }; | ||
116 | |||
117 | extern char *linux_prog; | ||
118 | |||
119 | static 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 | |||
143 | int 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 | |||
153 | void remove_gdb_cb(void *unused) | ||
154 | { | ||
155 | exit_debugger_cb(NULL); | ||
156 | } | ||
157 | |||
158 | int gdb_remove(int unused, char **error_out) | ||
159 | { | ||
160 | initial_thread_cb(remove_gdb_cb, NULL); | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | void 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 | |||
174 | int 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 | |||
188 | int 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 */ | ||
203 | static 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 | |||
214 | static 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 | |||
229 | int debugger_signal(int status, pid_t pid){ return(0); } | ||
230 | void child_signal(pid_t pid, int status){ } | ||
231 | int 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 | |||
238 | void signal_usr1(int sig) | ||
239 | { | ||
240 | printf("debug requested when CONFIG_PT_PROXY is off\n"); | ||
241 | } | ||
242 | |||
243 | int 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 | |||
250 | int config_gdb(char *str) | ||
251 | { | ||
252 | return(-1); | ||
253 | } | ||
254 | |||
255 | int remove_gdb(void) | ||
256 | { | ||
257 | return(-1); | ||
258 | } | ||
259 | |||
260 | int init_parent_proxy(int pid) | ||
261 | { | ||
262 | return(-1); | ||
263 | } | ||
264 | |||
265 | void 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 | |||
11 | extern int gdb_config(char *str, char **error_out); | ||
12 | extern int gdb_remove(int n, char **error_out); | ||
13 | |||
14 | static 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 | |||
21 | int 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 | |||
11 | enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB }; | ||
12 | |||
13 | extern int tracing_pid; | ||
14 | |||
15 | extern int tracer(int (*init_proc)(void *), void *sp); | ||
16 | extern void sig_handler_common_tt(int sig, void *sc); | ||
17 | extern void syscall_handler_tt(int sig, union uml_pt_regs *regs); | ||
18 | extern void reboot_tt(void); | ||
19 | extern void halt_tt(void); | ||
20 | extern int is_tracer_winch(int pid, int fd, void *data); | ||
21 | extern 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 | |||
10 | EXPORT_SYMBOL(__do_copy_from_user); | ||
11 | EXPORT_SYMBOL(__do_copy_to_user); | ||
12 | EXPORT_SYMBOL(__do_strncpy_from_user); | ||
13 | EXPORT_SYMBOL(__do_strnlen_user); | ||
14 | EXPORT_SYMBOL(__do_clear_user); | ||
15 | EXPORT_SYMBOL(clear_user_tt); | ||
16 | |||
17 | EXPORT_SYMBOL(tracing_pid); | ||
18 | EXPORT_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 | |||
14 | void 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 | |||
25 | unsigned 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 | |||
16 | void 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 | |||
27 | void 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 | |||
93 | void 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 | |||
111 | void 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 | |||
122 | void schedule_tail(struct task_struct *prev); | ||
123 | |||
124 | static 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(¤t->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(¤t->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, ¤t->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 | |||
163 | static 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 | |||
196 | void finish_fork_handler(int sig) | ||
197 | { | ||
198 | UPT_SC(¤t->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 | |||
220 | int 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 | |||
231 | int 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(®s->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 | |||
290 | void reboot_tt(void) | ||
291 | { | ||
292 | current->thread.request.op = OP_REBOOT; | ||
293 | os_usr1_process(os_getpid()); | ||
294 | change_sig(SIGUSR1, 1); | ||
295 | } | ||
296 | |||
297 | void halt_tt(void) | ||
298 | { | ||
299 | current->thread.request.op = OP_HALT; | ||
300 | os_usr1_process(os_getpid()); | ||
301 | change_sig(SIGUSR1, 1); | ||
302 | } | ||
303 | |||
304 | void 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 | |||
318 | void 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 | |||
334 | int 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 | |||
370 | void init_idle_tt(void) | ||
371 | { | ||
372 | default_idle(); | ||
373 | } | ||
374 | |||
375 | extern void start_kernel(void); | ||
376 | |||
377 | static 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 | |||
394 | void set_tracing(void *task, int tracing) | ||
395 | { | ||
396 | ((struct task_struct *) task)->thread.mode.tt.tracing = tracing; | ||
397 | } | ||
398 | |||
399 | int is_tracing(void *t) | ||
400 | { | ||
401 | return (((struct task_struct *) t)->thread.mode.tt.tracing); | ||
402 | } | ||
403 | |||
404 | int 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 | |||
416 | void 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 | |||
427 | int 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 | |||
438 | int external_pid_tt(struct task_struct *task) | ||
439 | { | ||
440 | return(task->thread.mode.tt.extern_pid); | ||
441 | } | ||
442 | |||
443 | int thread_pid_tt(struct task_struct *task) | ||
444 | { | ||
445 | return(task->thread.mode.tt.extern_pid); | ||
446 | } | ||
447 | |||
448 | int 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 | |||
6 | obj-y = proxy.o ptrace.o sysdep.o wait.o | ||
7 | |||
8 | USER_OBJS := $(obj-y) | ||
9 | |||
10 | include 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 | /********************************************************************** | ||
2 | proxy.c | ||
3 | |||
4 | Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing | ||
5 | terms and conditions. | ||
6 | |||
7 | Jeff 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 | |||
33 | static 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 | |||
72 | int 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 */ | ||
127 | static debugger_state parent; | ||
128 | static int parent_syscall(debugger_state *debugger, int pid); | ||
129 | |||
130 | int 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 | |||
143 | int 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 | |||
150 | static 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 | |||
169 | int 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 | |||
176 | void 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 */ | ||
184 | static debugger_state debugger; | ||
185 | static debugee_state debugee; | ||
186 | |||
187 | void 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 | |||
206 | int 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 | |||
244 | void 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 | |||
263 | void 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 | |||
274 | void 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 | |||
299 | char gdb_init_string[] = | ||
300 | "att 1 \n\ | ||
301 | b panic \n\ | ||
302 | b stop \n\ | ||
303 | handle SIGWINCH nostop noprint pass \n\ | ||
304 | "; | ||
305 | |||
306 | int 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 | /********************************************************************** | ||
2 | ptproxy.h | ||
3 | |||
4 | Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing | ||
5 | terms and conditions. | ||
6 | **********************************************************************/ | ||
7 | |||
8 | #ifndef __PTPROXY_H | ||
9 | #define __PTPROXY_H | ||
10 | |||
11 | #include <sys/types.h> | ||
12 | |||
13 | typedef struct debugger debugger_state; | ||
14 | typedef struct debugee debugee_state; | ||
15 | |||
16 | struct 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 | |||
29 | struct 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 | |||
43 | extern int debugger_syscall(debugger_state *debugger, pid_t pid); | ||
44 | extern int debugger_normal_return (debugger_state *debugger, pid_t unused); | ||
45 | |||
46 | extern long proxy_ptrace (struct debugger *, int, pid_t, long, long, pid_t, | ||
47 | int *strace_out); | ||
48 | extern 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 | /********************************************************************** | ||
2 | ptrace.c | ||
3 | |||
4 | Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing | ||
5 | terms and conditions. | ||
6 | |||
7 | Jeff 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 | |||
24 | long 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 | /********************************************************************** | ||
2 | sysdep.c | ||
3 | |||
4 | Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing | ||
5 | terms 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 | |||
19 | int 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 | |||
30 | void 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 | |||
42 | void syscall_set_result(pid_t pid, long result) | ||
43 | { | ||
44 | ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, result); | ||
45 | } | ||
46 | |||
47 | void syscall_continue(pid_t pid) | ||
48 | { | ||
49 | ptrace(PTRACE_SYSCALL, pid, 0, 0); | ||
50 | } | ||
51 | |||
52 | int 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 | /********************************************************************** | ||
2 | sysdep.h | ||
3 | |||
4 | Copyright (C) 1999 Lars Brinkhoff. | ||
5 | Copyright (C) 2001 Jeff Dike (jdike@karaya.com) | ||
6 | See the file COPYING for licensing terms and conditions. | ||
7 | **********************************************************************/ | ||
8 | |||
9 | extern int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, | ||
10 | long *arg4, long *arg5); | ||
11 | extern void syscall_cancel (pid_t pid, long result); | ||
12 | extern void syscall_set_result (pid_t pid, long result); | ||
13 | extern void syscall_continue (pid_t pid); | ||
14 | extern 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 | /********************************************************************** | ||
2 | wait.c | ||
3 | |||
4 | Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing | ||
5 | terms 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 | |||
20 | int 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 | |||
48 | int parent_wait_return(struct debugger *debugger, pid_t unused) | ||
49 | { | ||
50 | return(debugger_normal_return(debugger, -1)); | ||
51 | } | ||
52 | |||
53 | int 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 | /********************************************************************** | ||
2 | wait.h | ||
3 | |||
4 | Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing | ||
5 | terms and conditions. | ||
6 | **********************************************************************/ | ||
7 | |||
8 | #ifndef __PTPROXY_WAIT_H | ||
9 | #define __PTPROXY_WAIT_H | ||
10 | |||
11 | extern int proxy_wait_return(struct debugger *debugger, pid_t unused); | ||
12 | extern int real_wait_return(struct debugger *debugger); | ||
13 | extern 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 | |||
19 | void syscall_handler_tt(int sig, struct pt_regs *regs) | ||
20 | { | ||
21 | void *sc; | ||
22 | long result; | ||
23 | int syscall; | ||
24 | |||
25 | sc = UPT_SC(®s->regs); | ||
26 | SC_START_SYSCALL(sc); | ||
27 | |||
28 | syscall = UPT_SYSCALL_NR(®s->regs); | ||
29 | syscall_trace(®s->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(®s->regs) = sc; | ||
42 | |||
43 | SC_SET_SYSCALL_RETURN(sc, result); | ||
44 | |||
45 | syscall_trace(®s->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 | |||
18 | void do_sigtrap(void *task) | ||
19 | { | ||
20 | UPT_SYSCALL_NR(TASK_REGS(task)) = -1; | ||
21 | } | ||
22 | |||
23 | void 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 | |||
19 | static 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 | |||
57 | static 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 | |||
68 | atomic_t vmchange_seq = ATOMIC_INIT(1); | ||
69 | |||
70 | void 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 | |||
76 | void flush_tlb_kernel_vm_tt(void) | ||
77 | { | ||
78 | flush_tlb_kernel_range(start_vm, end_vm); | ||
79 | } | ||
80 | |||
81 | void __flush_tlb_one_tt(unsigned long addr) | ||
82 | { | ||
83 | flush_tlb_kernel_range(addr, addr + PAGE_SIZE); | ||
84 | } | ||
85 | |||
86 | void 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 | |||
101 | void 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 | |||
116 | void 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 | |||
31 | static int tracer_winch[2]; | ||
32 | |||
33 | int 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 | |||
42 | static 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 | |||
54 | static 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 | |||
66 | void 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 | |||
78 | void 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 | |||
89 | static 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 */ | ||
100 | int debug = 0; | ||
101 | int debug_stop = 1; | ||
102 | int debug_parent = 0; | ||
103 | int honeypot = 0; | ||
104 | |||
105 | static 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 | |||
126 | static 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 */ | ||
163 | int debugger_pid = -1; | ||
164 | int debugger_parent = -1; | ||
165 | int debugger_fd = -1; | ||
166 | int gdb_pid = -1; | ||
167 | |||
168 | struct { | ||
169 | int pid; | ||
170 | int signal; | ||
171 | unsigned long addr; | ||
172 | struct timeval time; | ||
173 | } signal_record[1024][32]; | ||
174 | |||
175 | int signal_index[32]; | ||
176 | int nsignals = 0; | ||
177 | int debug_trace = 0; | ||
178 | |||
179 | extern void signal_usr1(int sig); | ||
180 | |||
181 | int tracing_pid = -1; | ||
182 | |||
183 | int 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 | |||
410 | static 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 | |||
439 | static 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 | |||
16 | void 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 | |||
9 | int 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, ¤t->thread.fault_addr, | ||
15 | ¤t->thread.fault_catcher)); | ||
16 | } | ||
17 | |||
18 | int 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, ¤t->thread.fault_addr, | ||
24 | ¤t->thread.fault_catcher)); | ||
25 | } | ||
26 | |||
27 | int 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 | ¤t->thread.fault_addr, | ||
36 | ¤t->thread.fault_catcher); | ||
37 | if(n < 0) return(-EFAULT); | ||
38 | return(n); | ||
39 | } | ||
40 | |||
41 | int __clear_user_tt(void __user *mem, int len) | ||
42 | { | ||
43 | return(__do_clear_user(mem, len, | ||
44 | ¤t->thread.fault_addr, | ||
45 | ¤t->thread.fault_catcher)); | ||
46 | } | ||
47 | |||
48 | int 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, ¤t->thread.fault_addr, | ||
54 | ¤t->thread.fault_catcher)); | ||
55 | } | ||
56 | |||
57 | int strnlen_user_tt(const void __user *str, int len) | ||
58 | { | ||
59 | return(__do_strnlen_user(str, len, | ||
60 | ¤t->thread.fault_addr, | ||
61 | ¤t->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 | |||
14 | int __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 | |||
36 | static void __do_strncpy(void *dst, const void *src, int count) | ||
37 | { | ||
38 | strncpy(dst, src, count); | ||
39 | } | ||
40 | |||
41 | int __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 | |||
56 | static void __do_clear(void *to, const void *from, int n) | ||
57 | { | ||
58 | memset(to, 0, n); | ||
59 | } | ||
60 | |||
61 | int __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 | |||
76 | int __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 */ |
133 | int ncpus = 1; | 131 | int 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 | */ | ||
140 | static char *argv1_begin = NULL; | ||
141 | static char *argv1_end = NULL; | ||
142 | #endif | ||
143 | |||
144 | /* Set in early boot */ | 133 | /* Set in early boot */ |
145 | static int have_root __initdata = 0; | 134 | static 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 */ |
148 | long long physmem_size = 32 * 1024 * 1024; | 137 | long long physmem_size = 32 * 1024 * 1024; |
149 | 138 | ||
150 | void 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 | |||
172 | static char *usage_string = | 139 | static 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 | |||
206 | static int __init no_skas_debug_setup(char *line, int *add) | 171 | static 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 |
223 | static int __init uml_ncpus_setup(char *line, int *add) | 185 | static 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 | ||
239 | static int force_tt = 0; | ||
240 | |||
241 | #if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS) | ||
242 | #define DEFAULT_TT 0 | ||
243 | |||
244 | static 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 | |||
255 | static 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 | |||
266 | static 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 | |||
283 | int mode_tt = DEFAULT_TT; | ||
284 | |||
285 | static int __init Usage(char *line, int *add) | 201 | static 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 | ||
6 | obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ | 6 | obj-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 | |||
10 | obj-$(CONFIG_MODE_SKAS) += skas/ | ||
11 | |||
12 | obj-$(CONFIG_MODE_TT) += tt.o | ||
13 | user-objs-$(CONFIG_MODE_TT) += tt.o | ||
14 | 9 | ||
15 | obj-$(CONFIG_TTY_LOG) += tty_log.o | 10 | obj-$(CONFIG_TTY_LOG) += tty_log.o |
16 | user-objs-$(CONFIG_TTY_LOG) += tty_log.o | 11 | user-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 */ | ||
29 | char *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 | ||
137 | void 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 | ||
243 | void 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 | |||
266 | void init_new_thread_signals(void) | 235 | void 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 | ||
45 | static int ptrace_child(void *arg) | 42 | static 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 | ||
411 | static inline void check_skas3_ptrace_faultinfo(void) | 407 | static 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 | ||
508 | int can_do_skas(void) | ||
509 | { | ||
510 | return 0; | ||
511 | } | ||
512 | #endif | ||
513 | 503 | ||
514 | int __init parse_iomem(char *str, int *add) | 504 | int __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 | ||
6 | obj-$(CONFIG_MODE_SKAS) = registers.o signal.o tls.o | 6 | obj-y = registers.o signal.o tls.o |
7 | 7 | ||
8 | USER_OBJS := $(obj-y) | 8 | USER_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 | ||
6 | obj-$(CONFIG_MODE_SKAS) = registers.o prctl.o signal.o | 6 | obj-y = registers.o prctl.o signal.o |
7 | 7 | ||
8 | USER_OBJS := $(obj-y) | 8 | USER_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 | ||
34 | void enable_timer(void) | ||
35 | { | ||
36 | set_interval(1); | ||
37 | } | ||
38 | #endif | ||
39 | |||
40 | void disable_timer(void) | 33 | void 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 | ||
75 | void 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 | |||
86 | unsigned long long os_nsecs(void) | 67 | unsigned 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 | |||
37 | int os_get_thread_area(user_desc_t *info, int pid) | 30 | int 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 | |||
53 | int 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 | |||
64 | int 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 |
25 | define unprofile | 25 | define unprofile |
26 | $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1))) | 26 | $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1))) |
27 | endef | 27 | endef |
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 @@ | |||
1 | obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ | 1 | obj-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 | |||
5 | obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o | ||
6 | 4 | ||
7 | subarch-obj-y = lib/bitops_32.o lib/semaphore_32.o lib/string_32.o | 5 | subarch-obj-y = lib/bitops_32.o lib/semaphore_32.o lib/string_32.o |
8 | subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o | 6 | subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o |
@@ -13,11 +11,7 @@ USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o | |||
13 | USER_OBJS += user-offsets.s | 11 | USER_OBJS += user-offsets.s |
14 | extra-y += user-offsets.s | 12 | extra-y += user-offsets.s |
15 | 13 | ||
16 | extra-$(CONFIG_MODE_TT) += unmap.o | ||
17 | |||
18 | UNPROFILE_OBJS := stub_segv.o | 14 | UNPROFILE_OBJS := stub_segv.o |
19 | CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) | 15 | CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) |
20 | 16 | ||
21 | include arch/um/scripts/Makefile.rules | 17 | include 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 | ||
20 | extern int modify_ldt(int func, void *ptr, unsigned long bytecount); | 20 | extern int modify_ldt(int func, void *ptr, unsigned long bytecount); |
21 | 21 | ||
22 | #ifdef CONFIG_MODE_TT | ||
23 | |||
24 | static 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 | |||
79 | out: | ||
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 | ||
574 | int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) | 507 | int 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 | ||
17 | void 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 | |||
23 | void arch_switch_to_skas(struct task_struct *from, struct task_struct *to) | 17 | void 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 | ||
241 | static 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 | |||
271 | static inline int convert_fxsr_to_user(struct _fpstate __user *buf, | 230 | static 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 | ||
278 | static 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 | |||
309 | static inline int convert_fxsr_from_user(struct pt_regs *regs, | 236 | static 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 | ||
336 | int 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 | |||
349 | int get_fpxregs(unsigned long buf, struct task_struct *tsk) | 262 | int 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 | ||
355 | int 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 | |||
368 | int set_fpxregs(unsigned long buf, struct task_struct *tsk) | 267 | int 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 | ||
391 | static 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 | |||
409 | static inline void copy_fpu_fxsave(struct pt_regs *regs, | 289 | static 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 | |||
49 | static 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 | |||
66 | static 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 */ | ||
80 | static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 }; | ||
81 | |||
82 | void arch_enter_kernel(void *task, int pid) | ||
83 | { | ||
84 | read_debugregs(pid, TASK_DEBUGREGS(task)); | ||
85 | write_debugregs(pid, kernel_debugregs); | ||
86 | } | ||
87 | |||
88 | void 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 */ | ||
96 | static int debugregs_seq; | ||
97 | |||
98 | /* Only called by the ptrace proxy */ | ||
99 | void 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 | |||
112 | static 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 */ | ||
120 | void 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 | ||
21 | void copy_sc(union uml_pt_regs *regs, void *from) | 18 | void 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 | */ | ||
123 | int 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 | |||
142 | int 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 | ||
167 | static int copy_sc_from_user(struct pt_regs *to, void __user *from) | 109 | static 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 @@ | |||
31 | static int host_supports_tls = -1; | 28 | static int host_supports_tls = -1; |
32 | int host_gdt_entry_tls_min; | 29 | int host_gdt_entry_tls_min; |
33 | 30 | ||
34 | #ifdef CONFIG_MODE_SKAS | ||
35 | int do_set_thread_area_skas(struct user_desc *info) | 31 | int 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 | ||
190 | int 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 | |||
201 | static int set_tls_entry(struct task_struct* task, struct user_desc *info, | 185 | static 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 | |||
9 | static int errno; | ||
10 | |||
11 | static inline _syscall2(int,munmap,void *,start,size_t,len) | ||
12 | static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset) | ||
13 | int 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 | ||
7 | obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \ | 7 | obj-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 | ||
11 | obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o | ||
12 | obj-$(CONFIG_MODULES) += um_module.o | 11 | obj-$(CONFIG_MODULES) += um_module.o |
13 | 12 | ||
14 | subarch-obj-y = lib/bitops_64.o lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o | 13 | subarch-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 | |||
21 | USER_OBJS += user-offsets.s | 20 | USER_OBJS += user-offsets.s |
22 | extra-y += user-offsets.s | 21 | extra-y += user-offsets.s |
23 | 22 | ||
24 | extra-$(CONFIG_MODE_TT) += unmap.o | ||
25 | |||
26 | UNPROFILE_OBJS := stub_segv.o | 23 | UNPROFILE_OBJS := stub_segv.o |
27 | CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) | 24 | CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) |
28 | 25 | ||
29 | include arch/um/scripts/Makefile.rules | 26 | include 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 | ||
23 | void copy_sc(union uml_pt_regs *regs, void *from) | 20 | void 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 | ||
140 | int 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 | |||
159 | int 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 | |||
184 | static int copy_sc_from_user(struct pt_regs *to, void __user *from) | 134 | static 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 | ||
33 | extern long arch_prctl(int code, unsigned long addr); | ||
34 | |||
35 | static 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 | |||
62 | long arch_prctl_skas(struct task_struct *task, int code, | 32 | long 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 | ||
124 | long sys_arch_prctl(int code, unsigned long addr) | 93 | long 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 | |||
9 | static int errno; | ||
10 | |||
11 | static inline _syscall2(int,munmap,void *,start,size_t,len) | ||
12 | static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset) | ||
13 | int 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 | } | ||