summaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/Kconfig1
-rw-r--r--arch/um/Kconfig_i3866
-rw-r--r--arch/um/Kconfig_x86_646
-rw-r--r--arch/um/Makefile80
-rw-r--r--arch/um/Makefile-i3866
-rw-r--r--arch/um/Makefile-x86_644
-rw-r--r--arch/um/defconfig10
-rw-r--r--arch/um/drivers/chan_kern.c16
-rw-r--r--arch/um/drivers/line.c355
-rw-r--r--arch/um/drivers/ssl.c25
-rw-r--r--arch/um/drivers/stdio_console.c19
-rw-r--r--arch/um/drivers/ubd_kern.c14
-rw-r--r--arch/um/drivers/xterm_kern.c1
-rw-r--r--arch/um/include/common-offsets.h14
-rw-r--r--arch/um/include/kern_util.h7
-rw-r--r--arch/um/include/line.h36
-rw-r--r--arch/um/include/os.h1
-rw-r--r--arch/um/include/skas_ptrace.h15
-rw-r--r--arch/um/include/sysdep-i386/checksum.h39
-rw-r--r--arch/um/include/sysdep-i386/faultinfo.h29
-rw-r--r--arch/um/include/sysdep-i386/ptrace.h23
-rw-r--r--arch/um/include/sysdep-i386/sigcontext.h19
-rw-r--r--arch/um/include/sysdep-i386/signal.h2
-rw-r--r--arch/um/include/sysdep-i386/skas_ptrace.h22
-rw-r--r--arch/um/include/sysdep-i386/syscalls.h99
-rw-r--r--arch/um/include/sysdep-ia64/skas_ptrace.h22
-rw-r--r--arch/um/include/sysdep-ppc/skas_ptrace.h22
-rw-r--r--arch/um/include/sysdep-x86_64/faultinfo.h29
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace.h16
-rw-r--r--arch/um/include/sysdep-x86_64/sigcontext.h15
-rw-r--r--arch/um/include/sysdep-x86_64/signal.h2
-rw-r--r--arch/um/include/sysdep-x86_64/skas_ptrace.h22
-rw-r--r--arch/um/include/sysdep-x86_64/syscalls.h59
-rw-r--r--arch/um/include/user_util.h1
-rw-r--r--arch/um/kernel/Makefile17
-rw-r--r--arch/um/kernel/checksum.c36
-rw-r--r--arch/um/kernel/irq.c1
-rw-r--r--arch/um/kernel/ksyms.c3
-rw-r--r--arch/um/kernel/process.c2
-rw-r--r--arch/um/kernel/process_kern.c24
-rw-r--r--arch/um/kernel/ptrace.c123
-rw-r--r--arch/um/kernel/sigio_user.c1
-rw-r--r--arch/um/kernel/skas/include/mode_kern-skas.h1
-rw-r--r--arch/um/kernel/skas/include/skas.h3
-rw-r--r--arch/um/kernel/skas/include/uaccess-skas.h2
-rw-r--r--arch/um/kernel/skas/process.c68
-rw-r--r--arch/um/kernel/skas/process_kern.c4
-rw-r--r--arch/um/kernel/skas/trap_user.c24
-rw-r--r--arch/um/kernel/skas/uaccess.c11
-rw-r--r--arch/um/kernel/skas/util/Makefile1
-rw-r--r--arch/um/kernel/skas/util/mk_ptregs-i386.c46
-rw-r--r--arch/um/kernel/skas/util/mk_ptregs-x86_64.c60
-rw-r--r--arch/um/kernel/sys_call_table.c276
-rw-r--r--arch/um/kernel/syscall_kern.c1
-rw-r--r--arch/um/kernel/time_kern.c18
-rw-r--r--arch/um/kernel/trap_kern.c27
-rw-r--r--arch/um/kernel/trap_user.c13
-rw-r--r--arch/um/kernel/tt/Makefile1
-rw-r--r--arch/um/kernel/tt/include/mode_kern-tt.h1
-rw-r--r--arch/um/kernel/tt/include/uaccess-tt.h2
-rw-r--r--arch/um/kernel/tt/mem.c8
-rw-r--r--arch/um/kernel/tt/process_kern.c20
-rw-r--r--arch/um/kernel/tt/syscall_user.c4
-rw-r--r--arch/um/kernel/tt/tracer.c8
-rw-r--r--arch/um/kernel/tt/trap_user.c6
-rw-r--r--arch/um/kernel/um_arch.c7
-rw-r--r--arch/um/kernel/vmlinux.lds.S6
-rw-r--r--arch/um/os-Linux/process.c5
-rw-r--r--arch/um/os-Linux/signal.c4
-rw-r--r--arch/um/os-Linux/sys-i386/registers.c7
-rw-r--r--arch/um/os-Linux/util/Makefile2
-rw-r--r--arch/um/os-Linux/util/mk_user_constants.c10
-rw-r--r--arch/um/scripts/Makefile.rules25
-rw-r--r--arch/um/sys-i386/Makefile18
-rw-r--r--arch/um/sys-i386/checksum.S6
-rw-r--r--arch/um/sys-i386/delay.c18
-rw-r--r--arch/um/sys-i386/kernel-offsets.c25
-rw-r--r--arch/um/sys-i386/ksyms.c8
-rw-r--r--arch/um/sys-i386/ldt.c5
-rw-r--r--arch/um/sys-i386/ptrace.c40
-rw-r--r--arch/um/sys-i386/signal.c17
-rw-r--r--arch/um/sys-i386/sys_call_table.S16
-rw-r--r--arch/um/sys-i386/user-offsets.c69
-rw-r--r--arch/um/sys-i386/util/Makefile7
-rw-r--r--arch/um/sys-i386/util/mk_sc.c75
-rw-r--r--arch/um/sys-i386/util/mk_thread.c22
-rw-r--r--arch/um/sys-i386/util/mk_thread_kern.c22
-rw-r--r--arch/um/sys-i386/util/mk_thread_user.c30
-rw-r--r--arch/um/sys-ppc/ptrace.c40
-rw-r--r--arch/um/sys-x86_64/Makefile22
-rw-r--r--arch/um/sys-x86_64/delay.c18
-rw-r--r--arch/um/sys-x86_64/kernel-offsets.c24
-rw-r--r--arch/um/sys-x86_64/ksyms.c20
-rw-r--r--arch/um/sys-x86_64/ptrace.c44
-rw-r--r--arch/um/sys-x86_64/signal.c12
-rw-r--r--arch/um/sys-x86_64/syscall_table.c59
-rw-r--r--arch/um/sys-x86_64/syscalls.c16
-rw-r--r--arch/um/sys-x86_64/um_module.c19
-rw-r--r--arch/um/sys-x86_64/user-offsets.c78
-rw-r--r--arch/um/sys-x86_64/util/Makefile6
-rw-r--r--arch/um/sys-x86_64/util/mk_sc.c79
-rw-r--r--arch/um/sys-x86_64/util/mk_thread.c20
-rw-r--r--arch/um/sys-x86_64/util/mk_thread_kern.c21
-rw-r--r--arch/um/sys-x86_64/util/mk_thread_user.c30
-rw-r--r--arch/um/util/Makefile7
-rw-r--r--arch/um/util/mk_constants.c32
-rw-r--r--arch/um/util/mk_constants_kern.c28
-rw-r--r--arch/um/util/mk_constants_user.c28
-rw-r--r--arch/um/util/mk_task.c (renamed from arch/um/util/mk_task_user.c)18
-rw-r--r--arch/um/util/mk_task_kern.c17
110 files changed, 1555 insertions, 1376 deletions
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 9a23df1..c529218 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -244,6 +244,7 @@ config KERNEL_HALF_GIGS
config HIGHMEM
bool "Highmem support"
+ depends on !64BIT
config KERNEL_STACK_ORDER
int "Kernel stack size order"
diff --git a/arch/um/Kconfig_i386 b/arch/um/Kconfig_i386
index 203c242..e41f374 100644
--- a/arch/um/Kconfig_i386
+++ b/arch/um/Kconfig_i386
@@ -1,4 +1,8 @@
-config 64_BIT
+config UML_X86
+ bool
+ default y
+
+config 64BIT
bool
default n
diff --git a/arch/um/Kconfig_x86_64 b/arch/um/Kconfig_x86_64
index 768dc66..fd8d7e8 100644
--- a/arch/um/Kconfig_x86_64
+++ b/arch/um/Kconfig_x86_64
@@ -1,4 +1,8 @@
-config 64_BIT
+config UML_X86
+ bool
+ default y
+
+config 64BIT
bool
default y
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 97bca6b..f2a0c40 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -17,7 +17,7 @@ core-y += $(ARCH_DIR)/kernel/ \
# Have to precede the include because the included Makefiles reference them.
SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \
- arch-signal.h module.h vm-flags.h
+ module.h vm-flags.h elf.h
SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
# XXX: The "os" symlink is only used by arch/um/include/os.h, which includes
@@ -44,6 +44,11 @@ ifneq ($(MAKEFILES-INCL),)
endif
ARCH_INCLUDE := -I$(ARCH_DIR)/include
+ifneq ($(KBUILD_SRC),)
+ARCH_INCLUDE += -I$(ARCH_DIR)/include2
+ARCH_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include
+MRPROPER_DIRS += $(ARCH_DIR)/include2
+endif
SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH)
include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
@@ -94,17 +99,18 @@ define archhelp
echo ' find in the kernel root.'
endef
+ifneq ($(KBUILD_SRC),)
+$(shell mkdir -p $(ARCH_DIR) && ln -fsn $(srctree)/$(ARCH_DIR)/Kconfig_$(SUBARCH) $(ARCH_DIR)/Kconfig_arch)
+CLEAN_FILES += $(ARCH_DIR)/Kconfig_arch
+else
$(shell cd $(ARCH_DIR) && ln -sf Kconfig_$(SUBARCH) Kconfig_arch)
+endif
-prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) \
- $(ARCH_DIR)/kernel/vmlinux.lds.S
+prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS)
LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static
LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib
-LD_SCRIPT-$(CONFIG_LD_SCRIPT_STATIC) := uml.lds.S
-LD_SCRIPT-$(CONFIG_LD_SCRIPT_DYN) := dyn.lds.S
-
CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT
CONFIG_KERNEL_STACK_ORDER ?= 2
STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
@@ -126,7 +132,7 @@ define cmd_vmlinux__
$(CC) $(CFLAGS_vmlinux) -o $@ \
-Wl,-T,$(vmlinux-lds) $(vmlinux-init) \
-Wl,--start-group $(vmlinux-main) -Wl,--end-group \
- -L/usr/lib -lutil \
+ -lutil \
$(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) \
FORCE ,$^) ; rm -f linux
endef
@@ -145,31 +151,42 @@ archclean:
@find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
-o -name '*.gcov' \) -type f -print | xargs rm -f
-#We need to re-preprocess this when the symlink dest changes.
-#So we touch it when needed.
-$(ARCH_DIR)/kernel/vmlinux.lds.S: FORCE
- $(Q)if [ "$(shell readlink $@)" != "$(LD_SCRIPT-y)" ]; then \
- echo ' SYMLINK $@'; \
- ln -sf $(LD_SCRIPT-y) $@; \
- touch $@; \
- fi;
-
$(SYMLINK_HEADERS):
@echo ' SYMLINK $@'
+ifneq ($(KBUILD_SRC),)
+ ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@
+else
$(Q)cd $(TOPDIR)/$(dir $@) ; \
ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@)
+endif
include/asm-um/arch:
@echo ' SYMLINK $@'
+ifneq ($(KBUILD_SRC),)
+ $(Q)mkdir -p include/asm-um
+ $(Q)ln -fsn $(srctree)/include/asm-$(SUBARCH) include/asm-um/arch
+else
$(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch
+endif
$(ARCH_DIR)/include/sysdep:
@echo ' SYMLINK $@'
+ifneq ($(KBUILD_SRC),)
+ $(Q)mkdir -p $(ARCH_DIR)/include
+ $(Q)mkdir -p $(ARCH_DIR)/include2
+ $(Q)ln -fsn sysdep-$(SUBARCH) $(ARCH_DIR)/include/sysdep
+ $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/include/sysdep-$(SUBARCH) $(ARCH_DIR)/include2/sysdep
+else
$(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep
+endif
$(ARCH_DIR)/os:
@echo ' SYMLINK $@'
+ifneq ($(KBUILD_SRC),)
+ $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/os-$(OS) $(ARCH_DIR)/os
+else
$(Q)cd $(ARCH_DIR) && ln -sf os-$(OS) os
+endif
# Generated files
define filechk_umlconfig
@@ -179,10 +196,31 @@ endef
$(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h
$(call filechk,umlconfig)
+$(ARCH_DIR)/user-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.c
+ $(CC) $(USER_CFLAGS) -S -o $@ $<
+
+$(ARCH_DIR)/user-offsets.h: $(ARCH_DIR)/user-offsets.s
+ $(call filechk,gen-asm-offsets)
+
+CLEAN_FILES += $(ARCH_DIR)/user-offsets.s $(ARCH_DIR)/user-offsets.h
+
+$(ARCH_DIR)/kernel-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/kernel-offsets.c \
+ $(ARCH_SYMLINKS) \
+ $(SYS_DIR)/sc.h \
+ include/asm include/linux/version.h \
+ include/config/MARKER \
+ $(ARCH_DIR)/include/user_constants.h
+ $(CC) $(CFLAGS) $(NOSTDINC_FLAGS) $(CPPFLAGS) -S -o $@ $<
+
+$(ARCH_DIR)/kernel-offsets.h: $(ARCH_DIR)/kernel-offsets.s
+ $(call filechk,gen-asm-offsets)
+
+CLEAN_FILES += $(ARCH_DIR)/kernel-offsets.s $(ARCH_DIR)/kernel-offsets.h
+
$(ARCH_DIR)/include/task.h: $(ARCH_DIR)/util/mk_task
$(call filechk,gen_header)
-$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/os/util/mk_user_constants
+$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/os-$(OS)/util/mk_user_constants
$(call filechk,gen_header)
$(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
$(ARCH_DIR)/include/skas_ptregs.h: $(ARCH_DIR)/kernel/skas/util/mk_ptregs
$(call filechk,gen_header)
-$(ARCH_DIR)/os/util/mk_user_constants: $(ARCH_DIR)/os/util FORCE ;
+$(ARCH_DIR)/os-$(OS)/util/mk_user_constants: $(ARCH_DIR)/os-$(OS)/util FORCE ;
$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants: $(ARCH_DIR)/include/user_constants.h $(ARCH_DIR)/util \
FORCE ;
$(ARCH_DIR)/kernel/skas/util/mk_ptregs: $(ARCH_DIR)/kernel/skas/util FORCE ;
-$(ARCH_DIR)/util: scripts_basic $(SYS_DIR)/sc.h FORCE
+$(ARCH_DIR)/util: scripts_basic $(SYS_DIR)/sc.h $(ARCH_DIR)/kernel-offsets.h FORCE
$(Q)$(MAKE) $(build)=$@
-$(ARCH_DIR)/kernel/skas/util: scripts_basic FORCE
+$(ARCH_DIR)/kernel/skas/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
$(Q)$(MAKE) $(build)=$@
-$(ARCH_DIR)/os/util: scripts_basic FORCE
+$(ARCH_DIR)/os-$(OS)/util: scripts_basic FORCE
$(Q)$(MAKE) $(build)=$@
export SUBARCH USER_CFLAGS OS
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index 97b223b..29e182d 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -1,4 +1,4 @@
-SUBARCH_CORE := arch/um/sys-i386/
+SUBARCH_CORE := arch/um/sys-i386/ arch/i386/crypto/
TOP_ADDR := $(CONFIG_TOP_ADDR)
@@ -32,10 +32,10 @@ $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
$(call filechk,gen_header)
-$(SYS_UTIL_DIR)/mk_sc: scripts_basic FORCE
+$(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
$(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
-$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE
+$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_DIR)/kernel-offsets.h FORCE
$(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
$(SYS_UTIL_DIR): scripts_basic include/asm FORCE
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index a779711..3214456 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
$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
$(call filechk,gen_header)
-$(SYS_UTIL_DIR)/mk_sc: scripts_basic FORCE
+$(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
$(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
-$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE
+$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(GEN_HEADERS) $(ARCH_DIR)/kernel-offsets.h FORCE
$(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
CLEAN_FILES += $(SYS_HEADERS)
diff --git a/arch/um/defconfig b/arch/um/defconfig
index fc3075c..4067c3a 100644
--- a/arch/um/defconfig
+++ b/arch/um/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk1
-# Sun Mar 20 16:53:00 2005
+# Linux kernel version: 2.6.12-rc3-skas3-v9-pre2
+# Sun Apr 24 19:46:10 2005
#
CONFIG_GENERIC_HARDIRQS=y
CONFIG_UML=y
@@ -15,7 +15,8 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
#
CONFIG_MODE_TT=y
CONFIG_MODE_SKAS=y
-# CONFIG_64_BIT is not set
+CONFIG_UML_X86=y
+# CONFIG_64BIT is not set
CONFIG_TOP_ADDR=0xc0000000
# CONFIG_3_LEVEL_PGTABLES is not set
CONFIG_ARCH_HAS_SC_SIGNALS=y
@@ -41,6 +42,7 @@ CONFIG_UML_REAL_TIME_CLOCK=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
@@ -158,7 +160,6 @@ CONFIG_UML_NET_SLIRP=y
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
@@ -412,6 +413,5 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_FS is not set
CONFIG_FRAME_POINTER=y
CONFIG_PT_PROXY=y
-# CONFIG_GPROF is not set
# CONFIG_GCOV is not set
# CONFIG_SYSCALL_DEBUG is not set
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 1f77deb..0150038 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -22,7 +22,7 @@
#ifdef CONFIG_NOCONFIG_CHAN
static void *not_configged_init(char *str, int device, struct chan_opts *opts)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(NULL);
}
@@ -30,27 +30,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts)
static int not_configged_open(int input, int output, int primary, void *data,
char **dev_out)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-ENODEV);
}
static void not_configged_close(int fd, void *data)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
}
static int not_configged_read(int fd, char *c_out, void *data)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-EIO);
}
static int not_configged_write(int fd, const char *buf, int len, void *data)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-EIO);
}
@@ -58,7 +58,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data)
static int not_configged_console_write(int fd, const char *buf, int len,
void *data)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-EIO);
}
@@ -66,14 +66,14 @@ static int not_configged_console_write(int fd, const char *buf, int len,
static int not_configged_window_size(int fd, void *data, unsigned short *rows,
unsigned short *cols)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-ENODEV);
}
static void not_configged_free(void *data)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
}
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 6924f27..025d3be 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -39,19 +39,69 @@ static void line_timer_cb(void *arg)
line_interrupt(line->driver->read_irq, arg, NULL);
}
-static int write_room(struct line *dev)
+/* Returns the free space inside the ring buffer of this line.
+ *
+ * Should be called while holding line->lock (this does not modify datas).
+ */
+static int write_room(struct line *line)
{
int n;
- if (dev->buffer == NULL)
- return (LINE_BUFSIZE - 1);
+ if (line->buffer == NULL)
+ return LINE_BUFSIZE - 1;
+
+ /* This is for the case where the buffer is wrapped! */
+ n = line->head - line->tail;
- n = dev->head - dev->tail;
if (n <= 0)
- n = LINE_BUFSIZE + n;
- return (n - 1);
+ n = LINE_BUFSIZE + n; /* The other case */
+ return n - 1;
+}
+
+int line_write_room(struct tty_struct *tty)
+{
+ struct line *line = tty->driver_data;
+ unsigned long flags;
+ int room;
+
+ if (tty->stopped)
+ return 0;
+
+ spin_lock_irqsave(&line->lock, flags);
+ room = write_room(line);
+ spin_unlock_irqrestore(&line->lock, flags);
+
+ /*XXX: Warning to remove */
+ if (0 == room)
+ printk(KERN_DEBUG "%s: %s: no room left in buffer\n",
+ __FUNCTION__,tty->name);
+ return room;
+}
+
+int line_chars_in_buffer(struct tty_struct *tty)
+{
+ struct line *line = tty->driver_data;
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&line->lock, flags);
+
+ /*write_room subtracts 1 for the needed NULL, so we readd it.*/
+ ret = LINE_BUFSIZE - (write_room(line) + 1);
+ spin_unlock_irqrestore(&line->lock, flags);
+
+ return ret;
}
+/*
+ * This copies the content of buf into the circular buffer associated with
+ * this line.
+ * The return value is the number of characters actually copied, i.e. the ones
+ * for which there was space: this function is not supposed to ever flush out
+ * the circular buffer.
+ *
+ * Must be called while holding line->lock!
+ */
static int buffer_data(struct line *line, const char *buf, int len)
{
int end, room;
@@ -70,48 +120,95 @@ static int buffer_data(struct line *line, const char *buf, int len)
len = (len > room) ? room : len;
end = line->buffer + LINE_BUFSIZE - line->tail;
- if(len < end){
+
+ if (len < end){
memcpy(line->tail, buf, len);
line->tail += len;
- }
- else {
+ } else {
+ /* The circular buffer is wrapping */
memcpy(line->tail, buf, end);
buf += end;
memcpy(line->buffer, buf, len - end);
line->tail = line->buffer + len - end;
}
- return(len);
+ return len;
}
+/*
+ * Flushes the ring buffer to the output channels. That is, write_chan is
+ * called, passing it line->head as buffer, and an appropriate count.
+ *
+ * On exit, returns 1 when the buffer is empty,
+ * 0 when the buffer is not empty on exit,
+ * and -errno when an error occurred.
+ *
+ * Must be called while holding line->lock!*/
static int flush_buffer(struct line *line)
{
int n, count;
if ((line->buffer == NULL) || (line->head == line->tail))
- return(1);
+ return 1;
if (line->tail < line->head) {
+ /* line->buffer + LINE_BUFSIZE is the end of the buffer! */
count = line->buffer + LINE_BUFSIZE - line->head;
+
n = write_chan(&line->chan_list, line->head, count,
line->driver->write_irq);
if (n < 0)
- return(n);
- if (n == count)
+ return n;
+ if (n == count) {
+ /* We have flushed from ->head to buffer end, now we
+ * must flush only from the beginning to ->tail.*/
line->head = line->buffer;
- else {
+ } else {
line->head += n;
- return(0);
+ return 0;
}
}
count = line->tail - line->head;
n = write_chan(&line->chan_list, line->head, count,
line->driver->write_irq);
- if(n < 0) return(n);
+
+ if(n < 0)
+ return n;
line->head += n;
- return(line->head == line->tail);
+ return line->head == line->tail;
+}
+
+void line_flush_buffer(struct tty_struct *tty)
+{
+ struct line *line = tty->driver_data;
+ unsigned long flags;
+ int err;
+
+ /*XXX: copied from line_write, verify if it is correct!*/
+ if(tty->stopped)
+ return;
+ //return 0;
+
+ spin_lock_irqsave(&line->lock, flags);
+ err = flush_buffer(line);
+ /*if (err == 1)
+ err = 0;*/
+ spin_unlock_irqrestore(&line->lock, flags);
+ //return err;
+}
+
+/* We map both ->flush_chars and ->put_char (which go in pair) onto ->flush_buffer
+ * and ->write. Hope it's not that bad.*/
+void line_flush_chars(struct tty_struct *tty)
+{
+ line_flush_buffer(tty);
+}
+
+void line_put_char(struct tty_struct *tty, unsigned char ch)
+{
+ line_write(tty, &ch, sizeof(ch));
}
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)
unsigned long flags;
int n, err, ret = 0;
- if(tty->stopped) return 0;
+ if(tty->stopped)
+ return 0;
- down(&line->sem);
- if(line->head != line->tail){
- local_irq_save(flags);
+ spin_lock_irqsave(&line->lock, flags);
+ if (line->head != line->tail) {
ret = buffer_data(line, buf, len);
err = flush_buffer(line);
- local_irq_restore(flags);
- if(err <= 0 && (err != -EAGAIN || !ret))
+ if (err <= 0 && (err != -EAGAIN || !ret))
ret = err;
- }
- else {
+ } else {
n = write_chan(&line->chan_list, buf, len,
line->driver->write_irq);
- if(n < 0){
+ if (n < 0) {
ret = n;
goto out_up;
}
len -= n;
ret += n;
- if(len > 0)
+ if (len > 0)
ret += buffer_data(line, buf + n, len);
}
- out_up:
- up(&line->sem);
- return(ret);
-}
-
-void line_put_char(struct tty_struct *tty, unsigned char ch)
-{
- line_write(tty, &ch, sizeof(ch));
+out_up:
+ spin_unlock_irqrestore(&line->lock, flags);
+ return ret;
}
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)
/* nothing */
}
-int line_chars_in_buffer(struct tty_struct *tty)
-{
- return 0;
-}
-
static struct {
int cmd;
char *level;
@@ -250,7 +335,7 @@ int line_ioctl(struct tty_struct *tty, struct file * file,
ret = -ENOIOCTLCMD;
break;
}
- return(ret);
+ return ret;
}
static irqreturn_t line_write_interrupt(int irq, void *data,
@@ -260,18 +345,23 @@ static irqreturn_t line_write_interrupt(int irq, void *data,
struct line *line = tty->driver_data;
int err;
+ /* Interrupts are enabled here because we registered the interrupt with
+ * SA_INTERRUPT (see line_setup_irq).*/
+
+ spin_lock_irq(&line->lock);
err = flush_buffer(line);
- if(err == 0)
- return(IRQ_NONE);
- else if(err < 0){
+ if (err == 0) {
+ return IRQ_NONE;
+ } else if(err < 0) {
line->head = line->buffer;
line->tail = line->buffer;
}
+ spin_unlock_irq(&line->lock);
if(tty == NULL)
- return(IRQ_NONE);
+ return IRQ_NONE;
- if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
+ if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
(tty->ldisc.write_wakeup != NULL))
(tty->ldisc.write_wakeup)(tty);
@@ -281,9 +371,9 @@ static irqreturn_t line_write_interrupt(int irq, void *data,
* writes.
*/
- if(waitqueue_active(&tty->write_wait))
+ if (waitqueue_active(&tty->write_wait))
wake_up_interruptible(&tty->write_wait);
- return(IRQ_HANDLED);
+ return IRQ_HANDLED;
}
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)
struct line_driver *driver = line->driver;
int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM;
- if(input) err = um_request_irq(driver->read_irq, fd, IRQ_READ,
+ if (input)
+ err = um_request_irq(driver->read_irq, fd, IRQ_READ,
line_interrupt, flags,
driver->read_irq_name, tty);
- if(err) return(err);
- if(output) err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
+ if (err)
+ return err;
+ if (output)
+ err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
line_write_interrupt, flags,
driver->write_irq_name, tty);
line->have_irq = 1;
- return(err);
+ return err;
}
void line_disable(struct tty_struct *tty, int current_irq)
@@ -336,7 +429,9 @@ int line_open(struct line *lines, struct tty_struct *tty,
line = &lines[tty->index];
tty->driver_data = line;
- down(&line->sem);
+ /* The IRQ which takes this lock is not yet enabled and won't be run
+ * before the end, so we don't need to use spin_lock_irq.*/
+ spin_lock(&line->lock);
if (tty->count == 1) {
if (!line->valid) {
err = -ENODEV;
@@ -349,6 +444,7 @@ int line_open(struct line *lines, struct tty_struct *tty,
err = open_chan(&line->chan_list);
if(err) goto out;
}
+ /* Here the interrupt is registered.*/
enable_chan(&line->chan_list, tty);
INIT_WORK(&line->task, line_timer_cb, tty);
}
@@ -362,21 +458,36 @@ int line_open(struct line *lines, struct tty_struct *tty,
line->count++;
out:
- up(&line->sem);
- return(err);
+ spin_unlock(&line->lock);
+ return err;
}
+static void unregister_winch(struct tty_struct *tty);
+
void line_close(struct tty_struct *tty, struct file * filp)
{
struct line *line = tty->driver_data;
- down(&line->sem);
+ /* XXX: I assume this should be called in process context, not with
+ * interrupts disabled!
+ */
+ spin_lock_irq(&line->lock);
+
+ /* We ignore the error anyway! */
+ flush_buffer(line);
+
line->count--;
if (tty->count == 1) {
line_disable(tty, -1);
tty->driver_data = NULL;
}
- up(&line->sem);
+
+ if((line->count == 0) && line->sigio){
+ unregister_winch(tty);
+ line->sigio = 0;
+ }
+
+ spin_unlock_irq(&line->lock);
}
void close_lines(struct line *lines, int nlines)
@@ -387,31 +498,41 @@ void close_lines(struct line *lines, int nlines)
close_chan(&lines[i].chan_list);
}
-int line_setup(struct line *lines, int num, char *init, int all_allowed)
+/* Common setup code for both startup command line and mconsole initialization.
+ * @lines contains the the array (of size @num) to modify;
+ * @init is the setup string;
+ * @all_allowed is a boolean saying if we can setup the whole @lines
+ * at once. For instance, it will be usually true for startup init. (where we
+ * can use con=xterm) and false for mconsole.*/
+
+int line_setup(struct line *lines, unsigned int num, char *init, int all_allowed)
{
int i, n;
char *end;
- if(*init == '=') n = -1;
- else {
+ if(*init == '=') {
+ /* We said con=/ssl= instead of con#=, so we are configuring all
+ * consoles at once.*/
+ n = -1;
+ } else {
n = simple_strtoul(init, &end, 0);
if(*end != '='){
printk(KERN_ERR "line_setup failed to parse \"%s\"\n",
init);
- return(0);
+ return 0;
}
init = end;
}
init++;
- if((n >= 0) && (n >= num)){
+
+ if (n >= (signed int) num) {
printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
n, num - 1);
- return(0);
- }
- else if (n >= 0){
+ return 0;
+ } else if (n >= 0){
if (lines[n].count > 0) {
printk("line_setup - device %d is open\n", n);
- return(0);
+ return 0;
}
if (lines[n].init_pri <= INIT_ONE){
lines[n].init_pri = INIT_ONE;
@@ -422,13 +543,11 @@ int line_setup(struct line *lines, int num, char *init, int all_allowed)
lines[n].valid = 1;
}
}
- }
- else if(!all_allowed){
+ } else if(!all_allowed){
printk("line_setup - can't configure all devices from "
"mconsole\n");
- return(0);
- }
- else {
+ return 0;
+ } else {
for(i = 0; i < num; i++){
if(lines[i].init_pri <= INIT_ALL){
lines[i].init_pri = INIT_ALL;
@@ -440,21 +559,21 @@ int line_setup(struct line *lines, int num, char *init, int all_allowed)
}
}
}
- return(1);
+ return 1;
}
-int line_config(struct line *lines, int num, char *str)
+int line_config(struct line *lines, unsigned int num, char *str)
{
char *new = uml_strdup(str);
if(new == NULL){
printk("line_config - uml_strdup failed\n");
- return(-ENOMEM);
+ return -ENOMEM;
}
- return(!line_setup(lines, num, new, 0));
+ return !line_setup(lines, num, new, 0);
}
-int line_get_config(char *name, struct line *lines, int num, char *str,
+int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
int size, char **error_out)
{
struct line *line;
@@ -464,47 +583,33 @@ int line_get_config(char *name, struct line *lines, int num, char *str,
dev = simple_strtoul(name, &end, 0);
if((*end != '\0') || (end == name)){
*error_out = "line_get_config failed to parse device number";
- return(0);
+ return 0;
}
if((dev < 0) || (dev >= num)){
- *error_out = "device number of of range";
- return(0);
+ *error_out = "device number out of range";
+ return 0;
}
line = &lines[dev];
- down(&line->sem);
+ spin_lock(&line->lock);
if(!line->valid)
CONFIG_CHUNK(str, size, n, "none", 1);
else if(line->count == 0)
CONFIG_CHUNK(str, size, n, line->init_str, 1);
else n = chan_config_string(&line->chan_list, str, size, error_out);
- up(&line->sem);
+ spin_unlock(&line->lock);
- return(n);
+ return n;
}
-int line_remove(struct line *lines, int num, char *str)
+int line_remove(struct line *lines, unsigned int num, char *str)
{
char config[sizeof("conxxxx=none\0")];
sprintf(config, "%s=none", str);
- return(!line_setup(lines, num, config, 0));
-}
-
-int line_write_room(struct tty_struct *tty)
-{
- struct line *dev = tty->driver_data;
- int room;
-
- if (tty->stopped)
- return 0;
- room = write_room(dev);
- if (0 == room)
- printk(KERN_DEBUG "%s: %s: no room left in buffer\n",
- __FUNCTION__,tty->name);
- return room;
+ return !line_setup(lines, num, config, 0);
}
struct tty_driver *line_register_devfs(struct lines *set,
@@ -553,7 +658,7 @@ void lines_init(struct line *lines, int nlines)
for(i = 0; i < nlines; i++){
line = &lines[i];
INIT_LIST_HEAD(&line->chan_list);
- sema_init(&line->sem, 1);
+ spin_lock_init(&line->lock);
if(line->init_str != NULL){
line->init_str = uml_strdup(line->init_str);
if(line->init_str == NULL)
@@ -587,7 +692,7 @@ irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
"errno = %d\n", -err);
printk("fd %d is losing SIGWINCH support\n",
winch->tty_fd);
- return(IRQ_HANDLED);
+ return IRQ_HANDLED;
}
goto out;
}
@@ -603,7 +708,7 @@ irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
out:
if(winch->fd != -1)
reactivate_fd(winch->fd, WINCH_IRQ);
- return(IRQ_HANDLED);
+ return IRQ_HANDLED;
}
DECLARE_MUTEX(winch_handler_sem);
@@ -625,7 +730,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty)
.pid = pid,
.tty = tty });
list_add(&winch->list, &winch_handlers);
- if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
+ if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
"winch", winch) < 0)
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)
up(&winch_handler_sem);
}
+static void unregister_winch(struct tty_struct *tty)
+{
+ struct list_head *ele;
+ struct winch *winch, *found = NULL;
+
+ down(&winch_handler_sem);
+ list_for_each(ele, &winch_handlers){
+ winch = list_entry(ele, struct winch, list);
+ if(winch->tty == tty){
+ found = winch;
+ break;
+ }
+ }
+
+ if(found == NULL)
+ goto out;
+
+ if(winch->pid != -1)
+ os_kill_process(winch->pid, 1);
+
+ free_irq_by_irq_and_dev(WINCH_IRQ, winch);
+ free_irq(WINCH_IRQ, winch);
+ list_del(&winch->list);
+ kfree(winch);
+ out:
+ up(&winch_handler_sem);
+}
+
static void winch_cleanup(void)
{
struct list_head *ele;
@@ -656,26 +789,16 @@ char *add_xterm_umid(char *base)
int len;
umid = get_umid(1);
- if(umid == NULL) return(base);
+ if(umid == NULL)
+ return base;
len = strlen(base) + strlen(" ()") + strlen(umid) + 1;
title = kmalloc(len, GFP_KERNEL);
if(title == NULL){
printk("Failed to allocate buffer for xterm title\n");
- return(base);
+ return base;
}
snprintf(title, len, "%s (%s)", base, umid);
- return(title);
+ return title;
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index c5839c3..a2bac42 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)
}
#if 0
-static int ssl_chars_in_buffer(struct tty_struct *tty)
-{
- return(0);
-}
-
static void ssl_flush_buffer(struct tty_struct *tty)
{
return;
@@ -149,11 +144,11 @@ static struct tty_operations ssl_ops = {
.put_char = line_put_char,
.write_room = line_write_room,
.chars_in_buffer = line_chars_in_buffer,
+ .flush_buffer = line_flush_buffer,
+ .flush_chars = line_flush_chars,
.set_termios = line_set_termios,
.ioctl = line_ioctl,
#if 0
- .flush_chars = ssl_flush_chars,
- .flush_buffer = ssl_flush_buffer,
.throttle = ssl_throttle,
.unthrottle = ssl_unthrottle,
.stop = ssl_stop,
@@ -171,10 +166,11 @@ static void ssl_console_write(struct console *c, const char *string,
unsigned len)
{
struct line *line = &serial_lines[c->index];
+ unsigned long flags;
- down(&line->sem);
+ spin_lock_irqsave(&line->lock, flags);
console_write_chan(&line->chan_list, string, len);
- up(&line->sem);
+ spin_unlock_irqrestore(&line->lock, flags);
}
static struct tty_driver *ssl_console_device(struct console *c, int *index)
@@ -238,14 +234,3 @@ static int ssl_chan_setup(char *str)
__setup("ssl", ssl_chan_setup);
__channel_help(ssl_chan_setup, "ssl");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index e604d7c..361d0be 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 = {
.open = con_open,
.close = line_close,
.write = line_write,
+ .put_char = line_put_char,
.write_room = line_write_room,
.chars_in_buffer = line_chars_in_buffer,
+ .flush_buffer = line_flush_buffer,
+ .flush_chars = line_flush_chars,
.set_termios = line_set_termios,
.ioctl = line_ioctl,
};
@@ -126,10 +129,11 @@ static void uml_console_write(struct console *console, const char *string,
unsigned len)
{
struct line *line = &vts[console->index];
+ unsigned long flags;
- down(&line->sem);
+ spin_lock_irqsave(&line->lock, flags);
console_write_chan(&line->chan_list, string, len);
- up(&line->sem);
+ spin_unlock_irqrestore(&line->lock, flags);
}
static struct tty_driver *uml_console_device(struct console *c, int *index)
@@ -192,14 +196,3 @@ static int console_chan_setup(char *str)
}
__setup("con", console_chan_setup);
__channel_help(console_chan_setup, "con");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 4d8b165..9a56ff9 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];
static struct openflags global_openflags = OPEN_FLAGS;
struct cow {
+ /* This is the backing file, actually */
char *file;
int fd;
unsigned long *bitmap;
@@ -927,10 +928,14 @@ static int ubd_open(struct inode *inode, struct file *filp)
}
}
dev->count++;
- if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
+ set_disk_ro(disk, !dev->openflags.w);
+
+ /* This should no more be needed. And it didn't work anyway to exclude
+ * read-write remounting of filesystems.*/
+ /*if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
if(--dev->count == 0) ubd_close(dev);
err = -EROFS;
- }
+ }*/
out:
return(err);
}
@@ -1096,6 +1101,7 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
if(req->rq_status == RQ_INACTIVE) return(1);
+ /* This should be impossible now */
if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
printk("Write attempted on readonly ubd device %s\n",
disk->disk_name);
@@ -1243,6 +1249,7 @@ static int ubd_check_remapped(int fd, unsigned long address, int is_write,
/* It's a write to a ubd device */
+ /* This should be impossible now */
if(!dev->openflags.w){
/* It's a write access on a read-only device - probably
* shouldn't happen. If the kernel is trying to change
@@ -1605,8 +1612,7 @@ void do_io(struct io_thread_req *req)
}
} while((n < len) && (n != 0));
if (n < len) memset(&buf[n], 0, len - n);
- }
- else {
+ } else {
n = os_write_file(req->fds[bit], buf, len);
if(n != len){
printk("do_io - write failed err = %d "
diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
index 7917b9d..a4fdf35 100644
--- a/arch/um/drivers/xterm_kern.c
+++ b/arch/um/drivers/xterm_kern.c
@@ -7,7 +7,6 @@
#include "linux/slab.h"
#include "linux/signal.h"
#include "linux/interrupt.h"
-#include "asm/semaphore.h"
#include "asm/irq.h"
#include "irq_user.h"
#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 0000000..d705daa
--- /dev/null
+++ b/arch/um/include/common-offsets.h
@@ -0,0 +1,14 @@
+/* for use by sys-$SUBARCH/kernel-offsets.c */
+
+OFFSET(TASK_REGS, task_struct, thread.regs);
+OFFSET(TASK_PID, task_struct, pid);
+DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE);
+DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
+DEFINE_STR(UM_KERN_EMERG, KERN_EMERG);
+DEFINE_STR(UM_KERN_ALERT, KERN_ALERT);
+DEFINE_STR(UM_KERN_CRIT, KERN_CRIT);
+DEFINE_STR(UM_KERN_ERR, KERN_ERR);
+DEFINE_STR(UM_KERN_WARNING, KERN_WARNING);
+DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE);
+DEFINE_STR(UM_KERN_INFO, KERN_INFO);
+DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 15389c8..e5fec55 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -8,6 +8,7 @@
#include "linux/threads.h"
#include "sysdep/ptrace.h"
+#include "sysdep/faultinfo.h"
extern int ncpus;
extern char *linux_prog;
@@ -31,8 +32,8 @@ extern int current_pid(void);
extern unsigned long alloc_stack(int order, int atomic);
extern int do_signal(void);
extern int is_stack_fault(unsigned long sp);
-extern unsigned long segv(unsigned long address, unsigned long ip,
- int is_write, int is_user, void *sc);
+extern unsigned long segv(struct faultinfo fi, unsigned long ip,
+ int is_user, void *sc);
extern int handle_page_fault(unsigned long address, unsigned long ip,
int is_write, int is_user, int *code_out);
extern void syscall_ready(void);
@@ -82,7 +83,7 @@ extern void timer_irq(union uml_pt_regs *regs);
extern void unprotect_stack(unsigned long stack);
extern void do_uml_exitcalls(void);
extern int attach_debugger(int idle_pid, int pid, int stop);
-extern void bad_segv(unsigned long address, unsigned long ip, int is_write);
+extern void bad_segv(struct faultinfo fi, unsigned long ip);
extern int config_gdb(char *str);
extern int remove_gdb(void);
extern char *uml_strdup(char *string);
diff --git a/arch/um/include/line.h b/arch/um/include/line.h
index 6d81ecc..4c5e92c 100644
--- a/arch/um/include/line.h
+++ b/arch/um/include/line.h
@@ -10,7 +10,7 @@
#include "linux/workqueue.h"
#include "linux/tty.h"
#include "linux/interrupt.h"
-#include "asm/semaphore.h"
+#include "linux/spinlock.h"
#include "chan_user.h"
#include "mconsole_kern.h"
@@ -37,10 +37,18 @@ struct line {
struct list_head chan_list;
int valid;
int count;
- struct semaphore sem;
+ /*This lock is actually, mostly, local to*/
+ spinlock_t lock;
+
+ /* Yes, this is a real circular buffer.
+ * XXX: And this should become a struct kfifo!
+ *
+ * buffer points to a buffer allocated on demand, of length
+ * LINE_BUFSIZE, head to the start of the ring, tail to the end.*/
char *buffer;
char *head;
char *tail;
+
int sigio;
struct work_struct task;
struct line_driver *driver;
@@ -52,7 +60,6 @@ struct line {
init_pri : INIT_STATIC, \
chan_list : { }, \
valid : 1, \
- sem : { }, \
buffer : NULL, \
head : NULL, \
tail : NULL, \
@@ -69,15 +76,18 @@ struct lines {
extern void line_close(struct tty_struct *tty, struct file * filp);
extern int line_open(struct line *lines, struct tty_struct *tty,
struct chan_opts *opts);
-extern int line_setup(struct line *lines, int num, char *init,
+extern int line_setup(struct line *lines, unsigned int sizeof_lines, char *init,
int all_allowed);
extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len);
extern void line_put_char(struct tty_struct *tty, unsigned char ch);
extern void line_set_termios(struct tty_struct *tty, struct termios * old);
extern int line_chars_in_buffer(struct tty_struct *tty);
+extern void line_flush_buffer(struct tty_struct *tty);
+extern void line_flush_chars(struct tty_struct *tty);
extern int line_write_room(struct tty_struct *tty);
extern int line_ioctl(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned long arg);
+
extern char *add_xterm_umid(char *base);
extern int line_setup_irq(int fd, int input, int output, struct tty_struct *tty);
extern void line_close_chan(struct line *line);
@@ -89,20 +99,10 @@ extern struct tty_driver * line_register_devfs(struct lines *set,
int nlines);
extern void lines_init(struct line *lines, int nlines);
extern void close_lines(struct line *lines, int nlines);
-extern int line_config(struct line *lines, int num, char *str);
-extern int line_remove(struct line *lines, int num, char *str);
-extern int line_get_config(char *dev, struct line *lines, int num, char *str,
+
+extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str);
+extern int line_remove(struct line *lines, unsigned int sizeof_lines, char *str);
+extern int line_get_config(char *dev, struct line *lines, unsigned int sizeof_lines, char *str,
int size, char **error_out);
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 07340c8..d246d5a 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);
extern void os_kill_ptraced_process(int pid, int reap_child);
extern void os_usr1_process(int pid);
extern int os_getpid(void);
+extern int os_getpgrp(void);
extern int os_map_memory(void *virt, int fd, unsigned long long off,
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 cfb5fb4..cd2327d 100644
--- a/arch/um/include/skas_ptrace.h
+++ b/arch/um/include/skas_ptrace.h
@@ -6,22 +6,11 @@
#ifndef __SKAS_PTRACE_H
#define __SKAS_PTRACE_H
-struct ptrace_faultinfo {
- int is_write;
- unsigned long addr;
-};
-
-struct ptrace_ldt {
- int func;
- void *ptr;
- unsigned long bytecount;
-};
-
#define PTRACE_FAULTINFO 52
-#define PTRACE_SIGPENDING 53
-#define PTRACE_LDT 54
#define PTRACE_SWITCH_MM 55
+#include "sysdep/skas_ptrace.h"
+
#endif
/*
diff --git a/arch/um/include/sysdep-i386/checksum.h b/arch/um/include/sysdep-i386/checksum.h
index 3a2a458..764ba4d 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,
unsigned int sum);
/*
- * the same as csum_partial, but copies from src while it
- * checksums, and handles user-space pointer exceptions correctly, when needed.
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-
-unsigned int csum_partial_copy_to(const unsigned char *src, unsigned char *dst,
- int len, int sum, int *err_ptr);
-unsigned int csum_partial_copy_from(const unsigned char *src, unsigned char *dst,
- int len, int sum, int *err_ptr);
-
-/*
* Note: when you get a NULL pointer exception here this means someone
* passed in an incorrect kernel address to one of these functions.
*
@@ -52,11 +39,24 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *
return(csum_partial(dst, len, sum));
}
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums, and handles user-space pointer exceptions correctly, when needed.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
static __inline__
unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
int len, int sum, int *err_ptr)
{
- return csum_partial_copy_from(src, dst, len, sum, err_ptr);
+ if(copy_from_user(dst, src, len)){
+ *err_ptr = -EFAULT;
+ return(-1);
+ }
+
+ return csum_partial(dst, len, sum);
}
/*
@@ -67,7 +67,6 @@ unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char
*/
#define csum_partial_copy_fromuser csum_partial_copy_from_user
-unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, int len, int sum);
/*
* 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,
unsigned char *dst,
int len, int sum, int *err_ptr)
{
- if (access_ok(VERIFY_WRITE, dst, len))
- return(csum_partial_copy_to(src, dst, len, sum, err_ptr));
+ if (access_ok(VERIFY_WRITE, dst, len)){
+ if(copy_to_user(dst, src, len)){
+ *err_ptr = -EFAULT;
+ return(-1);
+ }
+
+ return csum_partial(src, len, sum);
+ }
if (len)
*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 0000000..db437cc
--- /dev/null
+++ b/arch/um/include/sysdep-i386/faultinfo.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
+ * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
+ * Licensed under the GPL
+ */
+
+#ifndef __FAULTINFO_I386_H
+#define __FAULTINFO_I386_H
+
+/* this structure contains the full arch-specific faultinfo
+ * from the traps.
+ * On i386, ptrace_faultinfo unfortunately doesn't provide
+ * all the info, since trap_no is missing.
+ * All common elements are defined at the same position in
+ * both structures, thus making it easy to copy the
+ * contents without knowledge about the structure elements.
+ */
+struct faultinfo {
+ int error_code; /* in ptrace_faultinfo misleadingly called is_write */
+ unsigned long cr2; /* in ptrace_faultinfo called addr */
+ int trap_no; /* missing in ptrace_faultinfo */
+};
+
+#define FAULT_WRITE(fi) ((fi).error_code & 2)
+#define FAULT_ADDRESS(fi) ((fi).cr2)
+
+#define PTRACE_FULL_FAULTINFO 0
+
+#endif
diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h
index 661d495..84ec7ff 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;
#ifdef UML_CONFIG_MODE_SKAS
#include "skas_ptregs.h"
+#include "sysdep/faultinfo.h"
#define REGS_IP(r) ((r)[HOST_IP])
#define REGS_SP(r) ((r)[HOST_SP])
@@ -53,12 +54,6 @@ extern int sysemu_supported;
#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
-#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
-
-#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
-
-#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
-
#endif
#ifndef PTRACE_SYSEMU_SINGLESTEP
#define PTRACE_SYSEMU_SINGLESTEP 32
@@ -71,6 +66,7 @@ union uml_pt_regs {
struct tt_regs {
long syscall;
void *sc;
+ struct faultinfo faultinfo;
} tt;
#endif
#ifdef UML_CONFIG_MODE_SKAS
@@ -78,9 +74,7 @@ union uml_pt_regs {
unsigned long regs[HOST_FRAME_SIZE];
unsigned long fp[HOST_FP_SIZE];
unsigned long xfp[HOST_XFP_SIZE];
- unsigned long fault_addr;
- unsigned long fault_type;
- unsigned long trap_type;
+ struct faultinfo faultinfo;
long syscall;
int is_user;
} skas;
@@ -217,15 +211,8 @@ struct syscall_args {
#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r)
#define UPT_SYSCALL_RET(r) UPT_EAX(r)
-#define UPT_SEGV_IS_FIXABLE(r) \
- CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
- REGS_SEGV_IS_FIXABLE(&r->skas))
-
-#define UPT_FAULT_ADDR(r) \
- __CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas))
-
-#define UPT_FAULT_WRITE(r) \
- CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
+#define UPT_FAULTINFO(r) \
+ CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo))
#endif
diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
index dfee589..1fe7292 100644
--- a/arch/um/include/sysdep-i386/sigcontext.h
+++ b/arch/um/include/sysdep-i386/sigcontext.h
@@ -13,15 +13,12 @@
#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc))
#define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result)
-#define SC_FAULT_ADDR(sc) SC_CR2(sc)
-#define SC_FAULT_TYPE(sc) SC_ERR(sc)
-
-#define FAULT_WRITE(err) (err & 2)
-#define TO_SC_ERR(is_write) ((is_write) ? 2 : 0)
-
-#define SC_FAULT_WRITE(sc) (FAULT_WRITE(SC_ERR(sc)))
-
-#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc)
+#define GET_FAULTINFO_FROM_SC(fi,sc) \
+ { \
+ (fi).cr2 = SC_CR2(sc); \
+ (fi).error_code = SC_ERR(sc); \
+ (fi).trap_no = SC_TRAPNO(sc); \
+ }
/* ptrace expects that, at the start of a system call, %eax contains
* -ENOSYS, so this makes it so.
@@ -29,9 +26,7 @@
#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
/* This is Page Fault */
-#define SEGV_IS_FIXABLE(trap) (trap == 14)
-
-#define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
+#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
extern unsigned long *sc_sigmask(void *sc_ptr);
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 b1e1f7a..07518b1 100644
--- a/arch/um/include/sysdep-i386/signal.h
+++ b/arch/um/include/sysdep-i386/signal.h
@@ -8,6 +8,8 @@
#include <signal.h>
+#define ARCH_SIGHDLR_PARAM int sig
+
#define ARCH_GET_SIGCONTEXT(sc, sig) \
do sc = (struct sigcontext *) (&sig + 1); while(0)
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 0000000..e27b8a7
--- /dev/null
+++ b/arch/um/include/sysdep-i386/skas_ptrace.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSDEP_I386_SKAS_PTRACE_H
+#define __SYSDEP_I386_SKAS_PTRACE_H
+
+struct ptrace_faultinfo {
+ int is_write;
+ unsigned long addr;
+};
+
+struct ptrace_ldt {
+ int func;
+ void *ptr;
+ unsigned long bytecount;
+};
+
+#define PTRACE_LDT 54
+
+#endif
diff --git a/arch/um/include/sysdep-i386/syscalls.h b/arch/um/include/sysdep-i386/syscalls.h
index 5db81ec..be0a3e3 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;
extern long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff);
-
-/* On i386 they choose a meaningless naming.*/
-#define __NR_kexec_load __NR_sys_kexec_load
-
-#define ARCH_SYSCALLS \
- [ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid, \
- [ __NR_break ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_oldstat ] = (syscall_handler_t *) sys_stat, \
- [ __NR_umount ] = (syscall_handler_t *) sys_oldumount, \
- [ __NR_stime ] = um_stime, \
- [ __NR_oldfstat ] = (syscall_handler_t *) sys_fstat, \
- [ __NR_stty ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_gtty ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_nice ] = (syscall_handler_t *) sys_nice, \
- [ __NR_ftime ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_prof ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_signal ] = (syscall_handler_t *) sys_signal, \
- [ __NR_lock ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_mpx ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_ulimit ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_oldolduname ] = (syscall_handler_t *) sys_olduname, \
- [ __NR_sigaction ] = (syscall_handler_t *) sys_sigaction, \
- [ __NR_sgetmask ] = (syscall_handler_t *) sys_sgetmask, \
- [ __NR_ssetmask ] = (syscall_handler_t *) sys_ssetmask, \
- [ __NR_sigsuspend ] = (syscall_handler_t *) sys_sigsuspend, \
- [ __NR_sigpending ] = (syscall_handler_t *) sys_sigpending, \
- [ __NR_oldlstat ] = (syscall_handler_t *) sys_lstat, \
- [ __NR_readdir ] = old_readdir, \
- [ __NR_profil ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_socketcall ] = (syscall_handler_t *) sys_socketcall, \
- [ __NR_olduname ] = (syscall_handler_t *) sys_uname, \
- [ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_idle ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_ipc ] = (syscall_handler_t *) sys_ipc, \
- [ __NR_sigreturn ] = (syscall_handler_t *) sys_sigreturn, \
- [ __NR_sigprocmask ] = (syscall_handler_t *) sys_sigprocmask, \
- [ __NR_bdflush ] = (syscall_handler_t *) sys_bdflush, \
- [ __NR__llseek ] = (syscall_handler_t *) sys_llseek, \
- [ __NR__newselect ] = (syscall_handler_t *) sys_select, \
- [ __NR_vm86 ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_mmap ] = (syscall_handler_t *) old_mmap_i386, \
- [ __NR_ugetrlimit ] = (syscall_handler_t *) sys_getrlimit, \
- [ __NR_mmap2 ] = (syscall_handler_t *) sys_mmap2, \
- [ __NR_truncate64 ] = (syscall_handler_t *) sys_truncate64, \
- [ __NR_ftruncate64 ] = (syscall_handler_t *) sys_ftruncate64, \
- [ __NR_stat64 ] = (syscall_handler_t *) sys_stat64, \
- [ __NR_lstat64 ] = (syscall_handler_t *) sys_lstat64, \
- [ __NR_fstat64 ] = (syscall_handler_t *) sys_fstat64, \
- [ __NR_fcntl64 ] = (syscall_handler_t *) sys_fcntl64, \
- [ __NR_sendfile64 ] = (syscall_handler_t *) sys_sendfile64, \
- [ __NR_statfs64 ] = (syscall_handler_t *) sys_statfs64, \
- [ __NR_fstatfs64 ] = (syscall_handler_t *) sys_fstatfs64, \
- [ __NR_fadvise64_64 ] = (syscall_handler_t *) sys_fadvise64_64, \
- [ __NR_select ] = (syscall_handler_t *) old_select, \
- [ __NR_vm86old ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \
- [ __NR_lchown32 ] = (syscall_handler_t *) sys_lchown, \
- [ __NR_getuid32 ] = (syscall_handler_t *) sys_getuid, \
- [ __NR_getgid32 ] = (syscall_handler_t *) sys_getgid, \
- [ __NR_geteuid32 ] = (syscall_handler_t *) sys_geteuid, \
- [ __NR_getegid32 ] = (syscall_handler_t *) sys_getegid, \
- [ __NR_setreuid32 ] = (syscall_handler_t *) sys_setreuid, \
- [ __NR_setregid32 ] = (syscall_handler_t *) sys_setregid, \
- [ __NR_getgroups32 ] = (syscall_handler_t *) sys_getgroups, \
- [ __NR_setgroups32 ] = (syscall_handler_t *) sys_setgroups, \
- [ __NR_fchown32 ] = (syscall_handler_t *) sys_fchown, \
- [ __NR_setresuid32 ] = (syscall_handler_t *) sys_setresuid, \
- [ __NR_getresuid32 ] = (syscall_handler_t *) sys_getresuid, \
- [ __NR_setresgid32 ] = (syscall_handler_t *) sys_setresgid, \
- [ __NR_getresgid32 ] = (syscall_handler_t *) sys_getresgid, \
- [ __NR_chown32 ] = (syscall_handler_t *) sys_chown, \
- [ __NR_setuid32 ] = (syscall_handler_t *) sys_setuid, \
- [ __NR_setgid32 ] = (syscall_handler_t *) sys_setgid, \
- [ __NR_setfsuid32 ] = (syscall_handler_t *) sys_setfsuid, \
- [ __NR_setfsgid32 ] = (syscall_handler_t *) sys_setfsgid, \
- [ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \
- [ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \
- [ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \
- [ 222 ] = (syscall_handler_t *) sys_ni_syscall, \
- [ 223 ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
- [ 251 ] = (syscall_handler_t *) sys_ni_syscall, \
- [ 285 ] = (syscall_handler_t *) sys_ni_syscall,
-
-/* 222 doesn't yet have a name in include/asm-i386/unistd.h */
-
-#define LAST_ARCH_SYSCALL 285
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
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 0000000..25a38e7
--- /dev/null
+++ b/arch/um/include/sysdep-ia64/skas_ptrace.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSDEP_IA64_SKAS_PTRACE_H
+#define __SYSDEP_IA64_SKAS_PTRACE_H
+
+struct ptrace_faultinfo {
+ int is_write;
+ unsigned long addr;
+};
+
+struct ptrace_ldt {
+ int func;
+ void *ptr;
+ unsigned long bytecount;
+};
+
+#define PTRACE_LDT 54
+
+#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 0000000..d9fbbac
--- /dev/null
+++ b/arch/um/include/sysdep-ppc/skas_ptrace.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSDEP_PPC_SKAS_PTRACE_H
+#define __SYSDEP_PPC_SKAS_PTRACE_H
+
+struct ptrace_faultinfo {
+ int is_write;
+ unsigned long addr;
+};
+
+struct ptrace_ldt {
+ int func;
+ void *ptr;
+ unsigned long bytecount;
+};
+
+#define PTRACE_LDT 54
+
+#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 0000000..cb917b0
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/faultinfo.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
+ * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
+ * Licensed under the GPL
+ */
+
+#ifndef __FAULTINFO_X86_64_H
+#define __FAULTINFO_X86_64_H
+
+/* this structure contains the full arch-specific faultinfo
+ * from the traps.
+ * On i386, ptrace_faultinfo unfortunately doesn't provide
+ * all the info, since trap_no is missing.
+ * All common elements are defined at the same position in
+ * both structures, thus making it easy to copy the
+ * contents without knowledge about the structure elements.
+ */
+struct faultinfo {
+ int error_code; /* in ptrace_faultinfo misleadingly called is_write */
+ unsigned long cr2; /* in ptrace_faultinfo called addr */
+ int trap_no; /* missing in ptrace_faultinfo */
+};
+
+#define FAULT_WRITE(fi) ((fi).error_code & 2)
+#define FAULT_ADDRESS(fi) ((fi).cr2)
+
+#define PTRACE_FULL_FAULTINFO 1
+
+#endif
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
index 915c82d..348e8fc 100644
--- a/arch/um/include/sysdep-x86_64/ptrace.h
+++ b/arch/um/include/sysdep-x86_64/ptrace.h
@@ -9,6 +9,7 @@
#include "uml-config.h"
#include "user_constants.h"
+#include "sysdep/faultinfo.h"
#define MAX_REG_OFFSET (UM_FRAME_SIZE)
#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long))
@@ -83,6 +84,7 @@ union uml_pt_regs {
long syscall;
unsigned long orig_rax;
void *sc;
+ struct faultinfo faultinfo;
} tt;
#endif
#ifdef UML_CONFIG_MODE_SKAS
@@ -90,9 +92,7 @@ union uml_pt_regs {
/* XXX */
unsigned long regs[27];
unsigned long fp[65];
- unsigned long fault_addr;
- unsigned long fault_type;
- unsigned long trap_type;
+ struct faultinfo faultinfo;
long syscall;
int is_user;
} skas;
@@ -241,14 +241,8 @@ struct syscall_args {
CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
REGS_SEGV_IS_FIXABLE(&r->skas))
-#define UPT_FAULT_ADDR(r) \
- __CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas))
-
-#define UPT_FAULT_WRITE(r) \
- CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
-
-#define UPT_TRAP(r) __CHOOSE_MODE(SC_TRAP_TYPE(UPT_SC(r)), REGS_TRAP(&r->skas))
-#define UPT_ERR(r) __CHOOSE_MODE(SC_FAULT_TYPE(UPT_SC(r)), REGS_ERR(&r->skas))
+#define UPT_FAULTINFO(r) \
+ CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo))
#endif
diff --git a/arch/um/include/sysdep-x86_64/sigcontext.h b/arch/um/include/sysdep-x86_64/sigcontext.h
index 1e38a54..2a78260 100644
--- a/arch/um/include/sysdep-x86_64/sigcontext.h
+++ b/arch/um/include/sysdep-x86_64/sigcontext.h
@@ -17,11 +17,12 @@
#define SC_FAULT_ADDR(sc) SC_CR2(sc)
#define SC_FAULT_TYPE(sc) SC_ERR(sc)
-#define FAULT_WRITE(err) ((err) & 2)
-
-#define SC_FAULT_WRITE(sc) FAULT_WRITE(SC_FAULT_TYPE(sc))
-
-#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc)
+#define GET_FAULTINFO_FROM_SC(fi,sc) \
+ { \
+ (fi).cr2 = SC_CR2(sc); \
+ (fi).error_code = SC_ERR(sc); \
+ (fi).trap_no = SC_TRAPNO(sc); \
+ }
/* ptrace expects that, at the start of a system call, %eax contains
* -ENOSYS, so this makes it so.
@@ -29,8 +30,8 @@
#define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0)
-#define SEGV_IS_FIXABLE(trap) ((trap) == 14)
-#define SC_SEGV_IS_FIXABLE(sc) SEGV_IS_FIXABLE(SC_TRAP_TYPE(sc))
+/* This is Page Fault */
+#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
extern unsigned long *sc_sigmask(void *sc_ptr);
diff --git a/arch/um/include/sysdep-x86_64/signal.h b/arch/um/include/sysdep-x86_64/signal.h
index e5e5275..6142897 100644
--- a/arch/um/include/sysdep-x86_64/signal.h
+++ b/arch/um/include/sysdep-x86_64/signal.h
@@ -6,6 +6,8 @@
#ifndef __X86_64_SIGNAL_H_
#define __X86_64_SIGNAL_H_
+#define ARCH_SIGHDLR_PARAM int sig
+
#define ARCH_GET_SIGCONTEXT(sc, sig_addr) \
do { \
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 0000000..95db4be7
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/skas_ptrace.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSDEP_X86_64_SKAS_PTRACE_H
+#define __SYSDEP_X86_64_SKAS_PTRACE_H
+
+struct ptrace_faultinfo {
+ int is_write;
+ unsigned long addr;
+};
+
+struct ptrace_ldt {
+ int func;
+ void *ptr;
+ unsigned long bytecount;
+};
+
+#define PTRACE_LDT 54
+
+#endif
diff --git a/arch/um/include/sysdep-x86_64/syscalls.h b/arch/um/include/sysdep-x86_64/syscalls.h
index b187a41..67923cc 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[];
extern long old_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff);
-extern syscall_handler_t wrap_sys_shmat;
extern syscall_handler_t sys_modify_ldt;
extern syscall_handler_t sys_arch_prctl;
-#define ARCH_SYSCALLS \
- [ __NR_mmap ] = (syscall_handler_t *) old_mmap, \
- [ __NR_select ] = (syscall_handler_t *) sys_select, \
- [ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \
- [ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \
- [ __NR_shmget ] = (syscall_handler_t *) sys_shmget, \
- [ __NR_shmat ] = (syscall_handler_t *) wrap_sys_shmat, \
- [ __NR_shmctl ] = (syscall_handler_t *) sys_shmctl, \
- [ __NR_semop ] = (syscall_handler_t *) sys_semop, \
- [ __NR_semget ] = (syscall_handler_t *) sys_semget, \
- [ __NR_semctl ] = (syscall_handler_t *) sys_semctl, \
- [ __NR_shmdt ] = (syscall_handler_t *) sys_shmdt, \
- [ __NR_msgget ] = (syscall_handler_t *) sys_msgget, \
- [ __NR_msgsnd ] = (syscall_handler_t *) sys_msgsnd, \
- [ __NR_msgrcv ] = (syscall_handler_t *) sys_msgrcv, \
- [ __NR_msgctl ] = (syscall_handler_t *) sys_msgctl, \
- [ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \
- [ __NR_tuxcall ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_security ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_epoll_ctl_old ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_epoll_wait_old ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \
- [ __NR_arch_prctl ] = (syscall_handler_t *) sys_arch_prctl, \
- [ __NR_socket ] = (syscall_handler_t *) sys_socket, \
- [ __NR_connect ] = (syscall_handler_t *) sys_connect, \
- [ __NR_accept ] = (syscall_handler_t *) sys_accept, \
- [ __NR_recvfrom ] = (syscall_handler_t *) sys_recvfrom, \
- [ __NR_recvmsg ] = (syscall_handler_t *) sys_recvmsg, \
- [ __NR_sendmsg ] = (syscall_handler_t *) sys_sendmsg, \
- [ __NR_bind ] = (syscall_handler_t *) sys_bind, \
- [ __NR_listen ] = (syscall_handler_t *) sys_listen, \
- [ __NR_getsockname ] = (syscall_handler_t *) sys_getsockname, \
- [ __NR_getpeername ] = (syscall_handler_t *) sys_getpeername, \
- [ __NR_socketpair ] = (syscall_handler_t *) sys_socketpair, \
- [ __NR_sendto ] = (syscall_handler_t *) sys_sendto, \
- [ __NR_shutdown ] = (syscall_handler_t *) sys_shutdown, \
- [ __NR_setsockopt ] = (syscall_handler_t *) sys_setsockopt, \
- [ __NR_getsockopt ] = (syscall_handler_t *) sys_getsockopt, \
- [ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_semtimedop ] = (syscall_handler_t *) sys_semtimedop, \
- [ 251 ] = (syscall_handler_t *) sys_ni_syscall,
-
-#define LAST_ARCH_SYSCALL 251
-#define NR_syscalls 1024
+#define NR_syscalls (__NR_syscall_max + 1)
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index 103cd32..b8c5b8a 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);
extern int switcheroo(int fd, int prot, void *from, void *to, int size);
extern void setup_machinename(char *machine_out);
extern void setup_hostinfo(void);
-extern void add_arg(char *arg);
extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
extern void init_new_thread_signals(int altstack);
extern void do_exec(int old_pid, int new_pid);
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index dc796c1..9736ca2 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -4,13 +4,13 @@
#
extra-y := vmlinux.lds
-clean-files := vmlinux.lds.S config.tmp
+clean-files :=
-obj-y = checksum.o config.o exec_kern.o exitcode.o \
+obj-y = config.o exec_kern.o exitcode.o \
helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \
physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \
sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \
- syscall_kern.o sysrq.o sys_call_table.o tempfile.o time.o time_kern.o \
+ syscall_kern.o sysrq.o tempfile.o time.o time_kern.o \
tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \
user_util.o
@@ -23,18 +23,14 @@ obj-$(CONFIG_SYSCALL_DEBUG) += syscall_user.o
obj-$(CONFIG_MODE_TT) += tt/
obj-$(CONFIG_MODE_SKAS) += skas/
-# This needs be compiled with frame pointers regardless of how the rest of the
-# kernel is built.
-CFLAGS_frame.o := -fno-omit-frame-pointer
-
user-objs-$(CONFIG_TTY_LOG) += tty_log.o
USER_OBJS := $(user-objs-y) config.o helper.o main.o process.o tempfile.o \
- time.o tty_log.o umid.o user_util.o frame.o
+ time.o tty_log.o umid.o user_util.o
include arch/um/scripts/Makefile.rules
-targets += config.c
+targets := config.c config.tmp
# Be careful with the below Sed code - sed is pitfall-rich!
# We use sed to lower build requirements, for "embedded" builders for instance.
@@ -53,6 +49,7 @@ quiet_cmd_quote2 = QUOTE $@
cmd_quote2 = sed -e '/CONFIG/{' \
-e 's/"CONFIG"\;/""/' \
-e 'r $(obj)/config.tmp' \
- -e 'a""\;' \
+ -e 'a \' \
+ -e '""\;' \
-e '}' \
$< > $@
diff --git a/arch/um/kernel/checksum.c b/arch/um/kernel/checksum.c
index e69b2be..e69de29 100644
--- a/arch/um/kernel/checksum.c
+++ b/arch/um/kernel/checksum.c
@@ -1,36 +0,0 @@
-#include "asm/uaccess.h"
-#include "linux/errno.h"
-#include "linux/module.h"
-
-unsigned int arch_csum_partial(const unsigned char *buff, int len, int sum);
-
-unsigned int csum_partial(unsigned char *buff, int len, int sum)
-{
- return arch_csum_partial(buff, len, sum);
-}
-
-EXPORT_SYMBOL(csum_partial);
-
-unsigned int csum_partial_copy_to(const unsigned char *src,
- unsigned char __user *dst, int len, int sum,
- int *err_ptr)
-{
- if(copy_to_user(dst, src, len)){
- *err_ptr = -EFAULT;
- return(-1);
- }
-
- return(arch_csum_partial(src, len, sum));
-}
-
-unsigned int csum_partial_copy_from(const unsigned char __user *src,
- unsigned char *dst, int len, int sum,
- int *err_ptr)
-{
- if(copy_from_user(dst, src, len)){
- *err_ptr = -EFAULT;
- return(-1);
- }
-
- return arch_csum_partial(dst, len, sum);
-}
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index d71e8f0..d44fb52 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -163,7 +163,6 @@ void __init init_IRQ(void)
irq_desc[i].handler = &SIGIO_irq_type;
enable_irq(i);
}
- init_irq_signals(0);
}
/*
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index b41d339..78d69dc 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -10,7 +10,6 @@
#include "linux/spinlock.h"
#include "linux/highmem.h"
#include "asm/current.h"
-#include "asm/delay.h"
#include "asm/processor.h"
#include "asm/unistd.h"
#include "asm/pgalloc.h"
@@ -28,8 +27,6 @@ EXPORT_SYMBOL(uml_physmem);
EXPORT_SYMBOL(set_signals);
EXPORT_SYMBOL(get_signals);
EXPORT_SYMBOL(kernel_thread);
-EXPORT_SYMBOL(__const_udelay);
-EXPORT_SYMBOL(__udelay);
EXPORT_SYMBOL(sys_waitpid);
EXPORT_SYMBOL(task_size);
EXPORT_SYMBOL(flush_tlb_range);
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index f76a269..51f8e5a 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -65,8 +65,6 @@ void init_new_thread_signals(int altstack)
SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
set_handler(SIGBUS, (__sighandler_t) sig_handler, flags,
SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
- set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags,
- SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
set_handler(SIGUSR2, (__sighandler_t) sig_handler,
flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
signal(SIGHUP, SIG_IGN);
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index 1d719d5..c1adf7b 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)
return(pid);
}
-void switch_mm(struct mm_struct *prev, struct mm_struct *next,
- struct task_struct *tsk)
-{
- int cpu = smp_processor_id();
-
- if (prev != next)
- cpu_clear(cpu, prev->cpu_vm_mask);
- cpu_set(cpu, next->cpu_vm_mask);
-}
-
void set_current(void *t)
{
struct task_struct *task = t;
@@ -152,7 +142,6 @@ void release_thread(struct task_struct *task)
void exit_thread(void)
{
- CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
unprotect_stack((unsigned long) current_thread);
}
@@ -161,10 +150,6 @@ void *get_current(void)
return(current);
}
-void prepare_to_copy(struct task_struct *tsk)
-{
-}
-
int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
unsigned long stack_top, struct task_struct * p,
struct pt_regs *regs)
@@ -480,12 +465,21 @@ int singlestepping(void * t)
return 2;
}
+/*
+ * Only x86 and x86_64 have an arch_align_stack().
+ * All other arches have "#define arch_align_stack(x) (x)"
+ * in their asm/system.h
+ * As this is included in UML from asm-um/system-generic.h,
+ * we can use it to behave as the subarch does.
+ */
+#ifndef arch_align_stack
unsigned long arch_align_stack(unsigned long sp)
{
if (randomize_va_space)
sp -= get_random_int() % 8192;
return sp & ~0xf;
}
+#endif
/*
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 3a99ee6..2b75d8d 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -19,15 +19,30 @@
#include "skas_ptrace.h"
#include "sysdep/ptrace.h"
+static inline void set_singlestepping(struct task_struct *child, int on)
+{
+ if (on)
+ child->ptrace |= PT_DTRACE;
+ else
+ child->ptrace &= ~PT_DTRACE;
+ child->thread.singlestep_syscall = 0;
+
+#ifdef SUBARCH_SET_SINGLESTEPPING
+ SUBARCH_SET_SINGLESTEPPING(child, on)
+#endif
+ }
+
/*
* Called by kernel/ptrace.c when detaching..
*/
void ptrace_disable(struct task_struct *child)
{
- child->ptrace &= ~PT_DTRACE;
- child->thread.singlestep_syscall = 0;
+ set_singlestepping(child,0);
}
+extern int peek_user(struct task_struct * child, long addr, long data);
+extern int poke_user(struct task_struct * child, long addr, long data);
+
long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
@@ -67,6 +82,10 @@ long sys_ptrace(long request, long pid, long addr, long data)
goto out_tsk;
}
+#ifdef SUBACH_PTRACE_SPECIAL
+ SUBARCH_PTRACE_SPECIAL(child,request,addr,data)
+#endif
+
ret = ptrace_check_attach(child, request == PTRACE_KILL);
if (ret < 0)
goto out_tsk;
@@ -87,26 +106,9 @@ long sys_ptrace(long request, long pid, long addr, long data)
}
/* read the word at location addr in the USER area. */
- case PTRACE_PEEKUSR: {
- unsigned long tmp;
-
- ret = -EIO;
- if ((addr & 3) || addr < 0)
- break;
-
- tmp = 0; /* Default return condition */
- if(addr < MAX_REG_OFFSET){
- tmp = getreg(child, addr);
- }
- else if((addr >= offsetof(struct user, u_debugreg[0])) &&
- (addr <= offsetof(struct user, u_debugreg[7]))){
- addr -= offsetof(struct user, u_debugreg[0]);
- addr = addr >> 2;
- tmp = child->thread.arch.debugregs[addr];
- }
- ret = put_user(tmp, (unsigned long __user *) data);
- break;
- }
+ case PTRACE_PEEKUSR:
+ ret = peek_user(child, addr, data);
+ break;
/* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */
@@ -119,35 +121,16 @@ long sys_ptrace(long request, long pid, long addr, long data)
break;
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
- ret = -EIO;
- if ((addr & 3) || addr < 0)
- break;
-
- if (addr < MAX_REG_OFFSET) {
- ret = putreg(child, addr, data);
- break;
- }
-#if 0 /* XXX x86_64 */
- else if((addr >= offsetof(struct user, u_debugreg[0])) &&
- (addr <= offsetof(struct user, u_debugreg[7]))){
- addr -= offsetof(struct user, u_debugreg[0]);
- addr = addr >> 2;
- if((addr == 4) || (addr == 5)) break;
- child->thread.arch.debugregs[addr] = data;
- ret = 0;
- }
-#endif
-
- break;
+ ret = poke_user(child, addr, data);
+ break;
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
- child->ptrace &= ~PT_DTRACE;
- child->thread.singlestep_syscall = 0;
+ set_singlestepping(child, 0);
if (request == PTRACE_SYSCALL) {
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
}
@@ -170,8 +153,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
- child->ptrace &= ~PT_DTRACE;
- child->thread.singlestep_syscall = 0;
+ set_singlestepping(child, 0);
child->exit_code = SIGKILL;
wake_up_process(child);
break;
@@ -179,11 +161,10 @@ long sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SINGLESTEP: { /* set the trap flag. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->ptrace |= PT_DTRACE;
- child->thread.singlestep_syscall = 0;
+ set_singlestepping(child, 1);
child->exit_code = data;
/* give it a chance to run. */
wake_up_process(child);
@@ -250,23 +231,19 @@ long sys_ptrace(long request, long pid, long addr, long data)
break;
#endif
case PTRACE_FAULTINFO: {
- struct ptrace_faultinfo fault;
-
- fault = ((struct ptrace_faultinfo)
- { .is_write = child->thread.err,
- .addr = child->thread.cr2 });
- ret = copy_to_user((unsigned long __user *) data, &fault,
- sizeof(fault));
+ /* Take the info from thread->arch->faultinfo,
+ * but transfer max. sizeof(struct ptrace_faultinfo).
+ * On i386, ptrace_faultinfo is smaller!
+ */
+ ret = copy_to_user((unsigned long __user *) data,
+ &child->thread.arch.faultinfo,
+ sizeof(struct ptrace_faultinfo));
if(ret)
break;
break;
}
- case PTRACE_SIGPENDING:
- ret = copy_to_user((unsigned long __user *) data,
- &child->pending.signal,
- sizeof(child->pending.signal));
- break;
+#ifdef PTRACE_LDT
case PTRACE_LDT: {
struct ptrace_ldt ldt;
@@ -282,6 +259,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
break;
}
+#endif
#ifdef CONFIG_PROC_MM
case PTRACE_SWITCH_MM: {
struct mm_struct *old = child->mm;
@@ -337,15 +315,18 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
if (unlikely(current->audit_context)) {
if (!entryexit)
- audit_syscall_entry(current,
- UPT_SYSCALL_NR(&regs->regs),
- UPT_SYSCALL_ARG1(&regs->regs),
- UPT_SYSCALL_ARG2(&regs->regs),
- UPT_SYSCALL_ARG3(&regs->regs),
- UPT_SYSCALL_ARG4(&regs->regs));
- else
- audit_syscall_exit(current,
- UPT_SYSCALL_RET(&regs->regs));
+ audit_syscall_entry(current,
+ HOST_AUDIT_ARCH,
+ UPT_SYSCALL_NR(regs),
+ UPT_SYSCALL_ARG1(regs),
+ UPT_SYSCALL_ARG2(regs),
+ UPT_SYSCALL_ARG3(regs),
+ UPT_SYSCALL_ARG4(regs));
+ else {
+ int res = UPT_SYSCALL_RET(regs);
+ audit_syscall_exit(current, AUDITSC_RESULT(res),
+ res);
+ }
}
/* Fake a debug trap */
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
index 668df13..e892189 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)
int i, n, respond_fd;
char c;
+ signal(SIGWINCH, SIG_IGN);
fds = &current_poll;
while(1){
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 94c5649..e484900 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,
unsigned long sp, unsigned long stack_top,
struct task_struct *p, struct pt_regs *regs);
extern void release_thread_skas(struct task_struct *task);
-extern void exit_thread_skas(void);
extern void initial_thread_cb_skas(void (*proc)(void *), void *arg);
extern void init_idle_skas(void);
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 f0702c2..96b51db 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,
extern int unmap(int fd, void *addr, unsigned long len);
extern int protect(int fd, unsigned long addr, unsigned long len,
int r, int w, int x);
-extern void user_signal(int sig, union uml_pt_regs *regs);
+extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
extern int new_mm(int from);
extern void start_userspace(int cpu);
+extern void get_skas_faultinfo(int pid, struct faultinfo * fi);
extern long execute_syscall_skas(void *r);
#endif
diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h
index 11986c9..cd6c280 100644
--- a/arch/um/kernel/skas/include/uaccess-skas.h
+++ b/arch/um/kernel/skas/include/uaccess-skas.h
@@ -19,7 +19,7 @@
((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
static inline int verify_area_skas(int type, const void * addr,
- unsigned long size)
+ unsigned long size)
{
return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
}
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index b4ffaaa..773cd2b 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -4,6 +4,7 @@
*/
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
@@ -27,27 +28,37 @@
#include "chan_user.h"
#include "signal_user.h"
#include "registers.h"
+#include "process.h"
int is_skas_winch(int pid, int fd, void *data)
{
- if(pid != os_getpid())
+ if(pid != os_getpgrp())
return(0);
register_winch_irq(-1, fd, -1, data);
return(1);
}
-static void handle_segv(int pid)
+void get_skas_faultinfo(int pid, struct faultinfo * fi)
{
- struct ptrace_faultinfo fault;
int err;
- err = ptrace(PTRACE_FAULTINFO, pid, 0, &fault);
+ err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
if(err)
- panic("handle_segv - PTRACE_FAULTINFO failed, errno = %d\n",
- errno);
+ panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
+ "errno = %d\n", errno);
+
+ /* Special handling for i386, which has different structs */
+ if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo))
+ memset((char *)fi + sizeof(struct ptrace_faultinfo), 0,
+ sizeof(struct faultinfo) -
+ sizeof(struct ptrace_faultinfo));
+}
- segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL);
+static void handle_segv(int pid, union uml_pt_regs * regs)
+{
+ get_skas_faultinfo(pid, &regs->skas.faultinfo);
+ segv(regs->skas.faultinfo, 0, 1, NULL);
}
/*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)
if(WIFSTOPPED(status)){
switch(WSTOPSIG(status)){
case SIGSEGV:
- handle_segv(pid);
+ handle_segv(pid, regs);
break;
case SIGTRAP + 0x80:
handle_trap(pid, regs, local_using_sysemu);
@@ -177,7 +188,7 @@ void userspace(union uml_pt_regs *regs)
case SIGBUS:
case SIGFPE:
case SIGWINCH:
- user_signal(WSTOPSIG(status), regs);
+ user_signal(WSTOPSIG(status), regs, pid);
break;
default:
printk("userspace - child stopped with signal "
@@ -190,6 +201,11 @@ void userspace(union uml_pt_regs *regs)
}
}
}
+#define INIT_JMP_NEW_THREAD 0
+#define INIT_JMP_REMOVE_SIGSTACK 1
+#define INIT_JMP_CALLBACK 2
+#define INIT_JMP_HALT 3
+#define INIT_JMP_REBOOT 4
void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
void (*handler)(int))
@@ -225,7 +241,7 @@ void thread_wait(void *sw, void *fb)
*switch_buf = &buf;
fork_buf = fb;
if(sigsetjmp(buf, 1) == 0)
- siglongjmp(*fork_buf, 1);
+ siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK);
}
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)
sigjmp_buf **switch_buf = switch_buf_ptr;
int n;
+ set_handler(SIGWINCH, (__sighandler_t) sig_handler,
+ SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
+ SIGVTALRM, -1);
+
*fork_buf_ptr = &initial_jmpbuf;
n = sigsetjmp(initial_jmpbuf, 1);
- if(n == 0)
- new_thread_proc((void *) stack, new_thread_handler);
- else if(n == 1)
- remove_sigstack();
- else if(n == 2){
+ switch(n){
+ case INIT_JMP_NEW_THREAD:
+ new_thread_proc((void *) stack, new_thread_handler);
+ break;
+ case INIT_JMP_REMOVE_SIGSTACK:
+ remove_sigstack();
+ break;
+ case INIT_JMP_CALLBACK:
(*cb_proc)(cb_arg);
siglongjmp(*cb_back, 1);
- }
- else if(n == 3){
+ break;
+ case INIT_JMP_HALT:
kmalloc_ok = 0;
return(0);
- }
- else if(n == 4){
+ case INIT_JMP_REBOOT:
kmalloc_ok = 0;
return(1);
+ default:
+ panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
}
siglongjmp(**switch_buf, 1);
}
@@ -290,7 +314,7 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
block_signals();
if(sigsetjmp(here, 1) == 0)
- siglongjmp(initial_jmpbuf, 2);
+ siglongjmp(initial_jmpbuf, INIT_JMP_CALLBACK);
unblock_signals();
cb_proc = NULL;
@@ -301,13 +325,13 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
void halt_skas(void)
{
block_signals();
- siglongjmp(initial_jmpbuf, 3);
+ siglongjmp(initial_jmpbuf, INIT_JMP_HALT);
}
void reboot_skas(void)
{
block_signals();
- siglongjmp(initial_jmpbuf, 4);
+ siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT);
}
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 5d096ea..ab5d327 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)
{
}
-void exit_thread_skas(void)
-{
-}
-
void fork_handler(int sig)
{
change_sig(SIGUSR1, 1);
diff --git a/arch/um/kernel/skas/trap_user.c b/arch/um/kernel/skas/trap_user.c
index 8e9b46d..0dee1d9 100644
--- a/arch/um/kernel/skas/trap_user.c
+++ b/arch/um/kernel/skas/trap_user.c
@@ -5,12 +5,15 @@
#include <signal.h>
#include <errno.h>
-#include "sysdep/ptrace.h"
#include "signal_user.h"
#include "user_util.h"
#include "kern_util.h"
#include "task.h"
#include "sigcontext.h"
+#include "skas.h"
+#include "ptrace_user.h"
+#include "sysdep/ptrace.h"
+#include "sysdep/ptrace_user.h"
void sig_handler_common_skas(int sig, void *sc_ptr)
{
@@ -31,9 +34,11 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
r = &TASK_REGS(get_current())->skas;
save_user = r->is_user;
r->is_user = 0;
- r->fault_addr = SC_FAULT_ADDR(sc);
- r->fault_type = SC_FAULT_TYPE(sc);
- r->trap_type = SC_TRAP_TYPE(sc);
+ if ( sig == SIGFPE || sig == SIGSEGV ||
+ sig == SIGBUS || sig == SIGILL ||
+ sig == SIGTRAP ) {
+ GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
+ }
change_sig(SIGUSR1, 1);
info = &sig_info[sig];
@@ -45,14 +50,17 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
r->is_user = save_user;
}
-void user_signal(int sig, union uml_pt_regs *regs)
+extern int ptrace_faultinfo;
+
+void user_signal(int sig, union uml_pt_regs *regs, int pid)
{
struct signal_info *info;
+ int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
+ (sig == SIGILL) || (sig == SIGTRAP));
regs->skas.is_user = 1;
- regs->skas.fault_addr = 0;
- regs->skas.fault_type = 0;
- regs->skas.trap_type = 0;
+ if (segv)
+ get_skas_faultinfo(pid, &regs->skas.faultinfo);
info = &sig_info[sig];
(*info->handler)(sig, regs);
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index 7575ec4..7519528 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -3,6 +3,7 @@
* Licensed under the GPL
*/
+#include "linux/compiler.h"
#include "linux/stddef.h"
#include "linux/kernel.h"
#include "linux/string.h"
@@ -28,9 +29,12 @@ static unsigned long maybe_map(unsigned long virt, int is_write)
if(IS_ERR(phys) || (is_write && !pte_write(pte))){
err = handle_page_fault(virt, 0, is_write, 1, &dummy_code);
if(err)
- return(0);
+ return(-1UL);
phys = um_virt_to_phys(current, virt, NULL);
}
+ if(IS_ERR(phys))
+ phys = (void *) -1;
+
return((unsigned long) phys);
}
@@ -41,7 +45,7 @@ static int do_op(unsigned long addr, int len, int is_write,
int n;
addr = maybe_map(addr, is_write);
- if(addr == -1)
+ if(addr == -1UL)
return(-1);
page = phys_to_page(addr);
@@ -61,8 +65,7 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr)
void *arg;
int *res;
- /* Some old gccs recognize __va_copy, but not va_copy */
- __va_copy(args, *(va_list *)arg_ptr);
+ va_copy(args, *(va_list *)arg_ptr);
addr = va_arg(args, unsigned long);
len = va_arg(args, int);
is_write = va_arg(args, int);
diff --git a/arch/um/kernel/skas/util/Makefile b/arch/um/kernel/skas/util/Makefile
index 17f5909..f7b7eba 100644
--- a/arch/um/kernel/skas/util/Makefile
+++ b/arch/um/kernel/skas/util/Makefile
@@ -2,3 +2,4 @@ hostprogs-y := mk_ptregs
always := $(hostprogs-y)
mk_ptregs-objs := mk_ptregs-$(SUBARCH).o
+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 0788dd0..1f96e1e 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 @@
#include <stdio.h>
-#include <asm/ptrace.h>
-#include <asm/user.h>
+#include <user-offsets.h>
-#define PRINT_REG(name, val) printf("#define HOST_%s %d\n", (name), (val))
+#define SHOW(name) printf("#define %s %d\n", #name, name)
int main(int argc, char **argv)
{
@@ -12,28 +11,27 @@ int main(int argc, char **argv)
printf("#ifndef __SKAS_PT_REGS_\n");
printf("#define __SKAS_PT_REGS_\n");
printf("\n");
- printf("#define HOST_FRAME_SIZE %d\n", FRAME_SIZE);
- printf("#define HOST_FP_SIZE %d\n",
- sizeof(struct user_i387_struct) / sizeof(unsigned long));
- printf("#define HOST_XFP_SIZE %d\n",
- sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
+ SHOW(HOST_FRAME_SIZE);
+ SHOW(HOST_FP_SIZE);
+ SHOW(HOST_XFP_SIZE);
+
+ SHOW(HOST_IP);
+ SHOW(HOST_SP);
+ SHOW(HOST_EFLAGS);
+ SHOW(HOST_EAX);
+ SHOW(HOST_EBX);
+ SHOW(HOST_ECX);
+ SHOW(HOST_EDX);
+ SHOW(HOST_ESI);
+ SHOW(HOST_EDI);
+ SHOW(HOST_EBP);
+ SHOW(HOST_CS);
+ SHOW(HOST_SS);
+ SHOW(HOST_DS);
+ SHOW(HOST_FS);
+ SHOW(HOST_ES);
+ SHOW(HOST_GS);
- PRINT_REG("IP", EIP);
- PRINT_REG("SP", UESP);
- PRINT_REG("EFLAGS", EFL);
- PRINT_REG("EAX", EAX);
- PRINT_REG("EBX", EBX);
- PRINT_REG("ECX", ECX);
- PRINT_REG("EDX", EDX);
- PRINT_REG("ESI", ESI);
- PRINT_REG("EDI", EDI);
- PRINT_REG("EBP", EBP);
- PRINT_REG("CS", CS);
- PRINT_REG("SS", SS);
- PRINT_REG("DS", DS);
- PRINT_REG("FS", FS);
- PRINT_REG("ES", ES);
- PRINT_REG("GS", GS);
printf("\n");
printf("#endif\n");
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 67aee92..5fccbfe3 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 @@
*/
#include <stdio.h>
-#define __FRAME_OFFSETS
-#include <asm/ptrace.h>
+#include <user-offsets.h>
-#define PRINT_REG(name, val) \
- printf("#define HOST_%s (%d / sizeof(unsigned long))\n", (name), (val))
+#define SHOW(name) \
+ printf("#define %s (%d / sizeof(unsigned long))\n", #name, name)
int main(int argc, char **argv)
{
@@ -18,36 +17,35 @@ int main(int argc, char **argv)
printf("\n");
printf("#ifndef __SKAS_PT_REGS_\n");
printf("#define __SKAS_PT_REGS_\n");
- printf("#define HOST_FRAME_SIZE (%d / sizeof(unsigned long))\n",
- FRAME_SIZE);
- PRINT_REG("RBX", RBX);
- PRINT_REG("RCX", RCX);
- PRINT_REG("RDI", RDI);
- PRINT_REG("RSI", RSI);
- PRINT_REG("RDX", RDX);
- PRINT_REG("RBP", RBP);
- PRINT_REG("RAX", RAX);
- PRINT_REG("R8", R8);
- PRINT_REG("R9", R9);
- PRINT_REG("R10", R10);
- PRINT_REG("R11", R11);
- PRINT_REG("R12", R12);
- PRINT_REG("R13", R13);
- PRINT_REG("R14", R14);
- PRINT_REG("R15", R15);
- PRINT_REG("ORIG_RAX", ORIG_RAX);
- PRINT_REG("CS", CS);
- PRINT_REG("SS", SS);
- PRINT_REG("EFLAGS", EFLAGS);
+ SHOW(HOST_FRAME_SIZE);
+ SHOW(HOST_RBX);
+ SHOW(HOST_RCX);
+ SHOW(HOST_RDI);
+ SHOW(HOST_RSI);
+ SHOW(HOST_RDX);
+ SHOW(HOST_RBP);
+ SHOW(HOST_RAX);
+ SHOW(HOST_R8);
+ SHOW(HOST_R9);
+ SHOW(HOST_R10);
+ SHOW(HOST_R11);
+ SHOW(HOST_R12);
+ SHOW(HOST_R13);
+ SHOW(HOST_R14);
+ SHOW(HOST_R15);
+ SHOW(HOST_ORIG_RAX);
+ SHOW(HOST_CS);
+ SHOW(HOST_SS);
+ SHOW(HOST_EFLAGS);
#if 0
- PRINT_REG("FS", FS);
- PRINT_REG("GS", GS);
- PRINT_REG("DS", DS);
- PRINT_REG("ES", ES);
+ SHOW(HOST_FS);
+ SHOW(HOST_GS);
+ SHOW(HOST_DS);
+ SHOW(HOST_ES);
#endif
- PRINT_REG("IP", RIP);
- PRINT_REG("SP", RSP);
+ SHOW(HOST_IP);
+ SHOW(HOST_SP);
printf("#define HOST_FP_SIZE 0\n");
printf("#define HOST_XFP_SIZE 0\n");
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 7fc06c8..0000000
--- a/arch/um/kernel/sys_call_table.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
- * Copyright 2003 PathScale, Inc.
- * Licensed under the GPL
- */
-
-#include "linux/config.h"
-#include "linux/unistd.h"
-#include "linux/sys.h"
-#include "linux/swap.h"
-#include "linux/syscalls.h"
-#include "linux/sysctl.h"
-#include "asm/signal.h"
-#include "sysdep/syscalls.h"
-#include "kern_util.h"
-
-#ifdef CONFIG_NFSD
-#define NFSSERVCTL sys_nfsservctl
-#else
-#define NFSSERVCTL sys_ni_syscall
-#endif
-
-#define LAST_GENERIC_SYSCALL __NR_keyctl
-
-#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
-#define LAST_SYSCALL LAST_GENERIC_SYSCALL
-#else
-#define LAST_SYSCALL LAST_ARCH_SYSCALL
-#endif
-
-extern syscall_handler_t sys_fork;
-extern syscall_handler_t sys_execve;
-extern syscall_handler_t um_time;
-extern syscall_handler_t um_stime;
-extern syscall_handler_t sys_pipe;
-extern syscall_handler_t sys_olduname;
-extern syscall_handler_t sys_sigaction;
-extern syscall_handler_t sys_sigsuspend;
-extern syscall_handler_t old_readdir;
-extern syscall_handler_t sys_uname;
-extern syscall_handler_t sys_ipc;
-extern syscall_handler_t sys_sigreturn;
-extern syscall_handler_t sys_clone;
-extern syscall_handler_t sys_rt_sigreturn;
-extern syscall_handler_t sys_sigaltstack;
-extern syscall_handler_t sys_vfork;
-extern syscall_handler_t old_select;
-extern syscall_handler_t sys_modify_ldt;
-extern syscall_handler_t sys_rt_sigsuspend;
-extern syscall_handler_t sys_mbind;
-extern syscall_handler_t sys_get_mempolicy;
-extern syscall_handler_t sys_set_mempolicy;
-extern syscall_handler_t sys_sys_setaltroot;
-
-syscall_handler_t *sys_call_table[] = {
- [ __NR_restart_syscall ] = (syscall_handler_t *) sys_restart_syscall,
- [ __NR_exit ] = (syscall_handler_t *) sys_exit,
- [ __NR_fork ] = (syscall_handler_t *) sys_fork,
- [ __NR_read ] = (syscall_handler_t *) sys_read,
- [ __NR_write ] = (syscall_handler_t *) sys_write,
-
- /* These three are declared differently in asm/unistd.h */
- [ __NR_open ] = (syscall_handler_t *) sys_open,
- [ __NR_close ] = (syscall_handler_t *) sys_close,
- [ __NR_creat ] = (syscall_handler_t *) sys_creat,
- [ __NR_link ] = (syscall_handler_t *) sys_link,
- [ __NR_unlink ] = (syscall_handler_t *) sys_unlink,
- [ __NR_execve ] = (syscall_handler_t *) sys_execve,
-
- /* declared differently in kern_util.h */
- [ __NR_chdir ] = (syscall_handler_t *) sys_chdir,
- [ __NR_time ] = um_time,
- [ __NR_mknod ] = (syscall_handler_t *) sys_mknod,
- [ __NR_chmod ] = (syscall_handler_t *) sys_chmod,
- [ __NR_lchown ] = (syscall_handler_t *) sys_lchown16,
- [ __NR_lseek ] = (syscall_handler_t *) sys_lseek,
- [ __NR_getpid ] = (syscall_handler_t *) sys_getpid,
- [ __NR_mount ] = (syscall_handler_t *) sys_mount,
- [ __NR_setuid ] = (syscall_handler_t *) sys_setuid16,
- [ __NR_getuid ] = (syscall_handler_t *) sys_getuid16,
- [ __NR_ptrace ] = (syscall_handler_t *) sys_ptrace,
- [ __NR_alarm ] = (syscall_handler_t *) sys_alarm,
- [ __NR_pause ] = (syscall_handler_t *) sys_pause,
- [ __NR_utime ] = (syscall_handler_t *) sys_utime,
- [ __NR_access ] = (syscall_handler_t *) sys_access,
- [ __NR_sync ] = (syscall_handler_t *) sys_sync,
- [ __NR_kill ] = (syscall_handler_t *) sys_kill,
- [ __NR_rename ] = (syscall_handler_t *) sys_rename,
- [ __NR_mkdir ] = (syscall_handler_t *) sys_mkdir,
- [ __NR_rmdir ] = (syscall_handler_t *) sys_rmdir,
-
- /* Declared differently in asm/unistd.h */
- [ __NR_dup ] = (syscall_handler_t *) sys_dup,
- [ __NR_pipe ] = (syscall_handler_t *) sys_pipe,
- [ __NR_times ] = (syscall_handler_t *) sys_times,
- [ __NR_brk ] = (syscall_handler_t *) sys_brk,
- [ __NR_setgid ] = (syscall_handler_t *) sys_setgid16,
- [ __NR_getgid ] = (syscall_handler_t *) sys_getgid16,
- [ __NR_geteuid ] = (syscall_handler_t *) sys_geteuid16,
- [ __NR_getegid ] = (syscall_handler_t *) sys_getegid16,
- [ __NR_acct ] = (syscall_handler_t *) sys_acct,
- [ __NR_umount2 ] = (syscall_handler_t *) sys_umount,
- [ __NR_ioctl ] = (syscall_handler_t *) sys_ioctl,
- [ __NR_fcntl ] = (syscall_handler_t *) sys_fcntl,
- [ __NR_setpgid ] = (syscall_handler_t *) sys_setpgid,
- [ __NR_umask ] = (syscall_handler_t *) sys_umask,
- [ __NR_chroot ] = (syscall_handler_t *) sys_chroot,
- [ __NR_ustat ] = (syscall_handler_t *) sys_ustat,
- [ __NR_dup2 ] = (syscall_handler_t *) sys_dup2,
- [ __NR_getppid ] = (syscall_handler_t *) sys_getppid,
- [ __NR_getpgrp ] = (syscall_handler_t *) sys_getpgrp,
- [ __NR_setsid ] = (syscall_handler_t *) sys_setsid,
- [ __NR_setreuid ] = (syscall_handler_t *) sys_setreuid16,
- [ __NR_setregid ] = (syscall_handler_t *) sys_setregid16,
- [ __NR_sethostname ] = (syscall_handler_t *) sys_sethostname,
- [ __NR_setrlimit ] = (syscall_handler_t *) sys_setrlimit,
- [ __NR_getrlimit ] = (syscall_handler_t *) sys_old_getrlimit,
- [ __NR_getrusage ] = (syscall_handler_t *) sys_getrusage,
- [ __NR_gettimeofday ] = (syscall_handler_t *) sys_gettimeofday,
- [ __NR_settimeofday ] = (syscall_handler_t *) sys_settimeofday,
- [ __NR_getgroups ] = (syscall_handler_t *) sys_getgroups16,
- [ __NR_setgroups ] = (syscall_handler_t *) sys_setgroups16,
- [ __NR_symlink ] = (syscall_handler_t *) sys_symlink,
- [ __NR_readlink ] = (syscall_handler_t *) sys_readlink,
- [ __NR_uselib ] = (syscall_handler_t *) sys_uselib,
- [ __NR_swapon ] = (syscall_handler_t *) sys_swapon,
- [ __NR_reboot ] = (syscall_handler_t *) sys_reboot,
- [ __NR_munmap ] = (syscall_handler_t *) sys_munmap,
- [ __NR_truncate ] = (syscall_handler_t *) sys_truncate,
- [ __NR_ftruncate ] = (syscall_handler_t *) sys_ftruncate,
- [ __NR_fchmod ] = (syscall_handler_t *) sys_fchmod,
- [ __NR_fchown ] = (syscall_handler_t *) sys_fchown16,
- [ __NR_getpriority ] = (syscall_handler_t *) sys_getpriority,
- [ __NR_setpriority ] = (syscall_handler_t *) sys_setpriority,
- [ __NR_statfs ] = (syscall_handler_t *) sys_statfs,
- [ __NR_fstatfs ] = (syscall_handler_t *) sys_fstatfs,
- [ __NR_ioperm ] = (syscall_handler_t *) sys_ni_syscall,
- [ __NR_syslog ] = (syscall_handler_t *) sys_syslog,
- [ __NR_setitimer ] = (syscall_handler_t *) sys_setitimer,
- [ __NR_getitimer ] = (syscall_handler_t *) sys_getitimer,
- [ __NR_stat ] = (syscall_handler_t *) sys_newstat,
- [ __NR_lstat ] = (syscall_handler_t *) sys_newlstat,
- [ __NR_fstat ] = (syscall_handler_t *) sys_newfstat,
- [ __NR_vhangup ] = (syscall_handler_t *) sys_vhangup,
- [ __NR_wait4 ] = (syscall_handler_t *) sys_wait4,
- [ __NR_swapoff ] = (syscall_handler_t *) sys_swapoff,
- [ __NR_sysinfo ] = (syscall_handler_t *) sys_sysinfo,
- [ __NR_fsync ] = (syscall_handler_t *) sys_fsync,
- [ __NR_clone ] = (syscall_handler_t *) sys_clone,
- [ __NR_setdomainname ] = (syscall_handler_t *) sys_setdomainname,
- [ __NR_uname ] = (syscall_handler_t *) sys_newuname,
- [ __NR_adjtimex ] = (syscall_handler_t *) sys_adjtimex,
- [ __NR_mprotect ] = (syscall_handler_t *) sys_mprotect,
- [ __NR_create_module ] = (syscall_handler_t *) sys_ni_syscall,
- [ __NR_init_module ] = (syscall_handler_t *) sys_init_module,
- [ __NR_delete_module ] = (syscall_handler_t *) sys_delete_module,
- [ __NR_get_kernel_syms ] = (syscall_handler_t *) sys_ni_syscall,
- [ __NR_quotactl ] = (syscall_handler_t *) sys_quotactl,
- [ __NR_getpgid ] = (syscall_handler_t *) sys_getpgid,
- [ __NR_fchdir ] = (syscall_handler_t *) sys_fchdir,
- [ __NR_sysfs ] = (syscall_handler_t *) sys_sysfs,
- [ __NR_personality ] = (syscall_handler_t *) sys_personality,
- [ __NR_afs_syscall ] = (syscall_handler_t *) sys_ni_syscall,
- [ __NR_setfsuid ] = (syscall_handler_t *) sys_setfsuid16,
- [ __NR_setfsgid ] = (syscall_handler_t *) sys_setfsgid16,
- [ __NR_getdents ] = (syscall_handler_t *) sys_getdents,
- [ __NR_flock ] = (syscall_handler_t *) sys_flock,
- [ __NR_msync ] = (syscall_handler_t *) sys_msync,
- [ __NR_readv ] = (syscall_handler_t *) sys_readv,
- [ __NR_writev ] = (syscall_handler_t *) sys_writev,
- [ __NR_getsid ] = (syscall_handler_t *) sys_getsid,
- [ __NR_fdatasync ] = (syscall_handler_t *) sys_fdatasync,
- [ __NR__sysctl ] = (syscall_handler_t *) sys_sysctl,
- [ __NR_mlock ] = (syscall_handler_t *) sys_mlock,
- [ __NR_munlock ] = (syscall_handler_t *) sys_munlock,
- [ __NR_mlockall ] = (syscall_handler_t *) sys_mlockall,
- [ __NR_munlockall ] = (syscall_handler_t *) sys_munlockall,
- [ __NR_sched_setparam ] = (syscall_handler_t *) sys_sched_setparam,
- [ __NR_sched_getparam ] = (syscall_handler_t *) sys_sched_getparam,
- [ __NR_sched_setscheduler ] = (syscall_handler_t *) sys_sched_setscheduler,
- [ __NR_sched_getscheduler ] = (syscall_handler_t *) sys_sched_getscheduler,
- [ __NR_sched_yield ] = (syscall_handler_t *) yield,
- [ __NR_sched_get_priority_max ] = (syscall_handler_t *) sys_sched_get_priority_max,
- [ __NR_sched_get_priority_min ] = (syscall_handler_t *) sys_sched_get_priority_min,
- [ __NR_sched_rr_get_interval ] = (syscall_handler_t *) sys_sched_rr_get_interval,
- [ __NR_nanosleep ] = (syscall_handler_t *) sys_nanosleep,
- [ __NR_mremap ] = (syscall_handler_t *) sys_mremap,
- [ __NR_setresuid ] = (syscall_handler_t *) sys_setresuid16,
- [ __NR_getresuid ] = (syscall_handler_t *) sys_getresuid16,
- [ __NR_query_module ] = (syscall_handler_t *) sys_ni_syscall,
- [ __NR_poll ] = (syscall_handler_t *) sys_poll,
- [ __NR_nfsservctl ] = (syscall_handler_t *) NFSSERVCTL,
- [ __NR_setresgid ] = (syscall_handler_t *) sys_setresgid16,
- [ __NR_getresgid ] = (syscall_handler_t *) sys_getresgid16,
- [ __NR_prctl ] = (syscall_handler_t *) sys_prctl,
- [ __NR_rt_sigreturn ] = (syscall_handler_t *) sys_rt_sigreturn,
- [ __NR_rt_sigaction ] = (syscall_handler_t *) sys_rt_sigaction,
- [ __NR_rt_sigprocmask ] = (syscall_handler_t *) sys_rt_sigprocmask,
- [ __NR_rt_sigpending ] = (syscall_handler_t *) sys_rt_sigpending,
- [ __NR_rt_sigtimedwait ] = (syscall_handler_t *) sys_rt_sigtimedwait,
- [ __NR_rt_sigqueueinfo ] = (syscall_handler_t *) sys_rt_sigqueueinfo,
- [ __NR_rt_sigsuspend ] = (syscall_handler_t *) sys_rt_sigsuspend,
- [ __NR_pread64 ] = (syscall_handler_t *) sys_pread64,
- [ __NR_pwrite64 ] = (syscall_handler_t *) sys_pwrite64,
- [ __NR_chown ] = (syscall_handler_t *) sys_chown16,
- [ __NR_getcwd ] = (syscall_handler_t *) sys_getcwd,
- [ __NR_capget ] = (syscall_handler_t *) sys_capget,
- [ __NR_capset ] = (syscall_handler_t *) sys_capset,
- [ __NR_sigaltstack ] = (syscall_handler_t *) sys_sigaltstack,
- [ __NR_sendfile ] = (syscall_handler_t *) sys_sendfile,
- [ __NR_getpmsg ] = (syscall_handler_t *) sys_ni_syscall,
- [ __NR_putpmsg ] = (syscall_handler_t *) sys_ni_syscall,
- [ __NR_vfork ] = (syscall_handler_t *) sys_vfork,
- [ __NR_getdents64 ] = (syscall_handler_t *) sys_getdents64,
- [ __NR_gettid ] = (syscall_handler_t *) sys_gettid,
- [ __NR_readahead ] = (syscall_handler_t *) sys_readahead,
- [ __NR_setxattr ] = (syscall_handler_t *) sys_setxattr,
- [ __NR_lsetxattr ] = (syscall_handler_t *) sys_lsetxattr,
- [ __NR_fsetxattr ] = (syscall_handler_t *) sys_fsetxattr,
- [ __NR_getxattr ] = (syscall_handler_t *) sys_getxattr,
- [ __NR_lgetxattr ] = (syscall_handler_t *) sys_lgetxattr,
- [ __NR_fgetxattr ] = (syscall_handler_t *) sys_fgetxattr,
- [ __NR_listxattr ] = (syscall_handler_t *) sys_listxattr,
- [ __NR_llistxattr ] = (syscall_handler_t *) sys_llistxattr,
- [ __NR_flistxattr ] = (syscall_handler_t *) sys_flistxattr,
- [ __NR_removexattr ] = (syscall_handler_t *) sys_removexattr,
- [ __NR_lremovexattr ] = (syscall_handler_t *) sys_lremovexattr,
- [ __NR_fremovexattr ] = (syscall_handler_t *) sys_fremovexattr,
- [ __NR_tkill ] = (syscall_handler_t *) sys_tkill,
- [ __NR_futex ] = (syscall_handler_t *) sys_futex,
- [ __NR_sched_setaffinity ] = (syscall_handler_t *) sys_sched_setaffinity,
- [ __NR_sched_getaffinity ] = (syscall_handler_t *) sys_sched_getaffinity,
- [ __NR_io_setup ] = (syscall_handler_t *) sys_io_setup,
- [ __NR_io_destroy ] = (syscall_handler_t *) sys_io_destroy,
- [ __NR_io_getevents ] = (syscall_handler_t *) sys_io_getevents,
- [ __NR_io_submit ] = (syscall_handler_t *) sys_io_submit,
- [ __NR_io_cancel ] = (syscall_handler_t *) sys_io_cancel,
- [ __NR_exit_group ] = (syscall_handler_t *) sys_exit_group,
- [ __NR_lookup_dcookie ] = (syscall_handler_t *) sys_lookup_dcookie,
- [ __NR_epoll_create ] = (syscall_handler_t *) sys_epoll_create,
- [ __NR_epoll_ctl ] = (syscall_handler_t *) sys_epoll_ctl,
- [ __NR_epoll_wait ] = (syscall_handler_t *) sys_epoll_wait,
- [ __NR_remap_file_pages ] = (syscall_handler_t *) sys_remap_file_pages,
- [ __NR_set_tid_address ] = (syscall_handler_t *) sys_set_tid_address,
- [ __NR_timer_create ] = (syscall_handler_t *) sys_timer_create,
- [ __NR_timer_settime ] = (syscall_handler_t *) sys_timer_settime,
- [ __NR_timer_gettime ] = (syscall_handler_t *) sys_timer_gettime,
- [ __NR_timer_getoverrun ] = (syscall_handler_t *) sys_timer_getoverrun,
- [ __NR_timer_delete ] = (syscall_handler_t *) sys_timer_delete,
- [ __NR_clock_settime ] = (syscall_handler_t *) sys_clock_settime,
- [ __NR_clock_gettime ] = (syscall_handler_t *) sys_clock_gettime,
- [ __NR_clock_getres ] = (syscall_handler_t *) sys_clock_getres,
- [ __NR_clock_nanosleep ] = (syscall_handler_t *) sys_clock_nanosleep,
- [ __NR_tgkill ] = (syscall_handler_t *) sys_tgkill,
- [ __NR_utimes ] = (syscall_handler_t *) sys_utimes,
- [ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64,
- [ __NR_vserver ] = (syscall_handler_t *) sys_ni_syscall,
- [ __NR_mbind ] = (syscall_handler_t *) sys_mbind,
- [ __NR_get_mempolicy ] = (syscall_handler_t *) sys_get_mempolicy,
- [ __NR_set_mempolicy ] = (syscall_handler_t *) sys_set_mempolicy,
- [ __NR_mq_open ] = (syscall_handler_t *) sys_mq_open,
- [ __NR_mq_unlink ] = (syscall_handler_t *) sys_mq_unlink,
- [ __NR_mq_timedsend ] = (syscall_handler_t *) sys_mq_timedsend,
- [ __NR_mq_timedreceive ] = (syscall_handler_t *) sys_mq_timedreceive,
- [ __NR_mq_notify ] = (syscall_handler_t *) sys_mq_notify,
- [ __NR_mq_getsetattr ] = (syscall_handler_t *) sys_mq_getsetattr,
- [ __NR_kexec_load ] = (syscall_handler_t *) sys_ni_syscall,
- [ __NR_waitid ] = (syscall_handler_t *) sys_waitid,
- [ __NR_add_key ] = (syscall_handler_t *) sys_add_key,
- [ __NR_request_key ] = (syscall_handler_t *) sys_request_key,
- [ __NR_keyctl ] = (syscall_handler_t *) sys_keyctl,
-
- ARCH_SYSCALLS
- [ LAST_SYSCALL + 1 ... NR_syscalls ] =
- (syscall_handler_t *) sys_ni_syscall
-};
diff --git a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c
index 42731e0..b7a5525 100644
--- a/arch/um/kernel/syscall_kern.c
+++ b/arch/um/kernel/syscall_kern.c
@@ -17,7 +17,6 @@
#include "linux/utime.h"
#include "asm/mman.h"
#include "asm/uaccess.h"
-#include "asm/ipc.h"
#include "kern_util.h"
#include "user_util.h"
#include "sysdep/syscalls.h"
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
index 2461cd7..6516fc5 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;
static long long delta; /* Deviation per interval */
#endif
-#define MILLION 1000000
-
void timer_irq(union uml_pt_regs *regs)
{
unsigned long long ticks = 0;
@@ -136,22 +134,6 @@ long um_stime(int __user *tptr)
return 0;
}
-void __udelay(unsigned long usecs)
-{
- int i, n;
-
- n = (loops_per_jiffy * HZ * usecs) / MILLION;
- for(i=0;i<n;i++) ;
-}
-
-void __const_udelay(unsigned long usecs)
-{
- int i, n;
-
- n = (loops_per_jiffy * HZ * usecs) / MILLION;
- for(i=0;i<n;i++) ;
-}
-
void timer_handler(int sig, union uml_pt_regs *regs)
{
local_irq_disable();
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
index 47e766e..5fca2c6 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,
goto good_area;
else if(!(vma->vm_flags & VM_GROWSDOWN))
goto out;
- else if(!ARCH_IS_STACKGROW(address))
+ else if(is_user && !ARCH_IS_STACKGROW(address))
goto out;
else if(expand_stack(vma, address))
goto out;
@@ -133,12 +133,19 @@ static int check_remapped_addr(unsigned long address, int is_write)
return(0);
}
-unsigned long segv(unsigned long address, unsigned long ip, int is_write,
- int is_user, void *sc)
+/*
+ * We give a *copy* of the faultinfo in the regs to segv.
+ * This must be done, since nesting SEGVs could overwrite
+ * the info in the regs. A pointer to the info then would
+ * give us bad data!
+ */
+unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
{
struct siginfo si;
void *catcher;
int err;
+ int is_write = FAULT_WRITE(fi);
+ unsigned long address = FAULT_ADDRESS(fi);
if(!is_user && (address >= start_vm) && (address < end_vm)){
flush_tlb_kernel_vm();
@@ -159,7 +166,7 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write,
}
else if(current->thread.fault_addr != NULL)
panic("fault_addr set but no fault catcher");
- else if(arch_fixup(ip, sc))
+ else if(!is_user && arch_fixup(ip, sc))
return(0);
if(!is_user)
@@ -171,6 +178,7 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write,
si.si_errno = 0;
si.si_code = BUS_ADRERR;
si.si_addr = (void *)address;
+ current->thread.arch.faultinfo = fi;
force_sig_info(SIGBUS, &si, current);
}
else if(err == -ENOMEM){
@@ -180,22 +188,20 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write,
else {
si.si_signo = SIGSEGV;
si.si_addr = (void *) address;
- current->thread.cr2 = address;
- current->thread.err = is_write;
+ current->thread.arch.faultinfo = fi;
force_sig_info(SIGSEGV, &si, current);
}
return(0);
}
-void bad_segv(unsigned long address, unsigned long ip, int is_write)
+void bad_segv(struct faultinfo fi, unsigned long ip)
{
struct siginfo si;
si.si_signo = SIGSEGV;
si.si_code = SEGV_ACCERR;
- si.si_addr = (void *) address;
- current->thread.cr2 = address;
- current->thread.err = is_write;
+ si.si_addr = (void *) FAULT_ADDRESS(fi);
+ current->thread.arch.faultinfo = fi;
force_sig_info(SIGSEGV, &si, current);
}
@@ -204,6 +210,7 @@ void relay_signal(int sig, union uml_pt_regs *regs)
if(arch_handle_signal(sig, regs)) return;
if(!UPT_IS_USER(regs))
panic("Kernel mode signal %d", sig);
+ current->thread.arch.faultinfo = *UPT_FAULTINFO(regs);
force_sig(sig, current);
}
diff --git a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c
index 50a4042..f825a6e 100644
--- a/arch/um/kernel/trap_user.c
+++ b/arch/um/kernel/trap_user.c
@@ -54,23 +54,22 @@ struct {
void segv_handler(int sig, union uml_pt_regs *regs)
{
int index, max;
+ struct faultinfo * fi = UPT_FAULTINFO(regs);
- if(UPT_IS_USER(regs) && !UPT_SEGV_IS_FIXABLE(regs)){
- bad_segv(UPT_FAULT_ADDR(regs), UPT_IP(regs),
- UPT_FAULT_WRITE(regs));
+ if(UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)){
+ bad_segv(*fi, UPT_IP(regs));
return;
}
max = sizeof(segfault_record)/sizeof(segfault_record[0]);
index = next_trap_index(max);
nsegfaults++;
- segfault_record[index].address = UPT_FAULT_ADDR(regs);
+ segfault_record[index].address = FAULT_ADDRESS(*fi);
segfault_record[index].pid = os_getpid();
- segfault_record[index].is_write = UPT_FAULT_WRITE(regs);
+ segfault_record[index].is_write = FAULT_WRITE(*fi);
segfault_record[index].sp = UPT_SP(regs);
segfault_record[index].is_user = UPT_IS_USER(regs);
- segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs),
- UPT_IS_USER(regs), regs);
+ segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs);
}
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 3d5177d..c3faea2 100644
--- a/arch/um/kernel/tt/Makefile
+++ b/arch/um/kernel/tt/Makefile
@@ -4,6 +4,7 @@
#
extra-y := unmap_fin.o
+targets := unmap.o
clean-files := unmap_tmp.o
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 28aaab3..e0ca0e0 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,
unsigned long stack_top, struct task_struct *p,
struct pt_regs *regs);
extern void release_thread_tt(struct task_struct *task);
-extern void exit_thread_tt(void);
extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
extern void init_idle_tt(void);
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 f0bad01..3fbb5fe 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;
(under_task_size(addr, size) || is_stack(addr, size))))
static inline int verify_area_tt(int type, const void * addr,
- unsigned long size)
+ unsigned long size)
{
return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
}
diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c
index 74346a0..bcb8796 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)
remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1);
}
-#ifdef CONFIG_HOST_2G_2G
-#define TOP 0x80000000
-#else
-#define TOP 0xc0000000
-#endif
-
#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
-#define START (TOP - SIZE)
+#define START (CONFIG_TOP_ADDR - SIZE)
unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
unsigned long *task_size_out)
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index f19f7c1..df810ca 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)
panic("write of switch_pipe failed, err = %d", -err);
reading = 1;
- if((from->exit_state == EXIT_ZOMBIE) ||
- (from->exit_state == EXIT_DEAD))
+ if(from->thread.mode.tt.switch_pipe[0] == -1)
os_kill_process(os_getpid(), 0);
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)
* in case it has not already killed itself.
*/
prev_sched = current->thread.prev_sched;
- if((prev_sched->exit_state == EXIT_ZOMBIE) ||
- (prev_sched->exit_state == EXIT_DEAD))
+ if(prev_sched->thread.mode.tt.switch_pipe[0] == -1)
os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1);
change_sig(SIGVTALRM, vtalrm);
@@ -101,14 +99,18 @@ void release_thread_tt(struct task_struct *task)
{
int pid = task->thread.mode.tt.extern_pid;
+ /*
+ * We first have to kill the other process, before
+ * closing its switch_pipe. Else it might wake up
+ * and receive "EOF" before we could kill it.
+ */
if(os_getpid() != pid)
os_kill_process(pid, 0);
-}
-void exit_thread_tt(void)
-{
- os_close_file(current->thread.mode.tt.switch_pipe[0]);
- os_close_file(current->thread.mode.tt.switch_pipe[1]);
+ os_close_file(task->thread.mode.tt.switch_pipe[0]);
+ os_close_file(task->thread.mode.tt.switch_pipe[1]);
+ /* use switch_pipe as flag: thread is released */
+ task->thread.mode.tt.switch_pipe[0] = -1;
}
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 e4e7e9c..b218316 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)
UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs);
+#ifdef UPT_ORIGGPR2
+ UPT_ORIGGPR2(TASK_REGS(task)) = REGS_ORIGGPR2(proc_regs);
+#endif
+
if(((unsigned long *) PT_IP(proc_regs) >= &_stext) &&
((unsigned long *) PT_IP(proc_regs) <= &_etext))
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 7b5d937..d11e739 100644
--- a/arch/um/kernel/tt/tracer.c
+++ b/arch/um/kernel/tt/tracer.c
@@ -26,6 +26,7 @@
#include "kern_util.h"
#include "chan_user.h"
#include "ptrace_user.h"
+#include "irq_user.h"
#include "mode.h"
#include "tt.h"
@@ -33,7 +34,7 @@ static int tracer_winch[2];
int is_tracer_winch(int pid, int fd, void *data)
{
- if(pid != tracing_pid)
+ if(pid != os_getpgrp())
return(0);
register_winch_irq(tracer_winch[0], fd, -1, data);
@@ -89,8 +90,10 @@ void tracer_panic(char *format, ...)
static void tracer_segv(int sig, struct sigcontext sc)
{
+ struct faultinfo fi;
+ GET_FAULTINFO_FROM_SC(fi, &sc);
printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n",
- SC_FAULT_ADDR(&sc), SC_IP(&sc));
+ FAULT_ADDRESS(fi), SC_IP(&sc));
while(1)
pause();
}
@@ -117,6 +120,7 @@ static int signal_tramp(void *arg)
signal(SIGSEGV, (__sighandler_t) sig_handler);
set_cmdline("(idle thread)");
set_init_pid(os_getpid());
+ init_irq_signals(0);
proc = arg;
return((*proc)(NULL));
}
diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c
index 92a3820..fc10861 100644
--- a/arch/um/kernel/tt/trap_user.c
+++ b/arch/um/kernel/tt/trap_user.c
@@ -7,6 +7,7 @@
#include <errno.h>
#include <signal.h>
#include "sysdep/ptrace.h"
+#include "sysdep/sigcontext.h"
#include "signal_user.h"
#include "user_util.h"
#include "kern_util.h"
@@ -28,6 +29,11 @@ void sig_handler_common_tt(int sig, void *sc_ptr)
change_sig(SIGSEGV, 1);
r = &TASK_REGS(get_current())->tt;
+ if ( sig == SIGFPE || sig == SIGSEGV ||
+ sig == SIGBUS || sig == SIGILL ||
+ sig == SIGTRAP ) {
+ GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
+ }
save_regs = *r;
is_user = user_context(SC_SP(sc));
r->sc = sc;
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 5c49d88..4d10ec3 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -23,6 +23,7 @@
#include "asm/ptrace.h"
#include "asm/elf.h"
#include "asm/user.h"
+#include "asm/setup.h"
#include "ubd_user.h"
#include "asm/current.h"
#include "asm/setup.h"
@@ -42,9 +43,9 @@
#define DEFAULT_COMMAND_LINE "root=98:0"
/* Changed in linux_main and setup_arch, which run before SMP is started */
-char command_line[COMMAND_LINE_SIZE] = { 0 };
+static char command_line[COMMAND_LINE_SIZE] = { 0 };
-void add_arg(char *arg)
+static void add_arg(char *arg)
{
if (strlen(command_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) {
printf("add_arg: Too many command line arguments!\n");
@@ -449,7 +450,7 @@ void __init setup_arch(char **cmdline_p)
{
notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
paging_init();
- strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
+ strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
*cmdline_p = command_line;
setup_hostinfo();
}
diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S
new file mode 100644
index 0000000..1660a769
--- /dev/null
+++ b/arch/um/kernel/vmlinux.lds.S
@@ -0,0 +1,6 @@
+#include <linux/config.h>
+#ifdef CONFIG_LD_SCRIPT_STATIC
+#include "uml.lds.S"
+#else
+#include "dyn.lds.S"
+#endif
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index ba9ca1cc..1e126bf 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -123,6 +123,11 @@ int os_getpid(void)
return(getpid());
}
+int os_getpgrp(void)
+{
+ return getpgrp();
+}
+
int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
int r, int w, int x)
{
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 7eac1ba..c7bfd5e 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -8,7 +8,7 @@
#include "mode.h"
#include "sysdep/signal.h"
-void sig_handler(int sig)
+void sig_handler(ARCH_SIGHDLR_PARAM)
{
struct sigcontext *sc;
@@ -19,7 +19,7 @@ void sig_handler(int sig)
extern int timer_irq_inited;
-void alarm_handler(int sig)
+void alarm_handler(ARCH_SIGHDLR_PARAM)
{
struct sigcontext *sc;
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index 148645b..9a0ad09 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)
panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
err);
+ errno = 0;
err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
if(!err)
return;
+ if(errno != EIO)
+ panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
+ errno);
have_fpx_regs = 0;
- if(err != EIO)
- panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
- err);
err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
if(err)
diff --git a/arch/um/os-Linux/util/Makefile b/arch/um/os-Linux/util/Makefile
index fb00ddf..9778aed 100644
--- a/arch/um/os-Linux/util/Makefile
+++ b/arch/um/os-Linux/util/Makefile
@@ -1,4 +1,4 @@
hostprogs-y := mk_user_constants
always := $(hostprogs-y)
-mk_user_constants-objs := mk_user_constants.o
+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 0933518..4838f30 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 @@
#include <stdio.h>
-#include <asm/types.h>
-/* For some reason, x86_64 nowhere defines u64 and u32, even though they're
- * used throughout the headers.
- */
-typedef __u64 u64;
-typedef __u32 u32;
-#include <asm/user.h>
+#include <user-offsets.h>
int main(int argc, char **argv)
{
@@ -20,7 +14,7 @@ int main(int argc, char **argv)
* x86_64 (216 vs 168 bytes). user_regs_struct is the correct size on
* both x86_64 and i386.
*/
- printf("#define UM_FRAME_SIZE %d\n", (int) sizeof(struct user_regs_struct));
+ printf("#define UM_FRAME_SIZE %d\n", __UM_FRAME_SIZE);
printf("\n");
printf("#endif\n");
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 143f6fe..0b24918 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -2,12 +2,27 @@
# arch/um: Generic definitions
# ===========================================================================
-USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
-USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS))
-
+USER_SINGLE_OBJS := \
+ $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
+USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS))
USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
-$(USER_OBJS): c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(notdir $@))
+$(USER_OBJS) : c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \
+ $(CFLAGS_$(notdir $@))
quiet_cmd_make_link = SYMLINK $@
-cmd_make_link = rm -f $@; ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@
+cmd_make_link = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@
+
+# this needs to be before the foreach, because targets does not accept
+# complete paths like $(obj)/$(f). To make sure this works, use a := assignment,
+# or we will get $(obj)/$(f) in the "targets" value.
+# Also, this forces you to use the := syntax when assigning to targets.
+# Otherwise the line below will cause an infinite loop (if you don't know why,
+# just do it).
+
+targets := $(targets) $(SYMLINKS)
+
+SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$(f))
+
+$(SYMLINKS): FORCE
+ $(call if_changed,make_link)
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 71b47e6..fcd67c3 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -1,29 +1,19 @@
obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
- ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o
+ ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o \
+ sys_call_table.o
obj-$(CONFIG_HIGHMEM) += highmem.o
obj-$(CONFIG_MODULES) += module.o
USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
-include arch/um/scripts/Makefile.rules
-
SYMLINKS = bitops.c semaphore.c highmem.c module.c
-# this needs to be before the foreach, because clean-files does not accept
-# complete paths like $(src)/$f.
-clean-files := $(SYMLINKS)
-
-targets += $(SYMLINKS)
-
-SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$f)
-
bitops.c-dir = lib
semaphore.c-dir = kernel
highmem.c-dir = mm
module.c-dir = kernel
-$(SYMLINKS): FORCE
- $(call if_changed,make_link)
-
subdir- := util
+
+include arch/um/scripts/Makefile.rules
diff --git a/arch/um/sys-i386/checksum.S b/arch/um/sys-i386/checksum.S
index a11171f..d98b2ff 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)
.text
.align 4
-.globl arch_csum_partial
+.globl csum_partial
#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
@@ -49,7 +49,7 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
* Fortunately, it is easy to convert 2-byte alignment to 4-byte
* alignment for the unrolled loop.
*/
-arch_csum_partial:
+csum_partial:
pushl %esi
pushl %ebx
movl 20(%esp),%eax # Function arg: unsigned int sum
@@ -119,7 +119,7 @@ arch_csum_partial:
/* Version for PentiumII/PPro */
-arch_csum_partial:
+csum_partial:
pushl %esi
pushl %ebx
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 20d37db..e9892ee 100644
--- a/arch/um/sys-i386/delay.c
+++ b/arch/um/sys-i386/delay.c
@@ -1,3 +1,6 @@
+#include "linux/delay.h"
+#include "asm/param.h"
+
void __delay(unsigned long time)
{
/* Stolen from the i386 __loop_delay */
@@ -12,3 +15,18 @@ void __delay(unsigned long time)
:"0" (time));
}
+void __udelay(unsigned long usecs)
+{
+ int i, n;
+
+ n = (loops_per_jiffy * HZ * usecs) / MILLION;
+ for(i=0;i<n;i++) ;
+}
+
+void __const_udelay(unsigned long usecs)
+{
+ int i, n;
+
+ n = (loops_per_jiffy * HZ * usecs) / MILLION;
+ for(i=0;i<n;i++) ;
+}
diff --git a/arch/um/sys-i386/kernel-offsets.c b/arch/um/sys-i386/kernel-offsets.c
new file mode 100644
index 0000000..9f8ecd1
--- /dev/null
+++ b/arch/um/sys-i386/kernel-offsets.c
@@ -0,0 +1,25 @@
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <asm/page.h>
+
+#define DEFINE(sym, val) \
+ asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define STR(x) #x
+#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " STR(val) " " #val: : )
+
+#define BLANK() asm volatile("\n->" : : )
+
+#define OFFSET(sym, str, mem) \
+ DEFINE(sym, offsetof(struct str, mem));
+
+void foo(void)
+{
+ OFFSET(TASK_DEBUGREGS, task_struct, thread.arch.debugregs);
+#ifdef CONFIG_MODE_TT
+ OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
+#endif
+#include <common-offsets.h>
+}
diff --git a/arch/um/sys-i386/ksyms.c b/arch/um/sys-i386/ksyms.c
index 74f70a1..db524ab3 100644
--- a/arch/um/sys-i386/ksyms.c
+++ b/arch/um/sys-i386/ksyms.c
@@ -2,6 +2,7 @@
#include "linux/in6.h"
#include "linux/rwsem.h"
#include "asm/byteorder.h"
+#include "asm/delay.h"
#include "asm/semaphore.h"
#include "asm/uaccess.h"
#include "asm/checksum.h"
@@ -13,5 +14,8 @@ EXPORT_SYMBOL(__down_failed_trylock);
EXPORT_SYMBOL(__up_wakeup);
/* Networking helper routines. */
-EXPORT_SYMBOL(csum_partial_copy_from);
-EXPORT_SYMBOL(csum_partial_copy_to);
+EXPORT_SYMBOL(csum_partial);
+
+/* delay core functions */
+EXPORT_SYMBOL(__const_udelay);
+EXPORT_SYMBOL(__udelay);
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index 31bcb2f..dc755b0 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)
#endif
#ifdef CONFIG_MODE_SKAS
-extern int userspace_pid;
+extern int userspace_pid[];
#include "skas_ptrace.h"
@@ -56,7 +56,8 @@ int sys_modify_ldt_skas(int func, void __user *ptr, unsigned long bytecount)
ldt = ((struct ptrace_ldt) { .func = func,
.ptr = buf,
.bytecount = bytecount });
- res = ptrace(PTRACE_LDT, userspace_pid, 0, (unsigned long) &ldt);
+#warning Need to look up userspace_pid by cpu
+ res = ptrace(PTRACE_LDT, userspace_pid[0], 0, (unsigned long) &ldt);
if(res < 0)
goto out;
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index e470d28..e839ce6 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)
return 0;
}
+int poke_user(struct task_struct *child, long addr, long data)
+{
+ if ((addr & 3) || addr < 0)
+ return -EIO;
+
+ if (addr < MAX_REG_OFFSET)
+ return putreg(child, addr, data);
+
+ else if((addr >= offsetof(struct user, u_debugreg[0])) &&
+ (addr <= offsetof(struct user, u_debugreg[7]))){
+ addr -= offsetof(struct user, u_debugreg[0]);
+ addr = addr >> 2;
+ if((addr == 4) || (addr == 5)) return -EIO;
+ child->thread.arch.debugregs[addr] = data;
+ return 0;
+ }
+ return -EIO;
+}
+
unsigned long getreg(struct task_struct *child, int regno)
{
unsigned long retval = ~0UL;
@@ -93,6 +112,27 @@ unsigned long getreg(struct task_struct *child, int regno)
return retval;
}
+int peek_user(struct task_struct *child, long addr, long data)
+{
+/* read the word at location addr in the USER area. */
+ unsigned long tmp;
+
+ if ((addr & 3) || addr < 0)
+ return -EIO;
+
+ tmp = 0; /* Default return condition */
+ if(addr < MAX_REG_OFFSET){
+ tmp = getreg(child, addr);
+ }
+ else if((addr >= offsetof(struct user, u_debugreg[0])) &&
+ (addr <= offsetof(struct user, u_debugreg[7]))){
+ addr -= offsetof(struct user, u_debugreg[0]);
+ addr = addr >> 2;
+ tmp = child->thread.arch.debugregs[addr];
+ }
+ return put_user(tmp, (unsigned long *) data);
+}
+
struct i387_fxsave_struct {
unsigned short cwd;
unsigned short swd;
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 76ba872..03913ca 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,
REGS_CS(regs->regs.skas.regs) = sc.cs;
REGS_EFLAGS(regs->regs.skas.regs) = sc.eflags;
REGS_SS(regs->regs.skas.regs) = sc.ss;
- regs->regs.skas.fault_addr = sc.cr2;
- regs->regs.skas.fault_type = FAULT_WRITE(sc.err);
- regs->regs.skas.trap_type = sc.trapno;
err = restore_fp_registers(userspace_pid[0], fpregs);
if(err < 0){
@@ -62,11 +59,11 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
}
int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
- struct pt_regs *regs, unsigned long fault_addr,
- int fault_type)
+ struct pt_regs *regs)
{
struct sigcontext sc;
unsigned long fpregs[HOST_FP_SIZE];
+ struct faultinfo * fi = &current->thread.arch.faultinfo;
int err;
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,
sc.eflags = REGS_EFLAGS(regs->regs.skas.regs);
sc.esp_at_signal = regs->regs.skas.regs[UESP];
sc.ss = regs->regs.skas.regs[SS];
- sc.cr2 = fault_addr;
- sc.err = TO_SC_ERR(fault_type);
- sc.trapno = regs->regs.skas.trap_type;
+ sc.cr2 = fi->cr2;
+ sc.err = fi->error_code;
+ sc.trapno = fi->trap_no;
err = save_fp_registers(userspace_pid[0], fpregs);
if(err < 0){
@@ -167,9 +164,7 @@ static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp,
{
return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
sizeof(*fp)),
- copy_sc_to_user_skas(to, fp, from,
- current->thread.cr2,
- current->thread.err)));
+ copy_sc_to_user_skas(to, fp, from)));
}
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 0000000..ad75c27
--- /dev/null
+++ b/arch/um/sys-i386/sys_call_table.S
@@ -0,0 +1,16 @@
+#include <linux/linkage.h>
+/* Steal i386 syscall table for our purposes, but with some slight changes.*/
+
+#define sys_iopl sys_ni_syscall
+#define sys_ioperm sys_ni_syscall
+
+#define sys_vm86old sys_ni_syscall
+#define sys_vm86 sys_ni_syscall
+#define sys_set_thread_area sys_ni_syscall
+#define sys_get_thread_area sys_ni_syscall
+
+#define sys_stime um_stime
+#define sys_time um_time
+#define old_mmap old_mmap_i386
+
+#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 0000000..3ceaabc
--- /dev/null
+++ b/arch/um/sys-i386/user-offsets.c
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <signal.h>
+#include <asm/ptrace.h>
+#include <asm/user.h>
+#include <linux/stddef.h>
+
+#define DEFINE(sym, val) \
+ asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define OFFSET(sym, str, mem) \
+ DEFINE(sym, offsetof(struct str, mem));
+
+void foo(void)
+{
+ OFFSET(SC_IP, sigcontext, eip);
+ OFFSET(SC_SP, sigcontext, esp);
+ OFFSET(SC_FS, sigcontext, fs);
+ OFFSET(SC_GS, sigcontext, gs);
+ OFFSET(SC_DS, sigcontext, ds);
+ OFFSET(SC_ES, sigcontext, es);
+ OFFSET(SC_SS, sigcontext, ss);
+ OFFSET(SC_CS, sigcontext, cs);
+ OFFSET(SC_EFLAGS, sigcontext, eflags);
+ OFFSET(SC_EAX, sigcontext, eax);
+ OFFSET(SC_EBX, sigcontext, ebx);
+ OFFSET(SC_ECX, sigcontext, ecx);
+ OFFSET(SC_EDX, sigcontext, edx);
+ OFFSET(SC_EDI, sigcontext, edi);
+ OFFSET(SC_ESI, sigcontext, esi);
+ OFFSET(SC_EBP, sigcontext, ebp);
+ OFFSET(SC_TRAPNO, sigcontext, trapno);
+ OFFSET(SC_ERR, sigcontext, err);
+ OFFSET(SC_CR2, sigcontext, cr2);
+ OFFSET(SC_FPSTATE, sigcontext, fpstate);
+ OFFSET(SC_SIGMASK, sigcontext, oldmask);
+ OFFSET(SC_FP_CW, _fpstate, cw);
+ OFFSET(SC_FP_SW, _fpstate, sw);
+ OFFSET(SC_FP_TAG, _fpstate, tag);
+ OFFSET(SC_FP_IPOFF, _fpstate, ipoff);
+ OFFSET(SC_FP_CSSEL, _fpstate, cssel);
+ OFFSET(SC_FP_DATAOFF, _fpstate, dataoff);
+ OFFSET(SC_FP_DATASEL, _fpstate, datasel);
+ OFFSET(SC_FP_ST, _fpstate, _st);
+ OFFSET(SC_FXSR_ENV, _fpstate, _fxsr_env);
+
+ DEFINE(HOST_FRAME_SIZE, FRAME_SIZE);
+ DEFINE(HOST_FP_SIZE,
+ sizeof(struct user_i387_struct) / sizeof(unsigned long));
+ DEFINE(HOST_XFP_SIZE,
+ sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
+
+ DEFINE(HOST_IP, EIP);
+ DEFINE(HOST_SP, UESP);
+ DEFINE(HOST_EFLAGS, EFL);
+ DEFINE(HOST_EAX, EAX);
+ DEFINE(HOST_EBX, EBX);
+ DEFINE(HOST_ECX, ECX);
+ DEFINE(HOST_EDX, EDX);
+ DEFINE(HOST_ESI, ESI);
+ DEFINE(HOST_EDI, EDI);
+ DEFINE(HOST_EBP, EBP);
+ DEFINE(HOST_CS, CS);
+ DEFINE(HOST_SS, SS);
+ DEFINE(HOST_DS, DS);
+ DEFINE(HOST_FS, FS);
+ DEFINE(HOST_ES, ES);
+ DEFINE(HOST_GS, GS);
+ DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct));
+}
diff --git a/arch/um/sys-i386/util/Makefile b/arch/um/sys-i386/util/Makefile
index 34860f9..bf61afd 100644
--- a/arch/um/sys-i386/util/Makefile
+++ b/arch/um/sys-i386/util/Makefile
@@ -1,8 +1,5 @@
-
hostprogs-y := mk_sc mk_thread
always := $(hostprogs-y)
-mk_thread-objs := mk_thread_kern.o mk_thread_user.o
-
-HOSTCFLAGS_mk_thread_kern.o := $(CFLAGS) $(CPPFLAGS)
-HOSTCFLAGS_mk_thread_user.o := $(USER_CFLAGS)
+HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um
+HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um
diff --git a/arch/um/sys-i386/util/mk_sc.c b/arch/um/sys-i386/util/mk_sc.c
index 85cbd30..04c0d73 100644
--- a/arch/um/sys-i386/util/mk_sc.c
+++ b/arch/um/sys-i386/util/mk_sc.c
@@ -1,52 +1,51 @@
#include <stdio.h>
-#include <signal.h>
-#include <linux/stddef.h>
+#include <user-offsets.h>
#define SC_OFFSET(name, field) \
- printf("#define " name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
- offsetof(struct sigcontext, field))
+ printf("#define " #name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
+ name)
#define SC_FP_OFFSET(name, field) \
- printf("#define " name \
+ printf("#define " #name \
"(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
- offsetof(struct _fpstate, field))
+ name)
#define SC_FP_OFFSET_PTR(name, field, type) \
- printf("#define " name \
+ printf("#define " #name \
"(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
- offsetof(struct _fpstate, field))
+ name)
int main(int argc, char **argv)
{
- SC_OFFSET("SC_IP", eip);
- SC_OFFSET("SC_SP", esp);
- SC_OFFSET("SC_FS", fs);
- SC_OFFSET("SC_GS", gs);
- SC_OFFSET("SC_DS", ds);
- SC_OFFSET("SC_ES", es);
- SC_OFFSET("SC_SS", ss);
- SC_OFFSET("SC_CS", cs);
- SC_OFFSET("SC_EFLAGS", eflags);
- SC_OFFSET("SC_EAX", eax);
- SC_OFFSET("SC_EBX", ebx);
- SC_OFFSET("SC_ECX", ecx);
- SC_OFFSET("SC_EDX", edx);
- SC_OFFSET("SC_EDI", edi);
- SC_OFFSET("SC_ESI", esi);
- SC_OFFSET("SC_EBP", ebp);
- SC_OFFSET("SC_TRAPNO", trapno);
- SC_OFFSET("SC_ERR", err);
- SC_OFFSET("SC_CR2", cr2);
- SC_OFFSET("SC_FPSTATE", fpstate);
- SC_OFFSET("SC_SIGMASK", oldmask);
- SC_FP_OFFSET("SC_FP_CW", cw);
- SC_FP_OFFSET("SC_FP_SW", sw);
- SC_FP_OFFSET("SC_FP_TAG", tag);
- SC_FP_OFFSET("SC_FP_IPOFF", ipoff);
- SC_FP_OFFSET("SC_FP_CSSEL", cssel);
- SC_FP_OFFSET("SC_FP_DATAOFF", dataoff);
- SC_FP_OFFSET("SC_FP_DATASEL", datasel);
- SC_FP_OFFSET_PTR("SC_FP_ST", _st, "struct _fpstate");
- SC_FP_OFFSET_PTR("SC_FXSR_ENV", _fxsr_env, "void");
+ SC_OFFSET(SC_IP, eip);
+ SC_OFFSET(SC_SP, esp);
+ SC_OFFSET(SC_FS, fs);
+ SC_OFFSET(SC_GS, gs);
+ SC_OFFSET(SC_DS, ds);
+ SC_OFFSET(SC_ES, es);
+ SC_OFFSET(SC_SS, ss);
+ SC_OFFSET(SC_CS, cs);
+ SC_OFFSET(SC_EFLAGS, eflags);
+ SC_OFFSET(SC_EAX, eax);
+ SC_OFFSET(SC_EBX, ebx);
+ SC_OFFSET(SC_ECX, ecx);
+ SC_OFFSET(SC_EDX, edx);
+ SC_OFFSET(SC_EDI, edi);
+ SC_OFFSET(SC_ESI, esi);
+ SC_OFFSET(SC_EBP, ebp);
+ SC_OFFSET(SC_TRAPNO, trapno);
+ SC_OFFSET(SC_ERR, err);
+ SC_OFFSET(SC_CR2, cr2);
+ SC_OFFSET(SC_FPSTATE, fpstate);
+ SC_OFFSET(SC_SIGMASK, oldmask);
+ SC_FP_OFFSET(SC_FP_CW, cw);
+ SC_FP_OFFSET(SC_FP_SW, sw);
+ SC_FP_OFFSET(SC_FP_TAG, tag);
+ SC_FP_OFFSET(SC_FP_IPOFF, ipoff);
+ SC_FP_OFFSET(SC_FP_CSSEL, cssel);
+ SC_FP_OFFSET(SC_FP_DATAOFF, dataoff);
+ SC_FP_OFFSET(SC_FP_DATASEL, datasel);
+ SC_FP_OFFSET_PTR(SC_FP_ST, _st, "struct _fpstate");
+ SC_FP_OFFSET_PTR(SC_FXSR_ENV, _fxsr_env, "void");
return(0);
}
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 0000000..7470d0d
--- /dev/null
+++ b/arch/um/sys-i386/util/mk_thread.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <kernel-offsets.h>
+
+int main(int argc, char **argv)
+{
+ printf("/*\n");
+ printf(" * Generated by mk_thread\n");
+ printf(" */\n");
+ printf("\n");
+ printf("#ifndef __UM_THREAD_H\n");
+ printf("#define __UM_THREAD_H\n");
+ printf("\n");
+ printf("#define TASK_DEBUGREGS(task) ((unsigned long *) "
+ "&(((char *) (task))[%d]))\n", TASK_DEBUGREGS);
+#ifdef TASK_EXTERN_PID
+ printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n",
+ TASK_EXTERN_PID);
+#endif
+ printf("\n");
+ printf("#endif\n");
+ return(0);
+}
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 948b1ce..0000000
--- a/arch/um/sys-i386/util/mk_thread_kern.c
+++ /dev/null
@@ -1,22 +0,0 @@
-#include "linux/config.h"
-#include "linux/stddef.h"
-#include "linux/sched.h"
-
-extern void print_head(void);
-extern void print_constant_ptr(char *name, int value);
-extern void print_constant(char *name, char *type, int value);
-extern void print_tail(void);
-
-#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field)
-
-int main(int argc, char **argv)
-{
- print_head();
- print_constant_ptr("TASK_DEBUGREGS", THREAD_OFFSET(arch.debugregs));
-#ifdef CONFIG_MODE_TT
- print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid));
-#endif
- print_tail();
- return(0);
-}
-
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 2620cd6..0000000
--- a/arch/um/sys-i386/util/mk_thread_user.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <stdio.h>
-
-void print_head(void)
-{
- printf("/*\n");
- printf(" * Generated by mk_thread\n");
- printf(" */\n");
- printf("\n");
- printf("#ifndef __UM_THREAD_H\n");
- printf("#define __UM_THREAD_H\n");
- printf("\n");
-}
-
-void print_constant_ptr(char *name, int value)
-{
- printf("#define %s(task) ((unsigned long *) "
- "&(((char *) (task))[%d]))\n", name, value);
-}
-
-void print_constant(char *name, char *type, int value)
-{
- printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
- value);
-}
-
-void print_tail(void)
-{
- printf("\n");
- printf("#endif\n");
-}
diff --git a/arch/um/sys-ppc/ptrace.c b/arch/um/sys-ppc/ptrace.c
index a971366d..8e71b47 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,
return 0;
}
+int poke_user(struct task_struct *child, long addr, long data)
+{
+ if ((addr & 3) || addr < 0)
+ return -EIO;
+
+ if (addr < MAX_REG_OFFSET)
+ return putreg(child, addr, data);
+
+ else if((addr >= offsetof(struct user, u_debugreg[0])) &&
+ (addr <= offsetof(struct user, u_debugreg[7]))){
+ addr -= offsetof(struct user, u_debugreg[0]);
+ addr = addr >> 2;
+ if((addr == 4) || (addr == 5)) return -EIO;
+ child->thread.arch.debugregs[addr] = data;
+ return 0;
+ }
+ return -EIO;
+}
+
unsigned long getreg(struct task_struct *child, unsigned long regno)
{
unsigned long retval = ~0UL;
@@ -16,6 +35,27 @@ unsigned long getreg(struct task_struct *child, unsigned long regno)
return retval;
}
+int peek_user(struct task_struct *child, long addr, long data)
+{
+ /* read the word at location addr in the USER area. */
+ unsigned long tmp;
+
+ if ((addr & 3) || addr < 0)
+ return -EIO;
+
+ tmp = 0; /* Default return condition */
+ if(addr < MAX_REG_OFFSET){
+ tmp = getreg(child, addr);
+ }
+ else if((addr >= offsetof(struct user, u_debugreg[0])) &&
+ (addr <= offsetof(struct user, u_debugreg[7]))){
+ addr -= offsetof(struct user, u_debugreg[0]);
+ addr = addr >> 2;
+ tmp = child->thread.arch.debugregs[addr];
+ }
+ return put_user(tmp, (unsigned long *) data);
+}
+
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* 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 2129e31..3d7da911 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -4,24 +4,20 @@
# Licensed under the GPL
#
+#XXX: why into lib-y?
lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \
ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \
- syscalls.o sysrq.o thunk.o
+ syscalls.o sysrq.o thunk.o syscall_table.o
+
+obj-y := ksyms.o
+obj-$(CONFIG_MODULES) += module.o um_module.o
USER_OBJS := ptrace_user.o sigcontext.o
include arch/um/scripts/Makefile.rules
SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \
- semaphore.c thunk.S
-
-# this needs to be before the foreach, because clean-files does not accept
-# complete paths like $(src)/$f.
-clean-files := $(SYMLINKS)
-
-targets += $(SYMLINKS)
-
-SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$f)
+ semaphore.c thunk.S module.c
bitops.c-dir = lib
csum-copy.S-dir = lib
@@ -30,8 +26,8 @@ csum-wrappers.c-dir = lib
memcpy.S-dir = lib
semaphore.c-dir = kernel
thunk.S-dir = lib
-
-$(SYMLINKS): FORCE
- $(call if_changed,make_link)
+module.c-dir = kernel
CFLAGS_csum-partial.o := -Dcsum_partial=arch_csum_partial
+
+subdir- := util
diff --git a/arch/um/sys-x86_64/delay.c b/arch/um/sys-x86_64/delay.c
index f3b5187..651332a 100644
--- a/arch/um/sys-x86_64/delay.c
+++ b/arch/um/sys-x86_64/delay.c
@@ -5,7 +5,9 @@
* Licensed under the GPL
*/
+#include "linux/delay.h"
#include "asm/processor.h"
+#include "asm/param.h"
void __delay(unsigned long loops)
{
@@ -14,6 +16,22 @@ void __delay(unsigned long loops)
for(i = 0; i < loops; i++) ;
}
+void __udelay(unsigned long usecs)
+{
+ int i, n;
+
+ n = (loops_per_jiffy * HZ * usecs) / MILLION;
+ for(i=0;i<n;i++) ;
+}
+
+void __const_udelay(unsigned long usecs)
+{
+ int i, n;
+
+ n = (loops_per_jiffy * HZ * usecs) / MILLION;
+ for(i=0;i<n;i++) ;
+}
+
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* 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 0000000..220e875
--- /dev/null
+++ b/arch/um/sys-x86_64/kernel-offsets.c
@@ -0,0 +1,24 @@
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <asm/page.h>
+
+#define DEFINE(sym, val) \
+ asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define DEFINE_STR1(x) #x
+#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " DEFINE_STR1(val) " " #val: : )
+
+#define BLANK() asm volatile("\n->" : : )
+
+#define OFFSET(sym, str, mem) \
+ DEFINE(sym, offsetof(struct str, mem));
+
+void foo(void)
+{
+#ifdef CONFIG_MODE_TT
+ OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
+#endif
+#include <common-offsets.h>
+}
diff --git a/arch/um/sys-x86_64/ksyms.c b/arch/um/sys-x86_64/ksyms.c
new file mode 100644
index 0000000..a27f0ee
--- /dev/null
+++ b/arch/um/sys-x86_64/ksyms.c
@@ -0,0 +1,20 @@
+#include "linux/module.h"
+#include "linux/in6.h"
+#include "linux/rwsem.h"
+#include "asm/byteorder.h"
+#include "asm/semaphore.h"
+#include "asm/uaccess.h"
+#include "asm/checksum.h"
+#include "asm/errno.h"
+
+EXPORT_SYMBOL(__down_failed);
+EXPORT_SYMBOL(__down_failed_interruptible);
+EXPORT_SYMBOL(__down_failed_trylock);
+EXPORT_SYMBOL(__up_wakeup);
+
+/*XXX: we need them because they would be exported by x86_64 */
+EXPORT_SYMBOL(__memcpy);
+
+/* Networking helper routines. */
+/*EXPORT_SYMBOL(csum_partial_copy_from);
+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 8c146b2..b593bb2 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)
return 0;
}
+int poke_user(struct task_struct *child, long addr, long data)
+{
+ if ((addr & 3) || addr < 0)
+ return -EIO;
+
+ if (addr < MAX_REG_OFFSET)
+ return putreg(child, addr, data);
+
+#if 0 /* Need x86_64 debugregs handling */
+ else if((addr >= offsetof(struct user, u_debugreg[0])) &&
+ (addr <= offsetof(struct user, u_debugreg[7]))){
+ addr -= offsetof(struct user, u_debugreg[0]);
+ addr = addr >> 2;
+ if((addr == 4) || (addr == 5)) return -EIO;
+ child->thread.arch.debugregs[addr] = data;
+ return 0;
+ }
+#endif
+ return -EIO;
+}
+
unsigned long getreg(struct task_struct *child, int regno)
{
unsigned long retval = ~0UL;
@@ -84,6 +105,29 @@ unsigned long getreg(struct task_struct *child, int regno)
return retval;
}
+int peek_user(struct task_struct *child, long addr, long data)
+{
+ /* read the word at location addr in the USER area. */
+ unsigned long tmp;
+
+ if ((addr & 3) || addr < 0)
+ return -EIO;
+
+ tmp = 0; /* Default return condition */
+ if(addr < MAX_REG_OFFSET){
+ tmp = getreg(child, addr);
+ }
+#if 0 /* Need x86_64 debugregs handling */
+ else if((addr >= offsetof(struct user, u_debugreg[0])) &&
+ (addr <= offsetof(struct user, u_debugreg[7]))){
+ addr -= offsetof(struct user, u_debugreg[0]);
+ addr = addr >> 2;
+ tmp = child->thread.arch.debugregs[addr];
+ }
+#endif
+ return put_user(tmp, (unsigned long *) data);
+}
+
void arch_switch(void)
{
/* XXX
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
index 5bc5a0d..73a7926 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,
int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
struct pt_regs *regs, unsigned long mask)
{
- unsigned long eflags;
+ struct faultinfo * fi = &current->thread.arch.faultinfo;
int err = 0;
err |= __put_user(0, &to->gs);
@@ -84,14 +84,16 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
err |= PUTREG(regs, R14, to, r14);
err |= PUTREG(regs, R15, to, r15);
err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */
- err |= __put_user(current->thread.err, &to->err);
- err |= __put_user(current->thread.trap_no, &to->trapno);
+
+ err |= __put_user(fi->cr2, &to->cr2);
+ err |= __put_user(fi->error_code, &to->err);
+ err |= __put_user(fi->trap_no, &to->trapno);
+
err |= PUTREG(regs, RIP, to, rip);
err |= PUTREG(regs, EFLAGS, to, eflags);
#undef PUTREG
err |= __put_user(mask, &to->oldmask);
- err |= __put_user(current->thread.cr2, &to->cr2);
return(err);
}
@@ -166,7 +168,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
frame = (struct rt_sigframe __user *)
round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8;
- frame -= 128;
+ ((unsigned char *) frame) -= 128;
if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
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 0000000..34b2e84
--- /dev/null
+++ b/arch/um/sys-x86_64/syscall_table.c
@@ -0,0 +1,59 @@
+/* System call table for UML/x86-64, copied from arch/x86_64/kernel/syscall.c
+ * with some changes for UML. */
+
+#include <linux/linkage.h>
+#include <linux/sys.h>
+#include <linux/cache.h>
+#include <linux/config.h>
+
+#define __NO_STUBS
+
+/* Below you can see, in terms of #define's, the differences between the x86-64
+ * and the UML syscall table. */
+
+/* Not going to be implemented by UML, since we have no hardware. */
+#define stub_iopl sys_ni_syscall
+#define sys_ioperm sys_ni_syscall
+
+/* The UML TLS problem. Note that x86_64 does not implement this, so the below
+ * is needed only for the ia32 compatibility. */
+/*#define sys_set_thread_area sys_ni_syscall
+#define sys_get_thread_area sys_ni_syscall*/
+
+/* For __NR_time. The x86-64 name hopefully will change from sys_time64 to
+ * sys_time (since the current situation is bogus). I've sent a patch to cleanup
+ * this. Remove below the obsoleted line. */
+#define sys_time64 um_time
+#define sys_time um_time
+
+/* On UML we call it this way ("old" means it's not mmap2) */
+#define sys_mmap old_mmap
+/* On x86-64 sys_uname is actually sys_newuname plus a compatibility trick.
+ * See arch/x86_64/kernel/sys_x86_64.c */
+#define sys_uname sys_uname64
+
+#define stub_clone sys_clone
+#define stub_fork sys_fork
+#define stub_vfork sys_vfork
+#define stub_execve sys_execve
+#define stub_rt_sigsuspend sys_rt_sigsuspend
+#define stub_sigaltstack sys_sigaltstack
+#define stub_rt_sigreturn sys_rt_sigreturn
+
+#define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ;
+#undef _ASM_X86_64_UNISTD_H_
+#include <asm-x86_64/unistd.h>
+
+#undef __SYSCALL
+#define __SYSCALL(nr, sym) [ nr ] = sym,
+#undef _ASM_X86_64_UNISTD_H_
+
+typedef void (*sys_call_ptr_t)(void);
+
+extern void sys_ni_syscall(void);
+
+sys_call_ptr_t sys_call_table[__NR_syscall_max+1] __cacheline_aligned = {
+ /* Smells like a like a compiler bug -- it doesn't work when the & below is removed. */
+ [0 ... __NR_syscall_max] = &sys_ni_syscall,
+#include <asm-x86_64/unistd.h>
+};
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index 68205a0..dd99146 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -7,6 +7,8 @@
#include "linux/linkage.h"
#include "linux/slab.h"
#include "linux/shm.h"
+#include "linux/utsname.h"
+#include "linux/personality.h"
#include "asm/uaccess.h"
#define __FRAME_OFFSETS
#include "asm/ptrace.h"
@@ -14,11 +16,15 @@
#include "asm/prctl.h" /* XXX This should get the constants from libc */
#include "choose-mode.h"
-asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg)
+asmlinkage long sys_uname64(struct new_utsname __user * name)
{
- unsigned long raddr;
-
- return do_shmat(shmid, shmaddr, shmflg, &raddr) ?: (long) raddr;
+ int err;
+ down_read(&uts_sem);
+ err = copy_to_user(name, &system_utsname, sizeof (*name));
+ up_read(&uts_sem);
+ if (personality(current->personality) == PER_LINUX32)
+ err |= copy_to_user(&name->machine, "i686", 5);
+ return err ? -EFAULT : 0;
}
#ifdef CONFIG_MODE_TT
@@ -38,6 +44,8 @@ long sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
#ifdef CONFIG_MODE_SKAS
extern int userspace_pid[];
+#include "skas_ptrace.h"
+
long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
{
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 0000000..8b8eff1
--- /dev/null
+++ b/arch/um/sys-x86_64/um_module.c
@@ -0,0 +1,19 @@
+#include <linux/vmalloc.h>
+#include <linux/moduleloader.h>
+
+/*Copied from i386 arch/i386/kernel/module.c */
+void *module_alloc(unsigned long size)
+{
+ if (size == 0)
+ return NULL;
+ return vmalloc_exec(size);
+}
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+ vfree(module_region);
+ /* FIXME: If module_region == mod->init_region, trim exception
+ table entries. */
+}
+
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 0000000..5e14792
--- /dev/null
+++ b/arch/um/sys-x86_64/user-offsets.c
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <stddef.h>
+#include <signal.h>
+#define __FRAME_OFFSETS
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+#define DEFINE(sym, val) \
+ asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define OFFSET(sym, str, mem) \
+ DEFINE(sym, offsetof(struct str, mem));
+
+void foo(void)
+{
+ OFFSET(SC_RBX, sigcontext, rbx);
+ OFFSET(SC_RCX, sigcontext, rcx);
+ OFFSET(SC_RDX, sigcontext, rdx);
+ OFFSET(SC_RSI, sigcontext, rsi);
+ OFFSET(SC_RDI, sigcontext, rdi);
+ OFFSET(SC_RBP, sigcontext, rbp);
+ OFFSET(SC_RAX, sigcontext, rax);
+ OFFSET(SC_R8, sigcontext, r8);
+ OFFSET(SC_R9, sigcontext, r9);
+ OFFSET(SC_R10, sigcontext, r10);
+ OFFSET(SC_R11, sigcontext, r11);
+ OFFSET(SC_R12, sigcontext, r12);
+ OFFSET(SC_R13, sigcontext, r13);
+ OFFSET(SC_R14, sigcontext, r14);
+ OFFSET(SC_R15, sigcontext, r15);
+ OFFSET(SC_IP, sigcontext, rip);
+ OFFSET(SC_SP, sigcontext, rsp);
+ OFFSET(SC_CR2, sigcontext, cr2);
+ OFFSET(SC_ERR, sigcontext, err);
+ OFFSET(SC_TRAPNO, sigcontext, trapno);
+ OFFSET(SC_CS, sigcontext, cs);
+ OFFSET(SC_FS, sigcontext, fs);
+ OFFSET(SC_GS, sigcontext, gs);
+ OFFSET(SC_EFLAGS, sigcontext, eflags);
+ OFFSET(SC_SIGMASK, sigcontext, oldmask);
+#if 0
+ OFFSET(SC_ORIG_RAX, sigcontext, orig_rax);
+ OFFSET(SC_DS, sigcontext, ds);
+ OFFSET(SC_ES, sigcontext, es);
+ OFFSET(SC_SS, sigcontext, ss);
+#endif
+
+ DEFINE(HOST_FRAME_SIZE, FRAME_SIZE);
+ DEFINE(HOST_RBX, RBX);
+ DEFINE(HOST_RCX, RCX);
+ DEFINE(HOST_RDI, RDI);
+ DEFINE(HOST_RSI, RSI);
+ DEFINE(HOST_RDX, RDX);
+ DEFINE(HOST_RBP, RBP);
+ DEFINE(HOST_RAX, RAX);
+ DEFINE(HOST_R8, R8);
+ DEFINE(HOST_R9, R9);
+ DEFINE(HOST_R10, R10);
+ DEFINE(HOST_R11, R11);
+ DEFINE(HOST_R12, R12);
+ DEFINE(HOST_R13, R13);
+ DEFINE(HOST_R14, R14);
+ DEFINE(HOST_R15, R15);
+ DEFINE(HOST_ORIG_RAX, ORIG_RAX);
+ DEFINE(HOST_CS, CS);
+ DEFINE(HOST_SS, SS);
+ DEFINE(HOST_EFLAGS, EFLAGS);
+#if 0
+ DEFINE(HOST_FS, FS);
+ DEFINE(HOST_GS, GS);
+ DEFINE(HOST_DS, DS);
+ DEFINE(HOST_ES, ES);
+#endif
+
+ DEFINE(HOST_IP, RIP);
+ DEFINE(HOST_SP, RSP);
+ DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct));
+}
diff --git a/arch/um/sys-x86_64/util/Makefile b/arch/um/sys-x86_64/util/Makefile
index 0026079..75b052c 100644
--- a/arch/um/sys-x86_64/util/Makefile
+++ b/arch/um/sys-x86_64/util/Makefile
@@ -4,7 +4,5 @@
hostprogs-y := mk_sc mk_thread
always := $(hostprogs-y)
-mk_thread-objs := mk_thread_kern.o mk_thread_user.o
-
-HOSTCFLAGS_mk_thread_kern.o := $(CFLAGS) $(CPPFLAGS)
-HOSTCFLAGS_mk_thread_user.o := $(USER_CFLAGS)
+HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um
+HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um
diff --git a/arch/um/sys-x86_64/util/mk_sc.c b/arch/um/sys-x86_64/util/mk_sc.c
index c236e21..7619bc3 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 @@
*/
#include <stdio.h>
-#include <signal.h>
-#include <linux/stddef.h>
+#include <user-offsets.h>
-#define SC_OFFSET(name, field) \
- printf("#define " name \
- "(sc) *((unsigned long *) &(((char *) (sc))[%ld]))\n",\
- offsetof(struct sigcontext, field))
-
-#define SC_FP_OFFSET(name, field) \
- printf("#define " name \
- "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%ld]))\n",\
- offsetof(struct _fpstate, field))
-
-#define SC_FP_OFFSET_PTR(name, field, type) \
- printf("#define " name \
- "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
- offsetof(struct _fpstate, field))
+#define SC_OFFSET(name) \
+ printf("#define " #name \
+ "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
+ name)
int main(int argc, char **argv)
{
- SC_OFFSET("SC_RBX", rbx);
- SC_OFFSET("SC_RCX", rcx);
- SC_OFFSET("SC_RDX", rdx);
- SC_OFFSET("SC_RSI", rsi);
- SC_OFFSET("SC_RDI", rdi);
- SC_OFFSET("SC_RBP", rbp);
- SC_OFFSET("SC_RAX", rax);
- SC_OFFSET("SC_R8", r8);
- SC_OFFSET("SC_R9", r9);
- SC_OFFSET("SC_R10", r10);
- SC_OFFSET("SC_R11", r11);
- SC_OFFSET("SC_R12", r12);
- SC_OFFSET("SC_R13", r13);
- SC_OFFSET("SC_R14", r14);
- SC_OFFSET("SC_R15", r15);
- SC_OFFSET("SC_IP", rip);
- SC_OFFSET("SC_SP", rsp);
- SC_OFFSET("SC_CR2", cr2);
- SC_OFFSET("SC_ERR", err);
- SC_OFFSET("SC_TRAPNO", trapno);
- SC_OFFSET("SC_CS", cs);
- SC_OFFSET("SC_FS", fs);
- SC_OFFSET("SC_GS", gs);
- SC_OFFSET("SC_EFLAGS", eflags);
- SC_OFFSET("SC_SIGMASK", oldmask);
+ SC_OFFSET(SC_RBX);
+ SC_OFFSET(SC_RCX);
+ SC_OFFSET(SC_RDX);
+ SC_OFFSET(SC_RSI);
+ SC_OFFSET(SC_RDI);
+ SC_OFFSET(SC_RBP);
+ SC_OFFSET(SC_RAX);
+ SC_OFFSET(SC_R8);
+ SC_OFFSET(SC_R9);
+ SC_OFFSET(SC_R10);
+ SC_OFFSET(SC_R11);
+ SC_OFFSET(SC_R12);
+ SC_OFFSET(SC_R13);
+ SC_OFFSET(SC_R14);
+ SC_OFFSET(SC_R15);
+ SC_OFFSET(SC_IP);
+ SC_OFFSET(SC_SP);
+ SC_OFFSET(SC_CR2);
+ SC_OFFSET(SC_ERR);
+ SC_OFFSET(SC_TRAPNO);
+ SC_OFFSET(SC_CS);
+ SC_OFFSET(SC_FS);
+ SC_OFFSET(SC_GS);
+ SC_OFFSET(SC_EFLAGS);
+ SC_OFFSET(SC_SIGMASK);
#if 0
- SC_OFFSET("SC_ORIG_RAX", orig_rax);
- SC_OFFSET("SC_DS", ds);
- SC_OFFSET("SC_ES", es);
- SC_OFFSET("SC_SS", ss);
+ SC_OFFSET(SC_ORIG_RAX);
+ SC_OFFSET(SC_DS);
+ SC_OFFSET(SC_ES);
+ SC_OFFSET(SC_SS);
#endif
return(0);
}
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 0000000..1551739
--- /dev/null
+++ b/arch/um/sys-x86_64/util/mk_thread.c
@@ -0,0 +1,20 @@
+#include <stdio.h>
+#include <kernel-offsets.h>
+
+int main(int argc, char **argv)
+{
+ printf("/*\n");
+ printf(" * Generated by mk_thread\n");
+ printf(" */\n");
+ printf("\n");
+ printf("#ifndef __UM_THREAD_H\n");
+ printf("#define __UM_THREAD_H\n");
+ printf("\n");
+#ifdef TASK_EXTERN_PID
+ printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n",
+ TASK_EXTERN_PID);
+#endif
+ printf("\n");
+ printf("#endif\n");
+ return(0);
+}
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 a281673..0000000
--- a/arch/um/sys-x86_64/util/mk_thread_kern.c
+++ /dev/null
@@ -1,21 +0,0 @@
-#include "linux/config.h"
-#include "linux/stddef.h"
-#include "linux/sched.h"
-
-extern void print_head(void);
-extern void print_constant_ptr(char *name, int value);
-extern void print_constant(char *name, char *type, int value);
-extern void print_tail(void);
-
-#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field)
-
-int main(int argc, char **argv)
-{
- print_head();
-#ifdef CONFIG_MODE_TT
- print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid));
-#endif
- print_tail();
- return(0);
-}
-
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 7989725..0000000
--- a/arch/um/sys-x86_64/util/mk_thread_user.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <stdio.h>
-
-void print_head(void)
-{
- printf("/*\n");
- printf(" * Generated by mk_thread\n");
- printf(" */\n");
- printf("\n");
- printf("#ifndef __UM_THREAD_H\n");
- printf("#define __UM_THREAD_H\n");
- printf("\n");
-}
-
-void print_constant_ptr(char *name, int value)
-{
- printf("#define %s(task) ((unsigned long *) "
- "&(((char *) (task))[%d]))\n", name, value);
-}
-
-void print_constant(char *name, char *type, int value)
-{
- printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
- value);
-}
-
-void print_tail(void)
-{
- printf("\n");
- printf("#endif\n");
-}
diff --git a/arch/um/util/Makefile b/arch/um/util/Makefile
index e2ab712..4c7551c 100644
--- a/arch/um/util/Makefile
+++ b/arch/um/util/Makefile
@@ -1,8 +1,5 @@
hostprogs-y := mk_task mk_constants
always := $(hostprogs-y)
-mk_task-objs := mk_task_user.o mk_task_kern.o
-mk_constants-objs := mk_constants_user.o mk_constants_kern.o
-
-HOSTCFLAGS_mk_task_kern.o := $(CFLAGS) $(CPPFLAGS)
-HOSTCFLAGS_mk_constants_kern.o := $(CFLAGS) $(CPPFLAGS)
+HOSTCFLAGS_mk_task.o := -I$(objtree)/arch/um
+HOSTCFLAGS_mk_constants.o := -I$(objtree)/arch/um
diff --git a/arch/um/util/mk_constants.c b/arch/um/util/mk_constants.c
new file mode 100644
index 0000000..ab217be
--- /dev/null
+++ b/arch/um/util/mk_constants.c
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include <kernel-offsets.h>
+
+#define SHOW_INT(sym) printf("#define %s %d\n", #sym, sym)
+#define SHOW_STR(sym) printf("#define %s %s\n", #sym, sym)
+
+int main(int argc, char **argv)
+{
+ printf("/*\n");
+ printf(" * Generated by mk_constants\n");
+ printf(" */\n");
+ printf("\n");
+ printf("#ifndef __UM_CONSTANTS_H\n");
+ printf("#define __UM_CONSTANTS_H\n");
+ printf("\n");
+
+ SHOW_INT(UM_KERN_PAGE_SIZE);
+
+ SHOW_STR(UM_KERN_EMERG);
+ SHOW_STR(UM_KERN_ALERT);
+ SHOW_STR(UM_KERN_CRIT);
+ SHOW_STR(UM_KERN_ERR);
+ SHOW_STR(UM_KERN_WARNING);
+ SHOW_STR(UM_KERN_NOTICE);
+ SHOW_STR(UM_KERN_INFO);
+ SHOW_STR(UM_KERN_DEBUG);
+
+ SHOW_INT(UM_NSEC_PER_SEC);
+ printf("\n");
+ printf("#endif\n");
+ return(0);
+}
diff --git a/arch/um/util/mk_constants_kern.c b/arch/um/util/mk_constants_kern.c
deleted file mode 100644
index cdcb123..0000000
--- a/arch/um/util/mk_constants_kern.c
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "linux/kernel.h"
-#include "linux/stringify.h"
-#include "linux/time.h"
-#include "asm/page.h"
-
-extern void print_head(void);
-extern void print_constant_str(char *name, char *value);
-extern void print_constant_int(char *name, int value);
-extern void print_tail(void);
-
-int main(int argc, char **argv)
-{
- print_head();
- print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
-
- print_constant_str("UM_KERN_EMERG", KERN_EMERG);
- print_constant_str("UM_KERN_ALERT", KERN_ALERT);
- print_constant_str("UM_KERN_CRIT", KERN_CRIT);
- print_constant_str("UM_KERN_ERR", KERN_ERR);
- print_constant_str("UM_KERN_WARNING", KERN_WARNING);
- print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
- print_constant_str("UM_KERN_INFO", KERN_INFO);
- print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
-
- print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC);
- print_tail();
- return(0);
-}
diff --git a/arch/um/util/mk_constants_user.c b/arch/um/util/mk_constants_user.c
deleted file mode 100644
index 8f4d7e5..0000000
--- a/arch/um/util/mk_constants_user.c
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <stdio.h>
-
-void print_head(void)
-{
- printf("/*\n");
- printf(" * Generated by mk_constants\n");
- printf(" */\n");
- printf("\n");
- printf("#ifndef __UM_CONSTANTS_H\n");
- printf("#define __UM_CONSTANTS_H\n");
- printf("\n");
-}
-
-void print_constant_str(char *name, char *value)
-{
- printf("#define %s \"%s\"\n", name, value);
-}
-
-void print_constant_int(char *name, int value)
-{
- printf("#define %s %d\n", name, value);
-}
-
-void print_tail(void)
-{
- printf("\n");
- printf("#endif\n");
-}
diff --git a/arch/um/util/mk_task_user.c b/arch/um/util/mk_task.c
index 9db849f..36c9606 100644
--- a/arch/um/util/mk_task_user.c
+++ b/arch/um/util/mk_task.c
@@ -1,18 +1,19 @@
#include <stdio.h>
+#include <kernel-offsets.h>
-void print(char *name, char *type, int offset)
+void print_ptr(char *name, char *type, int offset)
{
- printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
+ printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
offset);
}
-void print_ptr(char *name, char *type, int offset)
+void print(char *name, char *type, int offset)
{
- printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
+ printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
offset);
}
-void print_head(void)
+int main(int argc, char **argv)
{
printf("/*\n");
printf(" * Generated by mk_task\n");
@@ -21,10 +22,9 @@ void print_head(void)
printf("#ifndef __TASK_H\n");
printf("#define __TASK_H\n");
printf("\n");
-}
-
-void print_tail(void)
-{
+ print_ptr("TASK_REGS", "union uml_pt_regs", TASK_REGS);
+ print("TASK_PID", "int", TASK_PID);
printf("\n");
printf("#endif\n");
+ return(0);
}
diff --git a/arch/um/util/mk_task_kern.c b/arch/um/util/mk_task_kern.c
deleted file mode 100644
index c218103..0000000
--- a/arch/um/util/mk_task_kern.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "linux/sched.h"
-#include "linux/stddef.h"
-
-extern void print(char *name, char *type, int offset);
-extern void print_ptr(char *name, char *type, int offset);
-extern void print_head(void);
-extern void print_tail(void);
-
-int main(int argc, char **argv)
-{
- print_head();
- print_ptr("TASK_REGS", "union uml_pt_regs",
- offsetof(struct task_struct, thread.regs));
- print("TASK_PID", "int", offsetof(struct task_struct, pid));
- print_tail();
- return(0);
-}
OpenPOWER on IntegriCloud