aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/Kconfig1
-rw-r--r--arch/um/Kconfig_i3866
-rw-r--r--arch/um/Kconfig_x86_646
-rw-r--r--arch/um/Makefile80
-rw-r--r--arch/um/Makefile-i3866
-rw-r--r--arch/um/Makefile-x86_644
-rw-r--r--arch/um/defconfig10
-rw-r--r--arch/um/drivers/chan_kern.c16
-rw-r--r--arch/um/drivers/line.c355
-rw-r--r--arch/um/drivers/ssl.c25
-rw-r--r--arch/um/drivers/stdio_console.c19
-rw-r--r--arch/um/drivers/ubd_kern.c14
-rw-r--r--arch/um/drivers/xterm_kern.c1
-rw-r--r--arch/um/include/common-offsets.h14
-rw-r--r--arch/um/include/kern_util.h7
-rw-r--r--arch/um/include/line.h36
-rw-r--r--arch/um/include/os.h1
-rw-r--r--arch/um/include/skas_ptrace.h15
-rw-r--r--arch/um/include/sysdep-i386/checksum.h39
-rw-r--r--arch/um/include/sysdep-i386/faultinfo.h29
-rw-r--r--arch/um/include/sysdep-i386/ptrace.h23
-rw-r--r--arch/um/include/sysdep-i386/sigcontext.h19
-rw-r--r--arch/um/include/sysdep-i386/signal.h2
-rw-r--r--arch/um/include/sysdep-i386/skas_ptrace.h22
-rw-r--r--arch/um/include/sysdep-i386/syscalls.h99
-rw-r--r--arch/um/include/sysdep-ia64/skas_ptrace.h22
-rw-r--r--arch/um/include/sysdep-ppc/skas_ptrace.h22
-rw-r--r--arch/um/include/sysdep-x86_64/faultinfo.h29
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace.h16
-rw-r--r--arch/um/include/sysdep-x86_64/sigcontext.h15
-rw-r--r--arch/um/include/sysdep-x86_64/signal.h2
-rw-r--r--arch/um/include/sysdep-x86_64/skas_ptrace.h22
-rw-r--r--arch/um/include/sysdep-x86_64/syscalls.h59
-rw-r--r--arch/um/include/user_util.h1
-rw-r--r--arch/um/kernel/Makefile17
-rw-r--r--arch/um/kernel/checksum.c36
-rw-r--r--arch/um/kernel/irq.c1
-rw-r--r--arch/um/kernel/ksyms.c3
-rw-r--r--arch/um/kernel/process.c2
-rw-r--r--arch/um/kernel/process_kern.c24
-rw-r--r--arch/um/kernel/ptrace.c123
-rw-r--r--arch/um/kernel/sigio_user.c1
-rw-r--r--arch/um/kernel/skas/include/mode_kern-skas.h1
-rw-r--r--arch/um/kernel/skas/include/skas.h3
-rw-r--r--arch/um/kernel/skas/include/uaccess-skas.h2
-rw-r--r--arch/um/kernel/skas/process.c68
-rw-r--r--arch/um/kernel/skas/process_kern.c4
-rw-r--r--arch/um/kernel/skas/trap_user.c24
-rw-r--r--arch/um/kernel/skas/uaccess.c11
-rw-r--r--arch/um/kernel/skas/util/Makefile1
-rw-r--r--arch/um/kernel/skas/util/mk_ptregs-i386.c46
-rw-r--r--arch/um/kernel/skas/util/mk_ptregs-x86_64.c60
-rw-r--r--arch/um/kernel/sys_call_table.c276
-rw-r--r--arch/um/kernel/syscall_kern.c1
-rw-r--r--arch/um/kernel/time_kern.c18
-rw-r--r--arch/um/kernel/trap_kern.c27
-rw-r--r--arch/um/kernel/trap_user.c13
-rw-r--r--arch/um/kernel/tt/Makefile1
-rw-r--r--arch/um/kernel/tt/include/mode_kern-tt.h1
-rw-r--r--arch/um/kernel/tt/include/uaccess-tt.h2
-rw-r--r--arch/um/kernel/tt/mem.c8
-rw-r--r--arch/um/kernel/tt/process_kern.c20
-rw-r--r--arch/um/kernel/tt/syscall_user.c4
-rw-r--r--arch/um/kernel/tt/tracer.c8
-rw-r--r--arch/um/kernel/tt/trap_user.c6
-rw-r--r--arch/um/kernel/um_arch.c7
-rw-r--r--arch/um/kernel/vmlinux.lds.S6
-rw-r--r--arch/um/os-Linux/process.c5
-rw-r--r--arch/um/os-Linux/signal.c4
-rw-r--r--arch/um/os-Linux/sys-i386/registers.c7
-rw-r--r--arch/um/os-Linux/util/Makefile2
-rw-r--r--arch/um/os-Linux/util/mk_user_constants.c10
-rw-r--r--arch/um/scripts/Makefile.rules25
-rw-r--r--arch/um/sys-i386/Makefile18
-rw-r--r--arch/um/sys-i386/checksum.S6
-rw-r--r--arch/um/sys-i386/delay.c18
-rw-r--r--arch/um/sys-i386/kernel-offsets.c25
-rw-r--r--arch/um/sys-i386/ksyms.c8
-rw-r--r--arch/um/sys-i386/ldt.c5
-rw-r--r--arch/um/sys-i386/ptrace.c40
-rw-r--r--arch/um/sys-i386/signal.c17
-rw-r--r--arch/um/sys-i386/sys_call_table.S16
-rw-r--r--arch/um/sys-i386/user-offsets.c69
-rw-r--r--arch/um/sys-i386/util/Makefile7
-rw-r--r--arch/um/sys-i386/util/mk_sc.c75
-rw-r--r--arch/um/sys-i386/util/mk_thread.c22
-rw-r--r--arch/um/sys-i386/util/mk_thread_kern.c22
-rw-r--r--arch/um/sys-i386/util/mk_thread_user.c30
-rw-r--r--arch/um/sys-ppc/ptrace.c40
-rw-r--r--arch/um/sys-x86_64/Makefile22
-rw-r--r--arch/um/sys-x86_64/delay.c18
-rw-r--r--arch/um/sys-x86_64/kernel-offsets.c24
-rw-r--r--arch/um/sys-x86_64/ksyms.c20
-rw-r--r--arch/um/sys-x86_64/ptrace.c44
-rw-r--r--arch/um/sys-x86_64/signal.c12
-rw-r--r--arch/um/sys-x86_64/syscall_table.c59
-rw-r--r--arch/um/sys-x86_64/syscalls.c16
-rw-r--r--arch/um/sys-x86_64/um_module.c19
-rw-r--r--arch/um/sys-x86_64/user-offsets.c78
-rw-r--r--arch/um/sys-x86_64/util/Makefile6
-rw-r--r--arch/um/sys-x86_64/util/mk_sc.c79
-rw-r--r--arch/um/sys-x86_64/util/mk_thread.c20
-rw-r--r--arch/um/sys-x86_64/util/mk_thread_kern.c21
-rw-r--r--arch/um/sys-x86_64/util/mk_thread_user.c30
-rw-r--r--arch/um/util/Makefile7
-rw-r--r--arch/um/util/mk_constants.c32
-rw-r--r--arch/um/util/mk_constants_kern.c28
-rw-r--r--arch/um/util/mk_constants_user.c28
-rw-r--r--arch/um/util/mk_task.c (renamed from arch/um/util/mk_task_user.c)18
-rw-r--r--arch/um/util/mk_task_kern.c17
110 files changed, 1555 insertions, 1376 deletions
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 9a23df182123..c5292181a664 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -244,6 +244,7 @@ config KERNEL_HALF_GIGS
244 244
245config HIGHMEM 245config HIGHMEM
246 bool "Highmem support" 246 bool "Highmem support"
247 depends on !64BIT
247 248
248config KERNEL_STACK_ORDER 249config KERNEL_STACK_ORDER
249 int "Kernel stack size order" 250 int "Kernel stack size order"
diff --git a/arch/um/Kconfig_i386 b/arch/um/Kconfig_i386
index 203c242201b6..e41f3748d30f 100644
--- a/arch/um/Kconfig_i386
+++ b/arch/um/Kconfig_i386
@@ -1,4 +1,8 @@
1config 64_BIT 1config UML_X86
2 bool
3 default y
4
5config 64BIT
2 bool 6 bool
3 default n 7 default n
4 8
diff --git a/arch/um/Kconfig_x86_64 b/arch/um/Kconfig_x86_64
index 768dc6626a8d..fd8d7e8982b1 100644
--- a/arch/um/Kconfig_x86_64
+++ b/arch/um/Kconfig_x86_64
@@ -1,4 +1,8 @@
1config 64_BIT 1config UML_X86
2 bool
3 default y
4
5config 64BIT
2 bool 6 bool
3 default y 7 default y
4 8
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 97bca6b5ca95..f2a0c40a9204 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -17,7 +17,7 @@ core-y += $(ARCH_DIR)/kernel/ \
17 17
18# Have to precede the include because the included Makefiles reference them. 18# Have to precede the include because the included Makefiles reference them.
19SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \ 19SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \
20 arch-signal.h module.h vm-flags.h 20 module.h vm-flags.h elf.h
21SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header)) 21SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
22 22
23# XXX: The "os" symlink is only used by arch/um/include/os.h, which includes 23# XXX: The "os" symlink is only used by arch/um/include/os.h, which includes
@@ -44,6 +44,11 @@ ifneq ($(MAKEFILES-INCL),)
44endif 44endif
45 45
46ARCH_INCLUDE := -I$(ARCH_DIR)/include 46ARCH_INCLUDE := -I$(ARCH_DIR)/include
47ifneq ($(KBUILD_SRC),)
48ARCH_INCLUDE += -I$(ARCH_DIR)/include2
49ARCH_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include
50MRPROPER_DIRS += $(ARCH_DIR)/include2
51endif
47SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH) 52SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH)
48 53
49include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) 54include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
@@ -94,17 +99,18 @@ define archhelp
94 echo ' find in the kernel root.' 99 echo ' find in the kernel root.'
95endef 100endef
96 101
102ifneq ($(KBUILD_SRC),)
103$(shell mkdir -p $(ARCH_DIR) && ln -fsn $(srctree)/$(ARCH_DIR)/Kconfig_$(SUBARCH) $(ARCH_DIR)/Kconfig_arch)
104CLEAN_FILES += $(ARCH_DIR)/Kconfig_arch
105else
97$(shell cd $(ARCH_DIR) && ln -sf Kconfig_$(SUBARCH) Kconfig_arch) 106$(shell cd $(ARCH_DIR) && ln -sf Kconfig_$(SUBARCH) Kconfig_arch)
107endif
98 108
99prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) \ 109prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS)
100 $(ARCH_DIR)/kernel/vmlinux.lds.S
101 110
102LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static 111LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static
103LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib 112LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib
104 113
105LD_SCRIPT-$(CONFIG_LD_SCRIPT_STATIC) := uml.lds.S
106LD_SCRIPT-$(CONFIG_LD_SCRIPT_DYN) := dyn.lds.S
107
108CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT 114CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT
109CONFIG_KERNEL_STACK_ORDER ?= 2 115CONFIG_KERNEL_STACK_ORDER ?= 2
110STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) 116STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
@@ -126,7 +132,7 @@ define cmd_vmlinux__
126 $(CC) $(CFLAGS_vmlinux) -o $@ \ 132 $(CC) $(CFLAGS_vmlinux) -o $@ \
127 -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \ 133 -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \
128 -Wl,--start-group $(vmlinux-main) -Wl,--end-group \ 134 -Wl,--start-group $(vmlinux-main) -Wl,--end-group \
129 -L/usr/lib -lutil \ 135 -lutil \
130 $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) \ 136 $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) \
131 FORCE ,$^) ; rm -f linux 137 FORCE ,$^) ; rm -f linux
132endef 138endef
@@ -145,31 +151,42 @@ archclean:
145 @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ 151 @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
146 -o -name '*.gcov' \) -type f -print | xargs rm -f 152 -o -name '*.gcov' \) -type f -print | xargs rm -f
147 153
148#We need to re-preprocess this when the symlink dest changes.
149#So we touch it when needed.
150$(ARCH_DIR)/kernel/vmlinux.lds.S: FORCE
151 $(Q)if [ "$(shell readlink $@)" != "$(LD_SCRIPT-y)" ]; then \
152 echo ' SYMLINK $@'; \
153 ln -sf $(LD_SCRIPT-y) $@; \
154 touch $@; \
155 fi;
156
157$(SYMLINK_HEADERS): 154$(SYMLINK_HEADERS):
158 @echo ' SYMLINK $@' 155 @echo ' SYMLINK $@'
156ifneq ($(KBUILD_SRC),)
157 ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@
158else
159 $(Q)cd $(TOPDIR)/$(dir $@) ; \ 159 $(Q)cd $(TOPDIR)/$(dir $@) ; \
160 ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@) 160 ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@)
161endif
161 162
162include/asm-um/arch: 163include/asm-um/arch:
163 @echo ' SYMLINK $@' 164 @echo ' SYMLINK $@'
165ifneq ($(KBUILD_SRC),)
166 $(Q)mkdir -p include/asm-um
167 $(Q)ln -fsn $(srctree)/include/asm-$(SUBARCH) include/asm-um/arch
168else
164 $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch 169 $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch
170endif
165 171
166$(ARCH_DIR)/include/sysdep: 172$(ARCH_DIR)/include/sysdep:
167 @echo ' SYMLINK $@' 173 @echo ' SYMLINK $@'
174ifneq ($(KBUILD_SRC),)
175 $(Q)mkdir -p $(ARCH_DIR)/include
176 $(Q)mkdir -p $(ARCH_DIR)/include2
177 $(Q)ln -fsn sysdep-$(SUBARCH) $(ARCH_DIR)/include/sysdep
178 $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/include/sysdep-$(SUBARCH) $(ARCH_DIR)/include2/sysdep
179else
168 $(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep 180 $(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep
181endif
169 182
170$(ARCH_DIR)/os: 183$(ARCH_DIR)/os:
171 @echo ' SYMLINK $@' 184 @echo ' SYMLINK $@'
185ifneq ($(KBUILD_SRC),)
186 $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/os-$(OS) $(ARCH_DIR)/os
187else
172 $(Q)cd $(ARCH_DIR) && ln -sf os-$(OS) os 188 $(Q)cd $(ARCH_DIR) && ln -sf os-$(OS) os
189endif
173 190
174# Generated files 191# Generated files
175define filechk_umlconfig 192define filechk_umlconfig
@@ -179,10 +196,31 @@ endef
179$(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h 196$(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h
180 $(call filechk,umlconfig) 197 $(call filechk,umlconfig)
181 198
199$(ARCH_DIR)/user-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.c
200 $(CC) $(USER_CFLAGS) -S -o $@ $<
201
202$(ARCH_DIR)/user-offsets.h: $(ARCH_DIR)/user-offsets.s
203 $(call filechk,gen-asm-offsets)
204
205CLEAN_FILES += $(ARCH_DIR)/user-offsets.s $(ARCH_DIR)/user-offsets.h
206
207$(ARCH_DIR)/kernel-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/kernel-offsets.c \
208 $(ARCH_SYMLINKS) \
209 $(SYS_DIR)/sc.h \
210 include/asm include/linux/version.h \
211 include/config/MARKER \
212 $(ARCH_DIR)/include/user_constants.h
213 $(CC) $(CFLAGS) $(NOSTDINC_FLAGS) $(CPPFLAGS) -S -o $@ $<
214
215$(ARCH_DIR)/kernel-offsets.h: $(ARCH_DIR)/kernel-offsets.s
216 $(call filechk,gen-asm-offsets)
217
218CLEAN_FILES += $(ARCH_DIR)/kernel-offsets.s $(ARCH_DIR)/kernel-offsets.h
219
182$(ARCH_DIR)/include/task.h: $(ARCH_DIR)/util/mk_task 220$(ARCH_DIR)/include/task.h: $(ARCH_DIR)/util/mk_task
183 $(call filechk,gen_header) 221 $(call filechk,gen_header)
184 222
185$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/os/util/mk_user_constants 223$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/os-$(OS)/util/mk_user_constants
186 $(call filechk,gen_header) 224 $(call filechk,gen_header)
187 225
188$(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/util/mk_constants 226$(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/util/mk_constants
@@ -191,20 +229,20 @@ $(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/util/mk_constants
191$(ARCH_DIR)/include/skas_ptregs.h: $(ARCH_DIR)/kernel/skas/util/mk_ptregs 229$(ARCH_DIR)/include/skas_ptregs.h: $(ARCH_DIR)/kernel/skas/util/mk_ptregs
192 $(call filechk,gen_header) 230 $(call filechk,gen_header)
193 231
194$(ARCH_DIR)/os/util/mk_user_constants: $(ARCH_DIR)/os/util FORCE ; 232$(ARCH_DIR)/os-$(OS)/util/mk_user_constants: $(ARCH_DIR)/os-$(OS)/util FORCE ;
195 233
196$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants: $(ARCH_DIR)/include/user_constants.h $(ARCH_DIR)/util \ 234$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants: $(ARCH_DIR)/include/user_constants.h $(ARCH_DIR)/util \
197 FORCE ; 235 FORCE ;
198 236
199$(ARCH_DIR)/kernel/skas/util/mk_ptregs: $(ARCH_DIR)/kernel/skas/util FORCE ; 237$(ARCH_DIR)/kernel/skas/util/mk_ptregs: $(ARCH_DIR)/kernel/skas/util FORCE ;
200 238
201$(ARCH_DIR)/util: scripts_basic $(SYS_DIR)/sc.h FORCE 239$(ARCH_DIR)/util: scripts_basic $(SYS_DIR)/sc.h $(ARCH_DIR)/kernel-offsets.h FORCE
202 $(Q)$(MAKE) $(build)=$@ 240 $(Q)$(MAKE) $(build)=$@
203 241
204$(ARCH_DIR)/kernel/skas/util: scripts_basic FORCE 242$(ARCH_DIR)/kernel/skas/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
205 $(Q)$(MAKE) $(build)=$@ 243 $(Q)$(MAKE) $(build)=$@
206 244
207$(ARCH_DIR)/os/util: scripts_basic FORCE 245$(ARCH_DIR)/os-$(OS)/util: scripts_basic FORCE
208 $(Q)$(MAKE) $(build)=$@ 246 $(Q)$(MAKE) $(build)=$@
209 247
210export SUBARCH USER_CFLAGS OS 248export SUBARCH USER_CFLAGS OS
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index 97b223bfa78e..29e182d5a83a 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -1,4 +1,4 @@
1SUBARCH_CORE := arch/um/sys-i386/ 1SUBARCH_CORE := arch/um/sys-i386/ arch/i386/crypto/
2 2
3TOP_ADDR := $(CONFIG_TOP_ADDR) 3TOP_ADDR := $(CONFIG_TOP_ADDR)
4 4
@@ -32,10 +32,10 @@ $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
32$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread 32$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
33 $(call filechk,gen_header) 33 $(call filechk,gen_header)
34 34
35$(SYS_UTIL_DIR)/mk_sc: scripts_basic FORCE 35$(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
36 $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ 36 $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
37 37
38$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE 38$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_DIR)/kernel-offsets.h FORCE
39 $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ 39 $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
40 40
41$(SYS_UTIL_DIR): scripts_basic include/asm FORCE 41$(SYS_UTIL_DIR): scripts_basic include/asm FORCE
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index a77971133e91..32144562c279 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -23,10 +23,10 @@ $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
23$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread 23$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
24 $(call filechk,gen_header) 24 $(call filechk,gen_header)
25 25
26$(SYS_UTIL_DIR)/mk_sc: scripts_basic FORCE 26$(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
27 $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ 27 $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
28 28
29$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE 29$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(GEN_HEADERS) $(ARCH_DIR)/kernel-offsets.h FORCE
30 $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ 30 $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
31 31
32CLEAN_FILES += $(SYS_HEADERS) 32CLEAN_FILES += $(SYS_HEADERS)
diff --git a/arch/um/defconfig b/arch/um/defconfig
index fc3075c589d8..4067c3aa5b60 100644
--- a/arch/um/defconfig
+++ b/arch/um/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc1-bk1 3# Linux kernel version: 2.6.12-rc3-skas3-v9-pre2
4# Sun Mar 20 16:53:00 2005 4# Sun Apr 24 19:46:10 2005
5# 5#
6CONFIG_GENERIC_HARDIRQS=y 6CONFIG_GENERIC_HARDIRQS=y
7CONFIG_UML=y 7CONFIG_UML=y
@@ -15,7 +15,8 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
15# 15#
16CONFIG_MODE_TT=y 16CONFIG_MODE_TT=y
17CONFIG_MODE_SKAS=y 17CONFIG_MODE_SKAS=y
18# CONFIG_64_BIT is not set 18CONFIG_UML_X86=y
19# CONFIG_64BIT is not set
19CONFIG_TOP_ADDR=0xc0000000 20CONFIG_TOP_ADDR=0xc0000000
20# CONFIG_3_LEVEL_PGTABLES is not set 21# CONFIG_3_LEVEL_PGTABLES is not set
21CONFIG_ARCH_HAS_SC_SIGNALS=y 22CONFIG_ARCH_HAS_SC_SIGNALS=y
@@ -41,6 +42,7 @@ CONFIG_UML_REAL_TIME_CLOCK=y
41CONFIG_EXPERIMENTAL=y 42CONFIG_EXPERIMENTAL=y
42CONFIG_CLEAN_COMPILE=y 43CONFIG_CLEAN_COMPILE=y
43CONFIG_BROKEN_ON_SMP=y 44CONFIG_BROKEN_ON_SMP=y
45CONFIG_INIT_ENV_ARG_LIMIT=32
44 46
45# 47#
46# General setup 48# General setup
@@ -158,7 +160,6 @@ CONFIG_UML_NET_SLIRP=y
158# 160#
159CONFIG_PACKET=y 161CONFIG_PACKET=y
160CONFIG_PACKET_MMAP=y 162CONFIG_PACKET_MMAP=y
161# CONFIG_NETLINK_DEV is not set
162CONFIG_UNIX=y 163CONFIG_UNIX=y
163# CONFIG_NET_KEY is not set 164# CONFIG_NET_KEY is not set
164CONFIG_INET=y 165CONFIG_INET=y
@@ -412,6 +413,5 @@ CONFIG_DEBUG_INFO=y
412# CONFIG_DEBUG_FS is not set 413# CONFIG_DEBUG_FS is not set
413CONFIG_FRAME_POINTER=y 414CONFIG_FRAME_POINTER=y
414CONFIG_PT_PROXY=y 415CONFIG_PT_PROXY=y
415# CONFIG_GPROF is not set
416# CONFIG_GCOV is not set 416# CONFIG_GCOV is not set
417# CONFIG_SYSCALL_DEBUG is not set 417# CONFIG_SYSCALL_DEBUG is not set
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 1f77deb3fd23..0150038af795 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -22,7 +22,7 @@
22#ifdef CONFIG_NOCONFIG_CHAN 22#ifdef CONFIG_NOCONFIG_CHAN
23static void *not_configged_init(char *str, int device, struct chan_opts *opts) 23static void *not_configged_init(char *str, int device, struct chan_opts *opts)
24{ 24{
25 printk(KERN_ERR "Using a channel type which is configured out of " 25 printf(KERN_ERR "Using a channel type which is configured out of "
26 "UML\n"); 26 "UML\n");
27 return(NULL); 27 return(NULL);
28} 28}
@@ -30,27 +30,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts)
30static int not_configged_open(int input, int output, int primary, void *data, 30static int not_configged_open(int input, int output, int primary, void *data,
31 char **dev_out) 31 char **dev_out)
32{ 32{
33 printk(KERN_ERR "Using a channel type which is configured out of " 33 printf(KERN_ERR "Using a channel type which is configured out of "
34 "UML\n"); 34 "UML\n");
35 return(-ENODEV); 35 return(-ENODEV);
36} 36}
37 37
38static void not_configged_close(int fd, void *data) 38static void not_configged_close(int fd, void *data)
39{ 39{
40 printk(KERN_ERR "Using a channel type which is configured out of " 40 printf(KERN_ERR "Using a channel type which is configured out of "
41 "UML\n"); 41 "UML\n");
42} 42}
43 43
44static int not_configged_read(int fd, char *c_out, void *data) 44static int not_configged_read(int fd, char *c_out, void *data)
45{ 45{
46 printk(KERN_ERR "Using a channel type which is configured out of " 46 printf(KERN_ERR "Using a channel type which is configured out of "
47 "UML\n"); 47 "UML\n");
48 return(-EIO); 48 return(-EIO);
49} 49}
50 50
51static int not_configged_write(int fd, const char *buf, int len, void *data) 51static int not_configged_write(int fd, const char *buf, int len, void *data)
52{ 52{
53 printk(KERN_ERR "Using a channel type which is configured out of " 53 printf(KERN_ERR "Using a channel type which is configured out of "
54 "UML\n"); 54 "UML\n");
55 return(-EIO); 55 return(-EIO);
56} 56}
@@ -58,7 +58,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data)
58static int not_configged_console_write(int fd, const char *buf, int len, 58static int not_configged_console_write(int fd, const char *buf, int len,
59 void *data) 59 void *data)
60{ 60{
61 printk(KERN_ERR "Using a channel type which is configured out of " 61 printf(KERN_ERR "Using a channel type which is configured out of "
62 "UML\n"); 62 "UML\n");
63 return(-EIO); 63 return(-EIO);
64} 64}
@@ -66,14 +66,14 @@ static int not_configged_console_write(int fd, const char *buf, int len,
66static int not_configged_window_size(int fd, void *data, unsigned short *rows, 66static int not_configged_window_size(int fd, void *data, unsigned short *rows,
67 unsigned short *cols) 67 unsigned short *cols)
68{ 68{
69 printk(KERN_ERR "Using a channel type which is configured out of " 69 printf(KERN_ERR "Using a channel type which is configured out of "
70 "UML\n"); 70 "UML\n");
71 return(-ENODEV); 71 return(-ENODEV);
72} 72}
73 73
74static void not_configged_free(void *data) 74static void not_configged_free(void *data)
75{ 75{
76 printk(KERN_ERR "Using a channel type which is configured out of " 76 printf(KERN_ERR "Using a channel type which is configured out of "
77 "UML\n"); 77 "UML\n");
78} 78}
79 79
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 6924f273ced9..025d3be8aca4 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -39,19 +39,69 @@ static void line_timer_cb(void *arg)
39 line_interrupt(line->driver->read_irq, arg, NULL); 39 line_interrupt(line->driver->read_irq, arg, NULL);
40} 40}
41 41
42static int write_room(struct line *dev) 42/* Returns the free space inside the ring buffer of this line.
43 *
44 * Should be called while holding line->lock (this does not modify datas).
45 */
46static int write_room(struct line *line)
43{ 47{
44 int n; 48 int n;
45 49
46 if (dev->buffer == NULL) 50 if (line->buffer == NULL)
47 return (LINE_BUFSIZE - 1); 51 return LINE_BUFSIZE - 1;
52
53 /* This is for the case where the buffer is wrapped! */
54 n = line->head - line->tail;
48 55
49 n = dev->head - dev->tail;
50 if (n <= 0) 56 if (n <= 0)
51 n = LINE_BUFSIZE + n; 57 n = LINE_BUFSIZE + n; /* The other case */
52 return (n - 1); 58 return n - 1;
59}
60
61int line_write_room(struct tty_struct *tty)
62{
63 struct line *line = tty->driver_data;
64 unsigned long flags;
65 int room;
66
67 if (tty->stopped)
68 return 0;
69
70 spin_lock_irqsave(&line->lock, flags);
71 room = write_room(line);
72 spin_unlock_irqrestore(&line->lock, flags);
73
74 /*XXX: Warning to remove */
75 if (0 == room)
76 printk(KERN_DEBUG "%s: %s: no room left in buffer\n",
77 __FUNCTION__,tty->name);
78 return room;
79}
80
81int line_chars_in_buffer(struct tty_struct *tty)
82{
83 struct line *line = tty->driver_data;
84 unsigned long flags;
85 int ret;
86
87 spin_lock_irqsave(&line->lock, flags);
88
89 /*write_room subtracts 1 for the needed NULL, so we readd it.*/
90 ret = LINE_BUFSIZE - (write_room(line) + 1);
91 spin_unlock_irqrestore(&line->lock, flags);
92
93 return ret;
53} 94}
54 95
96/*
97 * This copies the content of buf into the circular buffer associated with
98 * this line.
99 * The return value is the number of characters actually copied, i.e. the ones
100 * for which there was space: this function is not supposed to ever flush out
101 * the circular buffer.
102 *
103 * Must be called while holding line->lock!
104 */
55static int buffer_data(struct line *line, const char *buf, int len) 105static int buffer_data(struct line *line, const char *buf, int len)
56{ 106{
57 int end, room; 107 int end, room;
@@ -70,48 +120,95 @@ static int buffer_data(struct line *line, const char *buf, int len)
70 len = (len > room) ? room : len; 120 len = (len > room) ? room : len;
71 121
72 end = line->buffer + LINE_BUFSIZE - line->tail; 122 end = line->buffer + LINE_BUFSIZE - line->tail;
73 if(len < end){ 123
124 if (len < end){
74 memcpy(line->tail, buf, len); 125 memcpy(line->tail, buf, len);
75 line->tail += len; 126 line->tail += len;
76 } 127 } else {
77 else { 128 /* The circular buffer is wrapping */
78 memcpy(line->tail, buf, end); 129 memcpy(line->tail, buf, end);
79 buf += end; 130 buf += end;
80 memcpy(line->buffer, buf, len - end); 131 memcpy(line->buffer, buf, len - end);
81 line->tail = line->buffer + len - end; 132 line->tail = line->buffer + len - end;
82 } 133 }
83 134
84 return(len); 135 return len;
85} 136}
86 137
138/*
139 * Flushes the ring buffer to the output channels. That is, write_chan is
140 * called, passing it line->head as buffer, and an appropriate count.
141 *
142 * On exit, returns 1 when the buffer is empty,
143 * 0 when the buffer is not empty on exit,
144 * and -errno when an error occurred.
145 *
146 * Must be called while holding line->lock!*/
87static int flush_buffer(struct line *line) 147static int flush_buffer(struct line *line)
88{ 148{
89 int n, count; 149 int n, count;
90 150
91 if ((line->buffer == NULL) || (line->head == line->tail)) 151 if ((line->buffer == NULL) || (line->head == line->tail))
92 return(1); 152 return 1;
93 153
94 if (line->tail < line->head) { 154 if (line->tail < line->head) {
155 /* line->buffer + LINE_BUFSIZE is the end of the buffer! */
95 count = line->buffer + LINE_BUFSIZE - line->head; 156 count = line->buffer + LINE_BUFSIZE - line->head;
157
96 n = write_chan(&line->chan_list, line->head, count, 158 n = write_chan(&line->chan_list, line->head, count,
97 line->driver->write_irq); 159 line->driver->write_irq);
98 if (n < 0) 160 if (n < 0)
99 return(n); 161 return n;
100 if (n == count) 162 if (n == count) {
163 /* We have flushed from ->head to buffer end, now we
164 * must flush only from the beginning to ->tail.*/
101 line->head = line->buffer; 165 line->head = line->buffer;
102 else { 166 } else {
103 line->head += n; 167 line->head += n;
104 return(0); 168 return 0;
105 } 169 }
106 } 170 }
107 171
108 count = line->tail - line->head; 172 count = line->tail - line->head;
109 n = write_chan(&line->chan_list, line->head, count, 173 n = write_chan(&line->chan_list, line->head, count,
110 line->driver->write_irq); 174 line->driver->write_irq);
111 if(n < 0) return(n); 175
176 if(n < 0)
177 return n;
112 178
113 line->head += n; 179 line->head += n;
114 return(line->head == line->tail); 180 return line->head == line->tail;
181}
182
183void line_flush_buffer(struct tty_struct *tty)
184{
185 struct line *line = tty->driver_data;
186 unsigned long flags;
187 int err;
188
189 /*XXX: copied from line_write, verify if it is correct!*/
190 if(tty->stopped)
191 return;
192 //return 0;
193
194 spin_lock_irqsave(&line->lock, flags);
195 err = flush_buffer(line);
196 /*if (err == 1)
197 err = 0;*/
198 spin_unlock_irqrestore(&line->lock, flags);
199 //return err;
200}
201
202/* We map both ->flush_chars and ->put_char (which go in pair) onto ->flush_buffer
203 * and ->write. Hope it's not that bad.*/
204void line_flush_chars(struct tty_struct *tty)
205{
206 line_flush_buffer(tty);
207}
208
209void line_put_char(struct tty_struct *tty, unsigned char ch)
210{
211 line_write(tty, &ch, sizeof(ch));
115} 212}
116 213
117int line_write(struct tty_struct *tty, const unsigned char *buf, int len) 214int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
@@ -120,38 +217,31 @@ int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
120 unsigned long flags; 217 unsigned long flags;
121 int n, err, ret = 0; 218 int n, err, ret = 0;
122 219
123 if(tty->stopped) return 0; 220 if(tty->stopped)
221 return 0;
124 222
125 down(&line->sem); 223 spin_lock_irqsave(&line->lock, flags);
126 if(line->head != line->tail){ 224 if (line->head != line->tail) {
127 local_irq_save(flags);
128 ret = buffer_data(line, buf, len); 225 ret = buffer_data(line, buf, len);
129 err = flush_buffer(line); 226 err = flush_buffer(line);
130 local_irq_restore(flags); 227 if (err <= 0 && (err != -EAGAIN || !ret))
131 if(err <= 0 && (err != -EAGAIN || !ret))
132 ret = err; 228 ret = err;
133 } 229 } else {
134 else {
135 n = write_chan(&line->chan_list, buf, len, 230 n = write_chan(&line->chan_list, buf, len,
136 line->driver->write_irq); 231 line->driver->write_irq);
137 if(n < 0){ 232 if (n < 0) {
138 ret = n; 233 ret = n;
139 goto out_up; 234 goto out_up;
140 } 235 }
141 236
142 len -= n; 237 len -= n;
143 ret += n; 238 ret += n;
144 if(len > 0) 239 if (len > 0)
145 ret += buffer_data(line, buf + n, len); 240 ret += buffer_data(line, buf + n, len);
146 } 241 }
147 out_up: 242out_up:
148 up(&line->sem); 243 spin_unlock_irqrestore(&line->lock, flags);
149 return(ret); 244 return ret;
150}
151
152void line_put_char(struct tty_struct *tty, unsigned char ch)
153{
154 line_write(tty, &ch, sizeof(ch));
155} 245}
156 246
157void line_set_termios(struct tty_struct *tty, struct termios * old) 247void line_set_termios(struct tty_struct *tty, struct termios * old)
@@ -159,11 +249,6 @@ void line_set_termios(struct tty_struct *tty, struct termios * old)
159 /* nothing */ 249 /* nothing */
160} 250}
161 251
162int line_chars_in_buffer(struct tty_struct *tty)
163{
164 return 0;
165}
166
167static struct { 252static struct {
168 int cmd; 253 int cmd;
169 char *level; 254 char *level;
@@ -250,7 +335,7 @@ int line_ioctl(struct tty_struct *tty, struct file * file,
250 ret = -ENOIOCTLCMD; 335 ret = -ENOIOCTLCMD;
251 break; 336 break;
252 } 337 }
253 return(ret); 338 return ret;
254} 339}
255 340
256static irqreturn_t line_write_interrupt(int irq, void *data, 341static irqreturn_t line_write_interrupt(int irq, void *data,
@@ -260,18 +345,23 @@ static irqreturn_t line_write_interrupt(int irq, void *data,
260 struct line *line = tty->driver_data; 345 struct line *line = tty->driver_data;
261 int err; 346 int err;
262 347
348 /* Interrupts are enabled here because we registered the interrupt with
349 * SA_INTERRUPT (see line_setup_irq).*/
350
351 spin_lock_irq(&line->lock);
263 err = flush_buffer(line); 352 err = flush_buffer(line);
264 if(err == 0) 353 if (err == 0) {
265 return(IRQ_NONE); 354 return IRQ_NONE;
266 else if(err < 0){ 355 } else if(err < 0) {
267 line->head = line->buffer; 356 line->head = line->buffer;
268 line->tail = line->buffer; 357 line->tail = line->buffer;
269 } 358 }
359 spin_unlock_irq(&line->lock);
270 360
271 if(tty == NULL) 361 if(tty == NULL)
272 return(IRQ_NONE); 362 return IRQ_NONE;
273 363
274 if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && 364 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
275 (tty->ldisc.write_wakeup != NULL)) 365 (tty->ldisc.write_wakeup != NULL))
276 (tty->ldisc.write_wakeup)(tty); 366 (tty->ldisc.write_wakeup)(tty);
277 367
@@ -281,9 +371,9 @@ static irqreturn_t line_write_interrupt(int irq, void *data,
281 * writes. 371 * writes.
282 */ 372 */
283 373
284 if(waitqueue_active(&tty->write_wait)) 374 if (waitqueue_active(&tty->write_wait))
285 wake_up_interruptible(&tty->write_wait); 375 wake_up_interruptible(&tty->write_wait);
286 return(IRQ_HANDLED); 376 return IRQ_HANDLED;
287} 377}
288 378
289int line_setup_irq(int fd, int input, int output, struct tty_struct *tty) 379int line_setup_irq(int fd, int input, int output, struct tty_struct *tty)
@@ -292,15 +382,18 @@ int line_setup_irq(int fd, int input, int output, struct tty_struct *tty)
292 struct line_driver *driver = line->driver; 382 struct line_driver *driver = line->driver;
293 int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM; 383 int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM;
294 384
295 if(input) err = um_request_irq(driver->read_irq, fd, IRQ_READ, 385 if (input)
386 err = um_request_irq(driver->read_irq, fd, IRQ_READ,
296 line_interrupt, flags, 387 line_interrupt, flags,
297 driver->read_irq_name, tty); 388 driver->read_irq_name, tty);
298 if(err) return(err); 389 if (err)
299 if(output) err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, 390 return err;
391 if (output)
392 err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
300 line_write_interrupt, flags, 393 line_write_interrupt, flags,
301 driver->write_irq_name, tty); 394 driver->write_irq_name, tty);
302 line->have_irq = 1; 395 line->have_irq = 1;
303 return(err); 396 return err;
304} 397}
305 398
306void line_disable(struct tty_struct *tty, int current_irq) 399void line_disable(struct tty_struct *tty, int current_irq)
@@ -336,7 +429,9 @@ int line_open(struct line *lines, struct tty_struct *tty,
336 line = &lines[tty->index]; 429 line = &lines[tty->index];
337 tty->driver_data = line; 430 tty->driver_data = line;
338 431
339 down(&line->sem); 432 /* The IRQ which takes this lock is not yet enabled and won't be run
433 * before the end, so we don't need to use spin_lock_irq.*/
434 spin_lock(&line->lock);
340 if (tty->count == 1) { 435 if (tty->count == 1) {
341 if (!line->valid) { 436 if (!line->valid) {
342 err = -ENODEV; 437 err = -ENODEV;
@@ -349,6 +444,7 @@ int line_open(struct line *lines, struct tty_struct *tty,
349 err = open_chan(&line->chan_list); 444 err = open_chan(&line->chan_list);
350 if(err) goto out; 445 if(err) goto out;
351 } 446 }
447 /* Here the interrupt is registered.*/
352 enable_chan(&line->chan_list, tty); 448 enable_chan(&line->chan_list, tty);
353 INIT_WORK(&line->task, line_timer_cb, tty); 449 INIT_WORK(&line->task, line_timer_cb, tty);
354 } 450 }
@@ -362,21 +458,36 @@ int line_open(struct line *lines, struct tty_struct *tty,
362 line->count++; 458 line->count++;
363 459
364out: 460out:
365 up(&line->sem); 461 spin_unlock(&line->lock);
366 return(err); 462 return err;
367} 463}
368 464
465static void unregister_winch(struct tty_struct *tty);
466
369void line_close(struct tty_struct *tty, struct file * filp) 467void line_close(struct tty_struct *tty, struct file * filp)
370{ 468{
371 struct line *line = tty->driver_data; 469 struct line *line = tty->driver_data;
372 470
373 down(&line->sem); 471 /* XXX: I assume this should be called in process context, not with
472 * interrupts disabled!
473 */
474 spin_lock_irq(&line->lock);
475
476 /* We ignore the error anyway! */
477 flush_buffer(line);
478
374 line->count--; 479 line->count--;
375 if (tty->count == 1) { 480 if (tty->count == 1) {
376 line_disable(tty, -1); 481 line_disable(tty, -1);
377 tty->driver_data = NULL; 482 tty->driver_data = NULL;
378 } 483 }
379 up(&line->sem); 484
485 if((line->count == 0) && line->sigio){
486 unregister_winch(tty);
487 line->sigio = 0;
488 }
489
490 spin_unlock_irq(&line->lock);
380} 491}
381 492
382void close_lines(struct line *lines, int nlines) 493void close_lines(struct line *lines, int nlines)
@@ -387,31 +498,41 @@ void close_lines(struct line *lines, int nlines)
387 close_chan(&lines[i].chan_list); 498 close_chan(&lines[i].chan_list);
388} 499}
389 500
390int line_setup(struct line *lines, int num, char *init, int all_allowed) 501/* Common setup code for both startup command line and mconsole initialization.
502 * @lines contains the the array (of size @num) to modify;
503 * @init is the setup string;
504 * @all_allowed is a boolean saying if we can setup the whole @lines
505 * at once. For instance, it will be usually true for startup init. (where we
506 * can use con=xterm) and false for mconsole.*/
507
508int line_setup(struct line *lines, unsigned int num, char *init, int all_allowed)
391{ 509{
392 int i, n; 510 int i, n;
393 char *end; 511 char *end;
394 512
395 if(*init == '=') n = -1; 513 if(*init == '=') {
396 else { 514 /* We said con=/ssl= instead of con#=, so we are configuring all
515 * consoles at once.*/
516 n = -1;
517 } else {
397 n = simple_strtoul(init, &end, 0); 518 n = simple_strtoul(init, &end, 0);
398 if(*end != '='){ 519 if(*end != '='){
399 printk(KERN_ERR "line_setup failed to parse \"%s\"\n", 520 printk(KERN_ERR "line_setup failed to parse \"%s\"\n",
400 init); 521 init);
401 return(0); 522 return 0;
402 } 523 }
403 init = end; 524 init = end;
404 } 525 }
405 init++; 526 init++;
406 if((n >= 0) && (n >= num)){ 527
528 if (n >= (signed int) num) {
407 printk("line_setup - %d out of range ((0 ... %d) allowed)\n", 529 printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
408 n, num - 1); 530 n, num - 1);
409 return(0); 531 return 0;
410 } 532 } else if (n >= 0){
411 else if (n >= 0){
412 if (lines[n].count > 0) { 533 if (lines[n].count > 0) {
413 printk("line_setup - device %d is open\n", n); 534 printk("line_setup - device %d is open\n", n);
414 return(0); 535 return 0;
415 } 536 }
416 if (lines[n].init_pri <= INIT_ONE){ 537 if (lines[n].init_pri <= INIT_ONE){
417 lines[n].init_pri = INIT_ONE; 538 lines[n].init_pri = INIT_ONE;
@@ -422,13 +543,11 @@ int line_setup(struct line *lines, int num, char *init, int all_allowed)
422 lines[n].valid = 1; 543 lines[n].valid = 1;
423 } 544 }
424 } 545 }
425 } 546 } else if(!all_allowed){
426 else if(!all_allowed){
427 printk("line_setup - can't configure all devices from " 547 printk("line_setup - can't configure all devices from "
428 "mconsole\n"); 548 "mconsole\n");
429 return(0); 549 return 0;
430 } 550 } else {
431 else {
432 for(i = 0; i < num; i++){ 551 for(i = 0; i < num; i++){
433 if(lines[i].init_pri <= INIT_ALL){ 552 if(lines[i].init_pri <= INIT_ALL){
434 lines[i].init_pri = INIT_ALL; 553 lines[i].init_pri = INIT_ALL;
@@ -440,21 +559,21 @@ int line_setup(struct line *lines, int num, char *init, int all_allowed)
440 } 559 }
441 } 560 }
442 } 561 }
443 return(1); 562 return 1;
444} 563}
445 564
446int line_config(struct line *lines, int num, char *str) 565int line_config(struct line *lines, unsigned int num, char *str)
447{ 566{
448 char *new = uml_strdup(str); 567 char *new = uml_strdup(str);
449 568
450 if(new == NULL){ 569 if(new == NULL){
451 printk("line_config - uml_strdup failed\n"); 570 printk("line_config - uml_strdup failed\n");
452 return(-ENOMEM); 571 return -ENOMEM;
453 } 572 }
454 return(!line_setup(lines, num, new, 0)); 573 return !line_setup(lines, num, new, 0);
455} 574}
456 575
457int line_get_config(char *name, struct line *lines, int num, char *str, 576int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
458 int size, char **error_out) 577 int size, char **error_out)
459{ 578{
460 struct line *line; 579 struct line *line;
@@ -464,47 +583,33 @@ int line_get_config(char *name, struct line *lines, int num, char *str,
464 dev = simple_strtoul(name, &end, 0); 583 dev = simple_strtoul(name, &end, 0);
465 if((*end != '\0') || (end == name)){ 584 if((*end != '\0') || (end == name)){
466 *error_out = "line_get_config failed to parse device number"; 585 *error_out = "line_get_config failed to parse device number";
467 return(0); 586 return 0;
468 } 587 }
469 588
470 if((dev < 0) || (dev >= num)){ 589 if((dev < 0) || (dev >= num)){
471 *error_out = "device number of of range"; 590 *error_out = "device number out of range";
472 return(0); 591 return 0;
473 } 592 }
474 593
475 line = &lines[dev]; 594 line = &lines[dev];
476 595
477 down(&line->sem); 596 spin_lock(&line->lock);
478 if(!line->valid) 597 if(!line->valid)
479 CONFIG_CHUNK(str, size, n, "none", 1); 598 CONFIG_CHUNK(str, size, n, "none", 1);
480 else if(line->count == 0) 599 else if(line->count == 0)
481 CONFIG_CHUNK(str, size, n, line->init_str, 1); 600 CONFIG_CHUNK(str, size, n, line->init_str, 1);
482 else n = chan_config_string(&line->chan_list, str, size, error_out); 601 else n = chan_config_string(&line->chan_list, str, size, error_out);
483 up(&line->sem); 602 spin_unlock(&line->lock);
484 603
485 return(n); 604 return n;
486} 605}
487 606
488int line_remove(struct line *lines, int num, char *str) 607int line_remove(struct line *lines, unsigned int num, char *str)
489{ 608{
490 char config[sizeof("conxxxx=none\0")]; 609 char config[sizeof("conxxxx=none\0")];
491 610
492 sprintf(config, "%s=none", str); 611 sprintf(config, "%s=none", str);
493 return(!line_setup(lines, num, config, 0)); 612 return !line_setup(lines, num, config, 0);
494}
495
496int line_write_room(struct tty_struct *tty)
497{
498 struct line *dev = tty->driver_data;
499 int room;
500
501 if (tty->stopped)
502 return 0;
503 room = write_room(dev);
504 if (0 == room)
505 printk(KERN_DEBUG "%s: %s: no room left in buffer\n",
506 __FUNCTION__,tty->name);
507 return room;
508} 613}
509 614
510struct tty_driver *line_register_devfs(struct lines *set, 615struct tty_driver *line_register_devfs(struct lines *set,
@@ -553,7 +658,7 @@ void lines_init(struct line *lines, int nlines)
553 for(i = 0; i < nlines; i++){ 658 for(i = 0; i < nlines; i++){
554 line = &lines[i]; 659 line = &lines[i];
555 INIT_LIST_HEAD(&line->chan_list); 660 INIT_LIST_HEAD(&line->chan_list);
556 sema_init(&line->sem, 1); 661 spin_lock_init(&line->lock);
557 if(line->init_str != NULL){ 662 if(line->init_str != NULL){
558 line->init_str = uml_strdup(line->init_str); 663 line->init_str = uml_strdup(line->init_str);
559 if(line->init_str == NULL) 664 if(line->init_str == NULL)
@@ -587,7 +692,7 @@ irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
587 "errno = %d\n", -err); 692 "errno = %d\n", -err);
588 printk("fd %d is losing SIGWINCH support\n", 693 printk("fd %d is losing SIGWINCH support\n",
589 winch->tty_fd); 694 winch->tty_fd);
590 return(IRQ_HANDLED); 695 return IRQ_HANDLED;
591 } 696 }
592 goto out; 697 goto out;
593 } 698 }
@@ -603,7 +708,7 @@ irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
603 out: 708 out:
604 if(winch->fd != -1) 709 if(winch->fd != -1)
605 reactivate_fd(winch->fd, WINCH_IRQ); 710 reactivate_fd(winch->fd, WINCH_IRQ);
606 return(IRQ_HANDLED); 711 return IRQ_HANDLED;
607} 712}
608 713
609DECLARE_MUTEX(winch_handler_sem); 714DECLARE_MUTEX(winch_handler_sem);
@@ -625,7 +730,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty)
625 .pid = pid, 730 .pid = pid,
626 .tty = tty }); 731 .tty = tty });
627 list_add(&winch->list, &winch_handlers); 732 list_add(&winch->list, &winch_handlers);
628 if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, 733 if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
629 SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 734 SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
630 "winch", winch) < 0) 735 "winch", winch) < 0)
631 printk("register_winch_irq - failed to register IRQ\n"); 736 printk("register_winch_irq - failed to register IRQ\n");
@@ -633,6 +738,34 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty)
633 up(&winch_handler_sem); 738 up(&winch_handler_sem);
634} 739}
635 740
741static void unregister_winch(struct tty_struct *tty)
742{
743 struct list_head *ele;
744 struct winch *winch, *found = NULL;
745
746 down(&winch_handler_sem);
747 list_for_each(ele, &winch_handlers){
748 winch = list_entry(ele, struct winch, list);
749 if(winch->tty == tty){
750 found = winch;
751 break;
752 }
753 }
754
755 if(found == NULL)
756 goto out;
757
758 if(winch->pid != -1)
759 os_kill_process(winch->pid, 1);
760
761 free_irq_by_irq_and_dev(WINCH_IRQ, winch);
762 free_irq(WINCH_IRQ, winch);
763 list_del(&winch->list);
764 kfree(winch);
765 out:
766 up(&winch_handler_sem);
767}
768
636static void winch_cleanup(void) 769static void winch_cleanup(void)
637{ 770{
638 struct list_head *ele; 771 struct list_head *ele;
@@ -656,26 +789,16 @@ char *add_xterm_umid(char *base)
656 int len; 789 int len;
657 790
658 umid = get_umid(1); 791 umid = get_umid(1);
659 if(umid == NULL) return(base); 792 if(umid == NULL)
793 return base;
660 794
661 len = strlen(base) + strlen(" ()") + strlen(umid) + 1; 795 len = strlen(base) + strlen(" ()") + strlen(umid) + 1;
662 title = kmalloc(len, GFP_KERNEL); 796 title = kmalloc(len, GFP_KERNEL);
663 if(title == NULL){ 797 if(title == NULL){
664 printk("Failed to allocate buffer for xterm title\n"); 798 printk("Failed to allocate buffer for xterm title\n");
665 return(base); 799 return base;
666 } 800 }
667 801
668 snprintf(title, len, "%s (%s)", base, umid); 802 snprintf(title, len, "%s (%s)", base, umid);
669 return(title); 803 return title;
670} 804}
671
672/*
673 * Overrides for Emacs so that we follow Linus's tabbing style.
674 * Emacs will notice this stuff at the end of the file and automatically
675 * adjust the settings for this buffer only. This must remain at the end
676 * of the file.
677 * ---------------------------------------------------------------------------
678 * Local variables:
679 * c-file-style: "linux"
680 * End:
681 */
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index c5839c3141f8..a2bac429f3d4 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -107,11 +107,6 @@ int ssl_open(struct tty_struct *tty, struct file *filp)
107} 107}
108 108
109#if 0 109#if 0
110static int ssl_chars_in_buffer(struct tty_struct *tty)
111{
112 return(0);
113}
114
115static void ssl_flush_buffer(struct tty_struct *tty) 110static void ssl_flush_buffer(struct tty_struct *tty)
116{ 111{
117 return; 112 return;
@@ -149,11 +144,11 @@ static struct tty_operations ssl_ops = {
149 .put_char = line_put_char, 144 .put_char = line_put_char,
150 .write_room = line_write_room, 145 .write_room = line_write_room,
151 .chars_in_buffer = line_chars_in_buffer, 146 .chars_in_buffer = line_chars_in_buffer,
147 .flush_buffer = line_flush_buffer,
148 .flush_chars = line_flush_chars,
152 .set_termios = line_set_termios, 149 .set_termios = line_set_termios,
153 .ioctl = line_ioctl, 150 .ioctl = line_ioctl,
154#if 0 151#if 0
155 .flush_chars = ssl_flush_chars,
156 .flush_buffer = ssl_flush_buffer,
157 .throttle = ssl_throttle, 152 .throttle = ssl_throttle,
158 .unthrottle = ssl_unthrottle, 153 .unthrottle = ssl_unthrottle,
159 .stop = ssl_stop, 154 .stop = ssl_stop,
@@ -171,10 +166,11 @@ static void ssl_console_write(struct console *c, const char *string,
171 unsigned len) 166 unsigned len)
172{ 167{
173 struct line *line = &serial_lines[c->index]; 168 struct line *line = &serial_lines[c->index];
169 unsigned long flags;
174 170
175 down(&line->sem); 171 spin_lock_irqsave(&line->lock, flags);
176 console_write_chan(&line->chan_list, string, len); 172 console_write_chan(&line->chan_list, string, len);
177 up(&line->sem); 173 spin_unlock_irqrestore(&line->lock, flags);
178} 174}
179 175
180static struct tty_driver *ssl_console_device(struct console *c, int *index) 176static struct tty_driver *ssl_console_device(struct console *c, int *index)
@@ -238,14 +234,3 @@ static int ssl_chan_setup(char *str)
238 234
239__setup("ssl", ssl_chan_setup); 235__setup("ssl", ssl_chan_setup);
240__channel_help(ssl_chan_setup, "ssl"); 236__channel_help(ssl_chan_setup, "ssl");
241
242/*
243 * Overrides for Emacs so that we follow Linus's tabbing style.
244 * Emacs will notice this stuff at the end of the file and automatically
245 * adjust the settings for this buffer only. This must remain at the end
246 * of the file.
247 * ---------------------------------------------------------------------------
248 * Local variables:
249 * c-file-style: "linux"
250 * End:
251 */
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index e604d7c87695..361d0be342b3 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -116,8 +116,11 @@ static struct tty_operations console_ops = {
116 .open = con_open, 116 .open = con_open,
117 .close = line_close, 117 .close = line_close,
118 .write = line_write, 118 .write = line_write,
119 .put_char = line_put_char,
119 .write_room = line_write_room, 120 .write_room = line_write_room,
120 .chars_in_buffer = line_chars_in_buffer, 121 .chars_in_buffer = line_chars_in_buffer,
122 .flush_buffer = line_flush_buffer,
123 .flush_chars = line_flush_chars,
121 .set_termios = line_set_termios, 124 .set_termios = line_set_termios,
122 .ioctl = line_ioctl, 125 .ioctl = line_ioctl,
123}; 126};
@@ -126,10 +129,11 @@ static void uml_console_write(struct console *console, const char *string,
126 unsigned len) 129 unsigned len)
127{ 130{
128 struct line *line = &vts[console->index]; 131 struct line *line = &vts[console->index];
132 unsigned long flags;
129 133
130 down(&line->sem); 134 spin_lock_irqsave(&line->lock, flags);
131 console_write_chan(&line->chan_list, string, len); 135 console_write_chan(&line->chan_list, string, len);
132 up(&line->sem); 136 spin_unlock_irqrestore(&line->lock, flags);
133} 137}
134 138
135static struct tty_driver *uml_console_device(struct console *c, int *index) 139static struct tty_driver *uml_console_device(struct console *c, int *index)
@@ -192,14 +196,3 @@ static int console_chan_setup(char *str)
192} 196}
193__setup("con", console_chan_setup); 197__setup("con", console_chan_setup);
194__channel_help(console_chan_setup, "con"); 198__channel_help(console_chan_setup, "con");
195
196/*
197 * Overrides for Emacs so that we follow Linus's tabbing style.
198 * Emacs will notice this stuff at the end of the file and automatically
199 * adjust the settings for this buffer only. This must remain at the end
200 * of the file.
201 * ---------------------------------------------------------------------------
202 * Local variables:
203 * c-file-style: "linux"
204 * End:
205 */
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 4d8b165bfa48..9a56ff94308d 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -156,6 +156,7 @@ static struct gendisk *fake_gendisk[MAX_DEV];
156static struct openflags global_openflags = OPEN_FLAGS; 156static struct openflags global_openflags = OPEN_FLAGS;
157 157
158struct cow { 158struct cow {
159 /* This is the backing file, actually */
159 char *file; 160 char *file;
160 int fd; 161 int fd;
161 unsigned long *bitmap; 162 unsigned long *bitmap;
@@ -927,10 +928,14 @@ static int ubd_open(struct inode *inode, struct file *filp)
927 } 928 }
928 } 929 }
929 dev->count++; 930 dev->count++;
930 if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){ 931 set_disk_ro(disk, !dev->openflags.w);
932
933 /* This should no more be needed. And it didn't work anyway to exclude
934 * read-write remounting of filesystems.*/
935 /*if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
931 if(--dev->count == 0) ubd_close(dev); 936 if(--dev->count == 0) ubd_close(dev);
932 err = -EROFS; 937 err = -EROFS;
933 } 938 }*/
934 out: 939 out:
935 return(err); 940 return(err);
936} 941}
@@ -1096,6 +1101,7 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
1096 1101
1097 if(req->rq_status == RQ_INACTIVE) return(1); 1102 if(req->rq_status == RQ_INACTIVE) return(1);
1098 1103
1104 /* This should be impossible now */
1099 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){ 1105 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
1100 printk("Write attempted on readonly ubd device %s\n", 1106 printk("Write attempted on readonly ubd device %s\n",
1101 disk->disk_name); 1107 disk->disk_name);
@@ -1243,6 +1249,7 @@ static int ubd_check_remapped(int fd, unsigned long address, int is_write,
1243 1249
1244 /* It's a write to a ubd device */ 1250 /* It's a write to a ubd device */
1245 1251
1252 /* This should be impossible now */
1246 if(!dev->openflags.w){ 1253 if(!dev->openflags.w){
1247 /* It's a write access on a read-only device - probably 1254 /* It's a write access on a read-only device - probably
1248 * shouldn't happen. If the kernel is trying to change 1255 * shouldn't happen. If the kernel is trying to change
@@ -1605,8 +1612,7 @@ void do_io(struct io_thread_req *req)
1605 } 1612 }
1606 } while((n < len) && (n != 0)); 1613 } while((n < len) && (n != 0));
1607 if (n < len) memset(&buf[n], 0, len - n); 1614 if (n < len) memset(&buf[n], 0, len - n);
1608 } 1615 } else {
1609 else {
1610 n = os_write_file(req->fds[bit], buf, len); 1616 n = os_write_file(req->fds[bit], buf, len);
1611 if(n != len){ 1617 if(n != len){
1612 printk("do_io - write failed err = %d " 1618 printk("do_io - write failed err = %d "
diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
index 7917b9d1cec8..a4fdf3584ad2 100644
--- a/arch/um/drivers/xterm_kern.c
+++ b/arch/um/drivers/xterm_kern.c
@@ -7,7 +7,6 @@
7#include "linux/slab.h" 7#include "linux/slab.h"
8#include "linux/signal.h" 8#include "linux/signal.h"
9#include "linux/interrupt.h" 9#include "linux/interrupt.h"
10#include "asm/semaphore.h"
11#include "asm/irq.h" 10#include "asm/irq.h"
12#include "irq_user.h" 11#include "irq_user.h"
13#include "irq_kern.h" 12#include "irq_kern.h"
diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h
new file mode 100644
index 000000000000..d705daa2d854
--- /dev/null
+++ b/arch/um/include/common-offsets.h
@@ -0,0 +1,14 @@
1/* for use by sys-$SUBARCH/kernel-offsets.c */
2
3OFFSET(TASK_REGS, task_struct, thread.regs);
4OFFSET(TASK_PID, task_struct, pid);
5DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE);
6DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
7DEFINE_STR(UM_KERN_EMERG, KERN_EMERG);
8DEFINE_STR(UM_KERN_ALERT, KERN_ALERT);
9DEFINE_STR(UM_KERN_CRIT, KERN_CRIT);
10DEFINE_STR(UM_KERN_ERR, KERN_ERR);
11DEFINE_STR(UM_KERN_WARNING, KERN_WARNING);
12DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE);
13DEFINE_STR(UM_KERN_INFO, KERN_INFO);
14DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 15389c886b41..e5fec5570199 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -8,6 +8,7 @@
8 8
9#include "linux/threads.h" 9#include "linux/threads.h"
10#include "sysdep/ptrace.h" 10#include "sysdep/ptrace.h"
11#include "sysdep/faultinfo.h"
11 12
12extern int ncpus; 13extern int ncpus;
13extern char *linux_prog; 14extern char *linux_prog;
@@ -31,8 +32,8 @@ extern int current_pid(void);
31extern unsigned long alloc_stack(int order, int atomic); 32extern unsigned long alloc_stack(int order, int atomic);
32extern int do_signal(void); 33extern int do_signal(void);
33extern int is_stack_fault(unsigned long sp); 34extern int is_stack_fault(unsigned long sp);
34extern unsigned long segv(unsigned long address, unsigned long ip, 35extern unsigned long segv(struct faultinfo fi, unsigned long ip,
35 int is_write, int is_user, void *sc); 36 int is_user, void *sc);
36extern int handle_page_fault(unsigned long address, unsigned long ip, 37extern int handle_page_fault(unsigned long address, unsigned long ip,
37 int is_write, int is_user, int *code_out); 38 int is_write, int is_user, int *code_out);
38extern void syscall_ready(void); 39extern void syscall_ready(void);
@@ -82,7 +83,7 @@ extern void timer_irq(union uml_pt_regs *regs);
82extern void unprotect_stack(unsigned long stack); 83extern void unprotect_stack(unsigned long stack);
83extern void do_uml_exitcalls(void); 84extern void do_uml_exitcalls(void);
84extern int attach_debugger(int idle_pid, int pid, int stop); 85extern int attach_debugger(int idle_pid, int pid, int stop);
85extern void bad_segv(unsigned long address, unsigned long ip, int is_write); 86extern void bad_segv(struct faultinfo fi, unsigned long ip);
86extern int config_gdb(char *str); 87extern int config_gdb(char *str);
87extern int remove_gdb(void); 88extern int remove_gdb(void);
88extern char *uml_strdup(char *string); 89extern char *uml_strdup(char *string);
diff --git a/arch/um/include/line.h b/arch/um/include/line.h
index 6d81ecc17be5..4c5e92c04ccb 100644
--- a/arch/um/include/line.h
+++ b/arch/um/include/line.h
@@ -10,7 +10,7 @@
10#include "linux/workqueue.h" 10#include "linux/workqueue.h"
11#include "linux/tty.h" 11#include "linux/tty.h"
12#include "linux/interrupt.h" 12#include "linux/interrupt.h"
13#include "asm/semaphore.h" 13#include "linux/spinlock.h"
14#include "chan_user.h" 14#include "chan_user.h"
15#include "mconsole_kern.h" 15#include "mconsole_kern.h"
16 16
@@ -37,10 +37,18 @@ struct line {
37 struct list_head chan_list; 37 struct list_head chan_list;
38 int valid; 38 int valid;
39 int count; 39 int count;
40 struct semaphore sem; 40 /*This lock is actually, mostly, local to*/
41 spinlock_t lock;
42
43 /* Yes, this is a real circular buffer.
44 * XXX: And this should become a struct kfifo!
45 *
46 * buffer points to a buffer allocated on demand, of length
47 * LINE_BUFSIZE, head to the start of the ring, tail to the end.*/
41 char *buffer; 48 char *buffer;
42 char *head; 49 char *head;
43 char *tail; 50 char *tail;
51
44 int sigio; 52 int sigio;
45 struct work_struct task; 53 struct work_struct task;
46 struct line_driver *driver; 54 struct line_driver *driver;
@@ -52,7 +60,6 @@ struct line {
52 init_pri : INIT_STATIC, \ 60 init_pri : INIT_STATIC, \
53 chan_list : { }, \ 61 chan_list : { }, \
54 valid : 1, \ 62 valid : 1, \
55 sem : { }, \
56 buffer : NULL, \ 63 buffer : NULL, \
57 head : NULL, \ 64 head : NULL, \
58 tail : NULL, \ 65 tail : NULL, \
@@ -69,15 +76,18 @@ struct lines {
69extern void line_close(struct tty_struct *tty, struct file * filp); 76extern void line_close(struct tty_struct *tty, struct file * filp);
70extern int line_open(struct line *lines, struct tty_struct *tty, 77extern int line_open(struct line *lines, struct tty_struct *tty,
71 struct chan_opts *opts); 78 struct chan_opts *opts);
72extern int line_setup(struct line *lines, int num, char *init, 79extern int line_setup(struct line *lines, unsigned int sizeof_lines, char *init,
73 int all_allowed); 80 int all_allowed);
74extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len); 81extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len);
75extern void line_put_char(struct tty_struct *tty, unsigned char ch); 82extern void line_put_char(struct tty_struct *tty, unsigned char ch);
76extern void line_set_termios(struct tty_struct *tty, struct termios * old); 83extern void line_set_termios(struct tty_struct *tty, struct termios * old);
77extern int line_chars_in_buffer(struct tty_struct *tty); 84extern int line_chars_in_buffer(struct tty_struct *tty);
85extern void line_flush_buffer(struct tty_struct *tty);
86extern void line_flush_chars(struct tty_struct *tty);
78extern int line_write_room(struct tty_struct *tty); 87extern int line_write_room(struct tty_struct *tty);
79extern int line_ioctl(struct tty_struct *tty, struct file * file, 88extern int line_ioctl(struct tty_struct *tty, struct file * file,
80 unsigned int cmd, unsigned long arg); 89 unsigned int cmd, unsigned long arg);
90
81extern char *add_xterm_umid(char *base); 91extern char *add_xterm_umid(char *base);
82extern int line_setup_irq(int fd, int input, int output, struct tty_struct *tty); 92extern int line_setup_irq(int fd, int input, int output, struct tty_struct *tty);
83extern void line_close_chan(struct line *line); 93extern void line_close_chan(struct line *line);
@@ -89,20 +99,10 @@ extern struct tty_driver * line_register_devfs(struct lines *set,
89 int nlines); 99 int nlines);
90extern void lines_init(struct line *lines, int nlines); 100extern void lines_init(struct line *lines, int nlines);
91extern void close_lines(struct line *lines, int nlines); 101extern void close_lines(struct line *lines, int nlines);
92extern int line_config(struct line *lines, int num, char *str); 102
93extern int line_remove(struct line *lines, int num, char *str); 103extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str);
94extern int line_get_config(char *dev, struct line *lines, int num, char *str, 104extern int line_remove(struct line *lines, unsigned int sizeof_lines, char *str);
105extern int line_get_config(char *dev, struct line *lines, unsigned int sizeof_lines, char *str,
95 int size, char **error_out); 106 int size, char **error_out);
96 107
97#endif 108#endif
98
99/*
100 * Overrides for Emacs so that we follow Linus's tabbing style.
101 * Emacs will notice this stuff at the end of the file and automatically
102 * adjust the settings for this buffer only. This must remain at the end
103 * of the file.
104 * ---------------------------------------------------------------------------
105 * Local variables:
106 * c-file-style: "linux"
107 * End:
108 */
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 07340c8cf203..d246d5a24609 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -160,6 +160,7 @@ extern void os_kill_process(int pid, int reap_child);
160extern void os_kill_ptraced_process(int pid, int reap_child); 160extern void os_kill_ptraced_process(int pid, int reap_child);
161extern void os_usr1_process(int pid); 161extern void os_usr1_process(int pid);
162extern int os_getpid(void); 162extern int os_getpid(void);
163extern int os_getpgrp(void);
163 164
164extern int os_map_memory(void *virt, int fd, unsigned long long off, 165extern int os_map_memory(void *virt, int fd, unsigned long long off,
165 unsigned long len, int r, int w, int x); 166 unsigned long len, int r, int w, int x);
diff --git a/arch/um/include/skas_ptrace.h b/arch/um/include/skas_ptrace.h
index cfb5fb4f5b91..cd2327d09c8d 100644
--- a/arch/um/include/skas_ptrace.h
+++ b/arch/um/include/skas_ptrace.h
@@ -6,22 +6,11 @@
6#ifndef __SKAS_PTRACE_H 6#ifndef __SKAS_PTRACE_H
7#define __SKAS_PTRACE_H 7#define __SKAS_PTRACE_H
8 8
9struct ptrace_faultinfo {
10 int is_write;
11 unsigned long addr;
12};
13
14struct ptrace_ldt {
15 int func;
16 void *ptr;
17 unsigned long bytecount;
18};
19
20#define PTRACE_FAULTINFO 52 9#define PTRACE_FAULTINFO 52
21#define PTRACE_SIGPENDING 53
22#define PTRACE_LDT 54
23#define PTRACE_SWITCH_MM 55 10#define PTRACE_SWITCH_MM 55
24 11
12#include "sysdep/skas_ptrace.h"
13
25#endif 14#endif
26 15
27/* 16/*
diff --git a/arch/um/include/sysdep-i386/checksum.h b/arch/um/include/sysdep-i386/checksum.h
index 3a2a45811aa3..764ba4db4788 100644
--- a/arch/um/include/sysdep-i386/checksum.h
+++ b/arch/um/include/sysdep-i386/checksum.h
@@ -24,19 +24,6 @@ unsigned int csum_partial(const unsigned char * buff, int len,
24 unsigned int sum); 24 unsigned int sum);
25 25
26/* 26/*
27 * the same as csum_partial, but copies from src while it
28 * checksums, and handles user-space pointer exceptions correctly, when needed.
29 *
30 * here even more important to align src and dst on a 32-bit (or even
31 * better 64-bit) boundary
32 */
33
34unsigned int csum_partial_copy_to(const unsigned char *src, unsigned char *dst,
35 int len, int sum, int *err_ptr);
36unsigned int csum_partial_copy_from(const unsigned char *src, unsigned char *dst,
37 int len, int sum, int *err_ptr);
38
39/*
40 * Note: when you get a NULL pointer exception here this means someone 27 * Note: when you get a NULL pointer exception here this means someone
41 * passed in an incorrect kernel address to one of these functions. 28 * passed in an incorrect kernel address to one of these functions.
42 * 29 *
@@ -52,11 +39,24 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *
52 return(csum_partial(dst, len, sum)); 39 return(csum_partial(dst, len, sum));
53} 40}
54 41
42/*
43 * the same as csum_partial, but copies from src while it
44 * checksums, and handles user-space pointer exceptions correctly, when needed.
45 *
46 * here even more important to align src and dst on a 32-bit (or even
47 * better 64-bit) boundary
48 */
49
55static __inline__ 50static __inline__
56unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, 51unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
57 int len, int sum, int *err_ptr) 52 int len, int sum, int *err_ptr)
58{ 53{
59 return csum_partial_copy_from(src, dst, len, sum, err_ptr); 54 if(copy_from_user(dst, src, len)){
55 *err_ptr = -EFAULT;
56 return(-1);
57 }
58
59 return csum_partial(dst, len, sum);
60} 60}
61 61
62/* 62/*
@@ -67,7 +67,6 @@ unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char
67 */ 67 */
68 68
69#define csum_partial_copy_fromuser csum_partial_copy_from_user 69#define csum_partial_copy_fromuser csum_partial_copy_from_user
70unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, int len, int sum);
71 70
72/* 71/*
73 * This is a version of ip_compute_csum() optimized for IP headers, 72 * This is a version of ip_compute_csum() optimized for IP headers,
@@ -196,8 +195,14 @@ static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src,
196 unsigned char *dst, 195 unsigned char *dst,
197 int len, int sum, int *err_ptr) 196 int len, int sum, int *err_ptr)
198{ 197{
199 if (access_ok(VERIFY_WRITE, dst, len)) 198 if (access_ok(VERIFY_WRITE, dst, len)){
200 return(csum_partial_copy_to(src, dst, len, sum, err_ptr)); 199 if(copy_to_user(dst, src, len)){
200 *err_ptr = -EFAULT;
201 return(-1);
202 }
203
204 return csum_partial(src, len, sum);
205 }
201 206
202 if (len) 207 if (len)
203 *err_ptr = -EFAULT; 208 *err_ptr = -EFAULT;
diff --git a/arch/um/include/sysdep-i386/faultinfo.h b/arch/um/include/sysdep-i386/faultinfo.h
new file mode 100644
index 000000000000..db437cc373bc
--- /dev/null
+++ b/arch/um/include/sysdep-i386/faultinfo.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
3 * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
4 * Licensed under the GPL
5 */
6
7#ifndef __FAULTINFO_I386_H
8#define __FAULTINFO_I386_H
9
10/* this structure contains the full arch-specific faultinfo
11 * from the traps.
12 * On i386, ptrace_faultinfo unfortunately doesn't provide
13 * all the info, since trap_no is missing.
14 * All common elements are defined at the same position in
15 * both structures, thus making it easy to copy the
16 * contents without knowledge about the structure elements.
17 */
18struct faultinfo {
19 int error_code; /* in ptrace_faultinfo misleadingly called is_write */
20 unsigned long cr2; /* in ptrace_faultinfo called addr */
21 int trap_no; /* missing in ptrace_faultinfo */
22};
23
24#define FAULT_WRITE(fi) ((fi).error_code & 2)
25#define FAULT_ADDRESS(fi) ((fi).cr2)
26
27#define PTRACE_FULL_FAULTINFO 0
28
29#endif
diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h
index 661d495e2044..84ec7ff5cf8c 100644
--- a/arch/um/include/sysdep-i386/ptrace.h
+++ b/arch/um/include/sysdep-i386/ptrace.h
@@ -31,6 +31,7 @@ extern int sysemu_supported;
31#ifdef UML_CONFIG_MODE_SKAS 31#ifdef UML_CONFIG_MODE_SKAS
32 32
33#include "skas_ptregs.h" 33#include "skas_ptregs.h"
34#include "sysdep/faultinfo.h"
34 35
35#define REGS_IP(r) ((r)[HOST_IP]) 36#define REGS_IP(r) ((r)[HOST_IP])
36#define REGS_SP(r) ((r)[HOST_SP]) 37#define REGS_SP(r) ((r)[HOST_SP])
@@ -53,12 +54,6 @@ extern int sysemu_supported;
53 54
54#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) 55#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
55 56
56#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
57
58#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
59
60#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
61
62#endif 57#endif
63#ifndef PTRACE_SYSEMU_SINGLESTEP 58#ifndef PTRACE_SYSEMU_SINGLESTEP
64#define PTRACE_SYSEMU_SINGLESTEP 32 59#define PTRACE_SYSEMU_SINGLESTEP 32
@@ -71,6 +66,7 @@ union uml_pt_regs {
71 struct tt_regs { 66 struct tt_regs {
72 long syscall; 67 long syscall;
73 void *sc; 68 void *sc;
69 struct faultinfo faultinfo;
74 } tt; 70 } tt;
75#endif 71#endif
76#ifdef UML_CONFIG_MODE_SKAS 72#ifdef UML_CONFIG_MODE_SKAS
@@ -78,9 +74,7 @@ union uml_pt_regs {
78 unsigned long regs[HOST_FRAME_SIZE]; 74 unsigned long regs[HOST_FRAME_SIZE];
79 unsigned long fp[HOST_FP_SIZE]; 75 unsigned long fp[HOST_FP_SIZE];
80 unsigned long xfp[HOST_XFP_SIZE]; 76 unsigned long xfp[HOST_XFP_SIZE];
81 unsigned long fault_addr; 77 struct faultinfo faultinfo;
82 unsigned long fault_type;
83 unsigned long trap_type;
84 long syscall; 78 long syscall;
85 int is_user; 79 int is_user;
86 } skas; 80 } skas;
@@ -217,15 +211,8 @@ struct syscall_args {
217#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r) 211#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r)
218#define UPT_SYSCALL_RET(r) UPT_EAX(r) 212#define UPT_SYSCALL_RET(r) UPT_EAX(r)
219 213
220#define UPT_SEGV_IS_FIXABLE(r) \ 214#define UPT_FAULTINFO(r) \
221 CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \ 215 CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo))
222 REGS_SEGV_IS_FIXABLE(&r->skas))
223
224#define UPT_FAULT_ADDR(r) \
225 __CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas))
226
227#define UPT_FAULT_WRITE(r) \
228 CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
229 216
230#endif 217#endif
231 218
diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
index dfee589de360..1fe729265167 100644
--- a/arch/um/include/sysdep-i386/sigcontext.h
+++ b/arch/um/include/sysdep-i386/sigcontext.h
@@ -13,15 +13,12 @@
13#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc)) 13#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc))
14#define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result) 14#define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result)
15 15
16#define SC_FAULT_ADDR(sc) SC_CR2(sc) 16#define GET_FAULTINFO_FROM_SC(fi,sc) \
17#define SC_FAULT_TYPE(sc) SC_ERR(sc) 17 { \
18 18 (fi).cr2 = SC_CR2(sc); \
19#define FAULT_WRITE(err) (err & 2) 19 (fi).error_code = SC_ERR(sc); \
20#define TO_SC_ERR(is_write) ((is_write) ? 2 : 0) 20 (fi).trap_no = SC_TRAPNO(sc); \
21 21 }
22#define SC_FAULT_WRITE(sc) (FAULT_WRITE(SC_ERR(sc)))
23
24#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc)
25 22
26/* ptrace expects that, at the start of a system call, %eax contains 23/* ptrace expects that, at the start of a system call, %eax contains
27 * -ENOSYS, so this makes it so. 24 * -ENOSYS, so this makes it so.
@@ -29,9 +26,7 @@
29#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0) 26#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
30 27
31/* This is Page Fault */ 28/* This is Page Fault */
32#define SEGV_IS_FIXABLE(trap) (trap == 14) 29#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
33
34#define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
35 30
36extern unsigned long *sc_sigmask(void *sc_ptr); 31extern unsigned long *sc_sigmask(void *sc_ptr);
37extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); 32extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
diff --git a/arch/um/include/sysdep-i386/signal.h b/arch/um/include/sysdep-i386/signal.h
index b1e1f7a77499..07518b162136 100644
--- a/arch/um/include/sysdep-i386/signal.h
+++ b/arch/um/include/sysdep-i386/signal.h
@@ -8,6 +8,8 @@
8 8
9#include <signal.h> 9#include <signal.h>
10 10
11#define ARCH_SIGHDLR_PARAM int sig
12
11#define ARCH_GET_SIGCONTEXT(sc, sig) \ 13#define ARCH_GET_SIGCONTEXT(sc, sig) \
12 do sc = (struct sigcontext *) (&sig + 1); while(0) 14 do sc = (struct sigcontext *) (&sig + 1); while(0)
13 15
diff --git a/arch/um/include/sysdep-i386/skas_ptrace.h b/arch/um/include/sysdep-i386/skas_ptrace.h
new file mode 100644
index 000000000000..e27b8a791773
--- /dev/null
+++ b/arch/um/include/sysdep-i386/skas_ptrace.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYSDEP_I386_SKAS_PTRACE_H
7#define __SYSDEP_I386_SKAS_PTRACE_H
8
9struct ptrace_faultinfo {
10 int is_write;
11 unsigned long addr;
12};
13
14struct ptrace_ldt {
15 int func;
16 void *ptr;
17 unsigned long bytecount;
18};
19
20#define PTRACE_LDT 54
21
22#endif
diff --git a/arch/um/include/sysdep-i386/syscalls.h b/arch/um/include/sysdep-i386/syscalls.h
index 5db81ec9087d..be0a3e3469eb 100644
--- a/arch/um/include/sysdep-i386/syscalls.h
+++ b/arch/um/include/sysdep-i386/syscalls.h
@@ -22,102 +22,3 @@ extern syscall_handler_t old_mmap_i386;
22extern long sys_mmap2(unsigned long addr, unsigned long len, 22extern long sys_mmap2(unsigned long addr, unsigned long len,
23 unsigned long prot, unsigned long flags, 23 unsigned long prot, unsigned long flags,
24 unsigned long fd, unsigned long pgoff); 24 unsigned long fd, unsigned long pgoff);
25
26/* On i386 they choose a meaningless naming.*/
27#define __NR_kexec_load __NR_sys_kexec_load
28
29#define ARCH_SYSCALLS \
30 [ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid, \
31 [ __NR_break ] = (syscall_handler_t *) sys_ni_syscall, \
32 [ __NR_oldstat ] = (syscall_handler_t *) sys_stat, \
33 [ __NR_umount ] = (syscall_handler_t *) sys_oldumount, \
34 [ __NR_stime ] = um_stime, \
35 [ __NR_oldfstat ] = (syscall_handler_t *) sys_fstat, \
36 [ __NR_stty ] = (syscall_handler_t *) sys_ni_syscall, \
37 [ __NR_gtty ] = (syscall_handler_t *) sys_ni_syscall, \
38 [ __NR_nice ] = (syscall_handler_t *) sys_nice, \
39 [ __NR_ftime ] = (syscall_handler_t *) sys_ni_syscall, \
40 [ __NR_prof ] = (syscall_handler_t *) sys_ni_syscall, \
41 [ __NR_signal ] = (syscall_handler_t *) sys_signal, \
42 [ __NR_lock ] = (syscall_handler_t *) sys_ni_syscall, \
43 [ __NR_mpx ] = (syscall_handler_t *) sys_ni_syscall, \
44 [ __NR_ulimit ] = (syscall_handler_t *) sys_ni_syscall, \
45 [ __NR_oldolduname ] = (syscall_handler_t *) sys_olduname, \
46 [ __NR_sigaction ] = (syscall_handler_t *) sys_sigaction, \
47 [ __NR_sgetmask ] = (syscall_handler_t *) sys_sgetmask, \
48 [ __NR_ssetmask ] = (syscall_handler_t *) sys_ssetmask, \
49 [ __NR_sigsuspend ] = (syscall_handler_t *) sys_sigsuspend, \
50 [ __NR_sigpending ] = (syscall_handler_t *) sys_sigpending, \
51 [ __NR_oldlstat ] = (syscall_handler_t *) sys_lstat, \
52 [ __NR_readdir ] = old_readdir, \
53 [ __NR_profil ] = (syscall_handler_t *) sys_ni_syscall, \
54 [ __NR_socketcall ] = (syscall_handler_t *) sys_socketcall, \
55 [ __NR_olduname ] = (syscall_handler_t *) sys_uname, \
56 [ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
57 [ __NR_idle ] = (syscall_handler_t *) sys_ni_syscall, \
58 [ __NR_ipc ] = (syscall_handler_t *) sys_ipc, \
59 [ __NR_sigreturn ] = (syscall_handler_t *) sys_sigreturn, \
60 [ __NR_sigprocmask ] = (syscall_handler_t *) sys_sigprocmask, \
61 [ __NR_bdflush ] = (syscall_handler_t *) sys_bdflush, \
62 [ __NR__llseek ] = (syscall_handler_t *) sys_llseek, \
63 [ __NR__newselect ] = (syscall_handler_t *) sys_select, \
64 [ __NR_vm86 ] = (syscall_handler_t *) sys_ni_syscall, \
65 [ __NR_mmap ] = (syscall_handler_t *) old_mmap_i386, \
66 [ __NR_ugetrlimit ] = (syscall_handler_t *) sys_getrlimit, \
67 [ __NR_mmap2 ] = (syscall_handler_t *) sys_mmap2, \
68 [ __NR_truncate64 ] = (syscall_handler_t *) sys_truncate64, \
69 [ __NR_ftruncate64 ] = (syscall_handler_t *) sys_ftruncate64, \
70 [ __NR_stat64 ] = (syscall_handler_t *) sys_stat64, \
71 [ __NR_lstat64 ] = (syscall_handler_t *) sys_lstat64, \
72 [ __NR_fstat64 ] = (syscall_handler_t *) sys_fstat64, \
73 [ __NR_fcntl64 ] = (syscall_handler_t *) sys_fcntl64, \
74 [ __NR_sendfile64 ] = (syscall_handler_t *) sys_sendfile64, \
75 [ __NR_statfs64 ] = (syscall_handler_t *) sys_statfs64, \
76 [ __NR_fstatfs64 ] = (syscall_handler_t *) sys_fstatfs64, \
77 [ __NR_fadvise64_64 ] = (syscall_handler_t *) sys_fadvise64_64, \
78 [ __NR_select ] = (syscall_handler_t *) old_select, \
79 [ __NR_vm86old ] = (syscall_handler_t *) sys_ni_syscall, \
80 [ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \
81 [ __NR_lchown32 ] = (syscall_handler_t *) sys_lchown, \
82 [ __NR_getuid32 ] = (syscall_handler_t *) sys_getuid, \
83 [ __NR_getgid32 ] = (syscall_handler_t *) sys_getgid, \
84 [ __NR_geteuid32 ] = (syscall_handler_t *) sys_geteuid, \
85 [ __NR_getegid32 ] = (syscall_handler_t *) sys_getegid, \
86 [ __NR_setreuid32 ] = (syscall_handler_t *) sys_setreuid, \
87 [ __NR_setregid32 ] = (syscall_handler_t *) sys_setregid, \
88 [ __NR_getgroups32 ] = (syscall_handler_t *) sys_getgroups, \
89 [ __NR_setgroups32 ] = (syscall_handler_t *) sys_setgroups, \
90 [ __NR_fchown32 ] = (syscall_handler_t *) sys_fchown, \
91 [ __NR_setresuid32 ] = (syscall_handler_t *) sys_setresuid, \
92 [ __NR_getresuid32 ] = (syscall_handler_t *) sys_getresuid, \
93 [ __NR_setresgid32 ] = (syscall_handler_t *) sys_setresgid, \
94 [ __NR_getresgid32 ] = (syscall_handler_t *) sys_getresgid, \
95 [ __NR_chown32 ] = (syscall_handler_t *) sys_chown, \
96 [ __NR_setuid32 ] = (syscall_handler_t *) sys_setuid, \
97 [ __NR_setgid32 ] = (syscall_handler_t *) sys_setgid, \
98 [ __NR_setfsuid32 ] = (syscall_handler_t *) sys_setfsuid, \
99 [ __NR_setfsgid32 ] = (syscall_handler_t *) sys_setfsgid, \
100 [ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \
101 [ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \
102 [ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \
103 [ 222 ] = (syscall_handler_t *) sys_ni_syscall, \
104 [ 223 ] = (syscall_handler_t *) sys_ni_syscall, \
105 [ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
106 [ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
107 [ 251 ] = (syscall_handler_t *) sys_ni_syscall, \
108 [ 285 ] = (syscall_handler_t *) sys_ni_syscall,
109
110/* 222 doesn't yet have a name in include/asm-i386/unistd.h */
111
112#define LAST_ARCH_SYSCALL 285
113
114/*
115 * Overrides for Emacs so that we follow Linus's tabbing style.
116 * Emacs will notice this stuff at the end of the file and automatically
117 * adjust the settings for this buffer only. This must remain at the end
118 * of the file.
119 * ---------------------------------------------------------------------------
120 * Local variables:
121 * c-file-style: "linux"
122 * End:
123 */
diff --git a/arch/um/include/sysdep-ia64/skas_ptrace.h b/arch/um/include/sysdep-ia64/skas_ptrace.h
new file mode 100644
index 000000000000..25a38e715702
--- /dev/null
+++ b/arch/um/include/sysdep-ia64/skas_ptrace.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYSDEP_IA64_SKAS_PTRACE_H
7#define __SYSDEP_IA64_SKAS_PTRACE_H
8
9struct ptrace_faultinfo {
10 int is_write;
11 unsigned long addr;
12};
13
14struct ptrace_ldt {
15 int func;
16 void *ptr;
17 unsigned long bytecount;
18};
19
20#define PTRACE_LDT 54
21
22#endif
diff --git a/arch/um/include/sysdep-ppc/skas_ptrace.h b/arch/um/include/sysdep-ppc/skas_ptrace.h
new file mode 100644
index 000000000000..d9fbbac10de0
--- /dev/null
+++ b/arch/um/include/sysdep-ppc/skas_ptrace.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYSDEP_PPC_SKAS_PTRACE_H
7#define __SYSDEP_PPC_SKAS_PTRACE_H
8
9struct ptrace_faultinfo {
10 int is_write;
11 unsigned long addr;
12};
13
14struct ptrace_ldt {
15 int func;
16 void *ptr;
17 unsigned long bytecount;
18};
19
20#define PTRACE_LDT 54
21
22#endif
diff --git a/arch/um/include/sysdep-x86_64/faultinfo.h b/arch/um/include/sysdep-x86_64/faultinfo.h
new file mode 100644
index 000000000000..cb917b0d5660
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/faultinfo.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
3 * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
4 * Licensed under the GPL
5 */
6
7#ifndef __FAULTINFO_X86_64_H
8#define __FAULTINFO_X86_64_H
9
10/* this structure contains the full arch-specific faultinfo
11 * from the traps.
12 * On i386, ptrace_faultinfo unfortunately doesn't provide
13 * all the info, since trap_no is missing.
14 * All common elements are defined at the same position in
15 * both structures, thus making it easy to copy the
16 * contents without knowledge about the structure elements.
17 */
18struct faultinfo {
19 int error_code; /* in ptrace_faultinfo misleadingly called is_write */
20 unsigned long cr2; /* in ptrace_faultinfo called addr */
21 int trap_no; /* missing in ptrace_faultinfo */
22};
23
24#define FAULT_WRITE(fi) ((fi).error_code & 2)
25#define FAULT_ADDRESS(fi) ((fi).cr2)
26
27#define PTRACE_FULL_FAULTINFO 1
28
29#endif
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
index 915c82daffbd..348e8fcd513f 100644
--- a/arch/um/include/sysdep-x86_64/ptrace.h
+++ b/arch/um/include/sysdep-x86_64/ptrace.h
@@ -9,6 +9,7 @@
9 9
10#include "uml-config.h" 10#include "uml-config.h"
11#include "user_constants.h" 11#include "user_constants.h"
12#include "sysdep/faultinfo.h"
12 13
13#define MAX_REG_OFFSET (UM_FRAME_SIZE) 14#define MAX_REG_OFFSET (UM_FRAME_SIZE)
14#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long)) 15#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long))
@@ -83,6 +84,7 @@ union uml_pt_regs {
83 long syscall; 84 long syscall;
84 unsigned long orig_rax; 85 unsigned long orig_rax;
85 void *sc; 86 void *sc;
87 struct faultinfo faultinfo;
86 } tt; 88 } tt;
87#endif 89#endif
88#ifdef UML_CONFIG_MODE_SKAS 90#ifdef UML_CONFIG_MODE_SKAS
@@ -90,9 +92,7 @@ union uml_pt_regs {
90 /* XXX */ 92 /* XXX */
91 unsigned long regs[27]; 93 unsigned long regs[27];
92 unsigned long fp[65]; 94 unsigned long fp[65];
93 unsigned long fault_addr; 95 struct faultinfo faultinfo;
94 unsigned long fault_type;
95 unsigned long trap_type;
96 long syscall; 96 long syscall;
97 int is_user; 97 int is_user;
98 } skas; 98 } skas;
@@ -241,14 +241,8 @@ struct syscall_args {
241 CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \ 241 CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
242 REGS_SEGV_IS_FIXABLE(&r->skas)) 242 REGS_SEGV_IS_FIXABLE(&r->skas))
243 243
244#define UPT_FAULT_ADDR(r) \ 244#define UPT_FAULTINFO(r) \
245 __CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas)) 245 CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo))
246
247#define UPT_FAULT_WRITE(r) \
248 CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
249
250#define UPT_TRAP(r) __CHOOSE_MODE(SC_TRAP_TYPE(UPT_SC(r)), REGS_TRAP(&r->skas))
251#define UPT_ERR(r) __CHOOSE_MODE(SC_FAULT_TYPE(UPT_SC(r)), REGS_ERR(&r->skas))
252 246
253#endif 247#endif
254 248
diff --git a/arch/um/include/sysdep-x86_64/sigcontext.h b/arch/um/include/sysdep-x86_64/sigcontext.h
index 1e38a54ff4cf..2a78260d15a0 100644
--- a/arch/um/include/sysdep-x86_64/sigcontext.h
+++ b/arch/um/include/sysdep-x86_64/sigcontext.h
@@ -17,11 +17,12 @@
17#define SC_FAULT_ADDR(sc) SC_CR2(sc) 17#define SC_FAULT_ADDR(sc) SC_CR2(sc)
18#define SC_FAULT_TYPE(sc) SC_ERR(sc) 18#define SC_FAULT_TYPE(sc) SC_ERR(sc)
19 19
20#define FAULT_WRITE(err) ((err) & 2) 20#define GET_FAULTINFO_FROM_SC(fi,sc) \
21 21 { \
22#define SC_FAULT_WRITE(sc) FAULT_WRITE(SC_FAULT_TYPE(sc)) 22 (fi).cr2 = SC_CR2(sc); \
23 23 (fi).error_code = SC_ERR(sc); \
24#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc) 24 (fi).trap_no = SC_TRAPNO(sc); \
25 }
25 26
26/* ptrace expects that, at the start of a system call, %eax contains 27/* ptrace expects that, at the start of a system call, %eax contains
27 * -ENOSYS, so this makes it so. 28 * -ENOSYS, so this makes it so.
@@ -29,8 +30,8 @@
29 30
30#define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0) 31#define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0)
31 32
32#define SEGV_IS_FIXABLE(trap) ((trap) == 14) 33/* This is Page Fault */
33#define SC_SEGV_IS_FIXABLE(sc) SEGV_IS_FIXABLE(SC_TRAP_TYPE(sc)) 34#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
34 35
35extern unsigned long *sc_sigmask(void *sc_ptr); 36extern unsigned long *sc_sigmask(void *sc_ptr);
36 37
diff --git a/arch/um/include/sysdep-x86_64/signal.h b/arch/um/include/sysdep-x86_64/signal.h
index e5e52756fab4..6142897af3d1 100644
--- a/arch/um/include/sysdep-x86_64/signal.h
+++ b/arch/um/include/sysdep-x86_64/signal.h
@@ -6,6 +6,8 @@
6#ifndef __X86_64_SIGNAL_H_ 6#ifndef __X86_64_SIGNAL_H_
7#define __X86_64_SIGNAL_H_ 7#define __X86_64_SIGNAL_H_
8 8
9#define ARCH_SIGHDLR_PARAM int sig
10
9#define ARCH_GET_SIGCONTEXT(sc, sig_addr) \ 11#define ARCH_GET_SIGCONTEXT(sc, sig_addr) \
10 do { \ 12 do { \
11 struct ucontext *__uc; \ 13 struct ucontext *__uc; \
diff --git a/arch/um/include/sysdep-x86_64/skas_ptrace.h b/arch/um/include/sysdep-x86_64/skas_ptrace.h
new file mode 100644
index 000000000000..95db4be786e4
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/skas_ptrace.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYSDEP_X86_64_SKAS_PTRACE_H
7#define __SYSDEP_X86_64_SKAS_PTRACE_H
8
9struct ptrace_faultinfo {
10 int is_write;
11 unsigned long addr;
12};
13
14struct ptrace_ldt {
15 int func;
16 void *ptr;
17 unsigned long bytecount;
18};
19
20#define PTRACE_LDT 54
21
22#endif
diff --git a/arch/um/include/sysdep-x86_64/syscalls.h b/arch/um/include/sysdep-x86_64/syscalls.h
index b187a4157ff3..67923cca5691 100644
--- a/arch/um/include/sysdep-x86_64/syscalls.h
+++ b/arch/um/include/sysdep-x86_64/syscalls.h
@@ -26,66 +26,9 @@ extern syscall_handler_t *ia32_sys_call_table[];
26extern long old_mmap(unsigned long addr, unsigned long len, 26extern long old_mmap(unsigned long addr, unsigned long len,
27 unsigned long prot, unsigned long flags, 27 unsigned long prot, unsigned long flags,
28 unsigned long fd, unsigned long pgoff); 28 unsigned long fd, unsigned long pgoff);
29extern syscall_handler_t wrap_sys_shmat;
30extern syscall_handler_t sys_modify_ldt; 29extern syscall_handler_t sys_modify_ldt;
31extern syscall_handler_t sys_arch_prctl; 30extern syscall_handler_t sys_arch_prctl;
32 31
33#define ARCH_SYSCALLS \ 32#define NR_syscalls (__NR_syscall_max + 1)
34 [ __NR_mmap ] = (syscall_handler_t *) old_mmap, \
35 [ __NR_select ] = (syscall_handler_t *) sys_select, \
36 [ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \
37 [ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \
38 [ __NR_shmget ] = (syscall_handler_t *) sys_shmget, \
39 [ __NR_shmat ] = (syscall_handler_t *) wrap_sys_shmat, \
40 [ __NR_shmctl ] = (syscall_handler_t *) sys_shmctl, \
41 [ __NR_semop ] = (syscall_handler_t *) sys_semop, \
42 [ __NR_semget ] = (syscall_handler_t *) sys_semget, \
43 [ __NR_semctl ] = (syscall_handler_t *) sys_semctl, \
44 [ __NR_shmdt ] = (syscall_handler_t *) sys_shmdt, \
45 [ __NR_msgget ] = (syscall_handler_t *) sys_msgget, \
46 [ __NR_msgsnd ] = (syscall_handler_t *) sys_msgsnd, \
47 [ __NR_msgrcv ] = (syscall_handler_t *) sys_msgrcv, \
48 [ __NR_msgctl ] = (syscall_handler_t *) sys_msgctl, \
49 [ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \
50 [ __NR_tuxcall ] = (syscall_handler_t *) sys_ni_syscall, \
51 [ __NR_security ] = (syscall_handler_t *) sys_ni_syscall, \
52 [ __NR_epoll_ctl_old ] = (syscall_handler_t *) sys_ni_syscall, \
53 [ __NR_epoll_wait_old ] = (syscall_handler_t *) sys_ni_syscall, \
54 [ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \
55 [ __NR_arch_prctl ] = (syscall_handler_t *) sys_arch_prctl, \
56 [ __NR_socket ] = (syscall_handler_t *) sys_socket, \
57 [ __NR_connect ] = (syscall_handler_t *) sys_connect, \
58 [ __NR_accept ] = (syscall_handler_t *) sys_accept, \
59 [ __NR_recvfrom ] = (syscall_handler_t *) sys_recvfrom, \
60 [ __NR_recvmsg ] = (syscall_handler_t *) sys_recvmsg, \
61 [ __NR_sendmsg ] = (syscall_handler_t *) sys_sendmsg, \
62 [ __NR_bind ] = (syscall_handler_t *) sys_bind, \
63 [ __NR_listen ] = (syscall_handler_t *) sys_listen, \
64 [ __NR_getsockname ] = (syscall_handler_t *) sys_getsockname, \
65 [ __NR_getpeername ] = (syscall_handler_t *) sys_getpeername, \
66 [ __NR_socketpair ] = (syscall_handler_t *) sys_socketpair, \
67 [ __NR_sendto ] = (syscall_handler_t *) sys_sendto, \
68 [ __NR_shutdown ] = (syscall_handler_t *) sys_shutdown, \
69 [ __NR_setsockopt ] = (syscall_handler_t *) sys_setsockopt, \
70 [ __NR_getsockopt ] = (syscall_handler_t *) sys_getsockopt, \
71 [ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
72 [ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
73 [ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
74 [ __NR_semtimedop ] = (syscall_handler_t *) sys_semtimedop, \
75 [ 251 ] = (syscall_handler_t *) sys_ni_syscall,
76
77#define LAST_ARCH_SYSCALL 251
78#define NR_syscalls 1024
79 33
80#endif 34#endif
81
82/*
83 * Overrides for Emacs so that we follow Linus's tabbing style.
84 * Emacs will notice this stuff at the end of the file and automatically
85 * adjust the settings for this buffer only. This must remain at the end
86 * of the file.
87 * ---------------------------------------------------------------------------
88 * Local variables:
89 * c-file-style: "linux"
90 * End:
91 */
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index 103cd320386c..b8c5b8a95250 100644
--- a/arch/um/include/user_util.h
+++ b/arch/um/include/user_util.h
@@ -67,7 +67,6 @@ extern void *um_kmalloc(int size);
67extern int switcheroo(int fd, int prot, void *from, void *to, int size); 67extern int switcheroo(int fd, int prot, void *from, void *to, int size);
68extern void setup_machinename(char *machine_out); 68extern void setup_machinename(char *machine_out);
69extern void setup_hostinfo(void); 69extern void setup_hostinfo(void);
70extern void add_arg(char *arg);
71extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); 70extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
72extern void init_new_thread_signals(int altstack); 71extern void init_new_thread_signals(int altstack);
73extern void do_exec(int old_pid, int new_pid); 72extern void do_exec(int old_pid, int new_pid);
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index dc796c1bf39e..9736ca27c5f0 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -4,13 +4,13 @@
4# 4#
5 5
6extra-y := vmlinux.lds 6extra-y := vmlinux.lds
7clean-files := vmlinux.lds.S config.tmp 7clean-files :=
8 8
9obj-y = checksum.o config.o exec_kern.o exitcode.o \ 9obj-y = config.o exec_kern.o exitcode.o \
10 helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \ 10 helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \
11 physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \ 11 physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \
12 sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \ 12 sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \
13 syscall_kern.o sysrq.o sys_call_table.o tempfile.o time.o time_kern.o \ 13 syscall_kern.o sysrq.o tempfile.o time.o time_kern.o \
14 tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \ 14 tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \
15 user_util.o 15 user_util.o
16 16
@@ -23,18 +23,14 @@ obj-$(CONFIG_SYSCALL_DEBUG) += syscall_user.o
23obj-$(CONFIG_MODE_TT) += tt/ 23obj-$(CONFIG_MODE_TT) += tt/
24obj-$(CONFIG_MODE_SKAS) += skas/ 24obj-$(CONFIG_MODE_SKAS) += skas/
25 25
26# This needs be compiled with frame pointers regardless of how the rest of the
27# kernel is built.
28CFLAGS_frame.o := -fno-omit-frame-pointer
29
30user-objs-$(CONFIG_TTY_LOG) += tty_log.o 26user-objs-$(CONFIG_TTY_LOG) += tty_log.o
31 27
32USER_OBJS := $(user-objs-y) config.o helper.o main.o process.o tempfile.o \ 28USER_OBJS := $(user-objs-y) config.o helper.o main.o process.o tempfile.o \
33 time.o tty_log.o umid.o user_util.o frame.o 29 time.o tty_log.o umid.o user_util.o
34 30
35include arch/um/scripts/Makefile.rules 31include arch/um/scripts/Makefile.rules
36 32
37targets += config.c 33targets := config.c config.tmp
38 34
39# Be careful with the below Sed code - sed is pitfall-rich! 35# Be careful with the below Sed code - sed is pitfall-rich!
40# We use sed to lower build requirements, for "embedded" builders for instance. 36# We use sed to lower build requirements, for "embedded" builders for instance.
@@ -53,6 +49,7 @@ quiet_cmd_quote2 = QUOTE $@
53 cmd_quote2 = sed -e '/CONFIG/{' \ 49 cmd_quote2 = sed -e '/CONFIG/{' \
54 -e 's/"CONFIG"\;/""/' \ 50 -e 's/"CONFIG"\;/""/' \
55 -e 'r $(obj)/config.tmp' \ 51 -e 'r $(obj)/config.tmp' \
56 -e 'a""\;' \ 52 -e 'a \' \
53 -e '""\;' \
57 -e '}' \ 54 -e '}' \
58 $< > $@ 55 $< > $@
diff --git a/arch/um/kernel/checksum.c b/arch/um/kernel/checksum.c
index e69b2be951d1..e69de29bb2d1 100644
--- a/arch/um/kernel/checksum.c
+++ b/arch/um/kernel/checksum.c
@@ -1,36 +0,0 @@
1#include "asm/uaccess.h"
2#include "linux/errno.h"
3#include "linux/module.h"
4
5unsigned int arch_csum_partial(const unsigned char *buff, int len, int sum);
6
7unsigned int csum_partial(unsigned char *buff, int len, int sum)
8{
9 return arch_csum_partial(buff, len, sum);
10}
11
12EXPORT_SYMBOL(csum_partial);
13
14unsigned int csum_partial_copy_to(const unsigned char *src,
15 unsigned char __user *dst, int len, int sum,
16 int *err_ptr)
17{
18 if(copy_to_user(dst, src, len)){
19 *err_ptr = -EFAULT;
20 return(-1);
21 }
22
23 return(arch_csum_partial(src, len, sum));
24}
25
26unsigned int csum_partial_copy_from(const unsigned char __user *src,
27 unsigned char *dst, int len, int sum,
28 int *err_ptr)
29{
30 if(copy_from_user(dst, src, len)){
31 *err_ptr = -EFAULT;
32 return(-1);
33 }
34
35 return arch_csum_partial(dst, len, sum);
36}
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index d71e8f00810f..d44fb5282547 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -163,7 +163,6 @@ void __init init_IRQ(void)
163 irq_desc[i].handler = &SIGIO_irq_type; 163 irq_desc[i].handler = &SIGIO_irq_type;
164 enable_irq(i); 164 enable_irq(i);
165 } 165 }
166 init_irq_signals(0);
167} 166}
168 167
169/* 168/*
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index b41d3397d07b..78d69dc74b26 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -10,7 +10,6 @@
10#include "linux/spinlock.h" 10#include "linux/spinlock.h"
11#include "linux/highmem.h" 11#include "linux/highmem.h"
12#include "asm/current.h" 12#include "asm/current.h"
13#include "asm/delay.h"
14#include "asm/processor.h" 13#include "asm/processor.h"
15#include "asm/unistd.h" 14#include "asm/unistd.h"
16#include "asm/pgalloc.h" 15#include "asm/pgalloc.h"
@@ -28,8 +27,6 @@ EXPORT_SYMBOL(uml_physmem);
28EXPORT_SYMBOL(set_signals); 27EXPORT_SYMBOL(set_signals);
29EXPORT_SYMBOL(get_signals); 28EXPORT_SYMBOL(get_signals);
30EXPORT_SYMBOL(kernel_thread); 29EXPORT_SYMBOL(kernel_thread);
31EXPORT_SYMBOL(__const_udelay);
32EXPORT_SYMBOL(__udelay);
33EXPORT_SYMBOL(sys_waitpid); 30EXPORT_SYMBOL(sys_waitpid);
34EXPORT_SYMBOL(task_size); 31EXPORT_SYMBOL(task_size);
35EXPORT_SYMBOL(flush_tlb_range); 32EXPORT_SYMBOL(flush_tlb_range);
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index f76a2692adca..51f8e5a8ac6a 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -65,8 +65,6 @@ void init_new_thread_signals(int altstack)
65 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 65 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
66 set_handler(SIGBUS, (__sighandler_t) sig_handler, flags, 66 set_handler(SIGBUS, (__sighandler_t) sig_handler, flags,
67 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 67 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
68 set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags,
69 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
70 set_handler(SIGUSR2, (__sighandler_t) sig_handler, 68 set_handler(SIGUSR2, (__sighandler_t) sig_handler,
71 flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 69 flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
72 signal(SIGHUP, SIG_IGN); 70 signal(SIGHUP, SIG_IGN);
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index 1d719d5b4bb9..c1adf7ba3fd1 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -115,16 +115,6 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
115 return(pid); 115 return(pid);
116} 116}
117 117
118void switch_mm(struct mm_struct *prev, struct mm_struct *next,
119 struct task_struct *tsk)
120{
121 int cpu = smp_processor_id();
122
123 if (prev != next)
124 cpu_clear(cpu, prev->cpu_vm_mask);
125 cpu_set(cpu, next->cpu_vm_mask);
126}
127
128void set_current(void *t) 118void set_current(void *t)
129{ 119{
130 struct task_struct *task = t; 120 struct task_struct *task = t;
@@ -152,7 +142,6 @@ void release_thread(struct task_struct *task)
152 142
153void exit_thread(void) 143void exit_thread(void)
154{ 144{
155 CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
156 unprotect_stack((unsigned long) current_thread); 145 unprotect_stack((unsigned long) current_thread);
157} 146}
158 147
@@ -161,10 +150,6 @@ void *get_current(void)
161 return(current); 150 return(current);
162} 151}
163 152
164void prepare_to_copy(struct task_struct *tsk)
165{
166}
167
168int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, 153int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
169 unsigned long stack_top, struct task_struct * p, 154 unsigned long stack_top, struct task_struct * p,
170 struct pt_regs *regs) 155 struct pt_regs *regs)
@@ -480,12 +465,21 @@ int singlestepping(void * t)
480 return 2; 465 return 2;
481} 466}
482 467
468/*
469 * Only x86 and x86_64 have an arch_align_stack().
470 * All other arches have "#define arch_align_stack(x) (x)"
471 * in their asm/system.h
472 * As this is included in UML from asm-um/system-generic.h,
473 * we can use it to behave as the subarch does.
474 */
475#ifndef arch_align_stack
483unsigned long arch_align_stack(unsigned long sp) 476unsigned long arch_align_stack(unsigned long sp)
484{ 477{
485 if (randomize_va_space) 478 if (randomize_va_space)
486 sp -= get_random_int() % 8192; 479 sp -= get_random_int() % 8192;
487 return sp & ~0xf; 480 return sp & ~0xf;
488} 481}
482#endif
489 483
490 484
491/* 485/*
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 3a99ee6d94eb..2b75d8d9ba73 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -19,15 +19,30 @@
19#include "skas_ptrace.h" 19#include "skas_ptrace.h"
20#include "sysdep/ptrace.h" 20#include "sysdep/ptrace.h"
21 21
22static inline void set_singlestepping(struct task_struct *child, int on)
23{
24 if (on)
25 child->ptrace |= PT_DTRACE;
26 else
27 child->ptrace &= ~PT_DTRACE;
28 child->thread.singlestep_syscall = 0;
29
30#ifdef SUBARCH_SET_SINGLESTEPPING
31 SUBARCH_SET_SINGLESTEPPING(child, on)
32#endif
33 }
34
22/* 35/*
23 * Called by kernel/ptrace.c when detaching.. 36 * Called by kernel/ptrace.c when detaching..
24 */ 37 */
25void ptrace_disable(struct task_struct *child) 38void ptrace_disable(struct task_struct *child)
26{ 39{
27 child->ptrace &= ~PT_DTRACE; 40 set_singlestepping(child,0);
28 child->thread.singlestep_syscall = 0;
29} 41}
30 42
43extern int peek_user(struct task_struct * child, long addr, long data);
44extern int poke_user(struct task_struct * child, long addr, long data);
45
31long sys_ptrace(long request, long pid, long addr, long data) 46long sys_ptrace(long request, long pid, long addr, long data)
32{ 47{
33 struct task_struct *child; 48 struct task_struct *child;
@@ -67,6 +82,10 @@ long sys_ptrace(long request, long pid, long addr, long data)
67 goto out_tsk; 82 goto out_tsk;
68 } 83 }
69 84
85#ifdef SUBACH_PTRACE_SPECIAL
86 SUBARCH_PTRACE_SPECIAL(child,request,addr,data)
87#endif
88
70 ret = ptrace_check_attach(child, request == PTRACE_KILL); 89 ret = ptrace_check_attach(child, request == PTRACE_KILL);
71 if (ret < 0) 90 if (ret < 0)
72 goto out_tsk; 91 goto out_tsk;
@@ -87,26 +106,9 @@ long sys_ptrace(long request, long pid, long addr, long data)
87 } 106 }
88 107
89 /* read the word at location addr in the USER area. */ 108 /* read the word at location addr in the USER area. */
90 case PTRACE_PEEKUSR: { 109 case PTRACE_PEEKUSR:
91 unsigned long tmp; 110 ret = peek_user(child, addr, data);
92 111 break;
93 ret = -EIO;
94 if ((addr & 3) || addr < 0)
95 break;
96
97 tmp = 0; /* Default return condition */
98 if(addr < MAX_REG_OFFSET){
99 tmp = getreg(child, addr);
100 }
101 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
102 (addr <= offsetof(struct user, u_debugreg[7]))){
103 addr -= offsetof(struct user, u_debugreg[0]);
104 addr = addr >> 2;
105 tmp = child->thread.arch.debugregs[addr];
106 }
107 ret = put_user(tmp, (unsigned long __user *) data);
108 break;
109 }
110 112
111 /* when I and D space are separate, this will have to be fixed. */ 113 /* when I and D space are separate, this will have to be fixed. */
112 case PTRACE_POKETEXT: /* write the word at location addr. */ 114 case PTRACE_POKETEXT: /* write the word at location addr. */
@@ -119,35 +121,16 @@ long sys_ptrace(long request, long pid, long addr, long data)
119 break; 121 break;
120 122
121 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ 123 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
122 ret = -EIO; 124 ret = poke_user(child, addr, data);
123 if ((addr & 3) || addr < 0) 125 break;
124 break;
125
126 if (addr < MAX_REG_OFFSET) {
127 ret = putreg(child, addr, data);
128 break;
129 }
130#if 0 /* XXX x86_64 */
131 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
132 (addr <= offsetof(struct user, u_debugreg[7]))){
133 addr -= offsetof(struct user, u_debugreg[0]);
134 addr = addr >> 2;
135 if((addr == 4) || (addr == 5)) break;
136 child->thread.arch.debugregs[addr] = data;
137 ret = 0;
138 }
139#endif
140
141 break;
142 126
143 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ 127 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
144 case PTRACE_CONT: { /* restart after signal. */ 128 case PTRACE_CONT: { /* restart after signal. */
145 ret = -EIO; 129 ret = -EIO;
146 if ((unsigned long) data > _NSIG) 130 if (!valid_signal(data))
147 break; 131 break;
148 132
149 child->ptrace &= ~PT_DTRACE; 133 set_singlestepping(child, 0);
150 child->thread.singlestep_syscall = 0;
151 if (request == PTRACE_SYSCALL) { 134 if (request == PTRACE_SYSCALL) {
152 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 135 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
153 } 136 }
@@ -170,8 +153,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
170 if (child->exit_state == EXIT_ZOMBIE) /* already dead */ 153 if (child->exit_state == EXIT_ZOMBIE) /* already dead */
171 break; 154 break;
172 155
173 child->ptrace &= ~PT_DTRACE; 156 set_singlestepping(child, 0);
174 child->thread.singlestep_syscall = 0;
175 child->exit_code = SIGKILL; 157 child->exit_code = SIGKILL;
176 wake_up_process(child); 158 wake_up_process(child);
177 break; 159 break;
@@ -179,11 +161,10 @@ long sys_ptrace(long request, long pid, long addr, long data)
179 161
180 case PTRACE_SINGLESTEP: { /* set the trap flag. */ 162 case PTRACE_SINGLESTEP: { /* set the trap flag. */
181 ret = -EIO; 163 ret = -EIO;
182 if ((unsigned long) data > _NSIG) 164 if (!valid_signal(data))
183 break; 165 break;
184 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 166 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
185 child->ptrace |= PT_DTRACE; 167 set_singlestepping(child, 1);
186 child->thread.singlestep_syscall = 0;
187 child->exit_code = data; 168 child->exit_code = data;
188 /* give it a chance to run. */ 169 /* give it a chance to run. */
189 wake_up_process(child); 170 wake_up_process(child);
@@ -250,23 +231,19 @@ long sys_ptrace(long request, long pid, long addr, long data)
250 break; 231 break;
251#endif 232#endif
252 case PTRACE_FAULTINFO: { 233 case PTRACE_FAULTINFO: {
253 struct ptrace_faultinfo fault; 234 /* Take the info from thread->arch->faultinfo,
254 235 * but transfer max. sizeof(struct ptrace_faultinfo).
255 fault = ((struct ptrace_faultinfo) 236 * On i386, ptrace_faultinfo is smaller!
256 { .is_write = child->thread.err, 237 */
257 .addr = child->thread.cr2 }); 238 ret = copy_to_user((unsigned long __user *) data,
258 ret = copy_to_user((unsigned long __user *) data, &fault, 239 &child->thread.arch.faultinfo,
259 sizeof(fault)); 240 sizeof(struct ptrace_faultinfo));
260 if(ret) 241 if(ret)
261 break; 242 break;
262 break; 243 break;
263 } 244 }
264 case PTRACE_SIGPENDING:
265 ret = copy_to_user((unsigned long __user *) data,
266 &child->pending.signal,
267 sizeof(child->pending.signal));
268 break;
269 245
246#ifdef PTRACE_LDT
270 case PTRACE_LDT: { 247 case PTRACE_LDT: {
271 struct ptrace_ldt ldt; 248 struct ptrace_ldt ldt;
272 249
@@ -282,6 +259,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
282 ret = -EIO; 259 ret = -EIO;
283 break; 260 break;
284 } 261 }
262#endif
285#ifdef CONFIG_PROC_MM 263#ifdef CONFIG_PROC_MM
286 case PTRACE_SWITCH_MM: { 264 case PTRACE_SWITCH_MM: {
287 struct mm_struct *old = child->mm; 265 struct mm_struct *old = child->mm;
@@ -337,15 +315,18 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
337 315
338 if (unlikely(current->audit_context)) { 316 if (unlikely(current->audit_context)) {
339 if (!entryexit) 317 if (!entryexit)
340 audit_syscall_entry(current, 318 audit_syscall_entry(current,
341 UPT_SYSCALL_NR(&regs->regs), 319 HOST_AUDIT_ARCH,
342 UPT_SYSCALL_ARG1(&regs->regs), 320 UPT_SYSCALL_NR(regs),
343 UPT_SYSCALL_ARG2(&regs->regs), 321 UPT_SYSCALL_ARG1(regs),
344 UPT_SYSCALL_ARG3(&regs->regs), 322 UPT_SYSCALL_ARG2(regs),
345 UPT_SYSCALL_ARG4(&regs->regs)); 323 UPT_SYSCALL_ARG3(regs),
346 else 324 UPT_SYSCALL_ARG4(regs));
347 audit_syscall_exit(current, 325 else {
348 UPT_SYSCALL_RET(&regs->regs)); 326 int res = UPT_SYSCALL_RET(regs);
327 audit_syscall_exit(current, AUDITSC_RESULT(res),
328 res);
329 }
349 } 330 }
350 331
351 /* Fake a debug trap */ 332 /* Fake a debug trap */
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
index 668df13d8c9d..e89218958f38 100644
--- a/arch/um/kernel/sigio_user.c
+++ b/arch/um/kernel/sigio_user.c
@@ -182,6 +182,7 @@ static int write_sigio_thread(void *unused)
182 int i, n, respond_fd; 182 int i, n, respond_fd;
183 char c; 183 char c;
184 184
185 signal(SIGWINCH, SIG_IGN);
185 fds = &current_poll; 186 fds = &current_poll;
186 while(1){ 187 while(1){
187 n = poll(fds->poll, fds->used, -1); 188 n = poll(fds->poll, fds->used, -1);
diff --git a/arch/um/kernel/skas/include/mode_kern-skas.h b/arch/um/kernel/skas/include/mode_kern-skas.h
index 94c564962378..e48490028111 100644
--- a/arch/um/kernel/skas/include/mode_kern-skas.h
+++ b/arch/um/kernel/skas/include/mode_kern-skas.h
@@ -18,7 +18,6 @@ extern int copy_thread_skas(int nr, unsigned long clone_flags,
18 unsigned long sp, unsigned long stack_top, 18 unsigned long sp, unsigned long stack_top,
19 struct task_struct *p, struct pt_regs *regs); 19 struct task_struct *p, struct pt_regs *regs);
20extern void release_thread_skas(struct task_struct *task); 20extern void release_thread_skas(struct task_struct *task);
21extern void exit_thread_skas(void);
22extern void initial_thread_cb_skas(void (*proc)(void *), void *arg); 21extern void initial_thread_cb_skas(void (*proc)(void *), void *arg);
23extern void init_idle_skas(void); 22extern void init_idle_skas(void);
24extern void flush_tlb_kernel_range_skas(unsigned long start, 23extern void flush_tlb_kernel_range_skas(unsigned long start,
diff --git a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h
index f0702c2c7204..96b51dba3471 100644
--- a/arch/um/kernel/skas/include/skas.h
+++ b/arch/um/kernel/skas/include/skas.h
@@ -27,9 +27,10 @@ extern void map(int fd, unsigned long virt, unsigned long len, int r, int w,
27extern int unmap(int fd, void *addr, unsigned long len); 27extern int unmap(int fd, void *addr, unsigned long len);
28extern int protect(int fd, unsigned long addr, unsigned long len, 28extern int protect(int fd, unsigned long addr, unsigned long len,
29 int r, int w, int x); 29 int r, int w, int x);
30extern void user_signal(int sig, union uml_pt_regs *regs); 30extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
31extern int new_mm(int from); 31extern int new_mm(int from);
32extern void start_userspace(int cpu); 32extern void start_userspace(int cpu);
33extern void get_skas_faultinfo(int pid, struct faultinfo * fi);
33extern long execute_syscall_skas(void *r); 34extern long execute_syscall_skas(void *r);
34 35
35#endif 36#endif
diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h
index 11986c9b9ddf..cd6c280482cb 100644
--- a/arch/um/kernel/skas/include/uaccess-skas.h
+++ b/arch/um/kernel/skas/include/uaccess-skas.h
@@ -19,7 +19,7 @@
19 ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))) 19 ((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
20 20
21static inline int verify_area_skas(int type, const void * addr, 21static inline int verify_area_skas(int type, const void * addr,
22 unsigned long size) 22 unsigned long size)
23{ 23{
24 return(access_ok_skas(type, addr, size) ? 0 : -EFAULT); 24 return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
25} 25}
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index b4ffaaa81241..773cd2b525fc 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -4,6 +4,7 @@
4 */ 4 */
5 5
6#include <stdlib.h> 6#include <stdlib.h>
7#include <string.h>
7#include <unistd.h> 8#include <unistd.h>
8#include <errno.h> 9#include <errno.h>
9#include <signal.h> 10#include <signal.h>
@@ -27,27 +28,37 @@
27#include "chan_user.h" 28#include "chan_user.h"
28#include "signal_user.h" 29#include "signal_user.h"
29#include "registers.h" 30#include "registers.h"
31#include "process.h"
30 32
31int is_skas_winch(int pid, int fd, void *data) 33int is_skas_winch(int pid, int fd, void *data)
32{ 34{
33 if(pid != os_getpid()) 35 if(pid != os_getpgrp())
34 return(0); 36 return(0);
35 37
36 register_winch_irq(-1, fd, -1, data); 38 register_winch_irq(-1, fd, -1, data);
37 return(1); 39 return(1);
38} 40}
39 41
40static void handle_segv(int pid) 42void get_skas_faultinfo(int pid, struct faultinfo * fi)
41{ 43{
42 struct ptrace_faultinfo fault;
43 int err; 44 int err;
44 45
45 err = ptrace(PTRACE_FAULTINFO, pid, 0, &fault); 46 err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
46 if(err) 47 if(err)
47 panic("handle_segv - PTRACE_FAULTINFO failed, errno = %d\n", 48 panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
48 errno); 49 "errno = %d\n", errno);
50
51 /* Special handling for i386, which has different structs */
52 if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo))
53 memset((char *)fi + sizeof(struct ptrace_faultinfo), 0,
54 sizeof(struct faultinfo) -
55 sizeof(struct ptrace_faultinfo));
56}
49 57
50 segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL); 58static void handle_segv(int pid, union uml_pt_regs * regs)
59{
60 get_skas_faultinfo(pid, &regs->skas.faultinfo);
61 segv(regs->skas.faultinfo, 0, 1, NULL);
51} 62}
52 63
53/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/ 64/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/
@@ -163,7 +174,7 @@ void userspace(union uml_pt_regs *regs)
163 if(WIFSTOPPED(status)){ 174 if(WIFSTOPPED(status)){
164 switch(WSTOPSIG(status)){ 175 switch(WSTOPSIG(status)){
165 case SIGSEGV: 176 case SIGSEGV:
166 handle_segv(pid); 177 handle_segv(pid, regs);
167 break; 178 break;
168 case SIGTRAP + 0x80: 179 case SIGTRAP + 0x80:
169 handle_trap(pid, regs, local_using_sysemu); 180 handle_trap(pid, regs, local_using_sysemu);
@@ -177,7 +188,7 @@ void userspace(union uml_pt_regs *regs)
177 case SIGBUS: 188 case SIGBUS:
178 case SIGFPE: 189 case SIGFPE:
179 case SIGWINCH: 190 case SIGWINCH:
180 user_signal(WSTOPSIG(status), regs); 191 user_signal(WSTOPSIG(status), regs, pid);
181 break; 192 break;
182 default: 193 default:
183 printk("userspace - child stopped with signal " 194 printk("userspace - child stopped with signal "
@@ -190,6 +201,11 @@ void userspace(union uml_pt_regs *regs)
190 } 201 }
191 } 202 }
192} 203}
204#define INIT_JMP_NEW_THREAD 0
205#define INIT_JMP_REMOVE_SIGSTACK 1
206#define INIT_JMP_CALLBACK 2
207#define INIT_JMP_HALT 3
208#define INIT_JMP_REBOOT 4
193 209
194void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, 210void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
195 void (*handler)(int)) 211 void (*handler)(int))
@@ -225,7 +241,7 @@ void thread_wait(void *sw, void *fb)
225 *switch_buf = &buf; 241 *switch_buf = &buf;
226 fork_buf = fb; 242 fork_buf = fb;
227 if(sigsetjmp(buf, 1) == 0) 243 if(sigsetjmp(buf, 1) == 0)
228 siglongjmp(*fork_buf, 1); 244 siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK);
229} 245}
230 246
231void switch_threads(void *me, void *next) 247void switch_threads(void *me, void *next)
@@ -249,23 +265,31 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
249 sigjmp_buf **switch_buf = switch_buf_ptr; 265 sigjmp_buf **switch_buf = switch_buf_ptr;
250 int n; 266 int n;
251 267
268 set_handler(SIGWINCH, (__sighandler_t) sig_handler,
269 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
270 SIGVTALRM, -1);
271
252 *fork_buf_ptr = &initial_jmpbuf; 272 *fork_buf_ptr = &initial_jmpbuf;
253 n = sigsetjmp(initial_jmpbuf, 1); 273 n = sigsetjmp(initial_jmpbuf, 1);
254 if(n == 0) 274 switch(n){
255 new_thread_proc((void *) stack, new_thread_handler); 275 case INIT_JMP_NEW_THREAD:
256 else if(n == 1) 276 new_thread_proc((void *) stack, new_thread_handler);
257 remove_sigstack(); 277 break;
258 else if(n == 2){ 278 case INIT_JMP_REMOVE_SIGSTACK:
279 remove_sigstack();
280 break;
281 case INIT_JMP_CALLBACK:
259 (*cb_proc)(cb_arg); 282 (*cb_proc)(cb_arg);
260 siglongjmp(*cb_back, 1); 283 siglongjmp(*cb_back, 1);
261 } 284 break;
262 else if(n == 3){ 285 case INIT_JMP_HALT:
263 kmalloc_ok = 0; 286 kmalloc_ok = 0;
264 return(0); 287 return(0);
265 } 288 case INIT_JMP_REBOOT:
266 else if(n == 4){
267 kmalloc_ok = 0; 289 kmalloc_ok = 0;
268 return(1); 290 return(1);
291 default:
292 panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
269 } 293 }
270 siglongjmp(**switch_buf, 1); 294 siglongjmp(**switch_buf, 1);
271} 295}
@@ -290,7 +314,7 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
290 314
291 block_signals(); 315 block_signals();
292 if(sigsetjmp(here, 1) == 0) 316 if(sigsetjmp(here, 1) == 0)
293 siglongjmp(initial_jmpbuf, 2); 317 siglongjmp(initial_jmpbuf, INIT_JMP_CALLBACK);
294 unblock_signals(); 318 unblock_signals();
295 319
296 cb_proc = NULL; 320 cb_proc = NULL;
@@ -301,13 +325,13 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
301void halt_skas(void) 325void halt_skas(void)
302{ 326{
303 block_signals(); 327 block_signals();
304 siglongjmp(initial_jmpbuf, 3); 328 siglongjmp(initial_jmpbuf, INIT_JMP_HALT);
305} 329}
306 330
307void reboot_skas(void) 331void reboot_skas(void)
308{ 332{
309 block_signals(); 333 block_signals();
310 siglongjmp(initial_jmpbuf, 4); 334 siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT);
311} 335}
312 336
313void switch_mm_skas(int mm_fd) 337void switch_mm_skas(int mm_fd)
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index 5d096ea63b97..ab5d3271da0b 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -83,10 +83,6 @@ void release_thread_skas(struct task_struct *task)
83{ 83{
84} 84}
85 85
86void exit_thread_skas(void)
87{
88}
89
90void fork_handler(int sig) 86void fork_handler(int sig)
91{ 87{
92 change_sig(SIGUSR1, 1); 88 change_sig(SIGUSR1, 1);
diff --git a/arch/um/kernel/skas/trap_user.c b/arch/um/kernel/skas/trap_user.c
index 8e9b46d4702e..0dee1d95c806 100644
--- a/arch/um/kernel/skas/trap_user.c
+++ b/arch/um/kernel/skas/trap_user.c
@@ -5,12 +5,15 @@
5 5
6#include <signal.h> 6#include <signal.h>
7#include <errno.h> 7#include <errno.h>
8#include "sysdep/ptrace.h"
9#include "signal_user.h" 8#include "signal_user.h"
10#include "user_util.h" 9#include "user_util.h"
11#include "kern_util.h" 10#include "kern_util.h"
12#include "task.h" 11#include "task.h"
13#include "sigcontext.h" 12#include "sigcontext.h"
13#include "skas.h"
14#include "ptrace_user.h"
15#include "sysdep/ptrace.h"
16#include "sysdep/ptrace_user.h"
14 17
15void sig_handler_common_skas(int sig, void *sc_ptr) 18void sig_handler_common_skas(int sig, void *sc_ptr)
16{ 19{
@@ -31,9 +34,11 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
31 r = &TASK_REGS(get_current())->skas; 34 r = &TASK_REGS(get_current())->skas;
32 save_user = r->is_user; 35 save_user = r->is_user;
33 r->is_user = 0; 36 r->is_user = 0;
34 r->fault_addr = SC_FAULT_ADDR(sc); 37 if ( sig == SIGFPE || sig == SIGSEGV ||
35 r->fault_type = SC_FAULT_TYPE(sc); 38 sig == SIGBUS || sig == SIGILL ||
36 r->trap_type = SC_TRAP_TYPE(sc); 39 sig == SIGTRAP ) {
40 GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
41 }
37 42
38 change_sig(SIGUSR1, 1); 43 change_sig(SIGUSR1, 1);
39 info = &sig_info[sig]; 44 info = &sig_info[sig];
@@ -45,14 +50,17 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
45 r->is_user = save_user; 50 r->is_user = save_user;
46} 51}
47 52
48void user_signal(int sig, union uml_pt_regs *regs) 53extern int ptrace_faultinfo;
54
55void user_signal(int sig, union uml_pt_regs *regs, int pid)
49{ 56{
50 struct signal_info *info; 57 struct signal_info *info;
58 int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
59 (sig == SIGILL) || (sig == SIGTRAP));
51 60
52 regs->skas.is_user = 1; 61 regs->skas.is_user = 1;
53 regs->skas.fault_addr = 0; 62 if (segv)
54 regs->skas.fault_type = 0; 63 get_skas_faultinfo(pid, &regs->skas.faultinfo);
55 regs->skas.trap_type = 0;
56 info = &sig_info[sig]; 64 info = &sig_info[sig];
57 (*info->handler)(sig, regs); 65 (*info->handler)(sig, regs);
58 66
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index 7575ec489b63..75195281081e 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -3,6 +3,7 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/compiler.h"
6#include "linux/stddef.h" 7#include "linux/stddef.h"
7#include "linux/kernel.h" 8#include "linux/kernel.h"
8#include "linux/string.h" 9#include "linux/string.h"
@@ -28,9 +29,12 @@ static unsigned long maybe_map(unsigned long virt, int is_write)
28 if(IS_ERR(phys) || (is_write && !pte_write(pte))){ 29 if(IS_ERR(phys) || (is_write && !pte_write(pte))){
29 err = handle_page_fault(virt, 0, is_write, 1, &dummy_code); 30 err = handle_page_fault(virt, 0, is_write, 1, &dummy_code);
30 if(err) 31 if(err)
31 return(0); 32 return(-1UL);
32 phys = um_virt_to_phys(current, virt, NULL); 33 phys = um_virt_to_phys(current, virt, NULL);
33 } 34 }
35 if(IS_ERR(phys))
36 phys = (void *) -1;
37
34 return((unsigned long) phys); 38 return((unsigned long) phys);
35} 39}
36 40
@@ -41,7 +45,7 @@ static int do_op(unsigned long addr, int len, int is_write,
41 int n; 45 int n;
42 46
43 addr = maybe_map(addr, is_write); 47 addr = maybe_map(addr, is_write);
44 if(addr == -1) 48 if(addr == -1UL)
45 return(-1); 49 return(-1);
46 50
47 page = phys_to_page(addr); 51 page = phys_to_page(addr);
@@ -61,8 +65,7 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr)
61 void *arg; 65 void *arg;
62 int *res; 66 int *res;
63 67
64 /* Some old gccs recognize __va_copy, but not va_copy */ 68 va_copy(args, *(va_list *)arg_ptr);
65 __va_copy(args, *(va_list *)arg_ptr);
66 addr = va_arg(args, unsigned long); 69 addr = va_arg(args, unsigned long);
67 len = va_arg(args, int); 70 len = va_arg(args, int);
68 is_write = va_arg(args, int); 71 is_write = va_arg(args, int);
diff --git a/arch/um/kernel/skas/util/Makefile b/arch/um/kernel/skas/util/Makefile
index 17f5909d60f7..f7b7eba83340 100644
--- a/arch/um/kernel/skas/util/Makefile
+++ b/arch/um/kernel/skas/util/Makefile
@@ -2,3 +2,4 @@ hostprogs-y := mk_ptregs
2always := $(hostprogs-y) 2always := $(hostprogs-y)
3 3
4mk_ptregs-objs := mk_ptregs-$(SUBARCH).o 4mk_ptregs-objs := mk_ptregs-$(SUBARCH).o
5HOSTCFLAGS_mk_ptregs-$(SUBARCH).o := -I$(objtree)/arch/um
diff --git a/arch/um/kernel/skas/util/mk_ptregs-i386.c b/arch/um/kernel/skas/util/mk_ptregs-i386.c
index 0788dd05bcac..1f96e1eeb8a7 100644
--- a/arch/um/kernel/skas/util/mk_ptregs-i386.c
+++ b/arch/um/kernel/skas/util/mk_ptregs-i386.c
@@ -1,8 +1,7 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <asm/ptrace.h> 2#include <user-offsets.h>
3#include <asm/user.h>
4 3
5#define PRINT_REG(name, val) printf("#define HOST_%s %d\n", (name), (val)) 4#define SHOW(name) printf("#define %s %d\n", #name, name)
6 5
7int main(int argc, char **argv) 6int main(int argc, char **argv)
8{ 7{
@@ -12,28 +11,27 @@ int main(int argc, char **argv)
12 printf("#ifndef __SKAS_PT_REGS_\n"); 11 printf("#ifndef __SKAS_PT_REGS_\n");
13 printf("#define __SKAS_PT_REGS_\n"); 12 printf("#define __SKAS_PT_REGS_\n");
14 printf("\n"); 13 printf("\n");
15 printf("#define HOST_FRAME_SIZE %d\n", FRAME_SIZE); 14 SHOW(HOST_FRAME_SIZE);
16 printf("#define HOST_FP_SIZE %d\n", 15 SHOW(HOST_FP_SIZE);
17 sizeof(struct user_i387_struct) / sizeof(unsigned long)); 16 SHOW(HOST_XFP_SIZE);
18 printf("#define HOST_XFP_SIZE %d\n", 17
19 sizeof(struct user_fxsr_struct) / sizeof(unsigned long)); 18 SHOW(HOST_IP);
19 SHOW(HOST_SP);
20 SHOW(HOST_EFLAGS);
21 SHOW(HOST_EAX);
22 SHOW(HOST_EBX);
23 SHOW(HOST_ECX);
24 SHOW(HOST_EDX);
25 SHOW(HOST_ESI);
26 SHOW(HOST_EDI);
27 SHOW(HOST_EBP);
28 SHOW(HOST_CS);
29 SHOW(HOST_SS);
30 SHOW(HOST_DS);
31 SHOW(HOST_FS);
32 SHOW(HOST_ES);
33 SHOW(HOST_GS);
20 34
21 PRINT_REG("IP", EIP);
22 PRINT_REG("SP", UESP);
23 PRINT_REG("EFLAGS", EFL);
24 PRINT_REG("EAX", EAX);
25 PRINT_REG("EBX", EBX);
26 PRINT_REG("ECX", ECX);
27 PRINT_REG("EDX", EDX);
28 PRINT_REG("ESI", ESI);
29 PRINT_REG("EDI", EDI);
30 PRINT_REG("EBP", EBP);
31 PRINT_REG("CS", CS);
32 PRINT_REG("SS", SS);
33 PRINT_REG("DS", DS);
34 PRINT_REG("FS", FS);
35 PRINT_REG("ES", ES);
36 PRINT_REG("GS", GS);
37 printf("\n"); 35 printf("\n");
38 printf("#endif\n"); 36 printf("#endif\n");
39 return(0); 37 return(0);
diff --git a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
index 67aee92a70ef..5fccbfe35f78 100644
--- a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
+++ b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
@@ -5,11 +5,10 @@
5 */ 5 */
6 6
7#include <stdio.h> 7#include <stdio.h>
8#define __FRAME_OFFSETS 8#include <user-offsets.h>
9#include <asm/ptrace.h>
10 9
11#define PRINT_REG(name, val) \ 10#define SHOW(name) \
12 printf("#define HOST_%s (%d / sizeof(unsigned long))\n", (name), (val)) 11 printf("#define %s (%d / sizeof(unsigned long))\n", #name, name)
13 12
14int main(int argc, char **argv) 13int main(int argc, char **argv)
15{ 14{
@@ -18,36 +17,35 @@ int main(int argc, char **argv)
18 printf("\n"); 17 printf("\n");
19 printf("#ifndef __SKAS_PT_REGS_\n"); 18 printf("#ifndef __SKAS_PT_REGS_\n");
20 printf("#define __SKAS_PT_REGS_\n"); 19 printf("#define __SKAS_PT_REGS_\n");
21 printf("#define HOST_FRAME_SIZE (%d / sizeof(unsigned long))\n", 20 SHOW(HOST_FRAME_SIZE);
22 FRAME_SIZE); 21 SHOW(HOST_RBX);
23 PRINT_REG("RBX", RBX); 22 SHOW(HOST_RCX);
24 PRINT_REG("RCX", RCX); 23 SHOW(HOST_RDI);
25 PRINT_REG("RDI", RDI); 24 SHOW(HOST_RSI);
26 PRINT_REG("RSI", RSI); 25 SHOW(HOST_RDX);
27 PRINT_REG("RDX", RDX); 26 SHOW(HOST_RBP);
28 PRINT_REG("RBP", RBP); 27 SHOW(HOST_RAX);
29 PRINT_REG("RAX", RAX); 28 SHOW(HOST_R8);
30 PRINT_REG("R8", R8); 29 SHOW(HOST_R9);
31 PRINT_REG("R9", R9); 30 SHOW(HOST_R10);
32 PRINT_REG("R10", R10); 31 SHOW(HOST_R11);
33 PRINT_REG("R11", R11); 32 SHOW(HOST_R12);
34 PRINT_REG("R12", R12); 33 SHOW(HOST_R13);
35 PRINT_REG("R13", R13); 34 SHOW(HOST_R14);
36 PRINT_REG("R14", R14); 35 SHOW(HOST_R15);
37 PRINT_REG("R15", R15); 36 SHOW(HOST_ORIG_RAX);
38 PRINT_REG("ORIG_RAX", ORIG_RAX); 37 SHOW(HOST_CS);
39 PRINT_REG("CS", CS); 38 SHOW(HOST_SS);
40 PRINT_REG("SS", SS); 39 SHOW(HOST_EFLAGS);
41 PRINT_REG("EFLAGS", EFLAGS);
42#if 0 40#if 0
43 PRINT_REG("FS", FS); 41 SHOW(HOST_FS);
44 PRINT_REG("GS", GS); 42 SHOW(HOST_GS);
45 PRINT_REG("DS", DS); 43 SHOW(HOST_DS);
46 PRINT_REG("ES", ES); 44 SHOW(HOST_ES);
47#endif 45#endif
48 46
49 PRINT_REG("IP", RIP); 47 SHOW(HOST_IP);
50 PRINT_REG("SP", RSP); 48 SHOW(HOST_SP);
51 printf("#define HOST_FP_SIZE 0\n"); 49 printf("#define HOST_FP_SIZE 0\n");
52 printf("#define HOST_XFP_SIZE 0\n"); 50 printf("#define HOST_XFP_SIZE 0\n");
53 printf("\n"); 51 printf("\n");
diff --git a/arch/um/kernel/sys_call_table.c b/arch/um/kernel/sys_call_table.c
deleted file mode 100644
index 7fc06c85b29d..000000000000
--- a/arch/um/kernel/sys_call_table.c
+++ /dev/null
@@ -1,276 +0,0 @@
1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Copyright 2003 PathScale, Inc.
4 * Licensed under the GPL
5 */
6
7#include "linux/config.h"
8#include "linux/unistd.h"
9#include "linux/sys.h"
10#include "linux/swap.h"
11#include "linux/syscalls.h"
12#include "linux/sysctl.h"
13#include "asm/signal.h"
14#include "sysdep/syscalls.h"
15#include "kern_util.h"
16
17#ifdef CONFIG_NFSD
18#define NFSSERVCTL sys_nfsservctl
19#else
20#define NFSSERVCTL sys_ni_syscall
21#endif
22
23#define LAST_GENERIC_SYSCALL __NR_keyctl
24
25#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
26#define LAST_SYSCALL LAST_GENERIC_SYSCALL
27#else
28#define LAST_SYSCALL LAST_ARCH_SYSCALL
29#endif
30
31extern syscall_handler_t sys_fork;
32extern syscall_handler_t sys_execve;
33extern syscall_handler_t um_time;
34extern syscall_handler_t um_stime;
35extern syscall_handler_t sys_pipe;
36extern syscall_handler_t sys_olduname;
37extern syscall_handler_t sys_sigaction;
38extern syscall_handler_t sys_sigsuspend;
39extern syscall_handler_t old_readdir;
40extern syscall_handler_t sys_uname;
41extern syscall_handler_t sys_ipc;
42extern syscall_handler_t sys_sigreturn;
43extern syscall_handler_t sys_clone;
44extern syscall_handler_t sys_rt_sigreturn;
45extern syscall_handler_t sys_sigaltstack;
46extern syscall_handler_t sys_vfork;
47extern syscall_handler_t old_select;
48extern syscall_handler_t sys_modify_ldt;
49extern syscall_handler_t sys_rt_sigsuspend;
50extern syscall_handler_t sys_mbind;
51extern syscall_handler_t sys_get_mempolicy;
52extern syscall_handler_t sys_set_mempolicy;
53extern syscall_handler_t sys_sys_setaltroot;
54
55syscall_handler_t *sys_call_table[] = {
56 [ __NR_restart_syscall ] = (syscall_handler_t *) sys_restart_syscall,
57 [ __NR_exit ] = (syscall_handler_t *) sys_exit,
58 [ __NR_fork ] = (syscall_handler_t *) sys_fork,
59 [ __NR_read ] = (syscall_handler_t *) sys_read,
60 [ __NR_write ] = (syscall_handler_t *) sys_write,
61
62 /* These three are declared differently in asm/unistd.h */
63 [ __NR_open ] = (syscall_handler_t *) sys_open,
64 [ __NR_close ] = (syscall_handler_t *) sys_close,
65 [ __NR_creat ] = (syscall_handler_t *) sys_creat,
66 [ __NR_link ] = (syscall_handler_t *) sys_link,
67 [ __NR_unlink ] = (syscall_handler_t *) sys_unlink,
68 [ __NR_execve ] = (syscall_handler_t *) sys_execve,
69
70 /* declared differently in kern_util.h */
71 [ __NR_chdir ] = (syscall_handler_t *) sys_chdir,
72 [ __NR_time ] = um_time,
73 [ __NR_mknod ] = (syscall_handler_t *) sys_mknod,
74 [ __NR_chmod ] = (syscall_handler_t *) sys_chmod,
75 [ __NR_lchown ] = (syscall_handler_t *) sys_lchown16,
76 [ __NR_lseek ] = (syscall_handler_t *) sys_lseek,
77 [ __NR_getpid ] = (syscall_handler_t *) sys_getpid,
78 [ __NR_mount ] = (syscall_handler_t *) sys_mount,
79 [ __NR_setuid ] = (syscall_handler_t *) sys_setuid16,
80 [ __NR_getuid ] = (syscall_handler_t *) sys_getuid16,
81 [ __NR_ptrace ] = (syscall_handler_t *) sys_ptrace,
82 [ __NR_alarm ] = (syscall_handler_t *) sys_alarm,
83 [ __NR_pause ] = (syscall_handler_t *) sys_pause,
84 [ __NR_utime ] = (syscall_handler_t *) sys_utime,
85 [ __NR_access ] = (syscall_handler_t *) sys_access,
86 [ __NR_sync ] = (syscall_handler_t *) sys_sync,
87 [ __NR_kill ] = (syscall_handler_t *) sys_kill,
88 [ __NR_rename ] = (syscall_handler_t *) sys_rename,
89 [ __NR_mkdir ] = (syscall_handler_t *) sys_mkdir,
90 [ __NR_rmdir ] = (syscall_handler_t *) sys_rmdir,
91
92 /* Declared differently in asm/unistd.h */
93 [ __NR_dup ] = (syscall_handler_t *) sys_dup,
94 [ __NR_pipe ] = (syscall_handler_t *) sys_pipe,
95 [ __NR_times ] = (syscall_handler_t *) sys_times,
96 [ __NR_brk ] = (syscall_handler_t *) sys_brk,
97 [ __NR_setgid ] = (syscall_handler_t *) sys_setgid16,
98 [ __NR_getgid ] = (syscall_handler_t *) sys_getgid16,
99 [ __NR_geteuid ] = (syscall_handler_t *) sys_geteuid16,
100 [ __NR_getegid ] = (syscall_handler_t *) sys_getegid16,
101 [ __NR_acct ] = (syscall_handler_t *) sys_acct,
102 [ __NR_umount2 ] = (syscall_handler_t *) sys_umount,
103 [ __NR_ioctl ] = (syscall_handler_t *) sys_ioctl,
104 [ __NR_fcntl ] = (syscall_handler_t *) sys_fcntl,
105 [ __NR_setpgid ] = (syscall_handler_t *) sys_setpgid,
106 [ __NR_umask ] = (syscall_handler_t *) sys_umask,
107 [ __NR_chroot ] = (syscall_handler_t *) sys_chroot,
108 [ __NR_ustat ] = (syscall_handler_t *) sys_ustat,
109 [ __NR_dup2 ] = (syscall_handler_t *) sys_dup2,
110 [ __NR_getppid ] = (syscall_handler_t *) sys_getppid,
111 [ __NR_getpgrp ] = (syscall_handler_t *) sys_getpgrp,
112 [ __NR_setsid ] = (syscall_handler_t *) sys_setsid,
113 [ __NR_setreuid ] = (syscall_handler_t *) sys_setreuid16,
114 [ __NR_setregid ] = (syscall_handler_t *) sys_setregid16,
115 [ __NR_sethostname ] = (syscall_handler_t *) sys_sethostname,
116 [ __NR_setrlimit ] = (syscall_handler_t *) sys_setrlimit,
117 [ __NR_getrlimit ] = (syscall_handler_t *) sys_old_getrlimit,
118 [ __NR_getrusage ] = (syscall_handler_t *) sys_getrusage,
119 [ __NR_gettimeofday ] = (syscall_handler_t *) sys_gettimeofday,
120 [ __NR_settimeofday ] = (syscall_handler_t *) sys_settimeofday,
121 [ __NR_getgroups ] = (syscall_handler_t *) sys_getgroups16,
122 [ __NR_setgroups ] = (syscall_handler_t *) sys_setgroups16,
123 [ __NR_symlink ] = (syscall_handler_t *) sys_symlink,
124 [ __NR_readlink ] = (syscall_handler_t *) sys_readlink,
125 [ __NR_uselib ] = (syscall_handler_t *) sys_uselib,
126 [ __NR_swapon ] = (syscall_handler_t *) sys_swapon,
127 [ __NR_reboot ] = (syscall_handler_t *) sys_reboot,
128 [ __NR_munmap ] = (syscall_handler_t *) sys_munmap,
129 [ __NR_truncate ] = (syscall_handler_t *) sys_truncate,
130 [ __NR_ftruncate ] = (syscall_handler_t *) sys_ftruncate,
131 [ __NR_fchmod ] = (syscall_handler_t *) sys_fchmod,
132 [ __NR_fchown ] = (syscall_handler_t *) sys_fchown16,
133 [ __NR_getpriority ] = (syscall_handler_t *) sys_getpriority,
134 [ __NR_setpriority ] = (syscall_handler_t *) sys_setpriority,
135 [ __NR_statfs ] = (syscall_handler_t *) sys_statfs,
136 [ __NR_fstatfs ] = (syscall_handler_t *) sys_fstatfs,
137 [ __NR_ioperm ] = (syscall_handler_t *) sys_ni_syscall,
138 [ __NR_syslog ] = (syscall_handler_t *) sys_syslog,
139 [ __NR_setitimer ] = (syscall_handler_t *) sys_setitimer,
140 [ __NR_getitimer ] = (syscall_handler_t *) sys_getitimer,
141 [ __NR_stat ] = (syscall_handler_t *) sys_newstat,
142 [ __NR_lstat ] = (syscall_handler_t *) sys_newlstat,
143 [ __NR_fstat ] = (syscall_handler_t *) sys_newfstat,
144 [ __NR_vhangup ] = (syscall_handler_t *) sys_vhangup,
145 [ __NR_wait4 ] = (syscall_handler_t *) sys_wait4,
146 [ __NR_swapoff ] = (syscall_handler_t *) sys_swapoff,
147 [ __NR_sysinfo ] = (syscall_handler_t *) sys_sysinfo,
148 [ __NR_fsync ] = (syscall_handler_t *) sys_fsync,
149 [ __NR_clone ] = (syscall_handler_t *) sys_clone,
150 [ __NR_setdomainname ] = (syscall_handler_t *) sys_setdomainname,
151 [ __NR_uname ] = (syscall_handler_t *) sys_newuname,
152 [ __NR_adjtimex ] = (syscall_handler_t *) sys_adjtimex,
153 [ __NR_mprotect ] = (syscall_handler_t *) sys_mprotect,
154 [ __NR_create_module ] = (syscall_handler_t *) sys_ni_syscall,
155 [ __NR_init_module ] = (syscall_handler_t *) sys_init_module,
156 [ __NR_delete_module ] = (syscall_handler_t *) sys_delete_module,
157 [ __NR_get_kernel_syms ] = (syscall_handler_t *) sys_ni_syscall,
158 [ __NR_quotactl ] = (syscall_handler_t *) sys_quotactl,
159 [ __NR_getpgid ] = (syscall_handler_t *) sys_getpgid,
160 [ __NR_fchdir ] = (syscall_handler_t *) sys_fchdir,
161 [ __NR_sysfs ] = (syscall_handler_t *) sys_sysfs,
162 [ __NR_personality ] = (syscall_handler_t *) sys_personality,
163 [ __NR_afs_syscall ] = (syscall_handler_t *) sys_ni_syscall,
164 [ __NR_setfsuid ] = (syscall_handler_t *) sys_setfsuid16,
165 [ __NR_setfsgid ] = (syscall_handler_t *) sys_setfsgid16,
166 [ __NR_getdents ] = (syscall_handler_t *) sys_getdents,
167 [ __NR_flock ] = (syscall_handler_t *) sys_flock,
168 [ __NR_msync ] = (syscall_handler_t *) sys_msync,
169 [ __NR_readv ] = (syscall_handler_t *) sys_readv,
170 [ __NR_writev ] = (syscall_handler_t *) sys_writev,
171 [ __NR_getsid ] = (syscall_handler_t *) sys_getsid,
172 [ __NR_fdatasync ] = (syscall_handler_t *) sys_fdatasync,
173 [ __NR__sysctl ] = (syscall_handler_t *) sys_sysctl,
174 [ __NR_mlock ] = (syscall_handler_t *) sys_mlock,
175 [ __NR_munlock ] = (syscall_handler_t *) sys_munlock,
176 [ __NR_mlockall ] = (syscall_handler_t *) sys_mlockall,
177 [ __NR_munlockall ] = (syscall_handler_t *) sys_munlockall,
178 [ __NR_sched_setparam ] = (syscall_handler_t *) sys_sched_setparam,
179 [ __NR_sched_getparam ] = (syscall_handler_t *) sys_sched_getparam,
180 [ __NR_sched_setscheduler ] = (syscall_handler_t *) sys_sched_setscheduler,
181 [ __NR_sched_getscheduler ] = (syscall_handler_t *) sys_sched_getscheduler,
182 [ __NR_sched_yield ] = (syscall_handler_t *) yield,
183 [ __NR_sched_get_priority_max ] = (syscall_handler_t *) sys_sched_get_priority_max,
184 [ __NR_sched_get_priority_min ] = (syscall_handler_t *) sys_sched_get_priority_min,
185 [ __NR_sched_rr_get_interval ] = (syscall_handler_t *) sys_sched_rr_get_interval,
186 [ __NR_nanosleep ] = (syscall_handler_t *) sys_nanosleep,
187 [ __NR_mremap ] = (syscall_handler_t *) sys_mremap,
188 [ __NR_setresuid ] = (syscall_handler_t *) sys_setresuid16,
189 [ __NR_getresuid ] = (syscall_handler_t *) sys_getresuid16,
190 [ __NR_query_module ] = (syscall_handler_t *) sys_ni_syscall,
191 [ __NR_poll ] = (syscall_handler_t *) sys_poll,
192 [ __NR_nfsservctl ] = (syscall_handler_t *) NFSSERVCTL,
193 [ __NR_setresgid ] = (syscall_handler_t *) sys_setresgid16,
194 [ __NR_getresgid ] = (syscall_handler_t *) sys_getresgid16,
195 [ __NR_prctl ] = (syscall_handler_t *) sys_prctl,
196 [ __NR_rt_sigreturn ] = (syscall_handler_t *) sys_rt_sigreturn,
197 [ __NR_rt_sigaction ] = (syscall_handler_t *) sys_rt_sigaction,
198 [ __NR_rt_sigprocmask ] = (syscall_handler_t *) sys_rt_sigprocmask,
199 [ __NR_rt_sigpending ] = (syscall_handler_t *) sys_rt_sigpending,
200 [ __NR_rt_sigtimedwait ] = (syscall_handler_t *) sys_rt_sigtimedwait,
201 [ __NR_rt_sigqueueinfo ] = (syscall_handler_t *) sys_rt_sigqueueinfo,
202 [ __NR_rt_sigsuspend ] = (syscall_handler_t *) sys_rt_sigsuspend,
203 [ __NR_pread64 ] = (syscall_handler_t *) sys_pread64,
204 [ __NR_pwrite64 ] = (syscall_handler_t *) sys_pwrite64,
205 [ __NR_chown ] = (syscall_handler_t *) sys_chown16,
206 [ __NR_getcwd ] = (syscall_handler_t *) sys_getcwd,
207 [ __NR_capget ] = (syscall_handler_t *) sys_capget,
208 [ __NR_capset ] = (syscall_handler_t *) sys_capset,
209 [ __NR_sigaltstack ] = (syscall_handler_t *) sys_sigaltstack,
210 [ __NR_sendfile ] = (syscall_handler_t *) sys_sendfile,
211 [ __NR_getpmsg ] = (syscall_handler_t *) sys_ni_syscall,
212 [ __NR_putpmsg ] = (syscall_handler_t *) sys_ni_syscall,
213 [ __NR_vfork ] = (syscall_handler_t *) sys_vfork,
214 [ __NR_getdents64 ] = (syscall_handler_t *) sys_getdents64,
215 [ __NR_gettid ] = (syscall_handler_t *) sys_gettid,
216 [ __NR_readahead ] = (syscall_handler_t *) sys_readahead,
217 [ __NR_setxattr ] = (syscall_handler_t *) sys_setxattr,
218 [ __NR_lsetxattr ] = (syscall_handler_t *) sys_lsetxattr,
219 [ __NR_fsetxattr ] = (syscall_handler_t *) sys_fsetxattr,
220 [ __NR_getxattr ] = (syscall_handler_t *) sys_getxattr,
221 [ __NR_lgetxattr ] = (syscall_handler_t *) sys_lgetxattr,
222 [ __NR_fgetxattr ] = (syscall_handler_t *) sys_fgetxattr,
223 [ __NR_listxattr ] = (syscall_handler_t *) sys_listxattr,
224 [ __NR_llistxattr ] = (syscall_handler_t *) sys_llistxattr,
225 [ __NR_flistxattr ] = (syscall_handler_t *) sys_flistxattr,
226 [ __NR_removexattr ] = (syscall_handler_t *) sys_removexattr,
227 [ __NR_lremovexattr ] = (syscall_handler_t *) sys_lremovexattr,
228 [ __NR_fremovexattr ] = (syscall_handler_t *) sys_fremovexattr,
229 [ __NR_tkill ] = (syscall_handler_t *) sys_tkill,
230 [ __NR_futex ] = (syscall_handler_t *) sys_futex,
231 [ __NR_sched_setaffinity ] = (syscall_handler_t *) sys_sched_setaffinity,
232 [ __NR_sched_getaffinity ] = (syscall_handler_t *) sys_sched_getaffinity,
233 [ __NR_io_setup ] = (syscall_handler_t *) sys_io_setup,
234 [ __NR_io_destroy ] = (syscall_handler_t *) sys_io_destroy,
235 [ __NR_io_getevents ] = (syscall_handler_t *) sys_io_getevents,
236 [ __NR_io_submit ] = (syscall_handler_t *) sys_io_submit,
237 [ __NR_io_cancel ] = (syscall_handler_t *) sys_io_cancel,
238 [ __NR_exit_group ] = (syscall_handler_t *) sys_exit_group,
239 [ __NR_lookup_dcookie ] = (syscall_handler_t *) sys_lookup_dcookie,
240 [ __NR_epoll_create ] = (syscall_handler_t *) sys_epoll_create,
241 [ __NR_epoll_ctl ] = (syscall_handler_t *) sys_epoll_ctl,
242 [ __NR_epoll_wait ] = (syscall_handler_t *) sys_epoll_wait,
243 [ __NR_remap_file_pages ] = (syscall_handler_t *) sys_remap_file_pages,
244 [ __NR_set_tid_address ] = (syscall_handler_t *) sys_set_tid_address,
245 [ __NR_timer_create ] = (syscall_handler_t *) sys_timer_create,
246 [ __NR_timer_settime ] = (syscall_handler_t *) sys_timer_settime,
247 [ __NR_timer_gettime ] = (syscall_handler_t *) sys_timer_gettime,
248 [ __NR_timer_getoverrun ] = (syscall_handler_t *) sys_timer_getoverrun,
249 [ __NR_timer_delete ] = (syscall_handler_t *) sys_timer_delete,
250 [ __NR_clock_settime ] = (syscall_handler_t *) sys_clock_settime,
251 [ __NR_clock_gettime ] = (syscall_handler_t *) sys_clock_gettime,
252 [ __NR_clock_getres ] = (syscall_handler_t *) sys_clock_getres,
253 [ __NR_clock_nanosleep ] = (syscall_handler_t *) sys_clock_nanosleep,
254 [ __NR_tgkill ] = (syscall_handler_t *) sys_tgkill,
255 [ __NR_utimes ] = (syscall_handler_t *) sys_utimes,
256 [ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64,
257 [ __NR_vserver ] = (syscall_handler_t *) sys_ni_syscall,
258 [ __NR_mbind ] = (syscall_handler_t *) sys_mbind,
259 [ __NR_get_mempolicy ] = (syscall_handler_t *) sys_get_mempolicy,
260 [ __NR_set_mempolicy ] = (syscall_handler_t *) sys_set_mempolicy,
261 [ __NR_mq_open ] = (syscall_handler_t *) sys_mq_open,
262 [ __NR_mq_unlink ] = (syscall_handler_t *) sys_mq_unlink,
263 [ __NR_mq_timedsend ] = (syscall_handler_t *) sys_mq_timedsend,
264 [ __NR_mq_timedreceive ] = (syscall_handler_t *) sys_mq_timedreceive,
265 [ __NR_mq_notify ] = (syscall_handler_t *) sys_mq_notify,
266 [ __NR_mq_getsetattr ] = (syscall_handler_t *) sys_mq_getsetattr,
267 [ __NR_kexec_load ] = (syscall_handler_t *) sys_ni_syscall,
268 [ __NR_waitid ] = (syscall_handler_t *) sys_waitid,
269 [ __NR_add_key ] = (syscall_handler_t *) sys_add_key,
270 [ __NR_request_key ] = (syscall_handler_t *) sys_request_key,
271 [ __NR_keyctl ] = (syscall_handler_t *) sys_keyctl,
272
273 ARCH_SYSCALLS
274 [ LAST_SYSCALL + 1 ... NR_syscalls ] =
275 (syscall_handler_t *) sys_ni_syscall
276};
diff --git a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c
index 42731e04f50f..b7a55251e897 100644
--- a/arch/um/kernel/syscall_kern.c
+++ b/arch/um/kernel/syscall_kern.c
@@ -17,7 +17,6 @@
17#include "linux/utime.h" 17#include "linux/utime.h"
18#include "asm/mman.h" 18#include "asm/mman.h"
19#include "asm/uaccess.h" 19#include "asm/uaccess.h"
20#include "asm/ipc.h"
21#include "kern_util.h" 20#include "kern_util.h"
22#include "user_util.h" 21#include "user_util.h"
23#include "sysdep/syscalls.h" 22#include "sysdep/syscalls.h"
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
index 2461cd73ca87..6516fc52afe0 100644
--- a/arch/um/kernel/time_kern.c
+++ b/arch/um/kernel/time_kern.c
@@ -48,8 +48,6 @@ static unsigned long long prev_usecs;
48static long long delta; /* Deviation per interval */ 48static long long delta; /* Deviation per interval */
49#endif 49#endif
50 50
51#define MILLION 1000000
52
53void timer_irq(union uml_pt_regs *regs) 51void timer_irq(union uml_pt_regs *regs)
54{ 52{
55 unsigned long long ticks = 0; 53 unsigned long long ticks = 0;
@@ -136,22 +134,6 @@ long um_stime(int __user *tptr)
136 return 0; 134 return 0;
137} 135}
138 136
139void __udelay(unsigned long usecs)
140{
141 int i, n;
142
143 n = (loops_per_jiffy * HZ * usecs) / MILLION;
144 for(i=0;i<n;i++) ;
145}
146
147void __const_udelay(unsigned long usecs)
148{
149 int i, n;
150
151 n = (loops_per_jiffy * HZ * usecs) / MILLION;
152 for(i=0;i<n;i++) ;
153}
154
155void timer_handler(int sig, union uml_pt_regs *regs) 137void timer_handler(int sig, union uml_pt_regs *regs)
156{ 138{
157 local_irq_disable(); 139 local_irq_disable();
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
index 47e766e6ba10..5fca2c61eb98 100644
--- a/arch/um/kernel/trap_kern.c
+++ b/arch/um/kernel/trap_kern.c
@@ -48,7 +48,7 @@ int handle_page_fault(unsigned long address, unsigned long ip,
48 goto good_area; 48 goto good_area;
49 else if(!(vma->vm_flags & VM_GROWSDOWN)) 49 else if(!(vma->vm_flags & VM_GROWSDOWN))
50 goto out; 50 goto out;
51 else if(!ARCH_IS_STACKGROW(address)) 51 else if(is_user && !ARCH_IS_STACKGROW(address))
52 goto out; 52 goto out;
53 else if(expand_stack(vma, address)) 53 else if(expand_stack(vma, address))
54 goto out; 54 goto out;
@@ -133,12 +133,19 @@ static int check_remapped_addr(unsigned long address, int is_write)
133 return(0); 133 return(0);
134} 134}
135 135
136unsigned long segv(unsigned long address, unsigned long ip, int is_write, 136/*
137 int is_user, void *sc) 137 * We give a *copy* of the faultinfo in the regs to segv.
138 * This must be done, since nesting SEGVs could overwrite
139 * the info in the regs. A pointer to the info then would
140 * give us bad data!
141 */
142unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
138{ 143{
139 struct siginfo si; 144 struct siginfo si;
140 void *catcher; 145 void *catcher;
141 int err; 146 int err;
147 int is_write = FAULT_WRITE(fi);
148 unsigned long address = FAULT_ADDRESS(fi);
142 149
143 if(!is_user && (address >= start_vm) && (address < end_vm)){ 150 if(!is_user && (address >= start_vm) && (address < end_vm)){
144 flush_tlb_kernel_vm(); 151 flush_tlb_kernel_vm();
@@ -159,7 +166,7 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write,
159 } 166 }
160 else if(current->thread.fault_addr != NULL) 167 else if(current->thread.fault_addr != NULL)
161 panic("fault_addr set but no fault catcher"); 168 panic("fault_addr set but no fault catcher");
162 else if(arch_fixup(ip, sc)) 169 else if(!is_user && arch_fixup(ip, sc))
163 return(0); 170 return(0);
164 171
165 if(!is_user) 172 if(!is_user)
@@ -171,6 +178,7 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write,
171 si.si_errno = 0; 178 si.si_errno = 0;
172 si.si_code = BUS_ADRERR; 179 si.si_code = BUS_ADRERR;
173 si.si_addr = (void *)address; 180 si.si_addr = (void *)address;
181 current->thread.arch.faultinfo = fi;
174 force_sig_info(SIGBUS, &si, current); 182 force_sig_info(SIGBUS, &si, current);
175 } 183 }
176 else if(err == -ENOMEM){ 184 else if(err == -ENOMEM){
@@ -180,22 +188,20 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write,
180 else { 188 else {
181 si.si_signo = SIGSEGV; 189 si.si_signo = SIGSEGV;
182 si.si_addr = (void *) address; 190 si.si_addr = (void *) address;
183 current->thread.cr2 = address; 191 current->thread.arch.faultinfo = fi;
184 current->thread.err = is_write;
185 force_sig_info(SIGSEGV, &si, current); 192 force_sig_info(SIGSEGV, &si, current);
186 } 193 }
187 return(0); 194 return(0);
188} 195}
189 196
190void bad_segv(unsigned long address, unsigned long ip, int is_write) 197void bad_segv(struct faultinfo fi, unsigned long ip)
191{ 198{
192 struct siginfo si; 199 struct siginfo si;
193 200
194 si.si_signo = SIGSEGV; 201 si.si_signo = SIGSEGV;
195 si.si_code = SEGV_ACCERR; 202 si.si_code = SEGV_ACCERR;
196 si.si_addr = (void *) address; 203 si.si_addr = (void *) FAULT_ADDRESS(fi);
197 current->thread.cr2 = address; 204 current->thread.arch.faultinfo = fi;
198 current->thread.err = is_write;
199 force_sig_info(SIGSEGV, &si, current); 205 force_sig_info(SIGSEGV, &si, current);
200} 206}
201 207
@@ -204,6 +210,7 @@ void relay_signal(int sig, union uml_pt_regs *regs)
204 if(arch_handle_signal(sig, regs)) return; 210 if(arch_handle_signal(sig, regs)) return;
205 if(!UPT_IS_USER(regs)) 211 if(!UPT_IS_USER(regs))
206 panic("Kernel mode signal %d", sig); 212 panic("Kernel mode signal %d", sig);
213 current->thread.arch.faultinfo = *UPT_FAULTINFO(regs);
207 force_sig(sig, current); 214 force_sig(sig, current);
208} 215}
209 216
diff --git a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c
index 50a4042a509f..f825a6eda3f5 100644
--- a/arch/um/kernel/trap_user.c
+++ b/arch/um/kernel/trap_user.c
@@ -54,23 +54,22 @@ struct {
54void segv_handler(int sig, union uml_pt_regs *regs) 54void segv_handler(int sig, union uml_pt_regs *regs)
55{ 55{
56 int index, max; 56 int index, max;
57 struct faultinfo * fi = UPT_FAULTINFO(regs);
57 58
58 if(UPT_IS_USER(regs) && !UPT_SEGV_IS_FIXABLE(regs)){ 59 if(UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)){
59 bad_segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), 60 bad_segv(*fi, UPT_IP(regs));
60 UPT_FAULT_WRITE(regs));
61 return; 61 return;
62 } 62 }
63 max = sizeof(segfault_record)/sizeof(segfault_record[0]); 63 max = sizeof(segfault_record)/sizeof(segfault_record[0]);
64 index = next_trap_index(max); 64 index = next_trap_index(max);
65 65
66 nsegfaults++; 66 nsegfaults++;
67 segfault_record[index].address = UPT_FAULT_ADDR(regs); 67 segfault_record[index].address = FAULT_ADDRESS(*fi);
68 segfault_record[index].pid = os_getpid(); 68 segfault_record[index].pid = os_getpid();
69 segfault_record[index].is_write = UPT_FAULT_WRITE(regs); 69 segfault_record[index].is_write = FAULT_WRITE(*fi);
70 segfault_record[index].sp = UPT_SP(regs); 70 segfault_record[index].sp = UPT_SP(regs);
71 segfault_record[index].is_user = UPT_IS_USER(regs); 71 segfault_record[index].is_user = UPT_IS_USER(regs);
72 segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs), 72 segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs);
73 UPT_IS_USER(regs), regs);
74} 73}
75 74
76void usr2_handler(int sig, union uml_pt_regs *regs) 75void usr2_handler(int sig, union uml_pt_regs *regs)
diff --git a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile
index 3d5177df3504..c3faea21a996 100644
--- a/arch/um/kernel/tt/Makefile
+++ b/arch/um/kernel/tt/Makefile
@@ -4,6 +4,7 @@
4# 4#
5 5
6extra-y := unmap_fin.o 6extra-y := unmap_fin.o
7targets := unmap.o
7clean-files := unmap_tmp.o 8clean-files := unmap_tmp.o
8 9
9obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \ 10obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
diff --git a/arch/um/kernel/tt/include/mode_kern-tt.h b/arch/um/kernel/tt/include/mode_kern-tt.h
index 28aaab3448fa..e0ca0e0b2516 100644
--- a/arch/um/kernel/tt/include/mode_kern-tt.h
+++ b/arch/um/kernel/tt/include/mode_kern-tt.h
@@ -19,7 +19,6 @@ extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
19 unsigned long stack_top, struct task_struct *p, 19 unsigned long stack_top, struct task_struct *p,
20 struct pt_regs *regs); 20 struct pt_regs *regs);
21extern void release_thread_tt(struct task_struct *task); 21extern void release_thread_tt(struct task_struct *task);
22extern void exit_thread_tt(void);
23extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); 22extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
24extern void init_idle_tt(void); 23extern void init_idle_tt(void);
25extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end); 24extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end);
diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/kernel/tt/include/uaccess-tt.h
index f0bad010cebd..3fbb5fe26f49 100644
--- a/arch/um/kernel/tt/include/uaccess-tt.h
+++ b/arch/um/kernel/tt/include/uaccess-tt.h
@@ -34,7 +34,7 @@ extern unsigned long uml_physmem;
34 (under_task_size(addr, size) || is_stack(addr, size)))) 34 (under_task_size(addr, size) || is_stack(addr, size))))
35 35
36static inline int verify_area_tt(int type, const void * addr, 36static inline int verify_area_tt(int type, const void * addr,
37 unsigned long size) 37 unsigned long size)
38{ 38{
39 return(access_ok_tt(type, addr, size) ? 0 : -EFAULT); 39 return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
40} 40}
diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c
index 74346a04a2b2..bcb8796c3cb1 100644
--- a/arch/um/kernel/tt/mem.c
+++ b/arch/um/kernel/tt/mem.c
@@ -21,14 +21,8 @@ void before_mem_tt(unsigned long brk_start)
21 remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1); 21 remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1);
22} 22}
23 23
24#ifdef CONFIG_HOST_2G_2G
25#define TOP 0x80000000
26#else
27#define TOP 0xc0000000
28#endif
29
30#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000) 24#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
31#define START (TOP - SIZE) 25#define START (CONFIG_TOP_ADDR - SIZE)
32 26
33unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, 27unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
34 unsigned long *task_size_out) 28 unsigned long *task_size_out)
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index f19f7c18febe..df810ca8fc12 100644
--- a/arch/um/kernel/tt/process_kern.c
+++ b/arch/um/kernel/tt/process_kern.c
@@ -65,8 +65,7 @@ void *switch_to_tt(void *prev, void *next, void *last)
65 panic("write of switch_pipe failed, err = %d", -err); 65 panic("write of switch_pipe failed, err = %d", -err);
66 66
67 reading = 1; 67 reading = 1;
68 if((from->exit_state == EXIT_ZOMBIE) || 68 if(from->thread.mode.tt.switch_pipe[0] == -1)
69 (from->exit_state == EXIT_DEAD))
70 os_kill_process(os_getpid(), 0); 69 os_kill_process(os_getpid(), 0);
71 70
72 err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); 71 err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c));
@@ -81,8 +80,7 @@ void *switch_to_tt(void *prev, void *next, void *last)
81 * in case it has not already killed itself. 80 * in case it has not already killed itself.
82 */ 81 */
83 prev_sched = current->thread.prev_sched; 82 prev_sched = current->thread.prev_sched;
84 if((prev_sched->exit_state == EXIT_ZOMBIE) || 83 if(prev_sched->thread.mode.tt.switch_pipe[0] == -1)
85 (prev_sched->exit_state == EXIT_DEAD))
86 os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1); 84 os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1);
87 85
88 change_sig(SIGVTALRM, vtalrm); 86 change_sig(SIGVTALRM, vtalrm);
@@ -101,14 +99,18 @@ void release_thread_tt(struct task_struct *task)
101{ 99{
102 int pid = task->thread.mode.tt.extern_pid; 100 int pid = task->thread.mode.tt.extern_pid;
103 101
102 /*
103 * We first have to kill the other process, before
104 * closing its switch_pipe. Else it might wake up
105 * and receive "EOF" before we could kill it.
106 */
104 if(os_getpid() != pid) 107 if(os_getpid() != pid)
105 os_kill_process(pid, 0); 108 os_kill_process(pid, 0);
106}
107 109
108void exit_thread_tt(void) 110 os_close_file(task->thread.mode.tt.switch_pipe[0]);
109{ 111 os_close_file(task->thread.mode.tt.switch_pipe[1]);
110 os_close_file(current->thread.mode.tt.switch_pipe[0]); 112 /* use switch_pipe as flag: thread is released */
111 os_close_file(current->thread.mode.tt.switch_pipe[1]); 113 task->thread.mode.tt.switch_pipe[0] = -1;
112} 114}
113 115
114void suspend_new_thread(int fd) 116void suspend_new_thread(int fd)
diff --git a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c
index e4e7e9c2224c..b218316cfdb2 100644
--- a/arch/um/kernel/tt/syscall_user.c
+++ b/arch/um/kernel/tt/syscall_user.c
@@ -63,6 +63,10 @@ void do_syscall(void *task, int pid, int local_using_sysemu)
63 63
64 UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs); 64 UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs);
65 65
66#ifdef UPT_ORIGGPR2
67 UPT_ORIGGPR2(TASK_REGS(task)) = REGS_ORIGGPR2(proc_regs);
68#endif
69
66 if(((unsigned long *) PT_IP(proc_regs) >= &_stext) && 70 if(((unsigned long *) PT_IP(proc_regs) >= &_stext) &&
67 ((unsigned long *) PT_IP(proc_regs) <= &_etext)) 71 ((unsigned long *) PT_IP(proc_regs) <= &_etext))
68 tracer_panic("I'm tracing myself and I can't get out"); 72 tracer_panic("I'm tracing myself and I can't get out");
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
index 7b5d937e5955..d11e7399d7a1 100644
--- a/arch/um/kernel/tt/tracer.c
+++ b/arch/um/kernel/tt/tracer.c
@@ -26,6 +26,7 @@
26#include "kern_util.h" 26#include "kern_util.h"
27#include "chan_user.h" 27#include "chan_user.h"
28#include "ptrace_user.h" 28#include "ptrace_user.h"
29#include "irq_user.h"
29#include "mode.h" 30#include "mode.h"
30#include "tt.h" 31#include "tt.h"
31 32
@@ -33,7 +34,7 @@ static int tracer_winch[2];
33 34
34int is_tracer_winch(int pid, int fd, void *data) 35int is_tracer_winch(int pid, int fd, void *data)
35{ 36{
36 if(pid != tracing_pid) 37 if(pid != os_getpgrp())
37 return(0); 38 return(0);
38 39
39 register_winch_irq(tracer_winch[0], fd, -1, data); 40 register_winch_irq(tracer_winch[0], fd, -1, data);
@@ -89,8 +90,10 @@ void tracer_panic(char *format, ...)
89 90
90static void tracer_segv(int sig, struct sigcontext sc) 91static void tracer_segv(int sig, struct sigcontext sc)
91{ 92{
93 struct faultinfo fi;
94 GET_FAULTINFO_FROM_SC(fi, &sc);
92 printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n", 95 printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n",
93 SC_FAULT_ADDR(&sc), SC_IP(&sc)); 96 FAULT_ADDRESS(fi), SC_IP(&sc));
94 while(1) 97 while(1)
95 pause(); 98 pause();
96} 99}
@@ -117,6 +120,7 @@ static int signal_tramp(void *arg)
117 signal(SIGSEGV, (__sighandler_t) sig_handler); 120 signal(SIGSEGV, (__sighandler_t) sig_handler);
118 set_cmdline("(idle thread)"); 121 set_cmdline("(idle thread)");
119 set_init_pid(os_getpid()); 122 set_init_pid(os_getpid());
123 init_irq_signals(0);
120 proc = arg; 124 proc = arg;
121 return((*proc)(NULL)); 125 return((*proc)(NULL));
122} 126}
diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c
index 92a3820ca543..fc108615beaf 100644
--- a/arch/um/kernel/tt/trap_user.c
+++ b/arch/um/kernel/tt/trap_user.c
@@ -7,6 +7,7 @@
7#include <errno.h> 7#include <errno.h>
8#include <signal.h> 8#include <signal.h>
9#include "sysdep/ptrace.h" 9#include "sysdep/ptrace.h"
10#include "sysdep/sigcontext.h"
10#include "signal_user.h" 11#include "signal_user.h"
11#include "user_util.h" 12#include "user_util.h"
12#include "kern_util.h" 13#include "kern_util.h"
@@ -28,6 +29,11 @@ void sig_handler_common_tt(int sig, void *sc_ptr)
28 change_sig(SIGSEGV, 1); 29 change_sig(SIGSEGV, 1);
29 30
30 r = &TASK_REGS(get_current())->tt; 31 r = &TASK_REGS(get_current())->tt;
32 if ( sig == SIGFPE || sig == SIGSEGV ||
33 sig == SIGBUS || sig == SIGILL ||
34 sig == SIGTRAP ) {
35 GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
36 }
31 save_regs = *r; 37 save_regs = *r;
32 is_user = user_context(SC_SP(sc)); 38 is_user = user_context(SC_SP(sc));
33 r->sc = sc; 39 r->sc = sc;
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 5c49d88eed3d..4d10ec372a67 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -23,6 +23,7 @@
23#include "asm/ptrace.h" 23#include "asm/ptrace.h"
24#include "asm/elf.h" 24#include "asm/elf.h"
25#include "asm/user.h" 25#include "asm/user.h"
26#include "asm/setup.h"
26#include "ubd_user.h" 27#include "ubd_user.h"
27#include "asm/current.h" 28#include "asm/current.h"
28#include "asm/setup.h" 29#include "asm/setup.h"
@@ -42,9 +43,9 @@
42#define DEFAULT_COMMAND_LINE "root=98:0" 43#define DEFAULT_COMMAND_LINE "root=98:0"
43 44
44/* Changed in linux_main and setup_arch, which run before SMP is started */ 45/* Changed in linux_main and setup_arch, which run before SMP is started */
45char command_line[COMMAND_LINE_SIZE] = { 0 }; 46static char command_line[COMMAND_LINE_SIZE] = { 0 };
46 47
47void add_arg(char *arg) 48static void add_arg(char *arg)
48{ 49{
49 if (strlen(command_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) { 50 if (strlen(command_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) {
50 printf("add_arg: Too many command line arguments!\n"); 51 printf("add_arg: Too many command line arguments!\n");
@@ -449,7 +450,7 @@ void __init setup_arch(char **cmdline_p)
449{ 450{
450 notifier_chain_register(&panic_notifier_list, &panic_exit_notifier); 451 notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
451 paging_init(); 452 paging_init();
452 strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); 453 strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
453 *cmdline_p = command_line; 454 *cmdline_p = command_line;
454 setup_hostinfo(); 455 setup_hostinfo();
455} 456}
diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S
new file mode 100644
index 000000000000..1660a769674b
--- /dev/null
+++ b/arch/um/kernel/vmlinux.lds.S
@@ -0,0 +1,6 @@
1#include <linux/config.h>
2#ifdef CONFIG_LD_SCRIPT_STATIC
3#include "uml.lds.S"
4#else
5#include "dyn.lds.S"
6#endif
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index ba9ca1cc790a..1e126bfd31a7 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -123,6 +123,11 @@ int os_getpid(void)
123 return(getpid()); 123 return(getpid());
124} 124}
125 125
126int os_getpgrp(void)
127{
128 return getpgrp();
129}
130
126int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len, 131int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
127 int r, int w, int x) 132 int r, int w, int x)
128{ 133{
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 7eac1baf5975..c7bfd5ee3925 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -8,7 +8,7 @@
8#include "mode.h" 8#include "mode.h"
9#include "sysdep/signal.h" 9#include "sysdep/signal.h"
10 10
11void sig_handler(int sig) 11void sig_handler(ARCH_SIGHDLR_PARAM)
12{ 12{
13 struct sigcontext *sc; 13 struct sigcontext *sc;
14 14
@@ -19,7 +19,7 @@ void sig_handler(int sig)
19 19
20extern int timer_irq_inited; 20extern int timer_irq_inited;
21 21
22void alarm_handler(int sig) 22void alarm_handler(ARCH_SIGHDLR_PARAM)
23{ 23{
24 struct sigcontext *sc; 24 struct sigcontext *sc;
25 25
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index 148645b14480..9a0ad094d926 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -105,14 +105,15 @@ void init_registers(int pid)
105 panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", 105 panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
106 err); 106 err);
107 107
108 errno = 0;
108 err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs); 109 err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
109 if(!err) 110 if(!err)
110 return; 111 return;
112 if(errno != EIO)
113 panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
114 errno);
111 115
112 have_fpx_regs = 0; 116 have_fpx_regs = 0;
113 if(err != EIO)
114 panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
115 err);
116 117
117 err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs); 118 err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
118 if(err) 119 if(err)
diff --git a/arch/um/os-Linux/util/Makefile b/arch/um/os-Linux/util/Makefile
index fb00ddf969bd..9778aed0c314 100644
--- a/arch/um/os-Linux/util/Makefile
+++ b/arch/um/os-Linux/util/Makefile
@@ -1,4 +1,4 @@
1hostprogs-y := mk_user_constants 1hostprogs-y := mk_user_constants
2always := $(hostprogs-y) 2always := $(hostprogs-y)
3 3
4mk_user_constants-objs := mk_user_constants.o 4HOSTCFLAGS_mk_user_constants.o := -I$(objtree)/arch/um
diff --git a/arch/um/os-Linux/util/mk_user_constants.c b/arch/um/os-Linux/util/mk_user_constants.c
index 0933518aa8bd..4838f30eecf0 100644
--- a/arch/um/os-Linux/util/mk_user_constants.c
+++ b/arch/um/os-Linux/util/mk_user_constants.c
@@ -1,11 +1,5 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <asm/types.h> 2#include <user-offsets.h>
3/* For some reason, x86_64 nowhere defines u64 and u32, even though they're
4 * used throughout the headers.
5 */
6typedef __u64 u64;
7typedef __u32 u32;
8#include <asm/user.h>
9 3
10int main(int argc, char **argv) 4int main(int argc, char **argv)
11{ 5{
@@ -20,7 +14,7 @@ int main(int argc, char **argv)
20 * x86_64 (216 vs 168 bytes). user_regs_struct is the correct size on 14 * x86_64 (216 vs 168 bytes). user_regs_struct is the correct size on
21 * both x86_64 and i386. 15 * both x86_64 and i386.
22 */ 16 */
23 printf("#define UM_FRAME_SIZE %d\n", (int) sizeof(struct user_regs_struct)); 17 printf("#define UM_FRAME_SIZE %d\n", __UM_FRAME_SIZE);
24 18
25 printf("\n"); 19 printf("\n");
26 printf("#endif\n"); 20 printf("#endif\n");
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 143f6fea0763..0b2491883d9c 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -2,12 +2,27 @@
2# arch/um: Generic definitions 2# arch/um: Generic definitions
3# =========================================================================== 3# ===========================================================================
4 4
5USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs)) 5USER_SINGLE_OBJS := \
6USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) 6 $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
7 7USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS))
8USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) 8USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
9 9
10$(USER_OBJS): c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(notdir $@)) 10$(USER_OBJS) : c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \
11 $(CFLAGS_$(notdir $@))
11 12
12quiet_cmd_make_link = SYMLINK $@ 13quiet_cmd_make_link = SYMLINK $@
13cmd_make_link = rm -f $@; ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@ 14cmd_make_link = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@
15
16# this needs to be before the foreach, because targets does not accept
17# complete paths like $(obj)/$(f). To make sure this works, use a := assignment,
18# or we will get $(obj)/$(f) in the "targets" value.
19# Also, this forces you to use the := syntax when assigning to targets.
20# Otherwise the line below will cause an infinite loop (if you don't know why,
21# just do it).
22
23targets := $(targets) $(SYMLINKS)
24
25SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$(f))
26
27$(SYMLINKS): FORCE
28 $(call if_changed,make_link)
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 71b47e618605..fcd67c3414e4 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -1,29 +1,19 @@
1obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ 1obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
2 ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o 2 ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o \
3 sys_call_table.o
3 4
4obj-$(CONFIG_HIGHMEM) += highmem.o 5obj-$(CONFIG_HIGHMEM) += highmem.o
5obj-$(CONFIG_MODULES) += module.o 6obj-$(CONFIG_MODULES) += module.o
6 7
7USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o 8USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
8 9
9include arch/um/scripts/Makefile.rules
10
11SYMLINKS = bitops.c semaphore.c highmem.c module.c 10SYMLINKS = bitops.c semaphore.c highmem.c module.c
12 11
13# this needs to be before the foreach, because clean-files does not accept
14# complete paths like $(src)/$f.
15clean-files := $(SYMLINKS)
16
17targets += $(SYMLINKS)
18
19SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$f)
20
21bitops.c-dir = lib 12bitops.c-dir = lib
22semaphore.c-dir = kernel 13semaphore.c-dir = kernel
23highmem.c-dir = mm 14highmem.c-dir = mm
24module.c-dir = kernel 15module.c-dir = kernel
25 16
26$(SYMLINKS): FORCE
27 $(call if_changed,make_link)
28
29subdir- := util 17subdir- := util
18
19include arch/um/scripts/Makefile.rules
diff --git a/arch/um/sys-i386/checksum.S b/arch/um/sys-i386/checksum.S
index a11171fb6223..d98b2fff3d08 100644
--- a/arch/um/sys-i386/checksum.S
+++ b/arch/um/sys-i386/checksum.S
@@ -38,7 +38,7 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
38 38
39.text 39.text
40.align 4 40.align 4
41.globl arch_csum_partial 41.globl csum_partial
42 42
43#ifndef CONFIG_X86_USE_PPRO_CHECKSUM 43#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
44 44
@@ -49,7 +49,7 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
49 * Fortunately, it is easy to convert 2-byte alignment to 4-byte 49 * Fortunately, it is easy to convert 2-byte alignment to 4-byte
50 * alignment for the unrolled loop. 50 * alignment for the unrolled loop.
51 */ 51 */
52arch_csum_partial: 52csum_partial:
53 pushl %esi 53 pushl %esi
54 pushl %ebx 54 pushl %ebx
55 movl 20(%esp),%eax # Function arg: unsigned int sum 55 movl 20(%esp),%eax # Function arg: unsigned int sum
@@ -119,7 +119,7 @@ arch_csum_partial:
119 119
120/* Version for PentiumII/PPro */ 120/* Version for PentiumII/PPro */
121 121
122arch_csum_partial: 122csum_partial:
123 pushl %esi 123 pushl %esi
124 pushl %ebx 124 pushl %ebx
125 movl 20(%esp),%eax # Function arg: unsigned int sum 125 movl 20(%esp),%eax # Function arg: unsigned int sum
diff --git a/arch/um/sys-i386/delay.c b/arch/um/sys-i386/delay.c
index 20d37dbbaf08..e9892eef51ce 100644
--- a/arch/um/sys-i386/delay.c
+++ b/arch/um/sys-i386/delay.c
@@ -1,3 +1,6 @@
1#include "linux/delay.h"
2#include "asm/param.h"
3
1void __delay(unsigned long time) 4void __delay(unsigned long time)
2{ 5{
3 /* Stolen from the i386 __loop_delay */ 6 /* Stolen from the i386 __loop_delay */
@@ -12,3 +15,18 @@ void __delay(unsigned long time)
12 :"0" (time)); 15 :"0" (time));
13} 16}
14 17
18void __udelay(unsigned long usecs)
19{
20 int i, n;
21
22 n = (loops_per_jiffy * HZ * usecs) / MILLION;
23 for(i=0;i<n;i++) ;
24}
25
26void __const_udelay(unsigned long usecs)
27{
28 int i, n;
29
30 n = (loops_per_jiffy * HZ * usecs) / MILLION;
31 for(i=0;i<n;i++) ;
32}
diff --git a/arch/um/sys-i386/kernel-offsets.c b/arch/um/sys-i386/kernel-offsets.c
new file mode 100644
index 000000000000..9f8ecd1fdd96
--- /dev/null
+++ b/arch/um/sys-i386/kernel-offsets.c
@@ -0,0 +1,25 @@
1#include <linux/config.h>
2#include <linux/stddef.h>
3#include <linux/sched.h>
4#include <linux/time.h>
5#include <asm/page.h>
6
7#define DEFINE(sym, val) \
8 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
9
10#define STR(x) #x
11#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " STR(val) " " #val: : )
12
13#define BLANK() asm volatile("\n->" : : )
14
15#define OFFSET(sym, str, mem) \
16 DEFINE(sym, offsetof(struct str, mem));
17
18void foo(void)
19{
20 OFFSET(TASK_DEBUGREGS, task_struct, thread.arch.debugregs);
21#ifdef CONFIG_MODE_TT
22 OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
23#endif
24#include <common-offsets.h>
25}
diff --git a/arch/um/sys-i386/ksyms.c b/arch/um/sys-i386/ksyms.c
index 74f70a120458..db524ab3f743 100644
--- a/arch/um/sys-i386/ksyms.c
+++ b/arch/um/sys-i386/ksyms.c
@@ -2,6 +2,7 @@
2#include "linux/in6.h" 2#include "linux/in6.h"
3#include "linux/rwsem.h" 3#include "linux/rwsem.h"
4#include "asm/byteorder.h" 4#include "asm/byteorder.h"
5#include "asm/delay.h"
5#include "asm/semaphore.h" 6#include "asm/semaphore.h"
6#include "asm/uaccess.h" 7#include "asm/uaccess.h"
7#include "asm/checksum.h" 8#include "asm/checksum.h"
@@ -13,5 +14,8 @@ EXPORT_SYMBOL(__down_failed_trylock);
13EXPORT_SYMBOL(__up_wakeup); 14EXPORT_SYMBOL(__up_wakeup);
14 15
15/* Networking helper routines. */ 16/* Networking helper routines. */
16EXPORT_SYMBOL(csum_partial_copy_from); 17EXPORT_SYMBOL(csum_partial);
17EXPORT_SYMBOL(csum_partial_copy_to); 18
19/* delay core functions */
20EXPORT_SYMBOL(__const_udelay);
21EXPORT_SYMBOL(__udelay);
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index 31bcb2f997d4..dc755b0b9db8 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -25,7 +25,7 @@ int sys_modify_ldt_tt(int func, void __user *ptr, unsigned long bytecount)
25#endif 25#endif
26 26
27#ifdef CONFIG_MODE_SKAS 27#ifdef CONFIG_MODE_SKAS
28extern int userspace_pid; 28extern int userspace_pid[];
29 29
30#include "skas_ptrace.h" 30#include "skas_ptrace.h"
31 31
@@ -56,7 +56,8 @@ int sys_modify_ldt_skas(int func, void __user *ptr, unsigned long bytecount)
56 ldt = ((struct ptrace_ldt) { .func = func, 56 ldt = ((struct ptrace_ldt) { .func = func,
57 .ptr = buf, 57 .ptr = buf,
58 .bytecount = bytecount }); 58 .bytecount = bytecount });
59 res = ptrace(PTRACE_LDT, userspace_pid, 0, (unsigned long) &ldt); 59#warning Need to look up userspace_pid by cpu
60 res = ptrace(PTRACE_LDT, userspace_pid[0], 0, (unsigned long) &ldt);
60 if(res < 0) 61 if(res < 0)
61 goto out; 62 goto out;
62 63
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index e470d28cdf84..e839ce65ad28 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -73,6 +73,25 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
73 return 0; 73 return 0;
74} 74}
75 75
76int poke_user(struct task_struct *child, long addr, long data)
77{
78 if ((addr & 3) || addr < 0)
79 return -EIO;
80
81 if (addr < MAX_REG_OFFSET)
82 return putreg(child, addr, data);
83
84 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
85 (addr <= offsetof(struct user, u_debugreg[7]))){
86 addr -= offsetof(struct user, u_debugreg[0]);
87 addr = addr >> 2;
88 if((addr == 4) || (addr == 5)) return -EIO;
89 child->thread.arch.debugregs[addr] = data;
90 return 0;
91 }
92 return -EIO;
93}
94
76unsigned long getreg(struct task_struct *child, int regno) 95unsigned long getreg(struct task_struct *child, int regno)
77{ 96{
78 unsigned long retval = ~0UL; 97 unsigned long retval = ~0UL;
@@ -93,6 +112,27 @@ unsigned long getreg(struct task_struct *child, int regno)
93 return retval; 112 return retval;
94} 113}
95 114
115int peek_user(struct task_struct *child, long addr, long data)
116{
117/* read the word at location addr in the USER area. */
118 unsigned long tmp;
119
120 if ((addr & 3) || addr < 0)
121 return -EIO;
122
123 tmp = 0; /* Default return condition */
124 if(addr < MAX_REG_OFFSET){
125 tmp = getreg(child, addr);
126 }
127 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
128 (addr <= offsetof(struct user, u_debugreg[7]))){
129 addr -= offsetof(struct user, u_debugreg[0]);
130 addr = addr >> 2;
131 tmp = child->thread.arch.debugregs[addr];
132 }
133 return put_user(tmp, (unsigned long *) data);
134}
135
96struct i387_fxsave_struct { 136struct i387_fxsave_struct {
97 unsigned short cwd; 137 unsigned short cwd;
98 unsigned short swd; 138 unsigned short swd;
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 76ba87254b25..03913ca5d256 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -47,9 +47,6 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
47 REGS_CS(regs->regs.skas.regs) = sc.cs; 47 REGS_CS(regs->regs.skas.regs) = sc.cs;
48 REGS_EFLAGS(regs->regs.skas.regs) = sc.eflags; 48 REGS_EFLAGS(regs->regs.skas.regs) = sc.eflags;
49 REGS_SS(regs->regs.skas.regs) = sc.ss; 49 REGS_SS(regs->regs.skas.regs) = sc.ss;
50 regs->regs.skas.fault_addr = sc.cr2;
51 regs->regs.skas.fault_type = FAULT_WRITE(sc.err);
52 regs->regs.skas.trap_type = sc.trapno;
53 50
54 err = restore_fp_registers(userspace_pid[0], fpregs); 51 err = restore_fp_registers(userspace_pid[0], fpregs);
55 if(err < 0){ 52 if(err < 0){
@@ -62,11 +59,11 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
62} 59}
63 60
64int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, 61int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
65 struct pt_regs *regs, unsigned long fault_addr, 62 struct pt_regs *regs)
66 int fault_type)
67{ 63{
68 struct sigcontext sc; 64 struct sigcontext sc;
69 unsigned long fpregs[HOST_FP_SIZE]; 65 unsigned long fpregs[HOST_FP_SIZE];
66 struct faultinfo * fi = &current->thread.arch.faultinfo;
70 int err; 67 int err;
71 68
72 sc.gs = REGS_GS(regs->regs.skas.regs); 69 sc.gs = REGS_GS(regs->regs.skas.regs);
@@ -86,9 +83,9 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
86 sc.eflags = REGS_EFLAGS(regs->regs.skas.regs); 83 sc.eflags = REGS_EFLAGS(regs->regs.skas.regs);
87 sc.esp_at_signal = regs->regs.skas.regs[UESP]; 84 sc.esp_at_signal = regs->regs.skas.regs[UESP];
88 sc.ss = regs->regs.skas.regs[SS]; 85 sc.ss = regs->regs.skas.regs[SS];
89 sc.cr2 = fault_addr; 86 sc.cr2 = fi->cr2;
90 sc.err = TO_SC_ERR(fault_type); 87 sc.err = fi->error_code;
91 sc.trapno = regs->regs.skas.trap_type; 88 sc.trapno = fi->trap_no;
92 89
93 err = save_fp_registers(userspace_pid[0], fpregs); 90 err = save_fp_registers(userspace_pid[0], fpregs);
94 if(err < 0){ 91 if(err < 0){
@@ -167,9 +164,7 @@ static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp,
167{ 164{
168 return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), 165 return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
169 sizeof(*fp)), 166 sizeof(*fp)),
170 copy_sc_to_user_skas(to, fp, from, 167 copy_sc_to_user_skas(to, fp, from)));
171 current->thread.cr2,
172 current->thread.err)));
173} 168}
174 169
175static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp, 170static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp,
diff --git a/arch/um/sys-i386/sys_call_table.S b/arch/um/sys-i386/sys_call_table.S
new file mode 100644
index 000000000000..ad75c27afe38
--- /dev/null
+++ b/arch/um/sys-i386/sys_call_table.S
@@ -0,0 +1,16 @@
1#include <linux/linkage.h>
2/* Steal i386 syscall table for our purposes, but with some slight changes.*/
3
4#define sys_iopl sys_ni_syscall
5#define sys_ioperm sys_ni_syscall
6
7#define sys_vm86old sys_ni_syscall
8#define sys_vm86 sys_ni_syscall
9#define sys_set_thread_area sys_ni_syscall
10#define sys_get_thread_area sys_ni_syscall
11
12#define sys_stime um_stime
13#define sys_time um_time
14#define old_mmap old_mmap_i386
15
16#include "../../i386/kernel/syscall_table.S"
diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c
new file mode 100644
index 000000000000..3ceaabceb3d7
--- /dev/null
+++ b/arch/um/sys-i386/user-offsets.c
@@ -0,0 +1,69 @@
1#include <stdio.h>
2#include <signal.h>
3#include <asm/ptrace.h>
4#include <asm/user.h>
5#include <linux/stddef.h>
6
7#define DEFINE(sym, val) \
8 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
9
10#define OFFSET(sym, str, mem) \
11 DEFINE(sym, offsetof(struct str, mem));
12
13void foo(void)
14{
15 OFFSET(SC_IP, sigcontext, eip);
16 OFFSET(SC_SP, sigcontext, esp);
17 OFFSET(SC_FS, sigcontext, fs);
18 OFFSET(SC_GS, sigcontext, gs);
19 OFFSET(SC_DS, sigcontext, ds);
20 OFFSET(SC_ES, sigcontext, es);
21 OFFSET(SC_SS, sigcontext, ss);
22 OFFSET(SC_CS, sigcontext, cs);
23 OFFSET(SC_EFLAGS, sigcontext, eflags);
24 OFFSET(SC_EAX, sigcontext, eax);
25 OFFSET(SC_EBX, sigcontext, ebx);
26 OFFSET(SC_ECX, sigcontext, ecx);
27 OFFSET(SC_EDX, sigcontext, edx);
28 OFFSET(SC_EDI, sigcontext, edi);
29 OFFSET(SC_ESI, sigcontext, esi);
30 OFFSET(SC_EBP, sigcontext, ebp);
31 OFFSET(SC_TRAPNO, sigcontext, trapno);
32 OFFSET(SC_ERR, sigcontext, err);
33 OFFSET(SC_CR2, sigcontext, cr2);
34 OFFSET(SC_FPSTATE, sigcontext, fpstate);
35 OFFSET(SC_SIGMASK, sigcontext, oldmask);
36 OFFSET(SC_FP_CW, _fpstate, cw);
37 OFFSET(SC_FP_SW, _fpstate, sw);
38 OFFSET(SC_FP_TAG, _fpstate, tag);
39 OFFSET(SC_FP_IPOFF, _fpstate, ipoff);
40 OFFSET(SC_FP_CSSEL, _fpstate, cssel);
41 OFFSET(SC_FP_DATAOFF, _fpstate, dataoff);
42 OFFSET(SC_FP_DATASEL, _fpstate, datasel);
43 OFFSET(SC_FP_ST, _fpstate, _st);
44 OFFSET(SC_FXSR_ENV, _fpstate, _fxsr_env);
45
46 DEFINE(HOST_FRAME_SIZE, FRAME_SIZE);
47 DEFINE(HOST_FP_SIZE,
48 sizeof(struct user_i387_struct) / sizeof(unsigned long));
49 DEFINE(HOST_XFP_SIZE,
50 sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
51
52 DEFINE(HOST_IP, EIP);
53 DEFINE(HOST_SP, UESP);
54 DEFINE(HOST_EFLAGS, EFL);
55 DEFINE(HOST_EAX, EAX);
56 DEFINE(HOST_EBX, EBX);
57 DEFINE(HOST_ECX, ECX);
58 DEFINE(HOST_EDX, EDX);
59 DEFINE(HOST_ESI, ESI);
60 DEFINE(HOST_EDI, EDI);
61 DEFINE(HOST_EBP, EBP);
62 DEFINE(HOST_CS, CS);
63 DEFINE(HOST_SS, SS);
64 DEFINE(HOST_DS, DS);
65 DEFINE(HOST_FS, FS);
66 DEFINE(HOST_ES, ES);
67 DEFINE(HOST_GS, GS);
68 DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct));
69}
diff --git a/arch/um/sys-i386/util/Makefile b/arch/um/sys-i386/util/Makefile
index 34860f9ca7b0..bf61afd0b045 100644
--- a/arch/um/sys-i386/util/Makefile
+++ b/arch/um/sys-i386/util/Makefile
@@ -1,8 +1,5 @@
1
2hostprogs-y := mk_sc mk_thread 1hostprogs-y := mk_sc mk_thread
3always := $(hostprogs-y) 2always := $(hostprogs-y)
4 3
5mk_thread-objs := mk_thread_kern.o mk_thread_user.o 4HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um
6 5HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um
7HOSTCFLAGS_mk_thread_kern.o := $(CFLAGS) $(CPPFLAGS)
8HOSTCFLAGS_mk_thread_user.o := $(USER_CFLAGS)
diff --git a/arch/um/sys-i386/util/mk_sc.c b/arch/um/sys-i386/util/mk_sc.c
index 85cbd30396f7..04c0d73433aa 100644
--- a/arch/um/sys-i386/util/mk_sc.c
+++ b/arch/um/sys-i386/util/mk_sc.c
@@ -1,52 +1,51 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <signal.h> 2#include <user-offsets.h>
3#include <linux/stddef.h>
4 3
5#define SC_OFFSET(name, field) \ 4#define SC_OFFSET(name, field) \
6 printf("#define " name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\ 5 printf("#define " #name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
7 offsetof(struct sigcontext, field)) 6 name)
8 7
9#define SC_FP_OFFSET(name, field) \ 8#define SC_FP_OFFSET(name, field) \
10 printf("#define " name \ 9 printf("#define " #name \
11 "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\ 10 "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
12 offsetof(struct _fpstate, field)) 11 name)
13 12
14#define SC_FP_OFFSET_PTR(name, field, type) \ 13#define SC_FP_OFFSET_PTR(name, field, type) \
15 printf("#define " name \ 14 printf("#define " #name \
16 "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\ 15 "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
17 offsetof(struct _fpstate, field)) 16 name)
18 17
19int main(int argc, char **argv) 18int main(int argc, char **argv)
20{ 19{
21 SC_OFFSET("SC_IP", eip); 20 SC_OFFSET(SC_IP, eip);
22 SC_OFFSET("SC_SP", esp); 21 SC_OFFSET(SC_SP, esp);
23 SC_OFFSET("SC_FS", fs); 22 SC_OFFSET(SC_FS, fs);
24 SC_OFFSET("SC_GS", gs); 23 SC_OFFSET(SC_GS, gs);
25 SC_OFFSET("SC_DS", ds); 24 SC_OFFSET(SC_DS, ds);
26 SC_OFFSET("SC_ES", es); 25 SC_OFFSET(SC_ES, es);
27 SC_OFFSET("SC_SS", ss); 26 SC_OFFSET(SC_SS, ss);
28 SC_OFFSET("SC_CS", cs); 27 SC_OFFSET(SC_CS, cs);
29 SC_OFFSET("SC_EFLAGS", eflags); 28 SC_OFFSET(SC_EFLAGS, eflags);
30 SC_OFFSET("SC_EAX", eax); 29 SC_OFFSET(SC_EAX, eax);
31 SC_OFFSET("SC_EBX", ebx); 30 SC_OFFSET(SC_EBX, ebx);
32 SC_OFFSET("SC_ECX", ecx); 31 SC_OFFSET(SC_ECX, ecx);
33 SC_OFFSET("SC_EDX", edx); 32 SC_OFFSET(SC_EDX, edx);
34 SC_OFFSET("SC_EDI", edi); 33 SC_OFFSET(SC_EDI, edi);
35 SC_OFFSET("SC_ESI", esi); 34 SC_OFFSET(SC_ESI, esi);
36 SC_OFFSET("SC_EBP", ebp); 35 SC_OFFSET(SC_EBP, ebp);
37 SC_OFFSET("SC_TRAPNO", trapno); 36 SC_OFFSET(SC_TRAPNO, trapno);
38 SC_OFFSET("SC_ERR", err); 37 SC_OFFSET(SC_ERR, err);
39 SC_OFFSET("SC_CR2", cr2); 38 SC_OFFSET(SC_CR2, cr2);
40 SC_OFFSET("SC_FPSTATE", fpstate); 39 SC_OFFSET(SC_FPSTATE, fpstate);
41 SC_OFFSET("SC_SIGMASK", oldmask); 40 SC_OFFSET(SC_SIGMASK, oldmask);
42 SC_FP_OFFSET("SC_FP_CW", cw); 41 SC_FP_OFFSET(SC_FP_CW, cw);
43 SC_FP_OFFSET("SC_FP_SW", sw); 42 SC_FP_OFFSET(SC_FP_SW, sw);
44 SC_FP_OFFSET("SC_FP_TAG", tag); 43 SC_FP_OFFSET(SC_FP_TAG, tag);
45 SC_FP_OFFSET("SC_FP_IPOFF", ipoff); 44 SC_FP_OFFSET(SC_FP_IPOFF, ipoff);
46 SC_FP_OFFSET("SC_FP_CSSEL", cssel); 45 SC_FP_OFFSET(SC_FP_CSSEL, cssel);
47 SC_FP_OFFSET("SC_FP_DATAOFF", dataoff); 46 SC_FP_OFFSET(SC_FP_DATAOFF, dataoff);
48 SC_FP_OFFSET("SC_FP_DATASEL", datasel); 47 SC_FP_OFFSET(SC_FP_DATASEL, datasel);
49 SC_FP_OFFSET_PTR("SC_FP_ST", _st, "struct _fpstate"); 48 SC_FP_OFFSET_PTR(SC_FP_ST, _st, "struct _fpstate");
50 SC_FP_OFFSET_PTR("SC_FXSR_ENV", _fxsr_env, "void"); 49 SC_FP_OFFSET_PTR(SC_FXSR_ENV, _fxsr_env, "void");
51 return(0); 50 return(0);
52} 51}
diff --git a/arch/um/sys-i386/util/mk_thread.c b/arch/um/sys-i386/util/mk_thread.c
new file mode 100644
index 000000000000..7470d0dda67e
--- /dev/null
+++ b/arch/um/sys-i386/util/mk_thread.c
@@ -0,0 +1,22 @@
1#include <stdio.h>
2#include <kernel-offsets.h>
3
4int main(int argc, char **argv)
5{
6 printf("/*\n");
7 printf(" * Generated by mk_thread\n");
8 printf(" */\n");
9 printf("\n");
10 printf("#ifndef __UM_THREAD_H\n");
11 printf("#define __UM_THREAD_H\n");
12 printf("\n");
13 printf("#define TASK_DEBUGREGS(task) ((unsigned long *) "
14 "&(((char *) (task))[%d]))\n", TASK_DEBUGREGS);
15#ifdef TASK_EXTERN_PID
16 printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n",
17 TASK_EXTERN_PID);
18#endif
19 printf("\n");
20 printf("#endif\n");
21 return(0);
22}
diff --git a/arch/um/sys-i386/util/mk_thread_kern.c b/arch/um/sys-i386/util/mk_thread_kern.c
deleted file mode 100644
index 948b1ce85230..000000000000
--- a/arch/um/sys-i386/util/mk_thread_kern.c
+++ /dev/null
@@ -1,22 +0,0 @@
1#include "linux/config.h"
2#include "linux/stddef.h"
3#include "linux/sched.h"
4
5extern void print_head(void);
6extern void print_constant_ptr(char *name, int value);
7extern void print_constant(char *name, char *type, int value);
8extern void print_tail(void);
9
10#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field)
11
12int main(int argc, char **argv)
13{
14 print_head();
15 print_constant_ptr("TASK_DEBUGREGS", THREAD_OFFSET(arch.debugregs));
16#ifdef CONFIG_MODE_TT
17 print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid));
18#endif
19 print_tail();
20 return(0);
21}
22
diff --git a/arch/um/sys-i386/util/mk_thread_user.c b/arch/um/sys-i386/util/mk_thread_user.c
deleted file mode 100644
index 2620cd6aa1f1..000000000000
--- a/arch/um/sys-i386/util/mk_thread_user.c
+++ /dev/null
@@ -1,30 +0,0 @@
1#include <stdio.h>
2
3void print_head(void)
4{
5 printf("/*\n");
6 printf(" * Generated by mk_thread\n");
7 printf(" */\n");
8 printf("\n");
9 printf("#ifndef __UM_THREAD_H\n");
10 printf("#define __UM_THREAD_H\n");
11 printf("\n");
12}
13
14void print_constant_ptr(char *name, int value)
15{
16 printf("#define %s(task) ((unsigned long *) "
17 "&(((char *) (task))[%d]))\n", name, value);
18}
19
20void print_constant(char *name, char *type, int value)
21{
22 printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
23 value);
24}
25
26void print_tail(void)
27{
28 printf("\n");
29 printf("#endif\n");
30}
diff --git a/arch/um/sys-ppc/ptrace.c b/arch/um/sys-ppc/ptrace.c
index a971366d3277..8e71b47f2b8e 100644
--- a/arch/um/sys-ppc/ptrace.c
+++ b/arch/um/sys-ppc/ptrace.c
@@ -8,6 +8,25 @@ int putreg(struct task_struct *child, unsigned long regno,
8 return 0; 8 return 0;
9} 9}
10 10
11int poke_user(struct task_struct *child, long addr, long data)
12{
13 if ((addr & 3) || addr < 0)
14 return -EIO;
15
16 if (addr < MAX_REG_OFFSET)
17 return putreg(child, addr, data);
18
19 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
20 (addr <= offsetof(struct user, u_debugreg[7]))){
21 addr -= offsetof(struct user, u_debugreg[0]);
22 addr = addr >> 2;
23 if((addr == 4) || (addr == 5)) return -EIO;
24 child->thread.arch.debugregs[addr] = data;
25 return 0;
26 }
27 return -EIO;
28}
29
11unsigned long getreg(struct task_struct *child, unsigned long regno) 30unsigned long getreg(struct task_struct *child, unsigned long regno)
12{ 31{
13 unsigned long retval = ~0UL; 32 unsigned long retval = ~0UL;
@@ -16,6 +35,27 @@ unsigned long getreg(struct task_struct *child, unsigned long regno)
16 return retval; 35 return retval;
17} 36}
18 37
38int peek_user(struct task_struct *child, long addr, long data)
39{
40 /* read the word at location addr in the USER area. */
41 unsigned long tmp;
42
43 if ((addr & 3) || addr < 0)
44 return -EIO;
45
46 tmp = 0; /* Default return condition */
47 if(addr < MAX_REG_OFFSET){
48 tmp = getreg(child, addr);
49 }
50 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
51 (addr <= offsetof(struct user, u_debugreg[7]))){
52 addr -= offsetof(struct user, u_debugreg[0]);
53 addr = addr >> 2;
54 tmp = child->thread.arch.debugregs[addr];
55 }
56 return put_user(tmp, (unsigned long *) data);
57}
58
19/* 59/*
20 * Overrides for Emacs so that we follow Linus's tabbing style. 60 * Overrides for Emacs so that we follow Linus's tabbing style.
21 * Emacs will notice this stuff at the end of the file and automatically 61 * Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index 2129e3143559..3d7da911cc8c 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -4,24 +4,20 @@
4# Licensed under the GPL 4# Licensed under the GPL
5# 5#
6 6
7#XXX: why into lib-y?
7lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \ 8lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \
8 ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \ 9 ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \
9 syscalls.o sysrq.o thunk.o 10 syscalls.o sysrq.o thunk.o syscall_table.o
11
12obj-y := ksyms.o
13obj-$(CONFIG_MODULES) += module.o um_module.o
10 14
11USER_OBJS := ptrace_user.o sigcontext.o 15USER_OBJS := ptrace_user.o sigcontext.o
12 16
13include arch/um/scripts/Makefile.rules 17include arch/um/scripts/Makefile.rules
14 18
15SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \ 19SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \
16 semaphore.c thunk.S 20 semaphore.c thunk.S module.c
17
18# this needs to be before the foreach, because clean-files does not accept
19# complete paths like $(src)/$f.
20clean-files := $(SYMLINKS)
21
22targets += $(SYMLINKS)
23
24SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$f)
25 21
26bitops.c-dir = lib 22bitops.c-dir = lib
27csum-copy.S-dir = lib 23csum-copy.S-dir = lib
@@ -30,8 +26,8 @@ csum-wrappers.c-dir = lib
30memcpy.S-dir = lib 26memcpy.S-dir = lib
31semaphore.c-dir = kernel 27semaphore.c-dir = kernel
32thunk.S-dir = lib 28thunk.S-dir = lib
33 29module.c-dir = kernel
34$(SYMLINKS): FORCE
35 $(call if_changed,make_link)
36 30
37CFLAGS_csum-partial.o := -Dcsum_partial=arch_csum_partial 31CFLAGS_csum-partial.o := -Dcsum_partial=arch_csum_partial
32
33subdir- := util
diff --git a/arch/um/sys-x86_64/delay.c b/arch/um/sys-x86_64/delay.c
index f3b5187942b4..651332aeec22 100644
--- a/arch/um/sys-x86_64/delay.c
+++ b/arch/um/sys-x86_64/delay.c
@@ -5,7 +5,9 @@
5 * Licensed under the GPL 5 * Licensed under the GPL
6 */ 6 */
7 7
8#include "linux/delay.h"
8#include "asm/processor.h" 9#include "asm/processor.h"
10#include "asm/param.h"
9 11
10void __delay(unsigned long loops) 12void __delay(unsigned long loops)
11{ 13{
@@ -14,6 +16,22 @@ void __delay(unsigned long loops)
14 for(i = 0; i < loops; i++) ; 16 for(i = 0; i < loops; i++) ;
15} 17}
16 18
19void __udelay(unsigned long usecs)
20{
21 int i, n;
22
23 n = (loops_per_jiffy * HZ * usecs) / MILLION;
24 for(i=0;i<n;i++) ;
25}
26
27void __const_udelay(unsigned long usecs)
28{
29 int i, n;
30
31 n = (loops_per_jiffy * HZ * usecs) / MILLION;
32 for(i=0;i<n;i++) ;
33}
34
17/* 35/*
18 * Overrides for Emacs so that we follow Linus's tabbing style. 36 * Overrides for Emacs so that we follow Linus's tabbing style.
19 * Emacs will notice this stuff at the end of the file and automatically 37 * Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/sys-x86_64/kernel-offsets.c b/arch/um/sys-x86_64/kernel-offsets.c
new file mode 100644
index 000000000000..220e875cbe29
--- /dev/null
+++ b/arch/um/sys-x86_64/kernel-offsets.c
@@ -0,0 +1,24 @@
1#include <linux/config.h>
2#include <linux/stddef.h>
3#include <linux/sched.h>
4#include <linux/time.h>
5#include <asm/page.h>
6
7#define DEFINE(sym, val) \
8 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
9
10#define DEFINE_STR1(x) #x
11#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " DEFINE_STR1(val) " " #val: : )
12
13#define BLANK() asm volatile("\n->" : : )
14
15#define OFFSET(sym, str, mem) \
16 DEFINE(sym, offsetof(struct str, mem));
17
18void foo(void)
19{
20#ifdef CONFIG_MODE_TT
21 OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
22#endif
23#include <common-offsets.h>
24}
diff --git a/arch/um/sys-x86_64/ksyms.c b/arch/um/sys-x86_64/ksyms.c
new file mode 100644
index 000000000000..a27f0ee6a4f6
--- /dev/null
+++ b/arch/um/sys-x86_64/ksyms.c
@@ -0,0 +1,20 @@
1#include "linux/module.h"
2#include "linux/in6.h"
3#include "linux/rwsem.h"
4#include "asm/byteorder.h"
5#include "asm/semaphore.h"
6#include "asm/uaccess.h"
7#include "asm/checksum.h"
8#include "asm/errno.h"
9
10EXPORT_SYMBOL(__down_failed);
11EXPORT_SYMBOL(__down_failed_interruptible);
12EXPORT_SYMBOL(__down_failed_trylock);
13EXPORT_SYMBOL(__up_wakeup);
14
15/*XXX: we need them because they would be exported by x86_64 */
16EXPORT_SYMBOL(__memcpy);
17
18/* Networking helper routines. */
19/*EXPORT_SYMBOL(csum_partial_copy_from);
20EXPORT_SYMBOL(csum_partial_copy_to);*/
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c
index 8c146b2a1e00..b593bb256f2c 100644
--- a/arch/um/sys-x86_64/ptrace.c
+++ b/arch/um/sys-x86_64/ptrace.c
@@ -62,6 +62,27 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
62 return 0; 62 return 0;
63} 63}
64 64
65int poke_user(struct task_struct *child, long addr, long data)
66{
67 if ((addr & 3) || addr < 0)
68 return -EIO;
69
70 if (addr < MAX_REG_OFFSET)
71 return putreg(child, addr, data);
72
73#if 0 /* Need x86_64 debugregs handling */
74 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
75 (addr <= offsetof(struct user, u_debugreg[7]))){
76 addr -= offsetof(struct user, u_debugreg[0]);
77 addr = addr >> 2;
78 if((addr == 4) || (addr == 5)) return -EIO;
79 child->thread.arch.debugregs[addr] = data;
80 return 0;
81 }
82#endif
83 return -EIO;
84}
85
65unsigned long getreg(struct task_struct *child, int regno) 86unsigned long getreg(struct task_struct *child, int regno)
66{ 87{
67 unsigned long retval = ~0UL; 88 unsigned long retval = ~0UL;
@@ -84,6 +105,29 @@ unsigned long getreg(struct task_struct *child, int regno)
84 return retval; 105 return retval;
85} 106}
86 107
108int peek_user(struct task_struct *child, long addr, long data)
109{
110 /* read the word at location addr in the USER area. */
111 unsigned long tmp;
112
113 if ((addr & 3) || addr < 0)
114 return -EIO;
115
116 tmp = 0; /* Default return condition */
117 if(addr < MAX_REG_OFFSET){
118 tmp = getreg(child, addr);
119 }
120#if 0 /* Need x86_64 debugregs handling */
121 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
122 (addr <= offsetof(struct user, u_debugreg[7]))){
123 addr -= offsetof(struct user, u_debugreg[0]);
124 addr = addr >> 2;
125 tmp = child->thread.arch.debugregs[addr];
126 }
127#endif
128 return put_user(tmp, (unsigned long *) data);
129}
130
87void arch_switch(void) 131void arch_switch(void)
88{ 132{
89/* XXX 133/* XXX
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
index 5bc5a0d796e5..73a7926f7370 100644
--- a/arch/um/sys-x86_64/signal.c
+++ b/arch/um/sys-x86_64/signal.c
@@ -57,7 +57,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
57int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, 57int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
58 struct pt_regs *regs, unsigned long mask) 58 struct pt_regs *regs, unsigned long mask)
59{ 59{
60 unsigned long eflags; 60 struct faultinfo * fi = &current->thread.arch.faultinfo;
61 int err = 0; 61 int err = 0;
62 62
63 err |= __put_user(0, &to->gs); 63 err |= __put_user(0, &to->gs);
@@ -84,14 +84,16 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
84 err |= PUTREG(regs, R14, to, r14); 84 err |= PUTREG(regs, R14, to, r14);
85 err |= PUTREG(regs, R15, to, r15); 85 err |= PUTREG(regs, R15, to, r15);
86 err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */ 86 err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */
87 err |= __put_user(current->thread.err, &to->err); 87
88 err |= __put_user(current->thread.trap_no, &to->trapno); 88 err |= __put_user(fi->cr2, &to->cr2);
89 err |= __put_user(fi->error_code, &to->err);
90 err |= __put_user(fi->trap_no, &to->trapno);
91
89 err |= PUTREG(regs, RIP, to, rip); 92 err |= PUTREG(regs, RIP, to, rip);
90 err |= PUTREG(regs, EFLAGS, to, eflags); 93 err |= PUTREG(regs, EFLAGS, to, eflags);
91#undef PUTREG 94#undef PUTREG
92 95
93 err |= __put_user(mask, &to->oldmask); 96 err |= __put_user(mask, &to->oldmask);
94 err |= __put_user(current->thread.cr2, &to->cr2);
95 97
96 return(err); 98 return(err);
97} 99}
@@ -166,7 +168,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
166 168
167 frame = (struct rt_sigframe __user *) 169 frame = (struct rt_sigframe __user *)
168 round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8; 170 round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8;
169 frame -= 128; 171 ((unsigned char *) frame) -= 128;
170 172
171 if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) 173 if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
172 goto out; 174 goto out;
diff --git a/arch/um/sys-x86_64/syscall_table.c b/arch/um/sys-x86_64/syscall_table.c
new file mode 100644
index 000000000000..34b2e842864f
--- /dev/null
+++ b/arch/um/sys-x86_64/syscall_table.c
@@ -0,0 +1,59 @@
1/* System call table for UML/x86-64, copied from arch/x86_64/kernel/syscall.c
2 * with some changes for UML. */
3
4#include <linux/linkage.h>
5#include <linux/sys.h>
6#include <linux/cache.h>
7#include <linux/config.h>
8
9#define __NO_STUBS
10
11/* Below you can see, in terms of #define's, the differences between the x86-64
12 * and the UML syscall table. */
13
14/* Not going to be implemented by UML, since we have no hardware. */
15#define stub_iopl sys_ni_syscall
16#define sys_ioperm sys_ni_syscall
17
18/* The UML TLS problem. Note that x86_64 does not implement this, so the below
19 * is needed only for the ia32 compatibility. */
20/*#define sys_set_thread_area sys_ni_syscall
21#define sys_get_thread_area sys_ni_syscall*/
22
23/* For __NR_time. The x86-64 name hopefully will change from sys_time64 to
24 * sys_time (since the current situation is bogus). I've sent a patch to cleanup
25 * this. Remove below the obsoleted line. */
26#define sys_time64 um_time
27#define sys_time um_time
28
29/* On UML we call it this way ("old" means it's not mmap2) */
30#define sys_mmap old_mmap
31/* On x86-64 sys_uname is actually sys_newuname plus a compatibility trick.
32 * See arch/x86_64/kernel/sys_x86_64.c */
33#define sys_uname sys_uname64
34
35#define stub_clone sys_clone
36#define stub_fork sys_fork
37#define stub_vfork sys_vfork
38#define stub_execve sys_execve
39#define stub_rt_sigsuspend sys_rt_sigsuspend
40#define stub_sigaltstack sys_sigaltstack
41#define stub_rt_sigreturn sys_rt_sigreturn
42
43#define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ;
44#undef _ASM_X86_64_UNISTD_H_
45#include <asm-x86_64/unistd.h>
46
47#undef __SYSCALL
48#define __SYSCALL(nr, sym) [ nr ] = sym,
49#undef _ASM_X86_64_UNISTD_H_
50
51typedef void (*sys_call_ptr_t)(void);
52
53extern void sys_ni_syscall(void);
54
55sys_call_ptr_t sys_call_table[__NR_syscall_max+1] __cacheline_aligned = {
56 /* Smells like a like a compiler bug -- it doesn't work when the & below is removed. */
57 [0 ... __NR_syscall_max] = &sys_ni_syscall,
58#include <asm-x86_64/unistd.h>
59};
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index 68205a03364c..dd9914642b8e 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -7,6 +7,8 @@
7#include "linux/linkage.h" 7#include "linux/linkage.h"
8#include "linux/slab.h" 8#include "linux/slab.h"
9#include "linux/shm.h" 9#include "linux/shm.h"
10#include "linux/utsname.h"
11#include "linux/personality.h"
10#include "asm/uaccess.h" 12#include "asm/uaccess.h"
11#define __FRAME_OFFSETS 13#define __FRAME_OFFSETS
12#include "asm/ptrace.h" 14#include "asm/ptrace.h"
@@ -14,11 +16,15 @@
14#include "asm/prctl.h" /* XXX This should get the constants from libc */ 16#include "asm/prctl.h" /* XXX This should get the constants from libc */
15#include "choose-mode.h" 17#include "choose-mode.h"
16 18
17asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg) 19asmlinkage long sys_uname64(struct new_utsname __user * name)
18{ 20{
19 unsigned long raddr; 21 int err;
20 22 down_read(&uts_sem);
21 return do_shmat(shmid, shmaddr, shmflg, &raddr) ?: (long) raddr; 23 err = copy_to_user(name, &system_utsname, sizeof (*name));
24 up_read(&uts_sem);
25 if (personality(current->personality) == PER_LINUX32)
26 err |= copy_to_user(&name->machine, "i686", 5);
27 return err ? -EFAULT : 0;
22} 28}
23 29
24#ifdef CONFIG_MODE_TT 30#ifdef CONFIG_MODE_TT
@@ -38,6 +44,8 @@ long sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
38#ifdef CONFIG_MODE_SKAS 44#ifdef CONFIG_MODE_SKAS
39extern int userspace_pid[]; 45extern int userspace_pid[];
40 46
47#include "skas_ptrace.h"
48
41long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount) 49long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
42{ 50{
43 struct ptrace_ldt ldt; 51 struct ptrace_ldt ldt;
diff --git a/arch/um/sys-x86_64/um_module.c b/arch/um/sys-x86_64/um_module.c
new file mode 100644
index 000000000000..8b8eff1bd977
--- /dev/null
+++ b/arch/um/sys-x86_64/um_module.c
@@ -0,0 +1,19 @@
1#include <linux/vmalloc.h>
2#include <linux/moduleloader.h>
3
4/*Copied from i386 arch/i386/kernel/module.c */
5void *module_alloc(unsigned long size)
6{
7 if (size == 0)
8 return NULL;
9 return vmalloc_exec(size);
10}
11
12/* Free memory returned from module_alloc */
13void module_free(struct module *mod, void *module_region)
14{
15 vfree(module_region);
16 /* FIXME: If module_region == mod->init_region, trim exception
17 table entries. */
18}
19
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
new file mode 100644
index 000000000000..5e14792e4838
--- /dev/null
+++ b/arch/um/sys-x86_64/user-offsets.c
@@ -0,0 +1,78 @@
1#include <stdio.h>
2#include <stddef.h>
3#include <signal.h>
4#define __FRAME_OFFSETS
5#include <asm/ptrace.h>
6#include <asm/user.h>
7
8#define DEFINE(sym, val) \
9 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
10
11#define OFFSET(sym, str, mem) \
12 DEFINE(sym, offsetof(struct str, mem));
13
14void foo(void)
15{
16 OFFSET(SC_RBX, sigcontext, rbx);
17 OFFSET(SC_RCX, sigcontext, rcx);
18 OFFSET(SC_RDX, sigcontext, rdx);
19 OFFSET(SC_RSI, sigcontext, rsi);
20 OFFSET(SC_RDI, sigcontext, rdi);
21 OFFSET(SC_RBP, sigcontext, rbp);
22 OFFSET(SC_RAX, sigcontext, rax);
23 OFFSET(SC_R8, sigcontext, r8);
24 OFFSET(SC_R9, sigcontext, r9);
25 OFFSET(SC_R10, sigcontext, r10);
26 OFFSET(SC_R11, sigcontext, r11);
27 OFFSET(SC_R12, sigcontext, r12);
28 OFFSET(SC_R13, sigcontext, r13);
29 OFFSET(SC_R14, sigcontext, r14);
30 OFFSET(SC_R15, sigcontext, r15);
31 OFFSET(SC_IP, sigcontext, rip);
32 OFFSET(SC_SP, sigcontext, rsp);
33 OFFSET(SC_CR2, sigcontext, cr2);
34 OFFSET(SC_ERR, sigcontext, err);
35 OFFSET(SC_TRAPNO, sigcontext, trapno);
36 OFFSET(SC_CS, sigcontext, cs);
37 OFFSET(SC_FS, sigcontext, fs);
38 OFFSET(SC_GS, sigcontext, gs);
39 OFFSET(SC_EFLAGS, sigcontext, eflags);
40 OFFSET(SC_SIGMASK, sigcontext, oldmask);
41#if 0
42 OFFSET(SC_ORIG_RAX, sigcontext, orig_rax);
43 OFFSET(SC_DS, sigcontext, ds);
44 OFFSET(SC_ES, sigcontext, es);
45 OFFSET(SC_SS, sigcontext, ss);
46#endif
47
48 DEFINE(HOST_FRAME_SIZE, FRAME_SIZE);
49 DEFINE(HOST_RBX, RBX);
50 DEFINE(HOST_RCX, RCX);
51 DEFINE(HOST_RDI, RDI);
52 DEFINE(HOST_RSI, RSI);
53 DEFINE(HOST_RDX, RDX);
54 DEFINE(HOST_RBP, RBP);
55 DEFINE(HOST_RAX, RAX);
56 DEFINE(HOST_R8, R8);
57 DEFINE(HOST_R9, R9);
58 DEFINE(HOST_R10, R10);
59 DEFINE(HOST_R11, R11);
60 DEFINE(HOST_R12, R12);
61 DEFINE(HOST_R13, R13);
62 DEFINE(HOST_R14, R14);
63 DEFINE(HOST_R15, R15);
64 DEFINE(HOST_ORIG_RAX, ORIG_RAX);
65 DEFINE(HOST_CS, CS);
66 DEFINE(HOST_SS, SS);
67 DEFINE(HOST_EFLAGS, EFLAGS);
68#if 0
69 DEFINE(HOST_FS, FS);
70 DEFINE(HOST_GS, GS);
71 DEFINE(HOST_DS, DS);
72 DEFINE(HOST_ES, ES);
73#endif
74
75 DEFINE(HOST_IP, RIP);
76 DEFINE(HOST_SP, RSP);
77 DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct));
78}
diff --git a/arch/um/sys-x86_64/util/Makefile b/arch/um/sys-x86_64/util/Makefile
index 002607980864..75b052cfc206 100644
--- a/arch/um/sys-x86_64/util/Makefile
+++ b/arch/um/sys-x86_64/util/Makefile
@@ -4,7 +4,5 @@
4hostprogs-y := mk_sc mk_thread 4hostprogs-y := mk_sc mk_thread
5always := $(hostprogs-y) 5always := $(hostprogs-y)
6 6
7mk_thread-objs := mk_thread_kern.o mk_thread_user.o 7HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um
8 8HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um
9HOSTCFLAGS_mk_thread_kern.o := $(CFLAGS) $(CPPFLAGS)
10HOSTCFLAGS_mk_thread_user.o := $(USER_CFLAGS)
diff --git a/arch/um/sys-x86_64/util/mk_sc.c b/arch/um/sys-x86_64/util/mk_sc.c
index c236e213918d..7619bc377c1f 100644
--- a/arch/um/sys-x86_64/util/mk_sc.c
+++ b/arch/um/sys-x86_64/util/mk_sc.c
@@ -3,56 +3,45 @@
3 */ 3 */
4 4
5#include <stdio.h> 5#include <stdio.h>
6#include <signal.h> 6#include <user-offsets.h>
7#include <linux/stddef.h>
8 7
9#define SC_OFFSET(name, field) \ 8#define SC_OFFSET(name) \
10 printf("#define " name \ 9 printf("#define " #name \
11 "(sc) *((unsigned long *) &(((char *) (sc))[%ld]))\n",\ 10 "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
12 offsetof(struct sigcontext, field)) 11 name)
13
14#define SC_FP_OFFSET(name, field) \
15 printf("#define " name \
16 "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%ld]))\n",\
17 offsetof(struct _fpstate, field))
18
19#define SC_FP_OFFSET_PTR(name, field, type) \
20 printf("#define " name \
21 "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
22 offsetof(struct _fpstate, field))
23 12
24int main(int argc, char **argv) 13int main(int argc, char **argv)
25{ 14{
26 SC_OFFSET("SC_RBX", rbx); 15 SC_OFFSET(SC_RBX);
27 SC_OFFSET("SC_RCX", rcx); 16 SC_OFFSET(SC_RCX);
28 SC_OFFSET("SC_RDX", rdx); 17 SC_OFFSET(SC_RDX);
29 SC_OFFSET("SC_RSI", rsi); 18 SC_OFFSET(SC_RSI);
30 SC_OFFSET("SC_RDI", rdi); 19 SC_OFFSET(SC_RDI);
31 SC_OFFSET("SC_RBP", rbp); 20 SC_OFFSET(SC_RBP);
32 SC_OFFSET("SC_RAX", rax); 21 SC_OFFSET(SC_RAX);
33 SC_OFFSET("SC_R8", r8); 22 SC_OFFSET(SC_R8);
34 SC_OFFSET("SC_R9", r9); 23 SC_OFFSET(SC_R9);
35 SC_OFFSET("SC_R10", r10); 24 SC_OFFSET(SC_R10);
36 SC_OFFSET("SC_R11", r11); 25 SC_OFFSET(SC_R11);
37 SC_OFFSET("SC_R12", r12); 26 SC_OFFSET(SC_R12);
38 SC_OFFSET("SC_R13", r13); 27 SC_OFFSET(SC_R13);
39 SC_OFFSET("SC_R14", r14); 28 SC_OFFSET(SC_R14);
40 SC_OFFSET("SC_R15", r15); 29 SC_OFFSET(SC_R15);
41 SC_OFFSET("SC_IP", rip); 30 SC_OFFSET(SC_IP);
42 SC_OFFSET("SC_SP", rsp); 31 SC_OFFSET(SC_SP);
43 SC_OFFSET("SC_CR2", cr2); 32 SC_OFFSET(SC_CR2);
44 SC_OFFSET("SC_ERR", err); 33 SC_OFFSET(SC_ERR);
45 SC_OFFSET("SC_TRAPNO", trapno); 34 SC_OFFSET(SC_TRAPNO);
46 SC_OFFSET("SC_CS", cs); 35 SC_OFFSET(SC_CS);
47 SC_OFFSET("SC_FS", fs); 36 SC_OFFSET(SC_FS);
48 SC_OFFSET("SC_GS", gs); 37 SC_OFFSET(SC_GS);
49 SC_OFFSET("SC_EFLAGS", eflags); 38 SC_OFFSET(SC_EFLAGS);
50 SC_OFFSET("SC_SIGMASK", oldmask); 39 SC_OFFSET(SC_SIGMASK);
51#if 0 40#if 0
52 SC_OFFSET("SC_ORIG_RAX", orig_rax); 41 SC_OFFSET(SC_ORIG_RAX);
53 SC_OFFSET("SC_DS", ds); 42 SC_OFFSET(SC_DS);
54 SC_OFFSET("SC_ES", es); 43 SC_OFFSET(SC_ES);
55 SC_OFFSET("SC_SS", ss); 44 SC_OFFSET(SC_SS);
56#endif 45#endif
57 return(0); 46 return(0);
58} 47}
diff --git a/arch/um/sys-x86_64/util/mk_thread.c b/arch/um/sys-x86_64/util/mk_thread.c
new file mode 100644
index 000000000000..15517396e9cf
--- /dev/null
+++ b/arch/um/sys-x86_64/util/mk_thread.c
@@ -0,0 +1,20 @@
1#include <stdio.h>
2#include <kernel-offsets.h>
3
4int main(int argc, char **argv)
5{
6 printf("/*\n");
7 printf(" * Generated by mk_thread\n");
8 printf(" */\n");
9 printf("\n");
10 printf("#ifndef __UM_THREAD_H\n");
11 printf("#define __UM_THREAD_H\n");
12 printf("\n");
13#ifdef TASK_EXTERN_PID
14 printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n",
15 TASK_EXTERN_PID);
16#endif
17 printf("\n");
18 printf("#endif\n");
19 return(0);
20}
diff --git a/arch/um/sys-x86_64/util/mk_thread_kern.c b/arch/um/sys-x86_64/util/mk_thread_kern.c
deleted file mode 100644
index a281673f02b2..000000000000
--- a/arch/um/sys-x86_64/util/mk_thread_kern.c
+++ /dev/null
@@ -1,21 +0,0 @@
1#include "linux/config.h"
2#include "linux/stddef.h"
3#include "linux/sched.h"
4
5extern void print_head(void);
6extern void print_constant_ptr(char *name, int value);
7extern void print_constant(char *name, char *type, int value);
8extern void print_tail(void);
9
10#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field)
11
12int main(int argc, char **argv)
13{
14 print_head();
15#ifdef CONFIG_MODE_TT
16 print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid));
17#endif
18 print_tail();
19 return(0);
20}
21
diff --git a/arch/um/sys-x86_64/util/mk_thread_user.c b/arch/um/sys-x86_64/util/mk_thread_user.c
deleted file mode 100644
index 7989725568b8..000000000000
--- a/arch/um/sys-x86_64/util/mk_thread_user.c
+++ /dev/null
@@ -1,30 +0,0 @@
1#include <stdio.h>
2
3void print_head(void)
4{
5 printf("/*\n");
6 printf(" * Generated by mk_thread\n");
7 printf(" */\n");
8 printf("\n");
9 printf("#ifndef __UM_THREAD_H\n");
10 printf("#define __UM_THREAD_H\n");
11 printf("\n");
12}
13
14void print_constant_ptr(char *name, int value)
15{
16 printf("#define %s(task) ((unsigned long *) "
17 "&(((char *) (task))[%d]))\n", name, value);
18}
19
20void print_constant(char *name, char *type, int value)
21{
22 printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
23 value);
24}
25
26void print_tail(void)
27{
28 printf("\n");
29 printf("#endif\n");
30}
diff --git a/arch/um/util/Makefile b/arch/um/util/Makefile
index e2ab71209f3f..4c7551c28033 100644
--- a/arch/um/util/Makefile
+++ b/arch/um/util/Makefile
@@ -1,8 +1,5 @@
1hostprogs-y := mk_task mk_constants 1hostprogs-y := mk_task mk_constants
2always := $(hostprogs-y) 2always := $(hostprogs-y)
3 3
4mk_task-objs := mk_task_user.o mk_task_kern.o 4HOSTCFLAGS_mk_task.o := -I$(objtree)/arch/um
5mk_constants-objs := mk_constants_user.o mk_constants_kern.o 5HOSTCFLAGS_mk_constants.o := -I$(objtree)/arch/um
6
7HOSTCFLAGS_mk_task_kern.o := $(CFLAGS) $(CPPFLAGS)
8HOSTCFLAGS_mk_constants_kern.o := $(CFLAGS) $(CPPFLAGS)
diff --git a/arch/um/util/mk_constants.c b/arch/um/util/mk_constants.c
new file mode 100644
index 000000000000..ab217becc36a
--- /dev/null
+++ b/arch/um/util/mk_constants.c
@@ -0,0 +1,32 @@
1#include <stdio.h>
2#include <kernel-offsets.h>
3
4#define SHOW_INT(sym) printf("#define %s %d\n", #sym, sym)
5#define SHOW_STR(sym) printf("#define %s %s\n", #sym, sym)
6
7int main(int argc, char **argv)
8{
9 printf("/*\n");
10 printf(" * Generated by mk_constants\n");
11 printf(" */\n");
12 printf("\n");
13 printf("#ifndef __UM_CONSTANTS_H\n");
14 printf("#define __UM_CONSTANTS_H\n");
15 printf("\n");
16
17 SHOW_INT(UM_KERN_PAGE_SIZE);
18
19 SHOW_STR(UM_KERN_EMERG);
20 SHOW_STR(UM_KERN_ALERT);
21 SHOW_STR(UM_KERN_CRIT);
22 SHOW_STR(UM_KERN_ERR);
23 SHOW_STR(UM_KERN_WARNING);
24 SHOW_STR(UM_KERN_NOTICE);
25 SHOW_STR(UM_KERN_INFO);
26 SHOW_STR(UM_KERN_DEBUG);
27
28 SHOW_INT(UM_NSEC_PER_SEC);
29 printf("\n");
30 printf("#endif\n");
31 return(0);
32}
diff --git a/arch/um/util/mk_constants_kern.c b/arch/um/util/mk_constants_kern.c
deleted file mode 100644
index cdcb1232a1ea..000000000000
--- a/arch/um/util/mk_constants_kern.c
+++ /dev/null
@@ -1,28 +0,0 @@
1#include "linux/kernel.h"
2#include "linux/stringify.h"
3#include "linux/time.h"
4#include "asm/page.h"
5
6extern void print_head(void);
7extern void print_constant_str(char *name, char *value);
8extern void print_constant_int(char *name, int value);
9extern void print_tail(void);
10
11int main(int argc, char **argv)
12{
13 print_head();
14 print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
15
16 print_constant_str("UM_KERN_EMERG", KERN_EMERG);
17 print_constant_str("UM_KERN_ALERT", KERN_ALERT);
18 print_constant_str("UM_KERN_CRIT", KERN_CRIT);
19 print_constant_str("UM_KERN_ERR", KERN_ERR);
20 print_constant_str("UM_KERN_WARNING", KERN_WARNING);
21 print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
22 print_constant_str("UM_KERN_INFO", KERN_INFO);
23 print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
24
25 print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC);
26 print_tail();
27 return(0);
28}
diff --git a/arch/um/util/mk_constants_user.c b/arch/um/util/mk_constants_user.c
deleted file mode 100644
index 8f4d7e50be7c..000000000000
--- a/arch/um/util/mk_constants_user.c
+++ /dev/null
@@ -1,28 +0,0 @@
1#include <stdio.h>
2
3void print_head(void)
4{
5 printf("/*\n");
6 printf(" * Generated by mk_constants\n");
7 printf(" */\n");
8 printf("\n");
9 printf("#ifndef __UM_CONSTANTS_H\n");
10 printf("#define __UM_CONSTANTS_H\n");
11 printf("\n");
12}
13
14void print_constant_str(char *name, char *value)
15{
16 printf("#define %s \"%s\"\n", name, value);
17}
18
19void print_constant_int(char *name, int value)
20{
21 printf("#define %s %d\n", name, value);
22}
23
24void print_tail(void)
25{
26 printf("\n");
27 printf("#endif\n");
28}
diff --git a/arch/um/util/mk_task_user.c b/arch/um/util/mk_task.c
index 9db849f3f3ac..36c9606505e2 100644
--- a/arch/um/util/mk_task_user.c
+++ b/arch/um/util/mk_task.c
@@ -1,18 +1,19 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <kernel-offsets.h>
2 3
3void print(char *name, char *type, int offset) 4void print_ptr(char *name, char *type, int offset)
4{ 5{
5 printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type, 6 printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
6 offset); 7 offset);
7} 8}
8 9
9void print_ptr(char *name, char *type, int offset) 10void print(char *name, char *type, int offset)
10{ 11{
11 printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type, 12 printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
12 offset); 13 offset);
13} 14}
14 15
15void print_head(void) 16int main(int argc, char **argv)
16{ 17{
17 printf("/*\n"); 18 printf("/*\n");
18 printf(" * Generated by mk_task\n"); 19 printf(" * Generated by mk_task\n");
@@ -21,10 +22,9 @@ void print_head(void)
21 printf("#ifndef __TASK_H\n"); 22 printf("#ifndef __TASK_H\n");
22 printf("#define __TASK_H\n"); 23 printf("#define __TASK_H\n");
23 printf("\n"); 24 printf("\n");
24} 25 print_ptr("TASK_REGS", "union uml_pt_regs", TASK_REGS);
25 26 print("TASK_PID", "int", TASK_PID);
26void print_tail(void)
27{
28 printf("\n"); 27 printf("\n");
29 printf("#endif\n"); 28 printf("#endif\n");
29 return(0);
30} 30}
diff --git a/arch/um/util/mk_task_kern.c b/arch/um/util/mk_task_kern.c
deleted file mode 100644
index c218103315ed..000000000000
--- a/arch/um/util/mk_task_kern.c
+++ /dev/null
@@ -1,17 +0,0 @@
1#include "linux/sched.h"
2#include "linux/stddef.h"
3
4extern void print(char *name, char *type, int offset);
5extern void print_ptr(char *name, char *type, int offset);
6extern void print_head(void);
7extern void print_tail(void);
8
9int main(int argc, char **argv)
10{
11 print_head();
12 print_ptr("TASK_REGS", "union uml_pt_regs",
13 offsetof(struct task_struct, thread.regs));
14 print("TASK_PID", "int", offsetof(struct task_struct, pid));
15 print_tail();
16 return(0);
17}