diff options
Diffstat (limited to 'arch/um')
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 | ||
245 | config HIGHMEM | 245 | config HIGHMEM |
246 | bool "Highmem support" | 246 | bool "Highmem support" |
247 | depends on !64BIT | ||
247 | 248 | ||
248 | config KERNEL_STACK_ORDER | 249 | config 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 @@ | |||
1 | config 64_BIT | 1 | config UML_X86 |
2 | bool | ||
3 | default y | ||
4 | |||
5 | config 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 @@ | |||
1 | config 64_BIT | 1 | config UML_X86 |
2 | bool | ||
3 | default y | ||
4 | |||
5 | config 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. |
19 | SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \ | 19 | SYMLINK_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 |
21 | SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header)) | 21 | SYMLINK_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),) | |||
44 | endif | 44 | endif |
45 | 45 | ||
46 | ARCH_INCLUDE := -I$(ARCH_DIR)/include | 46 | ARCH_INCLUDE := -I$(ARCH_DIR)/include |
47 | ifneq ($(KBUILD_SRC),) | ||
48 | ARCH_INCLUDE += -I$(ARCH_DIR)/include2 | ||
49 | ARCH_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include | ||
50 | MRPROPER_DIRS += $(ARCH_DIR)/include2 | ||
51 | endif | ||
47 | SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH) | 52 | SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH) |
48 | 53 | ||
49 | include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) | 54 | include $(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.' |
95 | endef | 100 | endef |
96 | 101 | ||
102 | ifneq ($(KBUILD_SRC),) | ||
103 | $(shell mkdir -p $(ARCH_DIR) && ln -fsn $(srctree)/$(ARCH_DIR)/Kconfig_$(SUBARCH) $(ARCH_DIR)/Kconfig_arch) | ||
104 | CLEAN_FILES += $(ARCH_DIR)/Kconfig_arch | ||
105 | else | ||
97 | $(shell cd $(ARCH_DIR) && ln -sf Kconfig_$(SUBARCH) Kconfig_arch) | 106 | $(shell cd $(ARCH_DIR) && ln -sf Kconfig_$(SUBARCH) Kconfig_arch) |
107 | endif | ||
98 | 108 | ||
99 | prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) \ | 109 | prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) |
100 | $(ARCH_DIR)/kernel/vmlinux.lds.S | ||
101 | 110 | ||
102 | LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static | 111 | LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static |
103 | LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib | 112 | LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib |
104 | 113 | ||
105 | LD_SCRIPT-$(CONFIG_LD_SCRIPT_STATIC) := uml.lds.S | ||
106 | LD_SCRIPT-$(CONFIG_LD_SCRIPT_DYN) := dyn.lds.S | ||
107 | |||
108 | CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT | 114 | CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT |
109 | CONFIG_KERNEL_STACK_ORDER ?= 2 | 115 | CONFIG_KERNEL_STACK_ORDER ?= 2 |
110 | STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) | 116 | STACK_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 |
132 | endef | 138 | endef |
@@ -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 $@' |
156 | ifneq ($(KBUILD_SRC),) | ||
157 | ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@ | ||
158 | else | ||
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 $@) |
161 | endif | ||
161 | 162 | ||
162 | include/asm-um/arch: | 163 | include/asm-um/arch: |
163 | @echo ' SYMLINK $@' | 164 | @echo ' SYMLINK $@' |
165 | ifneq ($(KBUILD_SRC),) | ||
166 | $(Q)mkdir -p include/asm-um | ||
167 | $(Q)ln -fsn $(srctree)/include/asm-$(SUBARCH) include/asm-um/arch | ||
168 | else | ||
164 | $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch | 169 | $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch |
170 | endif | ||
165 | 171 | ||
166 | $(ARCH_DIR)/include/sysdep: | 172 | $(ARCH_DIR)/include/sysdep: |
167 | @echo ' SYMLINK $@' | 173 | @echo ' SYMLINK $@' |
174 | ifneq ($(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 | ||
179 | else | ||
168 | $(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep | 180 | $(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep |
181 | endif | ||
169 | 182 | ||
170 | $(ARCH_DIR)/os: | 183 | $(ARCH_DIR)/os: |
171 | @echo ' SYMLINK $@' | 184 | @echo ' SYMLINK $@' |
185 | ifneq ($(KBUILD_SRC),) | ||
186 | $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/os-$(OS) $(ARCH_DIR)/os | ||
187 | else | ||
172 | $(Q)cd $(ARCH_DIR) && ln -sf os-$(OS) os | 188 | $(Q)cd $(ARCH_DIR) && ln -sf os-$(OS) os |
189 | endif | ||
173 | 190 | ||
174 | # Generated files | 191 | # Generated files |
175 | define filechk_umlconfig | 192 | define 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 | |||
205 | CLEAN_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 | |||
218 | CLEAN_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 | ||
210 | export SUBARCH USER_CFLAGS OS | 248 | export 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 @@ | |||
1 | SUBARCH_CORE := arch/um/sys-i386/ | 1 | SUBARCH_CORE := arch/um/sys-i386/ arch/i386/crypto/ |
2 | 2 | ||
3 | TOP_ADDR := $(CONFIG_TOP_ADDR) | 3 | TOP_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 | ||
32 | CLEAN_FILES += $(SYS_HEADERS) | 32 | CLEAN_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 | # |
6 | CONFIG_GENERIC_HARDIRQS=y | 6 | CONFIG_GENERIC_HARDIRQS=y |
7 | CONFIG_UML=y | 7 | CONFIG_UML=y |
@@ -15,7 +15,8 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y | |||
15 | # | 15 | # |
16 | CONFIG_MODE_TT=y | 16 | CONFIG_MODE_TT=y |
17 | CONFIG_MODE_SKAS=y | 17 | CONFIG_MODE_SKAS=y |
18 | # CONFIG_64_BIT is not set | 18 | CONFIG_UML_X86=y |
19 | # CONFIG_64BIT is not set | ||
19 | CONFIG_TOP_ADDR=0xc0000000 | 20 | CONFIG_TOP_ADDR=0xc0000000 |
20 | # CONFIG_3_LEVEL_PGTABLES is not set | 21 | # CONFIG_3_LEVEL_PGTABLES is not set |
21 | CONFIG_ARCH_HAS_SC_SIGNALS=y | 22 | CONFIG_ARCH_HAS_SC_SIGNALS=y |
@@ -41,6 +42,7 @@ CONFIG_UML_REAL_TIME_CLOCK=y | |||
41 | CONFIG_EXPERIMENTAL=y | 42 | CONFIG_EXPERIMENTAL=y |
42 | CONFIG_CLEAN_COMPILE=y | 43 | CONFIG_CLEAN_COMPILE=y |
43 | CONFIG_BROKEN_ON_SMP=y | 44 | CONFIG_BROKEN_ON_SMP=y |
45 | CONFIG_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 | # |
159 | CONFIG_PACKET=y | 161 | CONFIG_PACKET=y |
160 | CONFIG_PACKET_MMAP=y | 162 | CONFIG_PACKET_MMAP=y |
161 | # CONFIG_NETLINK_DEV is not set | ||
162 | CONFIG_UNIX=y | 163 | CONFIG_UNIX=y |
163 | # CONFIG_NET_KEY is not set | 164 | # CONFIG_NET_KEY is not set |
164 | CONFIG_INET=y | 165 | CONFIG_INET=y |
@@ -412,6 +413,5 @@ CONFIG_DEBUG_INFO=y | |||
412 | # CONFIG_DEBUG_FS is not set | 413 | # CONFIG_DEBUG_FS is not set |
413 | CONFIG_FRAME_POINTER=y | 414 | CONFIG_FRAME_POINTER=y |
414 | CONFIG_PT_PROXY=y | 415 | CONFIG_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 |
23 | static void *not_configged_init(char *str, int device, struct chan_opts *opts) | 23 | static 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) | |||
30 | static int not_configged_open(int input, int output, int primary, void *data, | 30 | static 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 | ||
38 | static void not_configged_close(int fd, void *data) | 38 | static 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 | ||
44 | static int not_configged_read(int fd, char *c_out, void *data) | 44 | static 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 | ||
51 | static int not_configged_write(int fd, const char *buf, int len, void *data) | 51 | static 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) | |||
58 | static int not_configged_console_write(int fd, const char *buf, int len, | 58 | static 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, | |||
66 | static int not_configged_window_size(int fd, void *data, unsigned short *rows, | 66 | static 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 | ||
74 | static void not_configged_free(void *data) | 74 | static 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 | ||
42 | static 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 | */ | ||
46 | static 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 | |||
61 | int 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 | |||
81 | int 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 | */ | ||
55 | static int buffer_data(struct line *line, const char *buf, int len) | 105 | static 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!*/ | ||
87 | static int flush_buffer(struct line *line) | 147 | static 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 | |||
183 | void 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.*/ | ||
204 | void line_flush_chars(struct tty_struct *tty) | ||
205 | { | ||
206 | line_flush_buffer(tty); | ||
207 | } | ||
208 | |||
209 | void line_put_char(struct tty_struct *tty, unsigned char ch) | ||
210 | { | ||
211 | line_write(tty, &ch, sizeof(ch)); | ||
115 | } | 212 | } |
116 | 213 | ||
117 | int line_write(struct tty_struct *tty, const unsigned char *buf, int len) | 214 | int 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: | 242 | out_up: |
148 | up(&line->sem); | 243 | spin_unlock_irqrestore(&line->lock, flags); |
149 | return(ret); | 244 | return ret; |
150 | } | ||
151 | |||
152 | void line_put_char(struct tty_struct *tty, unsigned char ch) | ||
153 | { | ||
154 | line_write(tty, &ch, sizeof(ch)); | ||
155 | } | 245 | } |
156 | 246 | ||
157 | void line_set_termios(struct tty_struct *tty, struct termios * old) | 247 | void 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 | ||
162 | int line_chars_in_buffer(struct tty_struct *tty) | ||
163 | { | ||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | static struct { | 252 | static 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 | ||
256 | static irqreturn_t line_write_interrupt(int irq, void *data, | 341 | static 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 | ||
289 | int line_setup_irq(int fd, int input, int output, struct tty_struct *tty) | 379 | int 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 | ||
306 | void line_disable(struct tty_struct *tty, int current_irq) | 399 | void 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 | ||
364 | out: | 460 | out: |
365 | up(&line->sem); | 461 | spin_unlock(&line->lock); |
366 | return(err); | 462 | return err; |
367 | } | 463 | } |
368 | 464 | ||
465 | static void unregister_winch(struct tty_struct *tty); | ||
466 | |||
369 | void line_close(struct tty_struct *tty, struct file * filp) | 467 | void 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 | ||
382 | void close_lines(struct line *lines, int nlines) | 493 | void 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 | ||
390 | int 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 | |||
508 | int 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 | ||
446 | int line_config(struct line *lines, int num, char *str) | 565 | int 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 | ||
457 | int line_get_config(char *name, struct line *lines, int num, char *str, | 576 | int 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 | ||
488 | int line_remove(struct line *lines, int num, char *str) | 607 | int 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 | |||
496 | int 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 | ||
510 | struct tty_driver *line_register_devfs(struct lines *set, | 615 | struct 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 | ||
609 | DECLARE_MUTEX(winch_handler_sem); | 714 | DECLARE_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 | ||
741 | static 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 | |||
636 | static void winch_cleanup(void) | 769 | static 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 |
110 | static int ssl_chars_in_buffer(struct tty_struct *tty) | ||
111 | { | ||
112 | return(0); | ||
113 | } | ||
114 | |||
115 | static void ssl_flush_buffer(struct tty_struct *tty) | 110 | static 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 | ||
180 | static struct tty_driver *ssl_console_device(struct console *c, int *index) | 176 | static 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 | ||
135 | static struct tty_driver *uml_console_device(struct console *c, int *index) | 139 | static 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]; | |||
156 | static struct openflags global_openflags = OPEN_FLAGS; | 156 | static struct openflags global_openflags = OPEN_FLAGS; |
157 | 157 | ||
158 | struct cow { | 158 | struct 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 | |||
3 | OFFSET(TASK_REGS, task_struct, thread.regs); | ||
4 | OFFSET(TASK_PID, task_struct, pid); | ||
5 | DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE); | ||
6 | DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); | ||
7 | DEFINE_STR(UM_KERN_EMERG, KERN_EMERG); | ||
8 | DEFINE_STR(UM_KERN_ALERT, KERN_ALERT); | ||
9 | DEFINE_STR(UM_KERN_CRIT, KERN_CRIT); | ||
10 | DEFINE_STR(UM_KERN_ERR, KERN_ERR); | ||
11 | DEFINE_STR(UM_KERN_WARNING, KERN_WARNING); | ||
12 | DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE); | ||
13 | DEFINE_STR(UM_KERN_INFO, KERN_INFO); | ||
14 | DEFINE_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 | ||
12 | extern int ncpus; | 13 | extern int ncpus; |
13 | extern char *linux_prog; | 14 | extern char *linux_prog; |
@@ -31,8 +32,8 @@ extern int current_pid(void); | |||
31 | extern unsigned long alloc_stack(int order, int atomic); | 32 | extern unsigned long alloc_stack(int order, int atomic); |
32 | extern int do_signal(void); | 33 | extern int do_signal(void); |
33 | extern int is_stack_fault(unsigned long sp); | 34 | extern int is_stack_fault(unsigned long sp); |
34 | extern unsigned long segv(unsigned long address, unsigned long ip, | 35 | extern unsigned long segv(struct faultinfo fi, unsigned long ip, |
35 | int is_write, int is_user, void *sc); | 36 | int is_user, void *sc); |
36 | extern int handle_page_fault(unsigned long address, unsigned long ip, | 37 | extern 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); |
38 | extern void syscall_ready(void); | 39 | extern void syscall_ready(void); |
@@ -82,7 +83,7 @@ extern void timer_irq(union uml_pt_regs *regs); | |||
82 | extern void unprotect_stack(unsigned long stack); | 83 | extern void unprotect_stack(unsigned long stack); |
83 | extern void do_uml_exitcalls(void); | 84 | extern void do_uml_exitcalls(void); |
84 | extern int attach_debugger(int idle_pid, int pid, int stop); | 85 | extern int attach_debugger(int idle_pid, int pid, int stop); |
85 | extern void bad_segv(unsigned long address, unsigned long ip, int is_write); | 86 | extern void bad_segv(struct faultinfo fi, unsigned long ip); |
86 | extern int config_gdb(char *str); | 87 | extern int config_gdb(char *str); |
87 | extern int remove_gdb(void); | 88 | extern int remove_gdb(void); |
88 | extern char *uml_strdup(char *string); | 89 | extern 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 { | |||
69 | extern void line_close(struct tty_struct *tty, struct file * filp); | 76 | extern void line_close(struct tty_struct *tty, struct file * filp); |
70 | extern int line_open(struct line *lines, struct tty_struct *tty, | 77 | extern int line_open(struct line *lines, struct tty_struct *tty, |
71 | struct chan_opts *opts); | 78 | struct chan_opts *opts); |
72 | extern int line_setup(struct line *lines, int num, char *init, | 79 | extern int line_setup(struct line *lines, unsigned int sizeof_lines, char *init, |
73 | int all_allowed); | 80 | int all_allowed); |
74 | extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len); | 81 | extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len); |
75 | extern void line_put_char(struct tty_struct *tty, unsigned char ch); | 82 | extern void line_put_char(struct tty_struct *tty, unsigned char ch); |
76 | extern void line_set_termios(struct tty_struct *tty, struct termios * old); | 83 | extern void line_set_termios(struct tty_struct *tty, struct termios * old); |
77 | extern int line_chars_in_buffer(struct tty_struct *tty); | 84 | extern int line_chars_in_buffer(struct tty_struct *tty); |
85 | extern void line_flush_buffer(struct tty_struct *tty); | ||
86 | extern void line_flush_chars(struct tty_struct *tty); | ||
78 | extern int line_write_room(struct tty_struct *tty); | 87 | extern int line_write_room(struct tty_struct *tty); |
79 | extern int line_ioctl(struct tty_struct *tty, struct file * file, | 88 | extern 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 | |||
81 | extern char *add_xterm_umid(char *base); | 91 | extern char *add_xterm_umid(char *base); |
82 | extern int line_setup_irq(int fd, int input, int output, struct tty_struct *tty); | 92 | extern int line_setup_irq(int fd, int input, int output, struct tty_struct *tty); |
83 | extern void line_close_chan(struct line *line); | 93 | extern 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); |
90 | extern void lines_init(struct line *lines, int nlines); | 100 | extern void lines_init(struct line *lines, int nlines); |
91 | extern void close_lines(struct line *lines, int nlines); | 101 | extern void close_lines(struct line *lines, int nlines); |
92 | extern int line_config(struct line *lines, int num, char *str); | 102 | |
93 | extern int line_remove(struct line *lines, int num, char *str); | 103 | extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str); |
94 | extern int line_get_config(char *dev, struct line *lines, int num, char *str, | 104 | extern int line_remove(struct line *lines, unsigned int sizeof_lines, char *str); |
105 | extern 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); | |||
160 | extern void os_kill_ptraced_process(int pid, int reap_child); | 160 | extern void os_kill_ptraced_process(int pid, int reap_child); |
161 | extern void os_usr1_process(int pid); | 161 | extern void os_usr1_process(int pid); |
162 | extern int os_getpid(void); | 162 | extern int os_getpid(void); |
163 | extern int os_getpgrp(void); | ||
163 | 164 | ||
164 | extern int os_map_memory(void *virt, int fd, unsigned long long off, | 165 | extern 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 | ||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct 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 | |||
34 | unsigned int csum_partial_copy_to(const unsigned char *src, unsigned char *dst, | ||
35 | int len, int sum, int *err_ptr); | ||
36 | unsigned 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 | |||
55 | static __inline__ | 50 | static __inline__ |
56 | unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, | 51 | unsigned 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 |
70 | unsigned 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 | */ | ||
18 | struct 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 | ||
36 | extern unsigned long *sc_sigmask(void *sc_ptr); | 31 | extern unsigned long *sc_sigmask(void *sc_ptr); |
37 | extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); | 32 | extern 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 | |||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct 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; | |||
22 | extern long sys_mmap2(unsigned long addr, unsigned long len, | 22 | extern 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 | |||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct 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 | |||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct 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 | */ | ||
18 | struct 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 | ||
35 | extern unsigned long *sc_sigmask(void *sc_ptr); | 36 | extern 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 | |||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct 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[]; | |||
26 | extern long old_mmap(unsigned long addr, unsigned long len, | 26 | extern 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); |
29 | extern syscall_handler_t wrap_sys_shmat; | ||
30 | extern syscall_handler_t sys_modify_ldt; | 29 | extern syscall_handler_t sys_modify_ldt; |
31 | extern syscall_handler_t sys_arch_prctl; | 30 | extern 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); | |||
67 | extern int switcheroo(int fd, int prot, void *from, void *to, int size); | 67 | extern int switcheroo(int fd, int prot, void *from, void *to, int size); |
68 | extern void setup_machinename(char *machine_out); | 68 | extern void setup_machinename(char *machine_out); |
69 | extern void setup_hostinfo(void); | 69 | extern void setup_hostinfo(void); |
70 | extern void add_arg(char *arg); | ||
71 | extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); | 70 | extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); |
72 | extern void init_new_thread_signals(int altstack); | 71 | extern void init_new_thread_signals(int altstack); |
73 | extern void do_exec(int old_pid, int new_pid); | 72 | extern 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 | ||
6 | extra-y := vmlinux.lds | 6 | extra-y := vmlinux.lds |
7 | clean-files := vmlinux.lds.S config.tmp | 7 | clean-files := |
8 | 8 | ||
9 | obj-y = checksum.o config.o exec_kern.o exitcode.o \ | 9 | obj-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 | |||
23 | obj-$(CONFIG_MODE_TT) += tt/ | 23 | obj-$(CONFIG_MODE_TT) += tt/ |
24 | obj-$(CONFIG_MODE_SKAS) += skas/ | 24 | obj-$(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. | ||
28 | CFLAGS_frame.o := -fno-omit-frame-pointer | ||
29 | |||
30 | user-objs-$(CONFIG_TTY_LOG) += tty_log.o | 26 | user-objs-$(CONFIG_TTY_LOG) += tty_log.o |
31 | 27 | ||
32 | USER_OBJS := $(user-objs-y) config.o helper.o main.o process.o tempfile.o \ | 28 | USER_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 | ||
35 | include arch/um/scripts/Makefile.rules | 31 | include arch/um/scripts/Makefile.rules |
36 | 32 | ||
37 | targets += config.c | 33 | targets := 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 | |||
5 | unsigned int arch_csum_partial(const unsigned char *buff, int len, int sum); | ||
6 | |||
7 | unsigned int csum_partial(unsigned char *buff, int len, int sum) | ||
8 | { | ||
9 | return arch_csum_partial(buff, len, sum); | ||
10 | } | ||
11 | |||
12 | EXPORT_SYMBOL(csum_partial); | ||
13 | |||
14 | unsigned 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 | |||
26 | unsigned 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); | |||
28 | EXPORT_SYMBOL(set_signals); | 27 | EXPORT_SYMBOL(set_signals); |
29 | EXPORT_SYMBOL(get_signals); | 28 | EXPORT_SYMBOL(get_signals); |
30 | EXPORT_SYMBOL(kernel_thread); | 29 | EXPORT_SYMBOL(kernel_thread); |
31 | EXPORT_SYMBOL(__const_udelay); | ||
32 | EXPORT_SYMBOL(__udelay); | ||
33 | EXPORT_SYMBOL(sys_waitpid); | 30 | EXPORT_SYMBOL(sys_waitpid); |
34 | EXPORT_SYMBOL(task_size); | 31 | EXPORT_SYMBOL(task_size); |
35 | EXPORT_SYMBOL(flush_tlb_range); | 32 | EXPORT_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 | ||
118 | void 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 | |||
128 | void set_current(void *t) | 118 | void 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 | ||
153 | void exit_thread(void) | 143 | void 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 | ||
164 | void prepare_to_copy(struct task_struct *tsk) | ||
165 | { | ||
166 | } | ||
167 | |||
168 | int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, | 153 | int 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 | ||
483 | unsigned long arch_align_stack(unsigned long sp) | 476 | unsigned 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 | ||
22 | static 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 | */ |
25 | void ptrace_disable(struct task_struct *child) | 38 | void 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 | ||
43 | extern int peek_user(struct task_struct * child, long addr, long data); | ||
44 | extern int poke_user(struct task_struct * child, long addr, long data); | ||
45 | |||
31 | long sys_ptrace(long request, long pid, long addr, long data) | 46 | long 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(®s->regs), | 319 | HOST_AUDIT_ARCH, |
342 | UPT_SYSCALL_ARG1(®s->regs), | 320 | UPT_SYSCALL_NR(regs), |
343 | UPT_SYSCALL_ARG2(®s->regs), | 321 | UPT_SYSCALL_ARG1(regs), |
344 | UPT_SYSCALL_ARG3(®s->regs), | 322 | UPT_SYSCALL_ARG2(regs), |
345 | UPT_SYSCALL_ARG4(®s->regs)); | 323 | UPT_SYSCALL_ARG3(regs), |
346 | else | 324 | UPT_SYSCALL_ARG4(regs)); |
347 | audit_syscall_exit(current, | 325 | else { |
348 | UPT_SYSCALL_RET(®s->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 = ¤t_poll; | 186 | fds = ¤t_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); |
20 | extern void release_thread_skas(struct task_struct *task); | 20 | extern void release_thread_skas(struct task_struct *task); |
21 | extern void exit_thread_skas(void); | ||
22 | extern void initial_thread_cb_skas(void (*proc)(void *), void *arg); | 21 | extern void initial_thread_cb_skas(void (*proc)(void *), void *arg); |
23 | extern void init_idle_skas(void); | 22 | extern void init_idle_skas(void); |
24 | extern void flush_tlb_kernel_range_skas(unsigned long start, | 23 | extern 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, | |||
27 | extern int unmap(int fd, void *addr, unsigned long len); | 27 | extern int unmap(int fd, void *addr, unsigned long len); |
28 | extern int protect(int fd, unsigned long addr, unsigned long len, | 28 | extern int protect(int fd, unsigned long addr, unsigned long len, |
29 | int r, int w, int x); | 29 | int r, int w, int x); |
30 | extern void user_signal(int sig, union uml_pt_regs *regs); | 30 | extern void user_signal(int sig, union uml_pt_regs *regs, int pid); |
31 | extern int new_mm(int from); | 31 | extern int new_mm(int from); |
32 | extern void start_userspace(int cpu); | 32 | extern void start_userspace(int cpu); |
33 | extern void get_skas_faultinfo(int pid, struct faultinfo * fi); | ||
33 | extern long execute_syscall_skas(void *r); | 34 | extern 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 | ||
21 | static inline int verify_area_skas(int type, const void * addr, | 21 | static 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 | ||
31 | int is_skas_winch(int pid, int fd, void *data) | 33 | int 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 | ||
40 | static void handle_segv(int pid) | 42 | void 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); | 58 | static void handle_segv(int pid, union uml_pt_regs * regs) |
59 | { | ||
60 | get_skas_faultinfo(pid, ®s->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 | ||
194 | void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | 210 | void 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 | ||
231 | void switch_threads(void *me, void *next) | 247 | void 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) | |||
301 | void halt_skas(void) | 325 | void 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 | ||
307 | void reboot_skas(void) | 331 | void 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 | ||
313 | void switch_mm_skas(int mm_fd) | 337 | void 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 | ||
86 | void exit_thread_skas(void) | ||
87 | { | ||
88 | } | ||
89 | |||
90 | void fork_handler(int sig) | 86 | void 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 | ||
15 | void sig_handler_common_skas(int sig, void *sc_ptr) | 18 | void 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 | ||
48 | void user_signal(int sig, union uml_pt_regs *regs) | 53 | extern int ptrace_faultinfo; |
54 | |||
55 | void 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, ®s->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 | |||
2 | always := $(hostprogs-y) | 2 | always := $(hostprogs-y) |
3 | 3 | ||
4 | mk_ptregs-objs := mk_ptregs-$(SUBARCH).o | 4 | mk_ptregs-objs := mk_ptregs-$(SUBARCH).o |
5 | HOSTCFLAGS_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 | ||
7 | int main(int argc, char **argv) | 6 | int 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 | ||
14 | int main(int argc, char **argv) | 13 | int 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 | |||
31 | extern syscall_handler_t sys_fork; | ||
32 | extern syscall_handler_t sys_execve; | ||
33 | extern syscall_handler_t um_time; | ||
34 | extern syscall_handler_t um_stime; | ||
35 | extern syscall_handler_t sys_pipe; | ||
36 | extern syscall_handler_t sys_olduname; | ||
37 | extern syscall_handler_t sys_sigaction; | ||
38 | extern syscall_handler_t sys_sigsuspend; | ||
39 | extern syscall_handler_t old_readdir; | ||
40 | extern syscall_handler_t sys_uname; | ||
41 | extern syscall_handler_t sys_ipc; | ||
42 | extern syscall_handler_t sys_sigreturn; | ||
43 | extern syscall_handler_t sys_clone; | ||
44 | extern syscall_handler_t sys_rt_sigreturn; | ||
45 | extern syscall_handler_t sys_sigaltstack; | ||
46 | extern syscall_handler_t sys_vfork; | ||
47 | extern syscall_handler_t old_select; | ||
48 | extern syscall_handler_t sys_modify_ldt; | ||
49 | extern syscall_handler_t sys_rt_sigsuspend; | ||
50 | extern syscall_handler_t sys_mbind; | ||
51 | extern syscall_handler_t sys_get_mempolicy; | ||
52 | extern syscall_handler_t sys_set_mempolicy; | ||
53 | extern syscall_handler_t sys_sys_setaltroot; | ||
54 | |||
55 | syscall_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; | |||
48 | static long long delta; /* Deviation per interval */ | 48 | static long long delta; /* Deviation per interval */ |
49 | #endif | 49 | #endif |
50 | 50 | ||
51 | #define MILLION 1000000 | ||
52 | |||
53 | void timer_irq(union uml_pt_regs *regs) | 51 | void 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 | ||
139 | void __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 | |||
147 | void __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 | |||
155 | void timer_handler(int sig, union uml_pt_regs *regs) | 137 | void 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 | ||
136 | unsigned 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 | */ | ||
142 | unsigned 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 | ||
190 | void bad_segv(unsigned long address, unsigned long ip, int is_write) | 197 | void 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 { | |||
54 | void segv_handler(int sig, union uml_pt_regs *regs) | 54 | void 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 | ||
76 | void usr2_handler(int sig, union uml_pt_regs *regs) | 75 | void 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 | ||
6 | extra-y := unmap_fin.o | 6 | extra-y := unmap_fin.o |
7 | targets := unmap.o | ||
7 | clean-files := unmap_tmp.o | 8 | clean-files := unmap_tmp.o |
8 | 9 | ||
9 | obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \ | 10 | obj-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); |
21 | extern void release_thread_tt(struct task_struct *task); | 21 | extern void release_thread_tt(struct task_struct *task); |
22 | extern void exit_thread_tt(void); | ||
23 | extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); | 22 | extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); |
24 | extern void init_idle_tt(void); | 23 | extern void init_idle_tt(void); |
25 | extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end); | 24 | extern 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 | ||
36 | static inline int verify_area_tt(int type, const void * addr, | 36 | static 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 | ||
33 | unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, | 27 | unsigned 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 | ||
108 | void 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 | ||
114 | void suspend_new_thread(int fd) | 116 | void 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 | ||
34 | int is_tracer_winch(int pid, int fd, void *data) | 35 | int 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 | ||
90 | static void tracer_segv(int sig, struct sigcontext sc) | 91 | static 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 */ |
45 | char command_line[COMMAND_LINE_SIZE] = { 0 }; | 46 | static char command_line[COMMAND_LINE_SIZE] = { 0 }; |
46 | 47 | ||
47 | void add_arg(char *arg) | 48 | static 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 | ||
126 | int os_getpgrp(void) | ||
127 | { | ||
128 | return getpgrp(); | ||
129 | } | ||
130 | |||
126 | int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len, | 131 | int 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 | ||
11 | void sig_handler(int sig) | 11 | void 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 | ||
20 | extern int timer_irq_inited; | 20 | extern int timer_irq_inited; |
21 | 21 | ||
22 | void alarm_handler(int sig) | 22 | void 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 @@ | |||
1 | hostprogs-y := mk_user_constants | 1 | hostprogs-y := mk_user_constants |
2 | always := $(hostprogs-y) | 2 | always := $(hostprogs-y) |
3 | 3 | ||
4 | mk_user_constants-objs := mk_user_constants.o | 4 | HOSTCFLAGS_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 | */ | ||
6 | typedef __u64 u64; | ||
7 | typedef __u32 u32; | ||
8 | #include <asm/user.h> | ||
9 | 3 | ||
10 | int main(int argc, char **argv) | 4 | int 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 | ||
5 | USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs)) | 5 | USER_SINGLE_OBJS := \ |
6 | USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) | 6 | $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs)) |
7 | 7 | USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) | |
8 | USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) | 8 | USER_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 | ||
12 | quiet_cmd_make_link = SYMLINK $@ | 13 | quiet_cmd_make_link = SYMLINK $@ |
13 | cmd_make_link = rm -f $@; ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@ | 14 | cmd_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 | |||
23 | targets := $(targets) $(SYMLINKS) | ||
24 | |||
25 | SYMLINKS := $(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 @@ | |||
1 | obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ | 1 | obj-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 | ||
4 | obj-$(CONFIG_HIGHMEM) += highmem.o | 5 | obj-$(CONFIG_HIGHMEM) += highmem.o |
5 | obj-$(CONFIG_MODULES) += module.o | 6 | obj-$(CONFIG_MODULES) += module.o |
6 | 7 | ||
7 | USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o | 8 | USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o |
8 | 9 | ||
9 | include arch/um/scripts/Makefile.rules | ||
10 | |||
11 | SYMLINKS = bitops.c semaphore.c highmem.c module.c | 10 | SYMLINKS = 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. | ||
15 | clean-files := $(SYMLINKS) | ||
16 | |||
17 | targets += $(SYMLINKS) | ||
18 | |||
19 | SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$f) | ||
20 | |||
21 | bitops.c-dir = lib | 12 | bitops.c-dir = lib |
22 | semaphore.c-dir = kernel | 13 | semaphore.c-dir = kernel |
23 | highmem.c-dir = mm | 14 | highmem.c-dir = mm |
24 | module.c-dir = kernel | 15 | module.c-dir = kernel |
25 | 16 | ||
26 | $(SYMLINKS): FORCE | ||
27 | $(call if_changed,make_link) | ||
28 | |||
29 | subdir- := util | 17 | subdir- := util |
18 | |||
19 | include 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 | */ |
52 | arch_csum_partial: | 52 | csum_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 | ||
122 | arch_csum_partial: | 122 | csum_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 | |||
1 | void __delay(unsigned long time) | 4 | void __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 | ||
18 | void __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 | |||
26 | void __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 | |||
18 | void 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); | |||
13 | EXPORT_SYMBOL(__up_wakeup); | 14 | EXPORT_SYMBOL(__up_wakeup); |
14 | 15 | ||
15 | /* Networking helper routines. */ | 16 | /* Networking helper routines. */ |
16 | EXPORT_SYMBOL(csum_partial_copy_from); | 17 | EXPORT_SYMBOL(csum_partial); |
17 | EXPORT_SYMBOL(csum_partial_copy_to); | 18 | |
19 | /* delay core functions */ | ||
20 | EXPORT_SYMBOL(__const_udelay); | ||
21 | EXPORT_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 |
28 | extern int userspace_pid; | 28 | extern 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 | ||
76 | int 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 | |||
76 | unsigned long getreg(struct task_struct *child, int regno) | 95 | unsigned 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 | ||
115 | int 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 | |||
96 | struct i387_fxsave_struct { | 136 | struct 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 | ||
64 | int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, | 61 | int 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 = ¤t->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 | ||
175 | static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp, | 170 | static 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 | |||
13 | void 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 | |||
2 | hostprogs-y := mk_sc mk_thread | 1 | hostprogs-y := mk_sc mk_thread |
3 | always := $(hostprogs-y) | 2 | always := $(hostprogs-y) |
4 | 3 | ||
5 | mk_thread-objs := mk_thread_kern.o mk_thread_user.o | 4 | HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um |
6 | 5 | HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um | |
7 | HOSTCFLAGS_mk_thread_kern.o := $(CFLAGS) $(CPPFLAGS) | ||
8 | HOSTCFLAGS_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 | ||
19 | int main(int argc, char **argv) | 18 | int 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 | |||
4 | int 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 | |||
5 | extern void print_head(void); | ||
6 | extern void print_constant_ptr(char *name, int value); | ||
7 | extern void print_constant(char *name, char *type, int value); | ||
8 | extern void print_tail(void); | ||
9 | |||
10 | #define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field) | ||
11 | |||
12 | int 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 | |||
3 | void 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 | |||
14 | void print_constant_ptr(char *name, int value) | ||
15 | { | ||
16 | printf("#define %s(task) ((unsigned long *) " | ||
17 | "&(((char *) (task))[%d]))\n", name, value); | ||
18 | } | ||
19 | |||
20 | void 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 | |||
26 | void 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 | ||
11 | int 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 | |||
11 | unsigned long getreg(struct task_struct *child, unsigned long regno) | 30 | unsigned 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 | ||
38 | int 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? | ||
7 | lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \ | 8 | lib-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 | |||
12 | obj-y := ksyms.o | ||
13 | obj-$(CONFIG_MODULES) += module.o um_module.o | ||
10 | 14 | ||
11 | USER_OBJS := ptrace_user.o sigcontext.o | 15 | USER_OBJS := ptrace_user.o sigcontext.o |
12 | 16 | ||
13 | include arch/um/scripts/Makefile.rules | 17 | include arch/um/scripts/Makefile.rules |
14 | 18 | ||
15 | SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \ | 19 | SYMLINKS = 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. | ||
20 | clean-files := $(SYMLINKS) | ||
21 | |||
22 | targets += $(SYMLINKS) | ||
23 | |||
24 | SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$f) | ||
25 | 21 | ||
26 | bitops.c-dir = lib | 22 | bitops.c-dir = lib |
27 | csum-copy.S-dir = lib | 23 | csum-copy.S-dir = lib |
@@ -30,8 +26,8 @@ csum-wrappers.c-dir = lib | |||
30 | memcpy.S-dir = lib | 26 | memcpy.S-dir = lib |
31 | semaphore.c-dir = kernel | 27 | semaphore.c-dir = kernel |
32 | thunk.S-dir = lib | 28 | thunk.S-dir = lib |
33 | 29 | module.c-dir = kernel | |
34 | $(SYMLINKS): FORCE | ||
35 | $(call if_changed,make_link) | ||
36 | 30 | ||
37 | CFLAGS_csum-partial.o := -Dcsum_partial=arch_csum_partial | 31 | CFLAGS_csum-partial.o := -Dcsum_partial=arch_csum_partial |
32 | |||
33 | subdir- := 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 | ||
10 | void __delay(unsigned long loops) | 12 | void __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 | ||
19 | void __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 | |||
27 | void __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 | |||
18 | void 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 | |||
10 | EXPORT_SYMBOL(__down_failed); | ||
11 | EXPORT_SYMBOL(__down_failed_interruptible); | ||
12 | EXPORT_SYMBOL(__down_failed_trylock); | ||
13 | EXPORT_SYMBOL(__up_wakeup); | ||
14 | |||
15 | /*XXX: we need them because they would be exported by x86_64 */ | ||
16 | EXPORT_SYMBOL(__memcpy); | ||
17 | |||
18 | /* Networking helper routines. */ | ||
19 | /*EXPORT_SYMBOL(csum_partial_copy_from); | ||
20 | EXPORT_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 | ||
65 | int 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 | |||
65 | unsigned long getreg(struct task_struct *child, int regno) | 86 | unsigned 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 | ||
108 | int 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 | |||
87 | void arch_switch(void) | 131 | void 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, | |||
57 | int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, | 57 | int 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 = ¤t->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 | |||
51 | typedef void (*sys_call_ptr_t)(void); | ||
52 | |||
53 | extern void sys_ni_syscall(void); | ||
54 | |||
55 | sys_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 | ||
17 | asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg) | 19 | asmlinkage 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 |
39 | extern int userspace_pid[]; | 45 | extern int userspace_pid[]; |
40 | 46 | ||
47 | #include "skas_ptrace.h" | ||
48 | |||
41 | long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount) | 49 | long 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 */ | ||
5 | void *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 */ | ||
13 | void 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 | |||
14 | void 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 @@ | |||
4 | hostprogs-y := mk_sc mk_thread | 4 | hostprogs-y := mk_sc mk_thread |
5 | always := $(hostprogs-y) | 5 | always := $(hostprogs-y) |
6 | 6 | ||
7 | mk_thread-objs := mk_thread_kern.o mk_thread_user.o | 7 | HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um |
8 | 8 | HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um | |
9 | HOSTCFLAGS_mk_thread_kern.o := $(CFLAGS) $(CPPFLAGS) | ||
10 | HOSTCFLAGS_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 | ||
24 | int main(int argc, char **argv) | 13 | int 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 | |||
4 | int 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 | |||
5 | extern void print_head(void); | ||
6 | extern void print_constant_ptr(char *name, int value); | ||
7 | extern void print_constant(char *name, char *type, int value); | ||
8 | extern void print_tail(void); | ||
9 | |||
10 | #define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field) | ||
11 | |||
12 | int 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 | |||
3 | void 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 | |||
14 | void print_constant_ptr(char *name, int value) | ||
15 | { | ||
16 | printf("#define %s(task) ((unsigned long *) " | ||
17 | "&(((char *) (task))[%d]))\n", name, value); | ||
18 | } | ||
19 | |||
20 | void 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 | |||
26 | void 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 @@ | |||
1 | hostprogs-y := mk_task mk_constants | 1 | hostprogs-y := mk_task mk_constants |
2 | always := $(hostprogs-y) | 2 | always := $(hostprogs-y) |
3 | 3 | ||
4 | mk_task-objs := mk_task_user.o mk_task_kern.o | 4 | HOSTCFLAGS_mk_task.o := -I$(objtree)/arch/um |
5 | mk_constants-objs := mk_constants_user.o mk_constants_kern.o | 5 | HOSTCFLAGS_mk_constants.o := -I$(objtree)/arch/um |
6 | |||
7 | HOSTCFLAGS_mk_task_kern.o := $(CFLAGS) $(CPPFLAGS) | ||
8 | HOSTCFLAGS_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 | |||
7 | int 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 | |||
6 | extern void print_head(void); | ||
7 | extern void print_constant_str(char *name, char *value); | ||
8 | extern void print_constant_int(char *name, int value); | ||
9 | extern void print_tail(void); | ||
10 | |||
11 | int 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 | |||
3 | void 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 | |||
14 | void print_constant_str(char *name, char *value) | ||
15 | { | ||
16 | printf("#define %s \"%s\"\n", name, value); | ||
17 | } | ||
18 | |||
19 | void print_constant_int(char *name, int value) | ||
20 | { | ||
21 | printf("#define %s %d\n", name, value); | ||
22 | } | ||
23 | |||
24 | void 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 | ||
3 | void print(char *name, char *type, int offset) | 4 | void 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 | ||
9 | void print_ptr(char *name, char *type, int offset) | 10 | void 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 | ||
15 | void print_head(void) | 16 | int 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); | |
26 | void 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 | |||
4 | extern void print(char *name, char *type, int offset); | ||
5 | extern void print_ptr(char *name, char *type, int offset); | ||
6 | extern void print_head(void); | ||
7 | extern void print_tail(void); | ||
8 | |||
9 | int 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 | } | ||