diff options
Diffstat (limited to 'arch/um')
224 files changed, 458 insertions, 8168 deletions
diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char index 70dabd1e065..b9d7c427668 100644 --- a/arch/um/Kconfig.char +++ b/arch/um/Kconfig.char @@ -1,5 +1,4 @@ - -menu "Character Devices" +menu "UML Character Devices" config STDERR_CONSOLE bool "stderr console" @@ -105,92 +104,6 @@ config SSL_CHAN this if you expect the UML that you build to be run in environments which don't have a set of /dev/pty* devices. -config UNIX98_PTYS - bool "Unix98 PTY support" - help - A pseudo terminal (PTY) is a software device consisting of two - halves: a master and a slave. The slave device behaves identical to - a physical terminal; the master device is used by a process to - read data from and write data to the slave, thereby emulating a - terminal. Typical programs for the master side are telnet servers - and xterms. - - Linux has traditionally used the BSD-like names /dev/ptyxx for - masters and /dev/ttyxx for slaves of pseudo terminals. This scheme - has a number of problems. The GNU C library glibc 2.1 and later, - however, supports the Unix98 naming standard: in order to acquire a - pseudo terminal, a process opens /dev/ptmx; the number of the pseudo - terminal is then made available to the process and the pseudo - terminal slave can be accessed as /dev/pts/<number>. What was - traditionally /dev/ttyp2 will then be /dev/pts/2, for example. - - All modern Linux systems use the Unix98 ptys. Say Y unless - you're on an embedded system and want to conserve memory. - -config LEGACY_PTYS - bool "Legacy (BSD) PTY support" - default y - help - A pseudo terminal (PTY) is a software device consisting of two - halves: a master and a slave. The slave device behaves identical to - a physical terminal; the master device is used by a process to - read data from and write data to the slave, thereby emulating a - terminal. Typical programs for the master side are telnet servers - and xterms. - - Linux has traditionally used the BSD-like names /dev/ptyxx - for masters and /dev/ttyxx for slaves of pseudo - terminals. This scheme has a number of problems, including - security. This option enables these legacy devices; on most - systems, it is safe to say N. - -config RAW_DRIVER - tristate "RAW driver (/dev/raw/rawN)" - depends on BLOCK - help - The raw driver permits block devices to be bound to /dev/raw/rawN. - Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O. - See the raw(8) manpage for more details. - - Applications should preferably open the device (eg /dev/hda1) - with the O_DIRECT flag. - -config MAX_RAW_DEVS - int "Maximum number of RAW devices to support (1-8192)" - depends on RAW_DRIVER - default "256" - help - The maximum number of RAW devices that are supported. - Default is 256. Increase this number in case you need lots of - raw devices. - -config LEGACY_PTY_COUNT - int "Maximum number of legacy PTY in use" - depends on LEGACY_PTYS - default "256" - help - The maximum number of legacy PTYs that can be used at any one time. - The default is 256, and should be more than enough. Embedded - systems may want to reduce this to save memory. - - When not in use, each legacy PTY occupies 12 bytes on 32-bit - architectures and 24 bytes on 64-bit architectures. - -config WATCHDOG - bool "Watchdog Timer Support" - -config WATCHDOG_NOWAYOUT - bool "Disable watchdog shutdown on close" - depends on WATCHDOG - -config SOFT_WATCHDOG - tristate "Software Watchdog" - depends on WATCHDOG - -config UML_WATCHDOG - tristate "UML watchdog" - depends on WATCHDOG - config UML_SOUND tristate "Sound support" help @@ -211,29 +124,4 @@ config HOSTAUDIO tristate default UML_SOUND -#It is selected elsewhere, so kconfig would warn without this. -config HW_RANDOM - tristate - default n - -config UML_RANDOM - tristate "Hardware random number generator" - help - This option enables UML's "hardware" random number generator. It - attaches itself to the host's /dev/random, supplying as much entropy - as the host has, rather than the small amount the UML gets from its - own drivers. It registers itself as a standard hardware random number - generator, major 10, minor 183, and the canonical device name is - /dev/hwrng. - The way to make use of this is to install the rng-tools package - (check your distro, or download from - http://sourceforge.net/projects/gkernel/). rngd periodically reads - /dev/hwrng and injects the entropy into /dev/random. - -config MMAPPER - tristate "iomem emulation driver" - help - This driver allows a host file to be used as emulated IO memory inside - UML. - endmenu diff --git a/arch/um/Kconfig.rest b/arch/um/Kconfig.rest index 0ccad0ff6d6..567eb5fc21d 100644 --- a/arch/um/Kconfig.rest +++ b/arch/um/Kconfig.rest @@ -2,20 +2,14 @@ source "init/Kconfig" source "kernel/Kconfig.freezer" -source "drivers/block/Kconfig" - source "arch/um/Kconfig.char" -source "drivers/base/Kconfig" +source "drivers/Kconfig" source "net/Kconfig" source "arch/um/Kconfig.net" -source "drivers/net/Kconfig" - -source "drivers/connector/Kconfig" - source "fs/Kconfig" source "security/Kconfig" @@ -24,19 +18,4 @@ source "crypto/Kconfig" source "lib/Kconfig" -source "drivers/scsi/Kconfig" - -source "drivers/md/Kconfig" - -if BROKEN - source "drivers/mtd/Kconfig" -endif - -source "drivers/leds/Kconfig" - -#This is just to shut up some Kconfig warnings, so no prompt. -config INPUT - tristate - default n - source "arch/um/Kconfig.debug" diff --git a/arch/um/Kconfig.um b/arch/um/Kconfig.um index b5e675e370c..70fd690964e 100644 --- a/arch/um/Kconfig.um +++ b/arch/um/Kconfig.um @@ -148,5 +148,11 @@ config KERNEL_STACK_ORDER be 1 << order pages. The default is OK unless you're running Valgrind on UML, in which case, set this to 3. +config MMAPPER + tristate "iomem emulation driver" + help + This driver allows a host file to be used as emulated IO memory inside + UML. + config NO_DMA def_bool y diff --git a/arch/um/Kconfig.x86 b/arch/um/Kconfig.x86 deleted file mode 100644 index 8aae429a56e..00000000000 --- a/arch/um/Kconfig.x86 +++ /dev/null @@ -1,64 +0,0 @@ -source "arch/um/Kconfig.common" - -menu "UML-specific options" - -menu "Host processor type and features" - -config CMPXCHG_LOCAL - bool - default n - -source "arch/x86/Kconfig.cpu" - -endmenu - -config UML_X86 - def_bool y - select GENERIC_FIND_FIRST_BIT - -config 64BIT - bool - default SUBARCH = "x86_64" - -config X86_32 - def_bool !64BIT - select HAVE_AOUT - -config X86_64 - def_bool 64BIT - -config RWSEM_XCHGADD_ALGORITHM - def_bool X86_XADD && 64BIT - -config RWSEM_GENERIC_SPINLOCK - def_bool !RWSEM_XCHGADD_ALGORITHM - -config 3_LEVEL_PGTABLES - bool "Three-level pagetables (EXPERIMENTAL)" if !64BIT - default 64BIT - depends on EXPERIMENTAL - help - Three-level pagetables will let UML have more than 4G of physical - memory. All the memory that can't be mapped directly will be treated - as high memory. - - However, this it experimental on 32-bit architectures, so if unsure say - N (on x86-64 it's automatically enabled, instead, as it's safe there). - -config ARCH_HAS_SC_SIGNALS - def_bool !64BIT - -config ARCH_REUSE_HOST_VSYSCALL_AREA - def_bool !64BIT - -config SMP_BROKEN - def_bool 64BIT - -config GENERIC_HWEIGHT - def_bool y - -source "arch/um/Kconfig.um" - -endmenu - -source "arch/um/Kconfig.rest" diff --git a/arch/um/Makefile b/arch/um/Makefile index fab8121d2b3..7730af6ec13 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -20,15 +20,27 @@ core-y += $(ARCH_DIR)/kernel/ \ MODE_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include/shared/skas +HEADER_ARCH := $(SUBARCH) + +# Additional ARCH settings for x86 +ifeq ($(SUBARCH),i386) + HEADER_ARCH := x86 +endif +ifeq ($(SUBARCH),x86_64) + HEADER_ARCH := x86 +endif + +HOST_DIR := arch/$(HEADER_ARCH) + include $(srctree)/$(ARCH_DIR)/Makefile-skas +include $(srctree)/$(HOST_DIR)/Makefile.um + +core-y += $(HOST_DIR)/um/ SHARED_HEADERS := $(ARCH_DIR)/include/shared ARCH_INCLUDE := -I$(srctree)/$(SHARED_HEADERS) -ARCH_INCLUDE += -I$(srctree)/$(ARCH_DIR)/sys-$(SUBARCH)/shared -ifneq ($(KBUILD_SRC),) -ARCH_INCLUDE += -I$(SHARED_HEADERS) -endif -KBUILD_CPPFLAGS += -I$(srctree)/$(ARCH_DIR)/sys-$(SUBARCH) +ARCH_INCLUDE += -I$(srctree)/$(HOST_DIR)/um/shared +KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/um # -Dvmap=kernel_vmap prevents anything from referencing the libpcap.o symbol so # named - it's a common symbol in libpcap, so we get a binary which crashes. @@ -41,20 +53,18 @@ KBUILD_CPPFLAGS += -I$(srctree)/$(ARCH_DIR)/sys-$(SUBARCH) KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \ $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \ -Din6addr_loopback=kernel_in6addr_loopback \ - -Din6addr_any=kernel_in6addr_any + -Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr KBUILD_AFLAGS += $(ARCH_INCLUDE) USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -D__KERNEL__,,\ $(patsubst -I%,,$(KBUILD_CFLAGS)))) $(ARCH_INCLUDE) $(MODE_INCLUDE) \ - $(filter -I%,$(CFLAGS)) -D_FILE_OFFSET_BITS=64 - -include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) + $(filter -I%,$(CFLAGS)) -D_FILE_OFFSET_BITS=64 -idirafter include #This will adjust *FLAGS accordingly to the platform. include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS) -KBUILD_CPPFLAGS += -I$(srctree)/arch/$(HEADER_ARCH)/include +KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/include # -Derrno=kernel_errno - This turns all kernel references to errno into # kernel_errno to separate them from the libc errno. This allows -fno-common @@ -84,10 +94,9 @@ define archhelp echo ' find in the kernel root.' endef -KBUILD_KCONFIG := arch/um/Kconfig.$(HEADER_ARCH) +KBUILD_KCONFIG := $(HOST_DIR)/um/Kconfig -archprepare: $(SHARED_HEADERS)/user_constants.h -archprepare: $(SHARED_HEADERS)/kern_constants.h +archprepare: include/generated/user_constants.h LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib @@ -118,9 +127,7 @@ endef # When cleaning we don't include .config, so we don't include # TT or skas makefiles and don't clean skas_ptregs.h. -CLEAN_FILES += linux x.i gmon.out \ - $(SHARED_HEADERS)/user_constants.h \ - $(SHARED_HEADERS)/kern_constants.h +CLEAN_FILES += linux x.i gmon.out archclean: @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ @@ -128,8 +135,8 @@ archclean: # Generated files -$(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s: FORCE - $(Q)$(MAKE) $(build)=$(ARCH_DIR)/sys-$(SUBARCH) $@ +$(HOST_DIR)/um/user-offsets.s: FORCE + $(Q)$(MAKE) $(build)=$(HOST_DIR)/um $@ define filechk_gen-asm-offsets (set -e; \ @@ -144,11 +151,7 @@ define filechk_gen-asm-offsets echo ""; ) endef -$(SHARED_HEADERS)/user_constants.h: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s +include/generated/user_constants.h: $(HOST_DIR)/um/user-offsets.s $(call filechk,gen-asm-offsets) -$(SHARED_HEADERS)/kern_constants.h: - $(Q)mkdir -p $(dir $@) - $(Q)echo '#include "../../../../include/generated/asm-offsets.h"' >$@ - -export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS HEADER_ARCH DEV_NULL_PATH +export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS DEV_NULL_PATH diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386 deleted file mode 100644 index 302cbe50454..00000000000 --- a/arch/um/Makefile-i386 +++ /dev/null @@ -1,42 +0,0 @@ -core-y += arch/um/sys-i386/ arch/x86/crypto/ - -TOP_ADDR := $(CONFIG_TOP_ADDR) - -START := 0x8048000 - -LDFLAGS += -m elf_i386 -ELF_ARCH := $(SUBARCH) -ELF_FORMAT := elf32-$(SUBARCH) -OBJCOPYFLAGS := -O binary -R .note -R .comment -S -HEADER_ARCH := x86 -CHECKFLAGS += -D__i386__ - -ifeq ("$(origin SUBARCH)", "command line") -ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)") -KBUILD_CFLAGS += $(call cc-option,-m32) -KBUILD_AFLAGS += $(call cc-option,-m32) -LINK-y += $(call cc-option,-m32) -UML_OBJCOPYFLAGS += -F $(ELF_FORMAT) - -export LDFLAGS HOSTCFLAGS HOSTLDFLAGS UML_OBJCOPYFLAGS -endif -endif - -# First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y. -include $(srctree)/arch/x86/Makefile_32.cpu - -# prevent gcc from keeping the stack 16 byte aligned. Taken from i386. -cflags-y += $(call cc-option,-mpreferred-stack-boundary=2) - -# Prevent sprintf in nfsd from being converted to strcpy and resulting in -# an unresolved reference. -cflags-y += -ffreestanding - -# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use -# a lot more stack due to the lack of sharing of stacklots. Also, gcc -# 4.3.0 needs -funit-at-a-time for extern inline functions. -KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then \ - echo $(call cc-option,-fno-unit-at-a-time); \ - else echo $(call cc-option,-funit-at-a-time); fi ;) - -KBUILD_CFLAGS += $(cflags-y) diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64 deleted file mode 100644 index a9cd7e77a7a..00000000000 --- a/arch/um/Makefile-x86_64 +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2003 - 2004 Pathscale, Inc -# Released under the GPL - -core-y += arch/um/sys-x86_64/ arch/x86/crypto/ -START := 0x60000000 - -_extra_flags_ = -fno-builtin -m64 - -KBUILD_CFLAGS += $(_extra_flags_) - -CHECKFLAGS += -m64 -D__x86_64__ -KBUILD_AFLAGS += -m64 -LDFLAGS += -m elf_x86_64 -KBUILD_CPPFLAGS += -m64 - -ELF_ARCH := i386:x86-64 -ELF_FORMAT := elf64-x86-64 -HEADER_ARCH := x86 - -# Not on all 64-bit distros /lib is a symlink to /lib64. PLD is an example. - -LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib64 -LINK-y += -m64 - -# Do unit-at-a-time unconditionally on x86_64, following the host -KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time) diff --git a/arch/um/defconfig b/arch/um/defconfig index 9f7634f08cf..761f5e1a657 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig @@ -13,7 +13,6 @@ CONFIG_LOCKDEP_SUPPORT=y # CONFIG_STACKTRACE_SUPPORT is not set CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_IRQ_RELEASE_METHOD=y CONFIG_HZ=100 diff --git a/arch/um/include/shared/chan_kern.h b/arch/um/drivers/chan.h index 1e651457e04..8df0fd9024d 100644 --- a/arch/um/include/shared/chan_kern.h +++ b/arch/um/drivers/chan.h @@ -6,9 +6,9 @@ #ifndef __CHAN_KERN_H__ #define __CHAN_KERN_H__ -#include "linux/tty.h" -#include "linux/list.h" -#include "linux/console.h" +#include <linux/tty.h> +#include <linux/list.h> +#include <linux/console.h> #include "chan_user.h" #include "line.h" diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 25e1965df7c..420e2c80079 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -6,7 +6,7 @@ #include <linux/slab.h> #include <linux/tty.h> #include <linux/tty_flip.h> -#include "chan_kern.h" +#include "chan.h" #include "os.h" #ifdef CONFIG_NOCONFIG_CHAN @@ -358,11 +358,11 @@ int chan_window_size(struct list_head *chans, unsigned short *rows_out, return 0; } -static void free_one_chan(struct chan *chan, int delay_free_irq) +static void free_one_chan(struct chan *chan) { list_del(&chan->list); - close_one_chan(chan, delay_free_irq); + close_one_chan(chan, 0); if (chan->ops->free != NULL) (*chan->ops->free)(chan->data); @@ -372,14 +372,14 @@ static void free_one_chan(struct chan *chan, int delay_free_irq) kfree(chan); } -static void free_chan(struct list_head *chans, int delay_free_irq) +static void free_chan(struct list_head *chans) { struct list_head *ele, *next; struct chan *chan; list_for_each_safe(ele, next, chans) { chan = list_entry(ele, struct chan, list); - free_one_chan(chan, delay_free_irq); + free_one_chan(chan); } } @@ -543,12 +543,11 @@ int parse_chan_pair(char *str, struct line *line, int device, const struct chan_opts *opts, char **error_out) { struct list_head *chans = &line->chan_list; - struct chan *new, *chan; + struct chan *new; char *in, *out; if (!list_empty(chans)) { - chan = list_entry(chans->next, struct chan, list); - free_chan(chans, 0); + free_chan(chans); INIT_LIST_HEAD(chans); } diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index cfeb3f4a44a..f180813ce2c 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -11,10 +11,8 @@ #include <termios.h> #include <sys/ioctl.h> #include "chan_user.h" -#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "user.h" void generic_close(int fd, void *unused) { @@ -283,7 +281,12 @@ void register_winch(int fd, struct tty_struct *tty) return; pid = tcgetpgrp(fd); - if (!is_skas_winch(pid, fd, tty) && (pid == -1)) { + if (is_skas_winch(pid, fd, tty)) { + register_winch_irq(-1, fd, -1, tty, 0); + return; + } + + if (pid == -1) { thread = winch_tramp(fd, tty, &thread_fd, &stack); if (thread < 0) return; diff --git a/arch/um/include/shared/chan_user.h b/arch/um/drivers/chan_user.h index 9b9ced85b70..9b9ced85b70 100644 --- a/arch/um/include/shared/chan_user.h +++ b/arch/um/drivers/chan_user.h diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h index f5701fd2ef9..7f2ed0b8824 100644 --- a/arch/um/drivers/cow_sys.h +++ b/arch/um/drivers/cow_sys.h @@ -3,7 +3,6 @@ #include "kern_util.h" #include "os.h" -#include "user.h" #include "um_malloc.h" static inline void *cow_malloc(int size) diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c index 93f227a25ba..9cbb426c0b9 100644 --- a/arch/um/drivers/cow_user.c +++ b/arch/um/drivers/cow_user.c @@ -186,7 +186,11 @@ static int absolutize(char *to, int size, char *from) strcat(to, "/"); strcat(to, from); } - chdir(save_cwd); + if (chdir(save_cwd)) { + cow_printf("absolutize : Can't cd to '%s' - " + "errno = %d\n", save_cwd, errno); + return -1; + } return 0; } diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index f8e85e0bdac..a4fd7bc14af 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -17,7 +17,6 @@ #include "net_user.h" #include "os.h" #include "um_malloc.h" -#include "user.h" enum request_type { REQ_NEW_CONTROL }; diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c index f5a981a1624..5b81d257441 100644 --- a/arch/um/drivers/fd.c +++ b/arch/um/drivers/fd.c @@ -9,10 +9,8 @@ #include <errno.h> #include <termios.h> #include "chan_user.h" -#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "user.h" struct fd_chan { int fd; diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c index b56f8e0196a..0345d6206d4 100644 --- a/arch/um/drivers/harddog_user.c +++ b/arch/um/drivers/harddog_user.c @@ -7,7 +7,6 @@ #include <unistd.h> #include <errno.h> #include "os.h" -#include "user.h" struct dog_data { int stdin; @@ -32,7 +31,7 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) { struct dog_data data; int in_fds[2], out_fds[2], pid, n, err; - char pid_buf[sizeof("nnnnn\0")], c; + char pid_buf[sizeof("nnnnnnn\0")], c; char *pid_args[] = { "/usr/bin/uml_watchdog", "-pid", pid_buf, NULL }; char *mconsole_args[] = { "/usr/bin/uml_watchdog", "-mconsole", NULL, NULL }; diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 35dd0b86401..c1cf2206b84 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -7,7 +7,7 @@ #include "linux/kd.h" #include "linux/sched.h" #include "linux/slab.h" -#include "chan_kern.h" +#include "chan.h" #include "irq_kern.h" #include "irq_user.h" #include "kern_util.h" @@ -176,10 +176,9 @@ void line_flush_buffer(struct tty_struct *tty) { struct line *line = tty->driver_data; unsigned long flags; - int err; spin_lock_irqsave(&line->lock, flags); - err = flush_buffer(line); + flush_buffer(line); spin_unlock_irqrestore(&line->lock, flags); } @@ -400,8 +399,8 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data) * is done under a spinlock. Checking whether the device is in use is * line->tty->count > 1, also under the spinlock. * - * tty->count serves to decide whether the device should be enabled or - * disabled on the host. If it's equal to 1, then we are doing the + * line->count serves to decide whether the device should be enabled or + * disabled on the host. If it's equal to 0, then we are doing the * first open or last close. Otherwise, open and close just return. */ @@ -415,16 +414,16 @@ int line_open(struct line *lines, struct tty_struct *tty) goto out_unlock; err = 0; - if (tty->count > 1) + if (line->count++) goto out_unlock; - spin_unlock(&line->count_lock); - + BUG_ON(tty->driver_data); tty->driver_data = line; line->tty = tty; + spin_unlock(&line->count_lock); err = enable_chan(line); - if (err) + if (err) /* line_close() will be called by our caller */ return err; INIT_DELAYED_WORK(&line->task, line_timer_cb); @@ -437,7 +436,7 @@ int line_open(struct line *lines, struct tty_struct *tty) chan_window_size(&line->chan_list, &tty->winsize.ws_row, &tty->winsize.ws_col); - return err; + return 0; out_unlock: spin_unlock(&line->count_lock); @@ -461,17 +460,16 @@ void line_close(struct tty_struct *tty, struct file * filp) flush_buffer(line); spin_lock(&line->count_lock); - if (!line->valid) - goto out_unlock; + BUG_ON(!line->valid); - if (tty->count > 1) + if (--line->count) goto out_unlock; - spin_unlock(&line->count_lock); - line->tty = NULL; tty->driver_data = NULL; + spin_unlock(&line->count_lock); + if (line->sigio) { unregister_winch(tty); line->sigio = 0; @@ -499,7 +497,7 @@ static int setup_one_line(struct line *lines, int n, char *init, int init_prio, spin_lock(&line->count_lock); - if (line->tty != NULL) { + if (line->count) { *error_out = "Device is already open"; goto out; } @@ -723,41 +721,53 @@ struct winch { int pid; struct tty_struct *tty; unsigned long stack; + struct work_struct work; }; -static void free_winch(struct winch *winch, int free_irq_ok) +static void __free_winch(struct work_struct *work) { - if (free_irq_ok) - free_irq(WINCH_IRQ, winch); - - list_del(&winch->list); + struct winch *winch = container_of(work, struct winch, work); + free_irq(WINCH_IRQ, winch); if (winch->pid != -1) os_kill_process(winch->pid, 1); - if (winch->fd != -1) - os_close_file(winch->fd); if (winch->stack != 0) free_stack(winch->stack, 0); kfree(winch); } +static void free_winch(struct winch *winch) +{ + int fd = winch->fd; + winch->fd = -1; + if (fd != -1) + os_close_file(fd); + list_del(&winch->list); + __free_winch(&winch->work); +} + static irqreturn_t winch_interrupt(int irq, void *data) { struct winch *winch = data; struct tty_struct *tty; struct line *line; + int fd = winch->fd; int err; char c; - if (winch->fd != -1) { - err = generic_read(winch->fd, &c, NULL); + if (fd != -1) { + err = generic_read(fd, &c, NULL); if (err < 0) { if (err != -EAGAIN) { + winch->fd = -1; + list_del(&winch->list); + os_close_file(fd); printk(KERN_ERR "winch_interrupt : " "read failed, errno = %d\n", -err); printk(KERN_ERR "fd %d is losing SIGWINCH " "support\n", winch->tty_fd); - free_winch(winch, 0); + INIT_WORK(&winch->work, __free_winch); + schedule_work(&winch->work); return IRQ_HANDLED; } goto out; @@ -829,7 +839,7 @@ static void unregister_winch(struct tty_struct *tty) list_for_each_safe(ele, next, &winch_handlers) { winch = list_entry(ele, struct winch, list); if (winch->tty == tty) { - free_winch(winch, 1); + free_winch(winch); break; } } @@ -845,7 +855,7 @@ static void winch_cleanup(void) list_for_each_safe(ele, next, &winch_handlers) { winch = list_entry(ele, struct winch, list); - free_winch(winch, 1); + free_winch(winch); } spin_unlock(&winch_handler_lock); diff --git a/arch/um/include/shared/line.h b/arch/um/drivers/line.h index 72f4f25af24..63df3ca02ac 100644 --- a/arch/um/include/shared/line.h +++ b/arch/um/drivers/line.h @@ -33,6 +33,7 @@ struct line_driver { struct line { struct tty_struct *tty; spinlock_t count_lock; + unsigned long count; int valid; char *init_str; diff --git a/arch/um/include/shared/mconsole.h b/arch/um/drivers/mconsole.h index c139ae1d682..c139ae1d682 100644 --- a/arch/um/include/shared/mconsole.h +++ b/arch/um/drivers/mconsole.h diff --git a/arch/um/include/shared/mconsole_kern.h b/arch/um/drivers/mconsole_kern.h index d2fe07e7895..d2fe07e7895 100644 --- a/arch/um/include/shared/mconsole_kern.h +++ b/arch/um/drivers/mconsole_kern.h diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c index f8cf4c8bede..99209826adb 100644 --- a/arch/um/drivers/mconsole_user.c +++ b/arch/um/drivers/mconsole_user.c @@ -10,9 +10,7 @@ #include <sys/socket.h> #include <sys/uio.h> #include <sys/un.h> -#include "kern_constants.h" #include "mconsole.h" -#include "user.h" static struct mconsole_command commands[] = { /* diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 47d0c37897d..a492e59883a 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -262,6 +262,15 @@ static int uml_net_change_mtu(struct net_device *dev, int new_mtu) return 0; } +#ifdef CONFIG_NET_POLL_CONTROLLER +static void uml_net_poll_controller(struct net_device *dev) +{ + disable_irq(dev->irq); + uml_net_interrupt(dev->irq, dev); + enable_irq(dev->irq); +} +#endif + static void uml_net_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { @@ -359,11 +368,14 @@ static const struct net_device_ops uml_netdev_ops = { .ndo_open = uml_net_open, .ndo_stop = uml_net_close, .ndo_start_xmit = uml_net_start_xmit, - .ndo_set_multicast_list = uml_net_set_multicast_list, + .ndo_set_rx_mode = uml_net_set_multicast_list, .ndo_tx_timeout = uml_net_tx_timeout, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = uml_net_change_mtu, .ndo_validate_addr = eth_validate_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = uml_net_poll_controller, +#endif }; /* diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 9415dd9e63e..05090c37fa8 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -12,10 +12,8 @@ #include <sys/socket.h> #include <sys/wait.h> #include "net_user.h" -#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "user.h" int tap_open_common(void *dev, char *gate_addr) { @@ -228,7 +226,10 @@ static void change(char *dev, char *what, unsigned char *addr, "buffer\n"); pid = change_tramp(argv, output, output_len); - if (pid < 0) return; + if (pid < 0) { + kfree(output); + return; + } if (output != NULL) { printk("%s", output); diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c index 5f903587d69..702a75b190e 100644 --- a/arch/um/drivers/pcap_user.c +++ b/arch/um/drivers/pcap_user.c @@ -9,9 +9,7 @@ #include <asm/types.h> #include "net_user.h" #include "pcap_user.h" -#include "kern_constants.h" #include "um_malloc.h" -#include "user.h" #define PCAP_FD(p) (*(int *)(p)) diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c index b49bf56a56a..7b010b76ddf 100644 --- a/arch/um/drivers/port_user.c +++ b/arch/um/drivers/port_user.c @@ -10,11 +10,9 @@ #include <unistd.h> #include <netinet/in.h> #include "chan_user.h" -#include "kern_constants.h" #include "os.h" #include "port.h" #include "um_malloc.h" -#include "user.h" struct port_chan { int raw; diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c index 1113911dcb2..cff2b75d31f 100644 --- a/arch/um/drivers/pty.c +++ b/arch/um/drivers/pty.c @@ -12,10 +12,8 @@ #include <termios.h> #include <sys/stat.h> #include "chan_user.h" -#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "user.h" struct pty_chan { void (*announce)(char *dev_name, int dev); diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index a1c2d2c98a9..932b4d69bec 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -11,12 +11,10 @@ #include <string.h> #include <sys/termios.h> #include <sys/wait.h> -#include "kern_constants.h" #include "net_user.h" #include "os.h" #include "slip.h" #include "um_malloc.h" -#include "user.h" static int slip_user_init(void *data, void *dev) { @@ -102,7 +100,7 @@ static int slip_tramp(char **argv, int fd) "buffer\n"); os_kill_process(pid, 1); err = -ENOMEM; - goto out_free; + goto out_close; } close(fds[1]); @@ -112,7 +110,6 @@ static int slip_tramp(char **argv, int fd) err = helper_wait(pid); close(fds[0]); -out_free: kfree(output); return err; diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c index a0ada8fec72..db4adb639ff 100644 --- a/arch/um/drivers/slirp_user.c +++ b/arch/um/drivers/slirp_user.c @@ -7,11 +7,9 @@ #include <errno.h> #include <string.h> #include <sys/wait.h> -#include "kern_constants.h" #include "net_user.h" #include "os.h" #include "slirp.h" -#include "user.h" static int slirp_user_init(void *data, void *dev) { diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index f1786e64607..9d8c20af6f8 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c @@ -12,10 +12,8 @@ #include "linux/console.h" #include "asm/termbits.h" #include "asm/irq.h" -#include "line.h" #include "ssl.h" -#include "chan_kern.h" -#include "kern.h" +#include "chan.h" #include "init.h" #include "irq_user.h" #include "mconsole_kern.h" diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index 49266f6108c..088776f0190 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c @@ -20,8 +20,7 @@ #include "asm/current.h" #include "asm/irq.h" #include "stdio_console.h" -#include "line.h" -#include "chan_kern.h" +#include "chan.h" #include "irq_user.h" #include "mconsole_kern.h" #include "init.h" diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c index 495858a090e..a97391f9ec5 100644 --- a/arch/um/drivers/tty.c +++ b/arch/um/drivers/tty.c @@ -7,10 +7,8 @@ #include <fcntl.h> #include <termios.h> #include "chan_user.h" -#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "user.h" struct tty_chan { char *dev; diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 620f5b70957..944453a3ec9 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -46,7 +46,6 @@ #include "asm/tlbflush.h" #include "mem_user.h" #include "kern_util.h" -#include "kern.h" #include "mconsole_kern.h" #include "init.h" #include "irq_user.h" @@ -54,7 +53,6 @@ #include "ubd_user.h" #include "os.h" #include "mem.h" -#include "mem_kern.h" #include "cow.h" enum ubd_req { UBD_READ, UBD_WRITE }; @@ -513,8 +511,37 @@ __uml_exitcall(kill_io_thread); static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) { char *file; + int fd; + int err; + + __u32 version; + __u32 align; + char *backing_file; + time_t mtime; + unsigned long long size; + int sector_size; + int bitmap_offset; + + if (ubd_dev->file && ubd_dev->cow.file) { + file = ubd_dev->cow.file; + + goto out; + } - file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file; + fd = os_open_file(ubd_dev->file, global_openflags, 0); + if (fd < 0) + return fd; + + err = read_cow_header(file_reader, &fd, &version, &backing_file, \ + &mtime, &size, §or_size, &align, &bitmap_offset); + os_close_file(fd); + + if(err == -EINVAL) + file = ubd_dev->file; + else + file = backing_file; + +out: return os_file_size(file, size_out); } diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index b591bb9c41d..007b94d9772 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c @@ -16,7 +16,6 @@ #include <sys/mman.h> #include <sys/param.h> #include "asm/types.h" -#include "user.h" #include "ubd_user.h" #include "os.h" #include "cow.h" diff --git a/arch/um/include/shared/ubd_user.h b/arch/um/drivers/ubd_user.h index 3845051f1b1..3845051f1b1 100644 --- a/arch/um/include/shared/ubd_user.h +++ b/arch/um/drivers/ubd_user.h diff --git a/arch/um/drivers/umcast_user.c b/arch/um/drivers/umcast_user.c index 59c56fd6f52..010fa2d849e 100644 --- a/arch/um/drivers/umcast_user.c +++ b/arch/um/drivers/umcast_user.c @@ -15,11 +15,9 @@ #include <unistd.h> #include <errno.h> #include <netinet/in.h> -#include "kern_constants.h" #include "umcast.h" #include "net_user.h" #include "um_malloc.h" -#include "user.h" static struct sockaddr_in *new_addr(char *addr, unsigned short port) { diff --git a/arch/um/drivers/vde_user.c b/arch/um/drivers/vde_user.c index c5c43253e6c..b8c286748d3 100644 --- a/arch/um/drivers/vde_user.c +++ b/arch/um/drivers/vde_user.c @@ -6,10 +6,8 @@ #include <stddef.h> #include <errno.h> #include <libvdeplug.h> -#include "kern_constants.h" #include "net_user.h" #include "um_malloc.h" -#include "user.h" #include "vde.h" static int vde_user_init(void *data, void *dev) diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c index 8ac7146c237..969110e5648 100644 --- a/arch/um/drivers/xterm.c +++ b/arch/um/drivers/xterm.c @@ -11,10 +11,8 @@ #include <string.h> #include <termios.h> #include "chan_user.h" -#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "user.h" #include "xterm.h" struct xterm_chan { @@ -123,6 +121,7 @@ static int xterm_open(int input, int output, int primary, void *d, err = -errno; printk(UM_KERN_ERR "xterm_open : unlink failed, errno = %d\n", errno); + close(fd); return err; } close(fd); diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild new file mode 100644 index 00000000000..451f4517b33 --- /dev/null +++ b/arch/um/include/asm/Kbuild @@ -0,0 +1,3 @@ +generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h +generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h +generic-y += ftrace.h diff --git a/arch/um/include/asm/apic.h b/arch/um/include/asm/apic.h deleted file mode 100644 index 876dee84ab1..00000000000 --- a/arch/um/include/asm/apic.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef __UM_APIC_H -#define __UM_APIC_H - -#endif diff --git a/arch/um/include/asm/arch_hweight.h b/arch/um/include/asm/arch_hweight.h deleted file mode 100644 index c656cf443f4..00000000000 --- a/arch/um/include/asm/arch_hweight.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_UM_HWEIGHT_H -#define _ASM_UM_HWEIGHT_H - -#include <asm-generic/bitops/arch_hweight.h> - -#endif diff --git a/arch/um/include/asm/bug.h b/arch/um/include/asm/bug.h deleted file mode 100644 index 9e33b864c35..00000000000 --- a/arch/um/include/asm/bug.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_BUG_H -#define __UM_BUG_H - -#include <asm-generic/bug.h> - -#endif diff --git a/arch/um/include/asm/checksum.h b/arch/um/include/asm/checksum.h deleted file mode 100644 index 5b501361e36..00000000000 --- a/arch/um/include/asm/checksum.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_CHECKSUM_H -#define __UM_CHECKSUM_H - -#include "sysdep/checksum.h" - -#endif diff --git a/arch/um/include/asm/cputime.h b/arch/um/include/asm/cputime.h deleted file mode 100644 index c84acbadfa2..00000000000 --- a/arch/um/include/asm/cputime.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_CPUTIME_H -#define __UM_CPUTIME_H - -#include <asm-generic/cputime.h> - -#endif /* __UM_CPUTIME_H */ diff --git a/arch/um/include/asm/delay.h b/arch/um/include/asm/delay.h index c71e32b6741..8a5576d8eda 100644 --- a/arch/um/include/asm/delay.h +++ b/arch/um/include/asm/delay.h @@ -1,20 +1,18 @@ #ifndef __UM_DELAY_H #define __UM_DELAY_H -#define MILLION 1000000 - /* Undefined on purpose */ extern void __bad_udelay(void); +extern void __bad_ndelay(void); extern void __udelay(unsigned long usecs); +extern void __ndelay(unsigned long usecs); extern void __delay(unsigned long loops); #define udelay(n) ((__builtin_constant_p(n) && (n) > 20000) ? \ __bad_udelay() : __udelay(n)) -/* It appears that ndelay is not used at all for UML, and has never been - * implemented. */ -extern void __unimplemented_ndelay(void); -#define ndelay(n) __unimplemented_ndelay() +#define ndelay(n) ((__builtin_constant_p(n) && (n) > 20000) ? \ + __bad_ndelay() : __ndelay(n)) #endif diff --git a/arch/um/include/asm/desc.h b/arch/um/include/asm/desc.h deleted file mode 100644 index 4ec34a51b62..00000000000 --- a/arch/um/include/asm/desc.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __UM_DESC_H -#define __UM_DESC_H - -/* Taken from asm-i386/desc.h, it's the only thing we need. The rest wouldn't - * compile, and has never been used. */ -#define LDT_empty(info) (\ - (info)->base_addr == 0 && \ - (info)->limit == 0 && \ - (info)->contents == 0 && \ - (info)->read_exec_only == 1 && \ - (info)->seg_32bit == 0 && \ - (info)->limit_in_pages == 0 && \ - (info)->seg_not_present == 1 && \ - (info)->useable == 0 ) - -#endif diff --git a/arch/um/include/asm/device.h b/arch/um/include/asm/device.h deleted file mode 100644 index d8f9872b0e2..00000000000 --- a/arch/um/include/asm/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include <asm-generic/device.h> - diff --git a/arch/um/include/asm/emergency-restart.h b/arch/um/include/asm/emergency-restart.h deleted file mode 100644 index 108d8c48e42..00000000000 --- a/arch/um/include/asm/emergency-restart.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_EMERGENCY_RESTART_H -#define _ASM_EMERGENCY_RESTART_H - -#include <asm-generic/emergency-restart.h> - -#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/arch/um/include/asm/ftrace.h b/arch/um/include/asm/ftrace.h deleted file mode 100644 index 40a8c178f10..00000000000 --- a/arch/um/include/asm/ftrace.h +++ /dev/null @@ -1 +0,0 @@ -/* empty */ diff --git a/arch/um/include/asm/futex.h b/arch/um/include/asm/futex.h deleted file mode 100644 index 6a332a9f099..00000000000 --- a/arch/um/include/asm/futex.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_FUTEX_H -#define _ASM_FUTEX_H - -#include <asm-generic/futex.h> - -#endif diff --git a/arch/um/include/asm/hardirq.h b/arch/um/include/asm/hardirq.h deleted file mode 100644 index fb3c05a0cbb..00000000000 --- a/arch/um/include/asm/hardirq.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/hardirq.h> diff --git a/arch/um/include/asm/hw_irq.h b/arch/um/include/asm/hw_irq.h deleted file mode 100644 index 1cf84cf5f21..00000000000 --- a/arch/um/include/asm/hw_irq.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _ASM_UM_HW_IRQ_H -#define _ASM_UM_HW_IRQ_H - -#include "asm/irq.h" -#include "asm/archparam.h" - -#endif diff --git a/arch/um/include/asm/irq_regs.h b/arch/um/include/asm/irq_regs.h deleted file mode 100644 index 3dd9c0b7027..00000000000 --- a/arch/um/include/asm/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/irq_regs.h> diff --git a/arch/um/include/asm/irq_vectors.h b/arch/um/include/asm/irq_vectors.h deleted file mode 100644 index 272a81e0ce1..00000000000 --- a/arch/um/include/asm/irq_vectors.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __UM_IRQ_VECTORS_H -#define __UM_IRQ_VECTORS_H - -#endif - diff --git a/arch/um/include/asm/irqflags.h b/arch/um/include/asm/irqflags.h index 659b9abdfdb..c780d8a1677 100644 --- a/arch/um/include/asm/irqflags.h +++ b/arch/um/include/asm/irqflags.h @@ -1,6 +1,42 @@ #ifndef __UM_IRQFLAGS_H #define __UM_IRQFLAGS_H -/* Empty for now */ +extern int get_signals(void); +extern int set_signals(int enable); +extern void block_signals(void); +extern void unblock_signals(void); + +static inline unsigned long arch_local_save_flags(void) +{ + return get_signals(); +} + +static inline void arch_local_irq_restore(unsigned long flags) +{ + set_signals(flags); +} + +static inline void arch_local_irq_enable(void) +{ + unblock_signals(); +} + +static inline void arch_local_irq_disable(void) +{ + block_signals(); +} + +static inline unsigned long arch_local_irq_save(void) +{ + unsigned long flags; + flags = arch_local_save_flags(); + arch_local_irq_disable(); + return flags; +} + +static inline bool arch_irqs_disabled(void) +{ + return arch_local_save_flags() == 0; +} #endif diff --git a/arch/um/include/asm/kdebug.h b/arch/um/include/asm/kdebug.h deleted file mode 100644 index 6ece1b03766..00000000000 --- a/arch/um/include/asm/kdebug.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/kdebug.h> diff --git a/arch/um/include/asm/mmu.h b/arch/um/include/asm/mmu.h index cf259de5153..30509b9f37f 100644 --- a/arch/um/include/asm/mmu.h +++ b/arch/um/include/asm/mmu.h @@ -1,12 +1,24 @@ /* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#ifndef __MMU_H -#define __MMU_H +#ifndef __ARCH_UM_MMU_H +#define __ARCH_UM_MMU_H -#include "um_mmu.h" +#include "mm_id.h" +#include <asm/mm_context.h> -#endif +typedef struct mm_context { + struct mm_id id; + struct uml_arch_mm_context arch; + struct page **stub_pages; +} mm_context_t; + +extern void __switch_mm(struct mm_id * mm_idp); +/* Avoid tangled inclusion with asm/ldt.h */ +extern long init_new_ldt(struct mm_context *to_mm, struct mm_context *from_mm); +extern void free_ldt(struct mm_context *mm); + +#endif diff --git a/arch/um/include/asm/mmu_context.h b/arch/um/include/asm/mmu_context.h index 34d813011b7..591b3d8d761 100644 --- a/arch/um/include/asm/mmu_context.h +++ b/arch/um/include/asm/mmu_context.h @@ -6,15 +6,12 @@ #ifndef __UM_MMU_CONTEXT_H #define __UM_MMU_CONTEXT_H -#include "linux/sched.h" -#include "um_mmu.h" +#include <linux/sched.h> +#include <asm/mmu.h> extern void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm); extern void arch_exit_mmap(struct mm_struct *mm); -#define get_mmu_context(task) do ; while(0) -#define activate_context(tsk) do ; while(0) - #define deactivate_mm(tsk,mm) do { } while (0) extern void force_flush_all(void); diff --git a/arch/um/include/asm/page.h b/arch/um/include/asm/page.h index 4cc9b6cf480..7cfc3cedce8 100644 --- a/arch/um/include/asm/page.h +++ b/arch/um/include/asm/page.h @@ -19,7 +19,7 @@ struct page; #include <linux/types.h> -#include <sysdep/vm-flags.h> +#include <asm/vm-flags.h> /* * These are used to make use of C type-checking.. diff --git a/arch/um/include/asm/page_offset.h b/arch/um/include/asm/page_offset.h deleted file mode 100644 index 1c168dfbf35..00000000000 --- a/arch/um/include/asm/page_offset.h +++ /dev/null @@ -1 +0,0 @@ -#define PAGE_OFFSET_RAW (uml_physmem) diff --git a/arch/um/include/asm/pda.h b/arch/um/include/asm/pda.h deleted file mode 100644 index ddcd774fc2a..00000000000 --- a/arch/um/include/asm/pda.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __UM_PDA_X86_64_H -#define __UM_PDA_X86_64_H - -/* XXX */ -struct foo { - unsigned int __softirq_pending; - unsigned int __nmi_count; -}; - -extern struct foo me; - -#define read_pda(me) (&me) - -#endif - diff --git a/arch/um/include/asm/percpu.h b/arch/um/include/asm/percpu.h deleted file mode 100644 index efe7508d8ab..00000000000 --- a/arch/um/include/asm/percpu.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_PERCPU_H -#define __UM_PERCPU_H - -#include <asm-generic/percpu.h> - -#endif /* __UM_PERCPU_H */ diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h index b7c5bab9bd7..f605d3c4844 100644 --- a/arch/um/include/asm/ptrace-generic.h +++ b/arch/um/include/asm/ptrace-generic.h @@ -23,17 +23,10 @@ struct pt_regs { #define PT_REGS_IP(r) UPT_IP(&(r)->regs) #define PT_REGS_SP(r) UPT_SP(&(r)->regs) -#define PT_REG(r, reg) UPT_REG(&(r)->regs, reg) -#define PT_REGS_SET(r, reg, val) UPT_SET(&(r)->regs, reg, val) - -#define PT_REGS_SET_SYSCALL_RETURN(r, res) \ - UPT_SET_SYSCALL_RETURN(&(r)->regs, res) #define PT_REGS_RESTART_SYSCALL(r) UPT_RESTART_SYSCALL(&(r)->regs) #define PT_REGS_SYSCALL_NR(r) UPT_SYSCALL_NR(&(r)->regs) -#define PT_REGS_SC(r) UPT_SC(&(r)->regs) - #define instruction_pointer(regs) PT_REGS_IP(regs) struct task_struct; @@ -42,12 +35,6 @@ extern long subarch_ptrace(struct task_struct *child, long request, unsigned long addr, unsigned long data); extern unsigned long getreg(struct task_struct *child, int regno); extern int putreg(struct task_struct *child, int regno, unsigned long value); -extern int get_fpregs(struct user_i387_struct __user *buf, - struct task_struct *child); -extern int set_fpregs(struct user_i387_struct __user *buf, - struct task_struct *child); - -extern void show_regs(struct pt_regs *regs); extern int arch_copy_tls(struct task_struct *new); extern void clear_flushed_tls(struct task_struct *task); diff --git a/arch/um/include/asm/required-features.h b/arch/um/include/asm/required-features.h deleted file mode 100644 index dfb967b2d2f..00000000000 --- a/arch/um/include/asm/required-features.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __UM_REQUIRED_FEATURES_H -#define __UM_REQUIRED_FEATURES_H - -/* - * Nothing to see, just need something for the i386 and x86_64 asm - * headers to include. - */ - -#endif diff --git a/arch/um/include/asm/sections.h b/arch/um/include/asm/sections.h deleted file mode 100644 index 6b0231eefea..00000000000 --- a/arch/um/include/asm/sections.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _UM_SECTIONS_H -#define _UM_SECTIONS_H - -/* nothing to see, move along */ -#include <asm-generic/sections.h> - -#endif diff --git a/arch/um/include/asm/segment.h b/arch/um/include/asm/segment.h deleted file mode 100644 index 45183fcd10b..00000000000 --- a/arch/um/include/asm/segment.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __UM_SEGMENT_H -#define __UM_SEGMENT_H - -extern int host_gdt_entry_tls_min; - -#define GDT_ENTRY_TLS_ENTRIES 3 -#define GDT_ENTRY_TLS_MIN host_gdt_entry_tls_min -#define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1) - -#endif diff --git a/arch/um/include/asm/system.h b/arch/um/include/asm/system.h deleted file mode 100644 index 68a90ecd145..00000000000 --- a/arch/um/include/asm/system.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef __UM_SYSTEM_GENERIC_H -#define __UM_SYSTEM_GENERIC_H - -#include "sysdep/system.h" - -extern int get_signals(void); -extern int set_signals(int enable); -extern void block_signals(void); -extern void unblock_signals(void); - -static inline unsigned long arch_local_save_flags(void) -{ - return get_signals(); -} - -static inline void arch_local_irq_restore(unsigned long flags) -{ - set_signals(flags); -} - -static inline void arch_local_irq_enable(void) -{ - unblock_signals(); -} - -static inline void arch_local_irq_disable(void) -{ - block_signals(); -} - -static inline unsigned long arch_local_irq_save(void) -{ - unsigned long flags; - flags = arch_local_save_flags(); - arch_local_irq_disable(); - return flags; -} - -static inline bool arch_irqs_disabled(void) -{ - return arch_local_save_flags() == 0; -} - -extern void *_switch_to(void *prev, void *next, void *last); -#define switch_to(prev, next, last) prev = _switch_to(prev, next, last) - -#endif diff --git a/arch/um/include/asm/topology.h b/arch/um/include/asm/topology.h deleted file mode 100644 index 0905e4f21d4..00000000000 --- a/arch/um/include/asm/topology.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_UM_TOPOLOGY_H -#define _ASM_UM_TOPOLOGY_H - -#include <asm-generic/topology.h> - -#endif diff --git a/arch/um/include/asm/uaccess.h b/arch/um/include/asm/uaccess.h index b9a895d6fa1..3f22fbf7ca1 100644 --- a/arch/um/include/asm/uaccess.h +++ b/arch/um/include/asm/uaccess.h @@ -6,15 +6,15 @@ #ifndef __UM_UACCESS_H #define __UM_UACCESS_H -#include <asm/errno.h> -#include <asm/processor.h> - /* thread_info has a mm_segment_t in it, so put the definition up here */ typedef struct { unsigned long seg; } mm_segment_t; -#include "linux/thread_info.h" +#include <linux/thread_info.h> +#include <linux/errno.h> +#include <asm/processor.h> +#include <asm/elf.h> #define VERIFY_READ 0 #define VERIFY_WRITE 1 @@ -38,7 +38,86 @@ typedef struct { #define segment_eq(a, b) ((a).seg == (b).seg) -#include "um_uaccess.h" +#define __under_task_size(addr, size) \ + (((unsigned long) (addr) < TASK_SIZE) && \ + (((unsigned long) (addr) + (size)) < TASK_SIZE)) + +#define __access_ok_vsyscall(type, addr, size) \ + ((type == VERIFY_READ) && \ + ((unsigned long) (addr) >= FIXADDR_USER_START) && \ + ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ + ((unsigned long) (addr) + (size) >= (unsigned long)(addr))) + +#define __addr_range_nowrap(addr, size) \ + ((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) + +#define access_ok(type, addr, size) \ + (__addr_range_nowrap(addr, size) && \ + (__under_task_size(addr, size) || \ + __access_ok_vsyscall(type, addr, size) || \ + segment_eq(get_fs(), KERNEL_DS))) + +extern int copy_from_user(void *to, const void __user *from, int n); +extern int copy_to_user(void __user *to, const void *from, int n); + +/* + * strncpy_from_user: - Copy a NUL terminated string from userspace. + * @dst: Destination address, in kernel space. This buffer must be at + * least @count bytes long. + * @src: Source address, in user space. + * @count: Maximum number of bytes to copy, including the trailing NUL. + * + * Copies a NUL-terminated string from userspace to kernel space. + * + * On success, returns the length of the string (not including the trailing + * NUL). + * + * If access to userspace fails, returns -EFAULT (some data may have been + * copied). + * + * If @count is smaller than the length of the string, copies @count bytes + * and returns @count. + */ + +extern int strncpy_from_user(char *dst, const char __user *src, int count); + +/* + * __clear_user: - Zero a block of memory in user space, with less checking. + * @to: Destination address, in user space. + * @n: Number of bytes to zero. + * + * Zero a block of memory in user space. Caller must check + * the specified block with access_ok() before calling this function. + * + * Returns number of bytes that could not be cleared. + * On success, this will be zero. + */ +extern int __clear_user(void __user *mem, int len); + +/* + * clear_user: - Zero a block of memory in user space. + * @to: Destination address, in user space. + * @n: Number of bytes to zero. + * + * Zero a block of memory in user space. + * + * Returns number of bytes that could not be cleared. + * On success, this will be zero. + */ +extern int clear_user(void __user *mem, int len); + +/* + * strlen_user: - Get the size of a string in user space. + * @str: The string to measure. + * @n: The maximum valid length + * + * Get the size of a NUL-terminated string in user space. + * + * Returns the size of the string INCLUDING the terminating NUL. + * On exception, returns 0. + * If the string is too long, returns a value greater than @n. + */ +extern int strnlen_user(const void __user *str, int len); #define __copy_from_user(to, from, n) copy_from_user(to, from, n) diff --git a/arch/um/include/asm/xor.h b/arch/um/include/asm/xor.h deleted file mode 100644 index a19db3e1724..00000000000 --- a/arch/um/include/asm/xor.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_XOR_H -#define __UM_XOR_H - -#include "asm-generic/xor.h" - -#endif diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h index a92b678503c..896e1660217 100644 --- a/arch/um/include/shared/as-layout.h +++ b/arch/um/include/shared/as-layout.h @@ -6,7 +6,7 @@ #ifndef __START_H__ #define __START_H__ -#include "kern_constants.h" +#include <generated/asm-offsets.h> /* * Stolen from linux/const.h, which can't be directly included since diff --git a/arch/um/include/shared/common-offsets.h b/arch/um/include/shared/common-offsets.h index 72009c7e321..d7fe563aa7e 100644 --- a/arch/um/include/shared/common-offsets.h +++ b/arch/um/include/shared/common-offsets.h @@ -2,7 +2,6 @@ DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); -OFFSET(HOST_TASK_REGS, task_struct, thread.regs); OFFSET(HOST_TASK_PID, task_struct, pid); DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE); diff --git a/arch/um/include/shared/initrd.h b/arch/um/include/shared/initrd.h deleted file mode 100644 index 22673bcc273..00000000000 --- a/arch/um/include/shared/initrd.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __INITRD_USER_H__ -#define __INITRD_USER_H__ - -extern int load_initrd(char *filename, void *buf, int size); - -#endif - diff --git a/arch/um/include/shared/kern.h b/arch/um/include/shared/kern.h index 4ce3fc650e5..6cd01240bbf 100644 --- a/arch/um/include/shared/kern.h +++ b/arch/um/include/shared/kern.h @@ -13,28 +13,10 @@ * includes. */ -extern int errno; - -extern int clone(int (*proc)(void *), void *sp, int flags, void *data); -extern int sleep(int); extern int printf(const char *fmt, ...); -extern char *strerror(int errnum); -extern char *ptsname(int __fd); -extern int munmap(void *, int); extern void *sbrk(int increment); -extern void *malloc(int size); -extern void perror(char *err); -extern int kill(int pid, int sig); -extern int getuid(void); -extern int getgid(void); extern int pause(void); -extern int write(int, const void *, int); extern void exit(int); -extern int close(int); -extern int read(unsigned int, char *, int); -extern int pipe(int *); -extern int sched_yield(void); -extern int ptrace(int op, int pid, long addr, long data); #endif diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h index 3c341222d25..0f148385246 100644 --- a/arch/um/include/shared/kern_util.h +++ b/arch/um/include/shared/kern_util.h @@ -21,7 +21,6 @@ extern unsigned long alloc_stack(int order, int atomic); extern void free_stack(unsigned long stack, int order); extern int do_signal(void); -extern void copy_sc(struct uml_pt_regs *regs, void *from); extern void interrupt_end(void); extern void relay_signal(int sig, struct uml_pt_regs *regs); diff --git a/arch/um/include/shared/ldt.h b/arch/um/include/shared/ldt.h deleted file mode 100644 index a7f999a5877..00000000000 --- a/arch/um/include/shared/ldt.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2004 Fujitsu Siemens Computers GmbH - * Licensed under the GPL - * - * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com> - */ - -#ifndef __ASM_LDT_H -#define __ASM_LDT_H - -#include <linux/mutex.h> -#include <sysdep/host_ldt.h> - -extern void ldt_host_info(void); - -#define LDT_PAGES_MAX \ - ((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE) -#define LDT_ENTRIES_PER_PAGE \ - (PAGE_SIZE/LDT_ENTRY_SIZE) -#define LDT_DIRECT_ENTRIES \ - ((LDT_PAGES_MAX*sizeof(void *))/LDT_ENTRY_SIZE) - -struct ldt_entry { - __u32 a; - __u32 b; -}; - -typedef struct uml_ldt { - int entry_count; - struct mutex lock; - union { - struct ldt_entry * pages[LDT_PAGES_MAX]; - struct ldt_entry entries[LDT_DIRECT_ENTRIES]; - } u; -} uml_ldt_t; - -#endif diff --git a/arch/um/include/shared/mem_kern.h b/arch/um/include/shared/mem_kern.h deleted file mode 100644 index 69be0fd0ce4..00000000000 --- a/arch/um/include/shared/mem_kern.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#ifndef __MEM_KERN_H__ -#define __MEM_KERN_H__ - -#include "linux/list.h" -#include "linux/types.h" - -struct remapper { - struct list_head list; - int (*proc)(int, unsigned long, int, __u64); -}; - -extern void register_remapper(struct remapper *info); - -#endif - diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index 83c7c2ecd61..89b686c1a3e 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -10,7 +10,6 @@ #include "irq_user.h" #include "longjmp.h" #include "mm_id.h" -#include "sysdep/tls.h" #define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR)) @@ -203,12 +202,6 @@ extern int os_drop_memory(void *addr, int length); extern int can_drop_memory(void); extern void os_flush_stdout(void); -/* uaccess.c */ -extern unsigned long __do_user_copy(void *to, const void *from, int n, - void **fault_addr, jmp_buf **fault_catcher, - void (*op)(void *to, const void *from, - int n), int *faulted_out); - /* execvp.c */ extern int execvp_noalloc(char *buf, const char *file, char *const argv[]); /* helper.c */ @@ -218,10 +211,6 @@ extern int run_helper_thread(int (*proc)(void *), void *arg, extern int helper_wait(int pid); -/* tls.c */ -extern int os_set_thread_area(user_desc_t *info, int pid); -extern int os_get_thread_area(user_desc_t *info, int pid); - /* umid.c */ extern int umid_file_name(char *name, char *buf, int len); extern int set_umid(char *name); @@ -231,7 +220,7 @@ extern char *get_umid(void); extern void timer_init(void); extern void set_sigstack(void *sig_stack, int size); extern void remove_sigstack(void); -extern void set_handler(int sig, void (*handler)(int), int flags, ...); +extern void set_handler(int sig); extern int change_sig(int signal, int on); extern void block_signals(void); extern void unblock_signals(void); diff --git a/arch/um/include/shared/process.h b/arch/um/include/shared/process.h deleted file mode 100644 index bb873a51262..00000000000 --- a/arch/um/include/shared/process.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2000 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __PROCESS_H__ -#define __PROCESS_H__ - -#include <signal.h> - -/* Copied from linux/compiler-gcc.h since we can't include it directly */ -#define barrier() __asm__ __volatile__("": : :"memory") - -extern void sig_handler(int sig, struct sigcontext *sc); -extern void alarm_handler(int sig, struct sigcontext *sc); - -#endif diff --git a/arch/um/include/shared/ptrace_user.h b/arch/um/include/shared/ptrace_user.h index 7fd8539bc19..56b2f284b10 100644 --- a/arch/um/include/shared/ptrace_user.h +++ b/arch/um/include/shared/ptrace_user.h @@ -6,7 +6,8 @@ #ifndef __PTRACE_USER_H__ #define __PTRACE_USER_H__ -#include "sysdep/ptrace_user.h" +#include <sys/ptrace.h> +#include <sysdep/ptrace_user.h> extern int ptrace_getregs(long pid, unsigned long *regs_out); extern int ptrace_setregs(long pid, unsigned long *regs_in); diff --git a/arch/um/include/shared/registers.h b/arch/um/include/shared/registers.h index b0b4589e0eb..f1e0aa56c52 100644 --- a/arch/um/include/shared/registers.h +++ b/arch/um/include/shared/registers.h @@ -16,7 +16,7 @@ extern int restore_fpx_registers(int pid, unsigned long *fp_regs); extern int save_registers(int pid, struct uml_pt_regs *regs); extern int restore_registers(int pid, struct uml_pt_regs *regs); extern int init_registers(int pid); -extern void get_safe_registers(unsigned long *regs); +extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs); extern unsigned long get_thread_reg(int reg, jmp_buf *buf); extern int get_fp_registers(int pid, unsigned long *regs); extern int put_fp_registers(int pid, unsigned long *regs); diff --git a/arch/um/include/shared/skas_ptregs.h b/arch/um/include/shared/skas_ptregs.h deleted file mode 100644 index 73db19e9c07..00000000000 --- a/arch/um/include/shared/skas_ptregs.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __SKAS_PT_REGS_ -#define __SKAS_PT_REGS_ - -#include <user_constants.h> - -#endif diff --git a/arch/um/include/shared/syscall.h b/arch/um/include/shared/syscall.h deleted file mode 100644 index dda1df901a0..00000000000 --- a/arch/um/include/shared/syscall.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __SYSCALL_USER_H -#define __SYSCALL_USER_H - -extern int record_syscall_start(int syscall); -extern void record_syscall_end(int index, long result); - -#endif diff --git a/arch/um/include/shared/task.h b/arch/um/include/shared/task.h deleted file mode 100644 index 3fe726b3cf4..00000000000 --- a/arch/um/include/shared/task.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __TASK_H -#define __TASK_H - -#include <kern_constants.h> - -#define TASK_REGS(task) ((struct uml_pt_regs *) &(((char *) (task))[HOST_TASK_REGS])) -#define TASK_PID(task) *((int *) &(((char *) (task))[HOST_TASK_PID])) - -#endif diff --git a/arch/um/include/shared/tlb.h b/arch/um/include/shared/tlb.h deleted file mode 100644 index ecd2265b301..00000000000 --- a/arch/um/include/shared/tlb.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __TLB_H__ -#define __TLB_H__ - -#include "um_mmu.h" - -extern void force_flush_all(void); -extern int flush_tlb_kernel_range_common(unsigned long start, - unsigned long end); - -#endif diff --git a/arch/um/include/shared/um_malloc.h b/arch/um/include/shared/um_malloc.h index c554d706d10..6395fef6b69 100644 --- a/arch/um/include/shared/um_malloc.h +++ b/arch/um/include/shared/um_malloc.h @@ -6,7 +6,7 @@ #ifndef __UM_MALLOC_H__ #define __UM_MALLOC_H__ -#include "kern_constants.h" +#include <generated/asm-offsets.h> extern void *uml_kmalloc(int size, int flags); extern void kfree(const void *ptr); diff --git a/arch/um/include/shared/um_mmu.h b/arch/um/include/shared/um_mmu.h deleted file mode 100644 index b1a7e47d102..00000000000 --- a/arch/um/include/shared/um_mmu.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __ARCH_UM_MMU_H -#define __ARCH_UM_MMU_H - -#include "mm_id.h" -#include "ldt.h" - -typedef struct mm_context { - struct mm_id id; - struct uml_ldt ldt; - struct page **stub_pages; -} mm_context_t; - -extern void __switch_mm(struct mm_id * mm_idp); - -/* Avoid tangled inclusion with asm/ldt.h */ -extern long init_new_ldt(struct mm_context *to_mm, struct mm_context *from_mm); -extern void free_ldt(struct mm_context *mm); - -#endif diff --git a/arch/um/include/shared/um_uaccess.h b/arch/um/include/shared/um_uaccess.h deleted file mode 100644 index 45c04999d67..00000000000 --- a/arch/um/include/shared/um_uaccess.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __ARCH_UM_UACCESS_H -#define __ARCH_UM_UACCESS_H - -#include <asm/elf.h> -#include <asm/fixmap.h> -#include "sysdep/archsetjmp.h" - -#define __under_task_size(addr, size) \ - (((unsigned long) (addr) < TASK_SIZE) && \ - (((unsigned long) (addr) + (size)) < TASK_SIZE)) - -#define __access_ok_vsyscall(type, addr, size) \ - ((type == VERIFY_READ) && \ - ((unsigned long) (addr) >= FIXADDR_USER_START) && \ - ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ - ((unsigned long) (addr) + (size) >= (unsigned long)(addr))) - -#define __addr_range_nowrap(addr, size) \ - ((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) - -#define access_ok(type, addr, size) \ - (__addr_range_nowrap(addr, size) && \ - (__under_task_size(addr, size) || \ - __access_ok_vsyscall(type, addr, size) || \ - segment_eq(get_fs(), KERNEL_DS))) - -extern int copy_from_user(void *to, const void __user *from, int n); -extern int copy_to_user(void __user *to, const void *from, int n); - -extern int __do_copy_to_user(void *to, const void *from, int n, - void **fault_addr, jmp_buf **fault_catcher); - -/* - * strncpy_from_user: - Copy a NUL terminated string from userspace. - * @dst: Destination address, in kernel space. This buffer must be at - * least @count bytes long. - * @src: Source address, in user space. - * @count: Maximum number of bytes to copy, including the trailing NUL. - * - * Copies a NUL-terminated string from userspace to kernel space. - * - * On success, returns the length of the string (not including the trailing - * NUL). - * - * If access to userspace fails, returns -EFAULT (some data may have been - * copied). - * - * If @count is smaller than the length of the string, copies @count bytes - * and returns @count. - */ - -extern int strncpy_from_user(char *dst, const char __user *src, int count); - -/* - * __clear_user: - Zero a block of memory in user space, with less checking. - * @to: Destination address, in user space. - * @n: Number of bytes to zero. - * - * Zero a block of memory in user space. Caller must check - * the specified block with access_ok() before calling this function. - * - * Returns number of bytes that could not be cleared. - * On success, this will be zero. - */ -extern int __clear_user(void __user *mem, int len); - -/* - * clear_user: - Zero a block of memory in user space. - * @to: Destination address, in user space. - * @n: Number of bytes to zero. - * - * Zero a block of memory in user space. - * - * Returns number of bytes that could not be cleared. - * On success, this will be zero. - */ -extern int clear_user(void __user *mem, int len); - -/* - * strlen_user: - Get the size of a string in user space. - * @str: The string to measure. - * @n: The maximum valid length - * - * Get the size of a NUL-terminated string in user space. - * - * Returns the size of the string INCLUDING the terminating NUL. - * On exception, returns 0. - * If the string is too long, returns a value greater than @n. - */ -extern int strnlen_user(const void __user *str, int len); - -#endif diff --git a/arch/um/include/shared/user.h b/arch/um/include/shared/user.h index 293f7c794fa..4fa82c055aa 100644 --- a/arch/um/include/shared/user.h +++ b/arch/um/include/shared/user.h @@ -6,7 +6,7 @@ #ifndef __USER_H__ #define __USER_H__ -#include "kern_constants.h" +#include <generated/asm-offsets.h> /* * The usual definition - copied here because the kernel provides its own, @@ -36,10 +36,11 @@ static inline int printk(const char *fmt, ...) } #endif -extern void schedule(void); extern int in_aton(char *str); -extern int open_gdb_chan(void); extern size_t strlcpy(char *, const char *, size_t); extern size_t strlcat(char *, const char *, size_t); +/* Copied from linux/compiler-gcc.h since we can't include it directly */ +#define barrier() __asm__ __volatile__("": : :"memory") + #endif diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index c4491c15afb..bc494741b1f 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile @@ -11,7 +11,7 @@ clean-files := obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \ physmem.o process.o ptrace.o reboot.o sigio.o \ - signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o uaccess.o \ + signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o \ um_arch.o umid.o skas/ obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 09bd7b58572..6cade936636 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -3,14 +3,15 @@ * Licensed under the GPL */ -#include "linux/stddef.h" -#include "linux/fs.h" -#include "linux/ptrace.h" -#include "linux/sched.h" -#include "linux/slab.h" -#include "asm/current.h" -#include "asm/processor.h" -#include "asm/uaccess.h" +#include <linux/stddef.h> +#include <linux/module.h> +#include <linux/fs.h> +#include <linux/ptrace.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <asm/current.h> +#include <asm/processor.h> +#include <asm/uaccess.h> #include "as-layout.h" #include "mem_user.h" #include "skas.h" @@ -38,10 +39,10 @@ void flush_thread(void) void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) { - set_fs(USER_DS); PT_REGS_IP(regs) = eip; PT_REGS_SP(regs) = esp; } +EXPORT_SYMBOL(start_thread); static long execve1(const char *file, const char __user *const __user *argv, diff --git a/arch/um/kernel/gmon_syms.c b/arch/um/kernel/gmon_syms.c index 72eccd2a411..e9bcf247bce 100644 --- a/arch/um/kernel/gmon_syms.c +++ b/arch/um/kernel/gmon_syms.c @@ -7,18 +7,3 @@ extern void __bb_init_func(void *) __attribute__((weak)); EXPORT_SYMBOL(__bb_init_func); - -/* - * This is defined (and referred to in profiling stub code) only by some GCC - * versions in libgcov. - * - * Since SuSE backported the fix, we cannot handle it depending on GCC version. - * So, unconditionally export it. But also give it a weak declaration, which - * will be overridden by any other one. - */ - -extern void __gcov_init(void *) __attribute__((weak)); -EXPORT_SYMBOL(__gcov_init); - -extern void __gcov_merge_add(void *) __attribute__((weak)); -EXPORT_SYMBOL(__gcov_merge_add); diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c index d386c75c88e..10cc18f729f 100644 --- a/arch/um/kernel/initrd.c +++ b/arch/um/kernel/initrd.c @@ -7,12 +7,12 @@ #include "linux/bootmem.h" #include "linux/initrd.h" #include "asm/types.h" -#include "initrd.h" #include "init.h" #include "os.h" /* Changed by uml_initrd_setup, which is a setup */ static char *initrd __initdata = NULL; +static int load_initrd(char *filename, void *buf, int size); static int __init read_initrd(void) { @@ -62,7 +62,7 @@ __uml_setup("initrd=", uml_initrd_setup, " name of the file containing the image.\n\n" ); -int load_initrd(char *filename, void *buf, int size) +static int load_initrd(char *filename, void *buf, int size) { int fd, n; diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 9e485c77030..71b8c947e5e 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -258,6 +258,7 @@ void deactivate_fd(int fd, int irqnum) ignore_sigio_fd(fd); } +EXPORT_SYMBOL(deactivate_fd); /* * Called just before shutdown in order to provide a clean exec diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index 0ae0dfcfbff..e17bea0b22e 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c @@ -3,33 +3,11 @@ * Licensed under the GPL */ -#include "linux/module.h" -#include "linux/syscalls.h" -#include "asm/tlbflush.h" -#include "asm/uaccess.h" -#include "as-layout.h" -#include "kern_util.h" -#include "mem_user.h" +#include <linux/module.h> #include "os.h" -EXPORT_SYMBOL(uml_physmem); EXPORT_SYMBOL(set_signals); EXPORT_SYMBOL(get_signals); -EXPORT_SYMBOL(kernel_thread); -EXPORT_SYMBOL(sys_waitpid); -EXPORT_SYMBOL(flush_tlb_range); - -EXPORT_SYMBOL(high_physmem); -EXPORT_SYMBOL(empty_zero_page); -EXPORT_SYMBOL(handle_page_fault); -EXPORT_SYMBOL(find_iomem); - -EXPORT_SYMBOL(strnlen_user); -EXPORT_SYMBOL(strncpy_from_user); -EXPORT_SYMBOL(copy_to_user); -EXPORT_SYMBOL(copy_from_user); -EXPORT_SYMBOL(clear_user); -EXPORT_SYMBOL(uml_strdup); EXPORT_SYMBOL(os_stat_fd); EXPORT_SYMBOL(os_stat_file); @@ -57,24 +35,10 @@ EXPORT_SYMBOL(os_connect_socket); EXPORT_SYMBOL(os_accept_connection); EXPORT_SYMBOL(os_rcv_fd); EXPORT_SYMBOL(run_helper); -EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(os_major); EXPORT_SYMBOL(os_minor); EXPORT_SYMBOL(os_makedev); EXPORT_SYMBOL(add_sigio_fd); EXPORT_SYMBOL(ignore_sigio_fd); -EXPORT_SYMBOL(deactivate_fd); EXPORT_SYMBOL(sigio_broken); - -#ifdef CONFIG_SMP - -/* required for SMP */ - -extern void __write_lock_failed(rwlock_t *rw); -EXPORT_SYMBOL(__write_lock_failed); - -extern void __read_lock_failed(rwlock_t *rw); -EXPORT_SYMBOL(__read_lock_failed); - -#endif diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index 8137ccc9635..ebb86b21844 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -4,6 +4,7 @@ */ #include <linux/stddef.h> +#include <linux/module.h> #include <linux/bootmem.h> #include <linux/highmem.h> #include <linux/mm.h> @@ -20,6 +21,7 @@ /* allocated in paging_init, zeroed in mem_init, and unchanged thereafter */ unsigned long *empty_zero_page = NULL; +EXPORT_SYMBOL(empty_zero_page); /* allocated in paging_init and unchanged thereafter */ static unsigned long *empty_bad_page = NULL; diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index a1a9090254c..f116db15d40 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -3,20 +3,22 @@ * Licensed under the GPL */ -#include "linux/bootmem.h" -#include "linux/mm.h" -#include "linux/pfn.h" -#include "asm/page.h" -#include "as-layout.h" -#include "init.h" -#include "kern.h" -#include "mem_user.h" -#include "os.h" +#include <linux/module.h> +#include <linux/bootmem.h> +#include <linux/mm.h> +#include <linux/pfn.h> +#include <asm/page.h> +#include <as-layout.h> +#include <init.h> +#include <kern.h> +#include <mem_user.h> +#include <os.h> static int physmem_fd = -1; /* Changed during early boot */ unsigned long high_physmem; +EXPORT_SYMBOL(high_physmem); extern unsigned long long physmem_size; @@ -184,6 +186,7 @@ unsigned long find_iomem(char *driver, unsigned long *len_out) return 0; } +EXPORT_SYMBOL(find_iomem); static int setup_iomem(void) { diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index fab4371184f..c5338351aec 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -20,12 +20,12 @@ #include <linux/threads.h> #include <asm/current.h> #include <asm/pgtable.h> +#include <asm/mmu_context.h> #include <asm/uaccess.h> #include "as-layout.h" #include "kern_util.h" #include "os.h" #include "skas.h" -#include "tlb.h" /* * This is a per-cpu array. A processor only modifies its entry and it only @@ -78,6 +78,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) ¤t->thread.regs, 0, NULL, NULL); return pid; } +EXPORT_SYMBOL(kernel_thread); static inline void set_current(struct task_struct *task) { @@ -202,7 +203,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, arch_copy_thread(¤t->thread.arch, &p->thread.arch); } else { - get_safe_registers(p->thread.regs.regs.gp); + get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp); p->thread.request.u.thread = current->thread.request.u.thread; handler = new_thread_handler; } @@ -286,6 +287,7 @@ char *uml_strdup(const char *string) { return kstrdup(string, GFP_KERNEL); } +EXPORT_SYMBOL(uml_strdup); int copy_to_user_proc(void __user *to, void *from, int size) { diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 701b672c112..c9da32b0c70 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c @@ -50,23 +50,11 @@ long arch_ptrace(struct task_struct *child, long request, void __user *vp = p; switch (request) { - /* read word at location addr. */ - case PTRACE_PEEKTEXT: - case PTRACE_PEEKDATA: - ret = generic_ptrace_peekdata(child, addr, data); - break; - /* read the word at location addr in the USER area. */ case PTRACE_PEEKUSR: ret = peek_user(child, addr, data); break; - /* write the word at location addr. */ - case PTRACE_POKETEXT: - case PTRACE_POKEDATA: - ret = generic_ptrace_pokedata(child, addr, data); - break; - /* write the word at location addr in the USER area */ case PTRACE_POKEUSR: ret = poke_user(child, addr, data); @@ -107,16 +95,6 @@ long arch_ptrace(struct task_struct *child, long request, break; } #endif -#ifdef PTRACE_GETFPREGS - case PTRACE_GETFPREGS: /* Get the child FPU state. */ - ret = get_fpregs(vp, child); - break; -#endif -#ifdef PTRACE_SETFPREGS - case PTRACE_SETFPREGS: /* Set the child FPU state. */ - ret = set_fpregs(vp, child); - break; -#endif case PTRACE_GET_THREAD_AREA: ret = ptrace_get_thread_area(child, addr, vp); break; @@ -154,12 +132,6 @@ long arch_ptrace(struct task_struct *child, long request, break; } #endif -#ifdef PTRACE_ARCH_PRCTL - case PTRACE_ARCH_PRCTL: - /* XXX Calls ptrace on the host - needs some SMP thinking */ - ret = arch_prctl(child, data, (void __user *) addr); - break; -#endif default: ret = ptrace_request(child, request, addr, data); if (ret == -EIO) diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c index 869bec9f251..4d93dff6b37 100644 --- a/arch/um/kernel/reboot.c +++ b/arch/um/kernel/reboot.c @@ -20,9 +20,8 @@ static void kill_off_processes(void) os_kill_ptraced_process(userspace_pid[0], 1); else { struct task_struct *p; - int pid, me; + int pid; - me = os_getpid(); for_each_process(p) { if (p->mm == NULL) continue; diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c index b5c094c4ade..e8b889d3bce 100644 --- a/arch/um/kernel/signal.c +++ b/arch/um/kernel/signal.c @@ -11,7 +11,6 @@ #include <asm/unistd.h> #include "frame_kern.h" #include "kern_util.h" -#include <sysdep/sigcontext.h> EXPORT_SYMBOL(block_signals); EXPORT_SYMBOL(unblock_signals); diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c index 2c8583c1a34..e1fd066a352 100644 --- a/arch/um/kernel/skas/clone.c +++ b/arch/um/kernel/skas/clone.c @@ -8,7 +8,6 @@ #include <asm/unistd.h> #include <sys/time.h> #include "as-layout.h" -#include "kern_constants.h" #include "ptrace_user.h" #include "stub-data.h" #include "sysdep/stub.h" diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index 696634214dc..9fefd924fb4 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c @@ -6,6 +6,7 @@ #include <linux/err.h> #include <linux/highmem.h> #include <linux/mm.h> +#include <linux/module.h> #include <linux/sched.h> #include <asm/current.h> #include <asm/page.h> @@ -149,6 +150,7 @@ int copy_from_user(void *to, const void __user *from, int n) buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to): n; } +EXPORT_SYMBOL(copy_from_user); static int copy_chunk_to_user(unsigned long to, int len, void *arg) { @@ -170,6 +172,7 @@ int copy_to_user(void __user *to, const void *from, int n) buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) : n; } +EXPORT_SYMBOL(copy_to_user); static int strncpy_chunk_from_user(unsigned long from, int len, void *arg) { @@ -204,6 +207,7 @@ int strncpy_from_user(char *dst, const char __user *src, int count) return -EFAULT; return strnlen(dst, count); } +EXPORT_SYMBOL(strncpy_from_user); static int clear_chunk(unsigned long addr, int len, void *unused) { @@ -226,6 +230,7 @@ int clear_user(void __user *mem, int len) return access_ok(VERIFY_WRITE, mem, len) ? buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len; } +EXPORT_SYMBOL(clear_user); static int strnlen_chunk(unsigned long str, int len, void *arg) { @@ -251,3 +256,4 @@ int strnlen_user(const void __user *str, int len) return count + 1; return -EFAULT; } +EXPORT_SYMBOL(strnlen_user); diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index d175d0566af..7f3d4d86431 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -4,6 +4,7 @@ */ #include <linux/mm.h> +#include <linux/module.h> #include <linux/sched.h> #include <asm/pgtable.h> #include <asm/tlbflush.h> @@ -11,7 +12,6 @@ #include "mem_user.h" #include "os.h" #include "skas.h" -#include "tlb.h" struct host_vm_change { struct host_vm_op { @@ -287,7 +287,7 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr, } } -int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) +static int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) { struct mm_struct *mm; pgd_t *pgd; @@ -499,6 +499,7 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, flush_tlb_kernel_range_common(start, end); else fix_range(vma->vm_mm, start, end, 0); } +EXPORT_SYMBOL(flush_tlb_range); void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, unsigned long end) diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 8c7b8823d1f..dafc9471595 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -6,6 +6,7 @@ #include <linux/mm.h> #include <linux/sched.h> #include <linux/hardirq.h> +#include <linux/module.h> #include <asm/current.h> #include <asm/pgtable.h> #include <asm/tlbflush.h> @@ -14,7 +15,6 @@ #include "kern_util.h" #include "os.h" #include "skas.h" -#include "sysdep/sigcontext.h" /* * Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by @@ -112,6 +112,7 @@ out_of_memory: pagefault_out_of_memory(); return 0; } +EXPORT_SYMBOL(handle_page_fault); static void show_segv_info(struct uml_pt_regs *regs) { diff --git a/arch/um/kernel/uaccess.c b/arch/um/kernel/uaccess.c deleted file mode 100644 index dd33f040c52..00000000000 --- a/arch/um/kernel/uaccess.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk) - * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -/* - * These are here rather than tt/uaccess.c because skas mode needs them in - * order to do SIGBUS recovery when a tmpfs mount runs out of room. - */ - -#include <linux/string.h> -#include "os.h" - -static void __do_copy(void *to, const void *from, int n) -{ - memcpy(to, from, n); -} - - -int __do_copy_to_user(void *to, const void *from, int n, - void **fault_addr, jmp_buf **fault_catcher) -{ - unsigned long fault; - int faulted; - - fault = __do_user_copy(to, from, n, fault_addr, fault_catcher, - __do_copy, &faulted); - if (!faulted) - return 0; - else - return n - (fault - (unsigned long) to); -} diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 8d84250324b..ba00eae45aa 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -102,6 +102,8 @@ const struct seq_operations cpuinfo_op = { /* Set in linux_main */ unsigned long uml_physmem; +EXPORT_SYMBOL(uml_physmem); + unsigned long uml_reserved; /* Also modified in mem_init */ unsigned long start_vm; unsigned long end_vm; diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile index d66f0388f09..dd764101e48 100644 --- a/arch/um/os-Linux/Makefile +++ b/arch/um/os-Linux/Makefile @@ -3,13 +3,15 @@ # Licensed under the GPL # -obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ - registers.o sigio.o signal.o start_up.o time.o tty.o uaccess.o \ - umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ skas/ +obj-y = aio.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ + registers.o sigio.o signal.o start_up.o time.o tty.o \ + umid.o user_syms.o util.o drivers/ skas/ + +obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \ main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \ - tty.o tls.o uaccess.o umid.o util.o + tty.o umid.o util.o CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index 57e3d46c989..c5d039e1ff3 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c @@ -11,10 +11,8 @@ #include <asm/unistd.h> #include "aio.h" #include "init.h" -#include "kern_constants.h" #include "kern_util.h" #include "os.h" -#include "user.h" struct aio_thread_req { enum aio_type type; diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index cc72cb2c1af..db3d6481375 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -13,11 +13,9 @@ #include <sys/socket.h> #include <sys/wait.h> #include "etap.h" -#include "kern_constants.h" #include "os.h" #include "net_user.h" #include "um_malloc.h" -#include "user.h" #define MAX_PACKET ETH_MAX_PACKET diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index 2448be03fd7..a2aacffdd90 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c @@ -13,11 +13,9 @@ #include <sys/socket.h> #include <sys/wait.h> #include <sys/uio.h> -#include "kern_constants.h" #include "kern_util.h" #include "os.h" #include "tuntap.h" -#include "user.h" static int tuntap_user_init(void *data, void *dev) { diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c index 608784d4ec5..d895271ad6f 100644 --- a/arch/um/os-Linux/elf_aux.c +++ b/arch/um/os-Linux/elf_aux.c @@ -12,18 +12,12 @@ #include "init.h" #include "elf_user.h" #include "mem_user.h" -#include <kern_constants.h> -/* Use the one from the kernel - the host may miss it, if having old headers. */ -#if UM_ELF_CLASS == UM_ELFCLASS32 typedef Elf32_auxv_t elf_auxv_t; -#else -typedef Elf64_auxv_t elf_auxv_t; -#endif /* These are initialized very early in boot and never changed */ char * elf_aux_platform; -long elf_aux_hwcap; +extern long elf_aux_hwcap; unsigned long vsyscall_ehdr; unsigned long vsyscall_end; unsigned long __kernel_vsyscall; diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 140e587bc0a..b049a63bb74 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -13,9 +13,7 @@ #include <sys/socket.h> #include <sys/stat.h> #include <sys/un.h> -#include "kern_constants.h" #include "os.h" -#include "user.h" static void copy_stat(struct uml_stat *dst, const struct stat64 *src) { diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index b6b1096152a..cf26c4a9a43 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -10,11 +10,9 @@ #include <linux/limits.h> #include <sys/socket.h> #include <sys/wait.h> -#include "kern_constants.h" #include "kern_util.h" #include "os.h" #include "um_malloc.h" -#include "user.h" struct helper_data { void (*pre_exec)(void*); @@ -28,14 +26,14 @@ static int helper_child(void *arg) { struct helper_data *data = arg; char **argv = data->argv; - int err; + int err, ret; if (data->pre_exec != NULL) (*data->pre_exec)(data->pre_data); err = execvp_noalloc(data->buf, argv[0], argv); /* If the exec succeeds, we don't get here */ - write(data->fd, &err, sizeof(err)); + CATCH_EINTR(ret = write(data->fd, &err, sizeof(err))); return 0; } diff --git a/arch/um/os-Linux/internal.h b/arch/um/os-Linux/internal.h new file mode 100644 index 00000000000..2c3c3ecd8c0 --- /dev/null +++ b/arch/um/os-Linux/internal.h @@ -0,0 +1 @@ +void alarm_handler(int, mcontext_t *); diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c index 0348b975e81..9a49908b576 100644 --- a/arch/um/os-Linux/irq.c +++ b/arch/um/os-Linux/irq.c @@ -9,11 +9,8 @@ #include <signal.h> #include <string.h> #include "irq_user.h" -#include "kern_constants.h" #include "os.h" -#include "process.h" #include "um_malloc.h" -#include "user.h" /* * Locked by irq_lock in arch/um/kernel/irq.c. Changed by os_create_pollfd diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index fb2a97a75fb..7a86dd516eb 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -12,7 +12,6 @@ #include <sys/resource.h> #include "as-layout.h" #include "init.h" -#include "kern_constants.h" #include "kern_util.h" #include "os.h" #include "um_malloc.h" @@ -21,6 +20,8 @@ #define STACKSIZE (8 * 1024 * 1024) #define THREAD_NAME_LEN (256) +long elf_aux_hwcap; + static void set_stklim(void) { struct rlimit lim; @@ -143,7 +144,9 @@ int __init main(int argc, char **argv, char **envp) install_fatal_handler(SIGINT); install_fatal_handler(SIGTERM); +#ifdef CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA scan_elf_aux(envp); +#endif do_uml_initcalls(); ret = linux_main(argc, argv); diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index e696144d2be..8e421e1d6d3 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c @@ -14,9 +14,7 @@ #include <sys/mman.h> #include <sys/param.h> #include "init.h" -#include "kern_constants.h" #include "os.h" -#include "user.h" /* Modified by which_tmpdir, which is called during early boot */ static char *default_tmpdir = "/tmp"; @@ -176,7 +174,7 @@ static int __init make_tempfile(const char *template, char **out_tempname, find_tempdir(); if ((tempdir == NULL) || (strlen(tempdir) >= MAXPATHLEN)) - return -1; + goto out; if (template[0] != '/') strcpy(tempname, tempdir); @@ -191,13 +189,15 @@ static int __init make_tempfile(const char *template, char **out_tempname, } if (do_unlink && (unlink(tempname) < 0)) { perror("unlink"); - goto out; + goto close; } if (out_tempname) { *out_tempname = tempname; } else free(tempname); return fd; +close: + close(fd); out: free(tempname); return -1; diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 0c45dc8efb0..307f173e7f8 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -13,12 +13,9 @@ #include <sys/wait.h> #include <asm/unistd.h> #include "init.h" -#include "kern_constants.h" #include "longjmp.h" #include "os.h" -#include "process.h" #include "skas_ptrace.h" -#include "user.h" #define ARBITRARY_ADDR -1 #define FAILURE_PID -1 @@ -237,21 +234,13 @@ out: void init_new_thread_signals(void) { - set_handler(SIGSEGV, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); - set_handler(SIGTRAP, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); - set_handler(SIGFPE, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); - set_handler(SIGILL, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); - set_handler(SIGBUS, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); + set_handler(SIGSEGV); + set_handler(SIGTRAP); + set_handler(SIGFPE); + set_handler(SIGILL); + set_handler(SIGBUS); signal(SIGHUP, SIG_IGN); - - set_handler(SIGIO, (__sighandler_t) sig_handler, - SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, - SIGVTALRM, -1); + set_handler(SIGIO); signal(SIGWINCH, SIG_IGN); signal(SIGTERM, SIG_DFL); } diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c index 830fe6a1518..b866b9e3bef 100644 --- a/arch/um/os-Linux/registers.c +++ b/arch/um/os-Linux/registers.c @@ -8,6 +8,8 @@ #include <string.h> #include <sys/ptrace.h> #include "sysdep/ptrace.h" +#include "sysdep/ptrace_user.h" +#include "registers.h" int save_registers(int pid, struct uml_pt_regs *regs) { @@ -32,6 +34,7 @@ int restore_registers(int pid, struct uml_pt_regs *regs) /* This is set once at boot time and not changed thereafter */ static unsigned long exec_regs[MAX_REG_NR]; +static unsigned long exec_fp_regs[FP_SIZE]; int init_registers(int pid) { @@ -42,10 +45,14 @@ int init_registers(int pid) return -errno; arch_init_registers(pid); + get_fp_registers(pid, exec_fp_regs); return 0; } -void get_safe_registers(unsigned long *regs) +void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) { memcpy(regs, exec_regs, sizeof(exec_regs)); + + if (fp_regs) + memcpy(fp_regs, exec_fp_regs, sizeof(exec_fp_regs)); } diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 63d299df152..3c161218c67 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -11,14 +11,11 @@ #include <sched.h> #include <signal.h> #include <string.h> -#include "kern_constants.h" #include "kern_util.h" #include "init.h" #include "os.h" -#include "process.h" #include "sigio.h" #include "um_malloc.h" -#include "user.h" /* * Protected by sigio_lock(), also used by sigio_cleanup, which is an diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 6ae180703a6..2d22f1fcd8e 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -12,13 +12,7 @@ #include "as-layout.h" #include "kern_util.h" #include "os.h" -#include "process.h" -#include "sysdep/barrier.h" -#include "sysdep/sigcontext.h" -#include "user.h" - -/* Copied from linux/compiler-gcc.h since we can't include it directly */ -#define barrier() __asm__ __volatile__("": : :"memory") +#include "sysdep/mcontext.h" void (*sig_info[NSIG])(int, struct uml_pt_regs *) = { [SIGTRAP] = relay_signal, @@ -30,7 +24,7 @@ void (*sig_info[NSIG])(int, struct uml_pt_regs *) = { [SIGIO] = sigio_handler, [SIGVTALRM] = timer_handler }; -static void sig_handler_common(int sig, struct sigcontext *sc) +static void sig_handler_common(int sig, mcontext_t *mc) { struct uml_pt_regs r; int save_errno = errno; @@ -38,8 +32,8 @@ static void sig_handler_common(int sig, struct sigcontext *sc) r.is_user = 0; if (sig == SIGSEGV) { /* For segfaults, we want the data from the sigcontext. */ - copy_sc(&r, sc); - GET_FAULTINFO_FROM_SC(r.faultinfo, sc); + get_regs_from_mc(&r, mc); + GET_FAULTINFO_FROM_MC(r.faultinfo, mc); } /* enable signals if sig isn't IRQ signal */ @@ -66,7 +60,7 @@ static void sig_handler_common(int sig, struct sigcontext *sc) static int signals_enabled; static unsigned int signals_pending; -void sig_handler(int sig, struct sigcontext *sc) +void sig_handler(int sig, mcontext_t *mc) { int enabled; @@ -78,23 +72,23 @@ void sig_handler(int sig, struct sigcontext *sc) block_signals(); - sig_handler_common(sig, sc); + sig_handler_common(sig, mc); set_signals(enabled); } -static void real_alarm_handler(struct sigcontext *sc) +static void real_alarm_handler(mcontext_t *mc) { struct uml_pt_regs regs; - if (sc != NULL) - copy_sc(®s, sc); + if (mc != NULL) + get_regs_from_mc(®s, mc); regs.is_user = 0; unblock_signals(); timer_handler(SIGVTALRM, ®s); } -void alarm_handler(int sig, struct sigcontext *sc) +void alarm_handler(int sig, mcontext_t *mc) { int enabled; @@ -106,14 +100,13 @@ void alarm_handler(int sig, struct sigcontext *sc) block_signals(); - real_alarm_handler(sc); + real_alarm_handler(mc); set_signals(enabled); } void timer_init(void) { - set_handler(SIGVTALRM, (__sighandler_t) alarm_handler, - SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, -1); + set_handler(SIGVTALRM); } void set_sigstack(void *sig_stack, int size) @@ -126,10 +119,23 @@ void set_sigstack(void *sig_stack, int size) panic("enabling signal stack failed, errno = %d\n", errno); } -static void (*handlers[_NSIG])(int sig, struct sigcontext *sc); +static void (*handlers[_NSIG])(int sig, mcontext_t *mc) = { + [SIGSEGV] = sig_handler, + [SIGBUS] = sig_handler, + [SIGILL] = sig_handler, + [SIGFPE] = sig_handler, + [SIGTRAP] = sig_handler, + + [SIGIO] = sig_handler, + [SIGWINCH] = sig_handler, + [SIGVTALRM] = alarm_handler +}; + -void handle_signal(int sig, struct sigcontext *sc) +static void hard_handler(int sig, siginfo_t *info, void *p) { + struct ucontext *uc = p; + mcontext_t *mc = &uc->uc_mcontext; unsigned long pending = 1UL << sig; do { @@ -155,7 +161,7 @@ void handle_signal(int sig, struct sigcontext *sc) while ((sig = ffs(pending)) != 0){ sig--; pending &= ~(1 << sig); - (*handlers[sig])(sig, sc); + (*handlers[sig])(sig, mc); } /* @@ -169,28 +175,26 @@ void handle_signal(int sig, struct sigcontext *sc) } while (pending); } -extern void hard_handler(int sig); - -void set_handler(int sig, void (*handler)(int), int flags, ...) +void set_handler(int sig) { struct sigaction action; - va_list ap; + int flags = SA_SIGINFO | SA_ONSTACK; sigset_t sig_mask; - int mask; - handlers[sig] = (void (*)(int, struct sigcontext *)) handler; - action.sa_handler = hard_handler; + action.sa_sigaction = hard_handler; + /* block irq ones */ sigemptyset(&action.sa_mask); - - va_start(ap, flags); - while ((mask = va_arg(ap, int)) != -1) - sigaddset(&action.sa_mask, mask); - va_end(ap); + sigaddset(&action.sa_mask, SIGVTALRM); + sigaddset(&action.sa_mask, SIGIO); + sigaddset(&action.sa_mask, SIGWINCH); if (sig == SIGSEGV) flags |= SA_NODEFER; + if (sigismember(&action.sa_mask, sig)) + flags |= SA_RESTART; /* if it's an irq signal */ + action.sa_flags = flags; action.sa_restorer = NULL; if (sigaction(sig, &action, NULL) < 0) diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index d261f170d12..c0afff7af4b 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -9,7 +9,6 @@ #include <string.h> #include <sys/mman.h> #include "init.h" -#include "kern_constants.h" #include "as-layout.h" #include "mm_id.h" #include "os.h" @@ -17,7 +16,6 @@ #include "ptrace_user.h" #include "registers.h" #include "skas.h" -#include "user.h" #include "sysdep/ptrace.h" #include "sysdep/stub.h" @@ -39,7 +37,7 @@ static unsigned long syscall_regs[MAX_REG_NR]; static int __init init_syscall_regs(void) { - get_safe_registers(syscall_regs); + get_safe_registers(syscall_regs, NULL); syscall_regs[REGS_IP_INDEX] = STUB_CODE + ((unsigned long) &batch_syscall_stub - (unsigned long) &__syscall_stub_start); diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index d6e0a2234b8..cd65727854e 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -9,31 +9,23 @@ #include <errno.h> #include <string.h> #include <sys/mman.h> -#include <sys/ptrace.h> #include <sys/wait.h> #include <asm/unistd.h> #include "as-layout.h" -#include "chan_user.h" -#include "kern_constants.h" +#include "init.h" #include "kern_util.h" #include "mem.h" #include "os.h" -#include "process.h" #include "proc_mm.h" #include "ptrace_user.h" #include "registers.h" #include "skas.h" #include "skas_ptrace.h" -#include "user.h" #include "sysdep/stub.h" int is_skas_winch(int pid, int fd, void *data) { - if (pid != getpgrp()) - return 0; - - register_winch_irq(-1, fd, -1, data, 0); - return 1; + return pid == getpgrp(); } static int ptrace_dump_regs(int pid) @@ -169,7 +161,7 @@ static void handle_trap(int pid, struct uml_pt_regs *regs, if (!local_using_sysemu) { - err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, + err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid); if (err < 0) { printk(UM_KERN_ERR "handle_trap - nullifying syscall " @@ -257,8 +249,8 @@ static int userspace_tramp(void *stack) set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE); sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_ONSTACK | SA_NODEFER; - sa.sa_handler = (void *) v; + sa.sa_flags = SA_ONSTACK | SA_NODEFER | SA_SIGINFO; + sa.sa_sigaction = (void *) v; sa.sa_restorer = NULL; if (sigaction(SIGSEGV, &sa, NULL) < 0) { printk(UM_KERN_ERR "userspace_tramp - setting SIGSEGV " @@ -373,6 +365,9 @@ void userspace(struct uml_pt_regs *regs) if (ptrace(PTRACE_SETREGS, pid, 0, regs->gp)) fatal_sigsegv(); + if (put_fp_registers(pid, regs->fp)) + fatal_sigsegv(); + /* Now we set local_using_sysemu to be used for one loop */ local_using_sysemu = get_using_sysemu(); @@ -399,6 +394,12 @@ void userspace(struct uml_pt_regs *regs) fatal_sigsegv(); } + if (get_fp_registers(pid, regs->fp)) { + printk(UM_KERN_ERR "userspace - get_fp_registers failed, " + "errno = %d\n", errno); + fatal_sigsegv(); + } + UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ if (WIFSTOPPED(status)) { @@ -457,10 +458,11 @@ void userspace(struct uml_pt_regs *regs) } static unsigned long thread_regs[MAX_REG_NR]; +static unsigned long thread_fp_regs[FP_SIZE]; static int __init init_thread_regs(void) { - get_safe_registers(thread_regs); + get_safe_registers(thread_regs, thread_fp_regs); /* Set parent's instruction pointer to start of clone-stub */ thread_regs[REGS_IP_INDEX] = STUB_CODE + (unsigned long) stub_clone_handler - @@ -503,6 +505,13 @@ int copy_context_skas0(unsigned long new_stack, int pid) return err; } + err = put_fp_registers(pid, thread_fp_regs); + if (err < 0) { + printk(UM_KERN_ERR "copy_context_skas0 : put_fp_registers " + "failed, pid = %d, err = %d\n", pid, err); + return err; + } + /* set a well known return code for detection of child write failure */ child_data->err = 12345678; @@ -644,8 +653,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) { int n; - set_handler(SIGWINCH, (__sighandler_t) sig_handler, - SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGVTALRM, -1); + set_handler(SIGWINCH); /* * Can't use UML_SETJMP or UML_LONGJMP here because they save diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 02ee9adff54..425162e22af 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -13,12 +13,10 @@ #include <signal.h> #include <string.h> #include <sys/mman.h> -#include <sys/ptrace.h> #include <sys/stat.h> #include <sys/wait.h> #include <asm/unistd.h> #include "init.h" -#include "kern_constants.h" #include "os.h" #include "mem_user.h" #include "ptrace_user.h" @@ -225,7 +223,7 @@ static void __init check_sysemu(void) goto fail; } - n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); + n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); if (n < 0) { non_fatal("check_sysemu : failed to modify system call " "return"); @@ -261,7 +259,7 @@ static void __init check_sysemu(void) "doesn't singlestep"); goto fail; } - n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, + n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); if (n < 0) fatal_perror("check_sysemu : failed to modify " @@ -317,10 +315,10 @@ static void __init check_ptrace(void) fatal("check_ptrace : expected (SIGTRAP|0x80), " "got status = %d", status); - syscall = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET, + syscall = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET, 0); if (syscall == __NR_getpid) { - n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, + n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getppid); if (n < 0) fatal_perror("check_ptrace : failed to modify " diff --git a/arch/um/os-Linux/sys-i386/Makefile b/arch/um/os-Linux/sys-i386/Makefile deleted file mode 100644 index b4bc6ac4f30..00000000000 --- a/arch/um/os-Linux/sys-i386/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) -# Licensed under the GPL -# - -obj-y = registers.o signal.o task_size.o tls.o - -USER_OBJS := $(obj-y) - -include arch/um/scripts/Makefile.rules diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c deleted file mode 100644 index 229f7a53d8d..00000000000 --- a/arch/um/os-Linux/sys-i386/registers.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2004 PathScale, Inc - * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include <errno.h> -#include <sys/ptrace.h> -#include <sys/user.h> -#include "kern_constants.h" -#include "longjmp.h" -#include "user.h" -#include "sysdep/ptrace_user.h" - -int save_fp_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -int restore_fp_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -int save_fpx_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_GETFPXREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -int restore_fpx_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_SETFPXREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -unsigned long get_thread_reg(int reg, jmp_buf *buf) -{ - switch (reg) { - case EIP: - return buf[0]->__eip; - case UESP: - return buf[0]->__esp; - case EBP: - return buf[0]->__ebp; - default: - printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n", - reg); - return 0; - } -} - -int have_fpx_regs = 1; - -int get_fp_registers(int pid, unsigned long *regs) -{ - if (have_fpx_regs) - return save_fpx_registers(pid, regs); - else - return save_fp_registers(pid, regs); -} - -int put_fp_registers(int pid, unsigned long *regs) -{ - if (have_fpx_regs) - return restore_fpx_registers(pid, regs); - else - return restore_fp_registers(pid, regs); -} - -void arch_init_registers(int pid) -{ - struct user_fpxregs_struct fpx_regs; - int err; - - err = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpx_regs); - if (!err) - return; - - if (errno != EIO) - panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", - errno); - - have_fpx_regs = 0; -} diff --git a/arch/um/os-Linux/sys-i386/signal.c b/arch/um/os-Linux/sys-i386/signal.c deleted file mode 100644 index f311609f93d..00000000000 --- a/arch/um/os-Linux/sys-i386/signal.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (C) 2006 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include <signal.h> - -extern void handle_signal(int sig, struct sigcontext *sc); - -void hard_handler(int sig) -{ - handle_signal(sig, (struct sigcontext *) (&sig + 1)); -} diff --git a/arch/um/os-Linux/sys-i386/task_size.c b/arch/um/os-Linux/sys-i386/task_size.c deleted file mode 100644 index be04c1e183b..00000000000 --- a/arch/um/os-Linux/sys-i386/task_size.c +++ /dev/null @@ -1,139 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <sys/mman.h> -#include "longjmp.h" -#include "kern_constants.h" - -static jmp_buf buf; - -static void segfault(int sig) -{ - longjmp(buf, 1); -} - -static int page_ok(unsigned long page) -{ - unsigned long *address = (unsigned long *) (page << UM_KERN_PAGE_SHIFT); - unsigned long n = ~0UL; - void *mapped = NULL; - int ok = 0; - - /* - * First see if the page is readable. If it is, it may still - * be a VDSO, so we go on to see if it's writable. If not - * then try mapping memory there. If that fails, then we're - * still in the kernel area. As a sanity check, we'll fail if - * the mmap succeeds, but gives us an address different from - * what we wanted. - */ - if (setjmp(buf) == 0) - n = *address; - else { - mapped = mmap(address, UM_KERN_PAGE_SIZE, - PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (mapped == MAP_FAILED) - return 0; - if (mapped != address) - goto out; - } - - /* - * Now, is it writeable? If so, then we're in user address - * space. If not, then try mprotecting it and try the write - * again. - */ - if (setjmp(buf) == 0) { - *address = n; - ok = 1; - goto out; - } else if (mprotect(address, UM_KERN_PAGE_SIZE, - PROT_READ | PROT_WRITE) != 0) - goto out; - - if (setjmp(buf) == 0) { - *address = n; - ok = 1; - } - - out: - if (mapped != NULL) - munmap(mapped, UM_KERN_PAGE_SIZE); - return ok; -} - -unsigned long os_get_top_address(void) -{ - struct sigaction sa, old; - unsigned long bottom = 0; - /* - * A 32-bit UML on a 64-bit host gets confused about the VDSO at - * 0xffffe000. It is mapped, is readable, can be reprotected writeable - * and written. However, exec discovers later that it can't be - * unmapped. So, just set the highest address to be checked to just - * below it. This might waste some address space on 4G/4G 32-bit - * hosts, but shouldn't hurt otherwise. - */ - unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT; - unsigned long test, original; - - printf("Locating the bottom of the address space ... "); - fflush(stdout); - - /* - * We're going to be longjmping out of the signal handler, so - * SA_DEFER needs to be set. - */ - sa.sa_handler = segfault; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_NODEFER; - if (sigaction(SIGSEGV, &sa, &old)) { - perror("os_get_top_address"); - exit(1); - } - - /* Manually scan the address space, bottom-up, until we find - * the first valid page (or run out of them). - */ - for (bottom = 0; bottom < top; bottom++) { - if (page_ok(bottom)) - break; - } - - /* If we've got this far, we ran out of pages. */ - if (bottom == top) { - fprintf(stderr, "Unable to determine bottom of address " - "space.\n"); - exit(1); - } - - printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT); - printf("Locating the top of the address space ... "); - fflush(stdout); - - original = bottom; - - /* This could happen with a 4G/4G split */ - if (page_ok(top)) - goto out; - - do { - test = bottom + (top - bottom) / 2; - if (page_ok(test)) - bottom = test; - else - top = test; - } while (top - bottom > 1); - -out: - /* Restore the old SIGSEGV handling */ - if (sigaction(SIGSEGV, &old, NULL)) { - perror("os_get_top_address"); - exit(1); - } - top <<= UM_KERN_PAGE_SHIFT; - printf("0x%x\n", top); - - return top; -} diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c deleted file mode 100644 index 32ed41ec1a3..00000000000 --- a/arch/um/os-Linux/sys-i386/tls.c +++ /dev/null @@ -1,36 +0,0 @@ -#include <errno.h> -#include <linux/unistd.h> - -#include <sys/syscall.h> -#include <unistd.h> - -#include "sysdep/tls.h" -#include "user.h" - -/* Checks whether host supports TLS, and sets *tls_min according to the value - * valid on the host. - * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */ -void check_host_supports_tls(int *supports_tls, int *tls_min) { - /* Values for x86 and x86_64.*/ - int val[] = {GDT_ENTRY_TLS_MIN_I386, GDT_ENTRY_TLS_MIN_X86_64}; - int i; - - for (i = 0; i < ARRAY_SIZE(val); i++) { - user_desc_t info; - info.entry_number = val[i]; - - if (syscall(__NR_get_thread_area, &info) == 0) { - *tls_min = val[i]; - *supports_tls = 1; - return; - } else { - if (errno == EINVAL) - continue; - else if (errno == ENOSYS) - *supports_tls = 0; - return; - } - } - - *supports_tls = 0; -} diff --git a/arch/um/os-Linux/sys-x86_64/Makefile b/arch/um/os-Linux/sys-x86_64/Makefile deleted file mode 100644 index a44a47f8f57..00000000000 --- a/arch/um/os-Linux/sys-x86_64/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) -# Licensed under the GPL -# - -obj-y = registers.o prctl.o signal.o task_size.o - -USER_OBJS := $(obj-y) - -include arch/um/scripts/Makefile.rules diff --git a/arch/um/os-Linux/sys-x86_64/prctl.c b/arch/um/os-Linux/sys-x86_64/prctl.c deleted file mode 100644 index 9d34eddb517..00000000000 --- a/arch/um/os-Linux/sys-x86_64/prctl.c +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (C) 2007 Jeff Dike (jdike@{addtoit.com,linux.intel.com}) - * Licensed under the GPL - */ - -#include <sys/ptrace.h> -#include <linux/ptrace.h> - -int os_arch_prctl(int pid, int code, unsigned long *addr) -{ - return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) addr, code); -} diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c deleted file mode 100644 index 594d97ad02b..00000000000 --- a/arch/um/os-Linux/sys-x86_64/registers.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2006 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include <errno.h> -#include <sys/ptrace.h> -#define __FRAME_OFFSETS -#include <asm/ptrace.h> -#include "kern_constants.h" -#include "longjmp.h" -#include "user.h" - -int save_fp_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -int restore_fp_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -unsigned long get_thread_reg(int reg, jmp_buf *buf) -{ - switch (reg) { - case RIP: - return buf[0]->__rip; - case RSP: - return buf[0]->__rsp; - case RBP: - return buf[0]->__rbp; - default: - printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n", - reg); - return 0; - } -} - -int get_fp_registers(int pid, unsigned long *regs) -{ - return save_fp_registers(pid, regs); -} - -int put_fp_registers(int pid, unsigned long *regs) -{ - return restore_fp_registers(pid, regs); -} diff --git a/arch/um/os-Linux/sys-x86_64/signal.c b/arch/um/os-Linux/sys-x86_64/signal.c deleted file mode 100644 index 82a388822cd..00000000000 --- a/arch/um/os-Linux/sys-x86_64/signal.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 2006 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include <signal.h> - -extern void handle_signal(int sig, struct sigcontext *sc); - -void hard_handler(int sig) -{ - struct ucontext *uc; - asm("movq %%rdx, %0" : "=r" (uc)); - - handle_signal(sig, (struct sigcontext *) &uc->uc_mcontext); -} diff --git a/arch/um/os-Linux/sys-x86_64/task_size.c b/arch/um/os-Linux/sys-x86_64/task_size.c deleted file mode 100644 index 26a0dd1f349..00000000000 --- a/arch/um/os-Linux/sys-x86_64/task_size.c +++ /dev/null @@ -1,5 +0,0 @@ -unsigned long os_get_top_address(unsigned long shift) -{ - /* The old value of CONFIG_TOP_ADDR */ - return 0x7fc0000000; -} diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 6e3359d6a83..910499d76a6 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -8,11 +8,9 @@ #include <signal.h> #include <time.h> #include <sys/time.h> -#include "kern_constants.h" #include "kern_util.h" #include "os.h" -#include "process.h" -#include "user.h" +#include "internal.h" int set_interval(void) { diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c deleted file mode 100644 index 73277801ef1..00000000000 --- a/arch/um/os-Linux/tls.c +++ /dev/null @@ -1,35 +0,0 @@ -#include <errno.h> -#include <sys/ptrace.h> -#include "sysdep/tls.h" - -/* TLS support - we basically rely on the host's one.*/ - -#ifndef PTRACE_GET_THREAD_AREA -#define PTRACE_GET_THREAD_AREA 25 -#endif - -#ifndef PTRACE_SET_THREAD_AREA -#define PTRACE_SET_THREAD_AREA 26 -#endif - -int os_set_thread_area(user_desc_t *info, int pid) -{ - int ret; - - ret = ptrace(PTRACE_SET_THREAD_AREA, pid, info->entry_number, - (unsigned long) info); - if (ret < 0) - ret = -errno; - return ret; -} - -int os_get_thread_area(user_desc_t *info, int pid) -{ - int ret; - - ret = ptrace(PTRACE_GET_THREAD_AREA, pid, info->entry_number, - (unsigned long) info); - if (ret < 0) - ret = -errno; - return ret; -} diff --git a/arch/um/os-Linux/tty.c b/arch/um/os-Linux/tty.c index b09ff66a77e..dd12b99dcb5 100644 --- a/arch/um/os-Linux/tty.c +++ b/arch/um/os-Linux/tty.c @@ -7,10 +7,8 @@ #include <unistd.h> #include <errno.h> #include <fcntl.h> -#include "kern_constants.h" #include "kern_util.h" #include "os.h" -#include "user.h" struct grantpt_info { int fd; diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c deleted file mode 100644 index 087ed74ffca..00000000000 --- a/arch/um/os-Linux/uaccess.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk) - * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include <stddef.h> -#include "longjmp.h" - -unsigned long __do_user_copy(void *to, const void *from, int n, - void **fault_addr, jmp_buf **fault_catcher, - void (*op)(void *to, const void *from, - int n), int *faulted_out) -{ - unsigned long *faddrp = (unsigned long *) fault_addr, ret; - - jmp_buf jbuf; - *fault_catcher = &jbuf; - if (UML_SETJMP(&jbuf) == 0) { - (*op)(to, from, n); - ret = 0; - *faulted_out = 0; - } - else { - ret = *faddrp; - *faulted_out = 1; - } - *fault_addr = NULL; - *fault_catcher = NULL; - return ret; -} - diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c index a27defb8188..4832eb519f8 100644 --- a/arch/um/os-Linux/umid.c +++ b/arch/um/os-Linux/umid.c @@ -13,9 +13,7 @@ #include <unistd.h> #include <sys/stat.h> #include "init.h" -#include "kern_constants.h" #include "os.h" -#include "user.h" #define UML_DIR "~/.uml/" diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c index 05f5ea8e83d..45ffe46871e 100644 --- a/arch/um/os-Linux/user_syms.c +++ b/arch/um/os-Linux/user_syms.c @@ -113,3 +113,8 @@ EXPORT_SYMBOL(__stack_smash_handler); extern long __guard __attribute__((weak)); EXPORT_SYMBOL(__guard); + +#ifdef _FORTIFY_SOURCE +extern int __sprintf_chk(char *str, int flag, size_t strlen, const char *format); +EXPORT_SYMBOL(__sprintf_chk); +#endif diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 5803b188767..9e3b43bb84c 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -13,9 +13,7 @@ #include <wait.h> #include <sys/mman.h> #include <sys/utsname.h> -#include "kern_constants.h" #include "os.h" -#include "user.h" void stack_protections(unsigned long address) { diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index 61107b68e05..2eb2843b063 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules @@ -8,7 +8,7 @@ USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) $(USER_OBJS:.o=.%): \ - c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(basetarget).o) + c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) -include user.h $(CFLAGS_$(basetarget).o) $(USER_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ -Dunix -D__unix__ -D__$(SUBARCH)__ $(CF) @@ -25,8 +25,3 @@ $(UNPROFILE_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ define unprofile $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1))) endef - -ifdef subarch-obj-y -obj-y += subarch.o -subarch-y = $(addprefix ../../$(HEADER_ARCH)/,$(subarch-obj-y)) -endif diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile deleted file mode 100644 index b1da91c1b20..00000000000 --- a/arch/um/sys-i386/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) -# - -obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ - ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \ - sys_call_table.o tls.o atomic64_cx8_32.o - -obj-$(CONFIG_BINFMT_ELF) += elfcore.o - -subarch-obj-y = lib/semaphore_32.o lib/string_32.o -subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o -subarch-obj-$(CONFIG_MODULES) += kernel/module.o - -USER_OBJS := bugs.o ptrace_user.o fault.o - -USER_OBJS += user-offsets.s -extra-y += user-offsets.s - -UNPROFILE_OBJS := stub_segv.o -CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) - -include arch/um/scripts/Makefile.rules diff --git a/arch/um/sys-i386/asm/archparam.h b/arch/um/sys-i386/asm/archparam.h deleted file mode 100644 index 2a18a884ca1..00000000000 --- a/arch/um/sys-i386/asm/archparam.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#ifndef __UM_ARCHPARAM_I386_H -#define __UM_ARCHPARAM_I386_H - -#ifdef CONFIG_X86_PAE -#define LAST_PKMAP 512 -#else -#define LAST_PKMAP 1024 -#endif - -#endif - diff --git a/arch/um/sys-i386/asm/elf.h b/arch/um/sys-i386/asm/elf.h deleted file mode 100644 index d964a4111ac..00000000000 --- a/arch/um/sys-i386/asm/elf.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ -#ifndef __UM_ELF_I386_H -#define __UM_ELF_I386_H - -#include <asm/user.h> -#include "skas.h" - -#define R_386_NONE 0 -#define R_386_32 1 -#define R_386_PC32 2 -#define R_386_GOT32 3 -#define R_386_PLT32 4 -#define R_386_COPY 5 -#define R_386_GLOB_DAT 6 -#define R_386_JMP_SLOT 7 -#define R_386_RELATIVE 8 -#define R_386_GOTOFF 9 -#define R_386_GOTPC 10 -#define R_386_NUM 11 - -typedef unsigned long elf_greg_t; - -#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -typedef struct user_i387_struct elf_fpregset_t; - -/* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(x) \ - (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486)) - -#define ELF_CLASS ELFCLASS32 -#define ELF_DATA ELFDATA2LSB -#define ELF_ARCH EM_386 - -#define ELF_PLAT_INIT(regs, load_addr) do { \ - PT_REGS_EBX(regs) = 0; \ - PT_REGS_ECX(regs) = 0; \ - PT_REGS_EDX(regs) = 0; \ - PT_REGS_ESI(regs) = 0; \ - PT_REGS_EDI(regs) = 0; \ - PT_REGS_EBP(regs) = 0; \ - PT_REGS_EAX(regs) = 0; \ -} while (0) - -#define ELF_EXEC_PAGESIZE 4096 - -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) - -/* Shamelessly stolen from include/asm-i386/elf.h */ - -#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ - pr_reg[0] = PT_REGS_EBX(regs); \ - pr_reg[1] = PT_REGS_ECX(regs); \ - pr_reg[2] = PT_REGS_EDX(regs); \ - pr_reg[3] = PT_REGS_ESI(regs); \ - pr_reg[4] = PT_REGS_EDI(regs); \ - pr_reg[5] = PT_REGS_EBP(regs); \ - pr_reg[6] = PT_REGS_EAX(regs); \ - pr_reg[7] = PT_REGS_DS(regs); \ - pr_reg[8] = PT_REGS_ES(regs); \ - /* fake once used fs and gs selectors? */ \ - pr_reg[9] = PT_REGS_DS(regs); \ - pr_reg[10] = PT_REGS_DS(regs); \ - pr_reg[11] = PT_REGS_SYSCALL_NR(regs); \ - pr_reg[12] = PT_REGS_IP(regs); \ - pr_reg[13] = PT_REGS_CS(regs); \ - pr_reg[14] = PT_REGS_EFLAGS(regs); \ - pr_reg[15] = PT_REGS_SP(regs); \ - pr_reg[16] = PT_REGS_SS(regs); \ -} while (0); - -#define task_pt_regs(t) (&(t)->thread.regs) - -struct task_struct; - -extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu); - -#define ELF_CORE_COPY_FPREGS(t, fpu) elf_core_copy_fpregs(t, fpu) - -extern long elf_aux_hwcap; -#define ELF_HWCAP (elf_aux_hwcap) - -extern char * elf_aux_platform; -#define ELF_PLATFORM (elf_aux_platform) - -#define SET_PERSONALITY(ex) do { } while (0) - -extern unsigned long vsyscall_ehdr; -extern unsigned long vsyscall_end; -extern unsigned long __kernel_vsyscall; - -#define VSYSCALL_BASE vsyscall_ehdr -#define VSYSCALL_END vsyscall_end - -/* - * This is the range that is readable by user mode, and things - * acting like user mode such as get_user_pages. - */ -#define FIXADDR_USER_START VSYSCALL_BASE -#define FIXADDR_USER_END VSYSCALL_END - -/* - * Architecture-neutral AT_ values in 0-17, leave some room - * for more of them, start the x86-specific ones at 32. - */ -#define AT_SYSINFO 32 -#define AT_SYSINFO_EHDR 33 - -#define ARCH_DLINFO \ -do { \ - if ( vsyscall_ehdr ) { \ - NEW_AUX_ENT(AT_SYSINFO, __kernel_vsyscall); \ - NEW_AUX_ENT(AT_SYSINFO_EHDR, vsyscall_ehdr); \ - } \ -} while (0) - -#endif diff --git a/arch/um/sys-i386/asm/module.h b/arch/um/sys-i386/asm/module.h deleted file mode 100644 index 5ead4a0b2e3..00000000000 --- a/arch/um/sys-i386/asm/module.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __UM_MODULE_I386_H -#define __UM_MODULE_I386_H - -/* UML is simple */ -struct mod_arch_specific -{ -}; - -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr - -#endif diff --git a/arch/um/sys-i386/asm/processor.h b/arch/um/sys-i386/asm/processor.h deleted file mode 100644 index 82a9061ab5b..00000000000 --- a/arch/um/sys-i386/asm/processor.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __UM_PROCESSOR_I386_H -#define __UM_PROCESSOR_I386_H - -#include "linux/string.h" -#include <sysdep/host_ldt.h> -#include "asm/segment.h" - -extern int host_has_cmov; - -/* include faultinfo structure */ -#include "sysdep/faultinfo.h" - -struct uml_tls_struct { - struct user_desc tls; - unsigned flushed:1; - unsigned present:1; -}; - -struct arch_thread { - struct uml_tls_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; - unsigned long debugregs[8]; - int debugregs_seq; - struct faultinfo faultinfo; -}; - -#define INIT_ARCH_THREAD { \ - .tls_array = { [ 0 ... GDT_ENTRY_TLS_ENTRIES - 1 ] = \ - { .present = 0, .flushed = 0 } }, \ - .debugregs = { [ 0 ... 7 ] = 0 }, \ - .debugregs_seq = 0, \ - .faultinfo = { 0, 0, 0 } \ -} - -static inline void arch_flush_thread(struct arch_thread *thread) -{ - /* Clear any TLS still hanging */ - memset(&thread->tls_array, 0, sizeof(thread->tls_array)); -} - -static inline void arch_copy_thread(struct arch_thread *from, - struct arch_thread *to) -{ - memcpy(&to->tls_array, &from->tls_array, sizeof(from->tls_array)); -} - -#include <asm/user.h> - -/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ -static inline void rep_nop(void) -{ - __asm__ __volatile__("rep;nop": : :"memory"); -} - -#define cpu_relax() rep_nop() - -/* - * Default implementation of macro that returns current - * instruction pointer ("program counter"). Stolen - * from asm-i386/processor.h - */ -#define current_text_addr() \ - ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; }) - -#define ARCH_IS_STACKGROW(address) \ - (address + 32 >= UPT_SP(¤t->thread.regs.regs)) - -#define KSTK_EIP(tsk) KSTK_REG(tsk, EIP) -#define KSTK_ESP(tsk) KSTK_REG(tsk, UESP) -#define KSTK_EBP(tsk) KSTK_REG(tsk, EBP) - -#include "asm/processor-generic.h" - -#endif diff --git a/arch/um/sys-i386/asm/ptrace.h b/arch/um/sys-i386/asm/ptrace.h deleted file mode 100644 index 0273e4d09af..00000000000 --- a/arch/um/sys-i386/asm/ptrace.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __UM_PTRACE_I386_H -#define __UM_PTRACE_I386_H - -#define HOST_AUDIT_ARCH AUDIT_ARCH_I386 - -#include "linux/compiler.h" -#include "asm/ptrace-generic.h" - -#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs) -#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs) -#define PT_REGS_ECX(r) UPT_ECX(&(r)->regs) -#define PT_REGS_EDX(r) UPT_EDX(&(r)->regs) -#define PT_REGS_ESI(r) UPT_ESI(&(r)->regs) -#define PT_REGS_EDI(r) UPT_EDI(&(r)->regs) -#define PT_REGS_EBP(r) UPT_EBP(&(r)->regs) - -#define PT_REGS_CS(r) UPT_CS(&(r)->regs) -#define PT_REGS_SS(r) UPT_SS(&(r)->regs) -#define PT_REGS_DS(r) UPT_DS(&(r)->regs) -#define PT_REGS_ES(r) UPT_ES(&(r)->regs) -#define PT_REGS_FS(r) UPT_FS(&(r)->regs) -#define PT_REGS_GS(r) UPT_GS(&(r)->regs) - -#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs) - -#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_EAX(r) -#define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r) -#define PT_FIX_EXEC_STACK(sp) do ; while(0) - -#define profile_pc(regs) PT_REGS_IP(regs) - -#define user_mode(r) UPT_IS_USER(&(r)->regs) - -/* - * Forward declaration to avoid including sysdep/tls.h, which causes a - * circular include, and compilation failures. - */ -struct user_desc; - -extern int get_fpxregs(struct user_fxsr_struct __user *buf, - struct task_struct *child); -extern int set_fpxregs(struct user_fxsr_struct __user *buf, - struct task_struct *tsk); - -extern int ptrace_get_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc); - -extern int ptrace_set_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc); - -#endif diff --git a/arch/um/sys-i386/atomic64_cx8_32.S b/arch/um/sys-i386/atomic64_cx8_32.S deleted file mode 100644 index 1e901d3d4a9..00000000000 --- a/arch/um/sys-i386/atomic64_cx8_32.S +++ /dev/null @@ -1,225 +0,0 @@ -/* - * atomic64_t for 586+ - * - * Copied from arch/x86/lib/atomic64_cx8_32.S - * - * Copyright © 2010 Luca Barbieri - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ - -#include <linux/linkage.h> -#include <asm/alternative-asm.h> -#include <asm/dwarf2.h> - -.macro SAVE reg - pushl_cfi %\reg - CFI_REL_OFFSET \reg, 0 -.endm - -.macro RESTORE reg - popl_cfi %\reg - CFI_RESTORE \reg -.endm - -.macro read64 reg - movl %ebx, %eax - movl %ecx, %edx -/* we need LOCK_PREFIX since otherwise cmpxchg8b always does the write */ - LOCK_PREFIX - cmpxchg8b (\reg) -.endm - -ENTRY(atomic64_read_cx8) - CFI_STARTPROC - - read64 %ecx - ret - CFI_ENDPROC -ENDPROC(atomic64_read_cx8) - -ENTRY(atomic64_set_cx8) - CFI_STARTPROC - -1: -/* we don't need LOCK_PREFIX since aligned 64-bit writes - * are atomic on 586 and newer */ - cmpxchg8b (%esi) - jne 1b - - ret - CFI_ENDPROC -ENDPROC(atomic64_set_cx8) - -ENTRY(atomic64_xchg_cx8) - CFI_STARTPROC - - movl %ebx, %eax - movl %ecx, %edx -1: - LOCK_PREFIX - cmpxchg8b (%esi) - jne 1b - - ret - CFI_ENDPROC -ENDPROC(atomic64_xchg_cx8) - -.macro addsub_return func ins insc -ENTRY(atomic64_\func\()_return_cx8) - CFI_STARTPROC - SAVE ebp - SAVE ebx - SAVE esi - SAVE edi - - movl %eax, %esi - movl %edx, %edi - movl %ecx, %ebp - - read64 %ebp -1: - movl %eax, %ebx - movl %edx, %ecx - \ins\()l %esi, %ebx - \insc\()l %edi, %ecx - LOCK_PREFIX - cmpxchg8b (%ebp) - jne 1b - -10: - movl %ebx, %eax - movl %ecx, %edx - RESTORE edi - RESTORE esi - RESTORE ebx - RESTORE ebp - ret - CFI_ENDPROC -ENDPROC(atomic64_\func\()_return_cx8) -.endm - -addsub_return add add adc -addsub_return sub sub sbb - -.macro incdec_return func ins insc -ENTRY(atomic64_\func\()_return_cx8) - CFI_STARTPROC - SAVE ebx - - read64 %esi -1: - movl %eax, %ebx - movl %edx, %ecx - \ins\()l $1, %ebx - \insc\()l $0, %ecx - LOCK_PREFIX - cmpxchg8b (%esi) - jne 1b - -10: - movl %ebx, %eax - movl %ecx, %edx - RESTORE ebx - ret - CFI_ENDPROC -ENDPROC(atomic64_\func\()_return_cx8) -.endm - -incdec_return inc add adc -incdec_return dec sub sbb - -ENTRY(atomic64_dec_if_positive_cx8) - CFI_STARTPROC - SAVE ebx - - read64 %esi -1: - movl %eax, %ebx - movl %edx, %ecx - subl $1, %ebx - sbb $0, %ecx - js 2f - LOCK_PREFIX - cmpxchg8b (%esi) - jne 1b - -2: - movl %ebx, %eax - movl %ecx, %edx - RESTORE ebx - ret - CFI_ENDPROC -ENDPROC(atomic64_dec_if_positive_cx8) - -ENTRY(atomic64_add_unless_cx8) - CFI_STARTPROC - SAVE ebp - SAVE ebx -/* these just push these two parameters on the stack */ - SAVE edi - SAVE esi - - movl %ecx, %ebp - movl %eax, %esi - movl %edx, %edi - - read64 %ebp -1: - cmpl %eax, 0(%esp) - je 4f -2: - movl %eax, %ebx - movl %edx, %ecx - addl %esi, %ebx - adcl %edi, %ecx - LOCK_PREFIX - cmpxchg8b (%ebp) - jne 1b - - movl $1, %eax -3: - addl $8, %esp - CFI_ADJUST_CFA_OFFSET -8 - RESTORE ebx - RESTORE ebp - ret -4: - cmpl %edx, 4(%esp) - jne 2b - xorl %eax, %eax - jmp 3b - CFI_ENDPROC -ENDPROC(atomic64_add_unless_cx8) - -ENTRY(atomic64_inc_not_zero_cx8) - CFI_STARTPROC - SAVE ebx - - read64 %esi -1: - testl %eax, %eax - je 4f -2: - movl %eax, %ebx - movl %edx, %ecx - addl $1, %ebx - adcl $0, %ecx - LOCK_PREFIX - cmpxchg8b (%esi) - jne 1b - - movl $1, %eax -3: - RESTORE ebx - ret -4: - testl %edx, %edx - jne 2b - jmp 3b - CFI_ENDPROC -ENDPROC(atomic64_inc_not_zero_cx8) diff --git a/arch/um/sys-i386/bug.c b/arch/um/sys-i386/bug.c deleted file mode 100644 index 8d4f273f121..00000000000 --- a/arch/um/sys-i386/bug.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL V2 - */ - -#include <linux/uaccess.h> -#include <asm/errno.h> - -/* Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because - * that's not relevant in skas mode. - */ - -int is_valid_bugaddr(unsigned long eip) -{ - unsigned short ud2; - - if (probe_kernel_address((unsigned short __user *)eip, ud2)) - return 0; - - return ud2 == 0x0b0f; -} diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c deleted file mode 100644 index 2c6d0d731c1..00000000000 --- a/arch/um/sys-i386/bugs.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include <signal.h> -#include "kern_constants.h" -#include "kern_util.h" -#include "longjmp.h" -#include "task.h" -#include "user.h" -#include "sysdep/ptrace.h" - -/* Set during early boot */ -static int host_has_cmov = 1; -static jmp_buf cmov_test_return; - -static void cmov_sigill_test_handler(int sig) -{ - host_has_cmov = 0; - longjmp(cmov_test_return, 1); -} - -void arch_check_bugs(void) -{ - struct sigaction old, new; - - printk(UM_KERN_INFO "Checking for host processor cmov support..."); - new.sa_handler = cmov_sigill_test_handler; - - /* Make sure that SIGILL is enabled after the handler longjmps back */ - new.sa_flags = SA_NODEFER; - sigemptyset(&new.sa_mask); - sigaction(SIGILL, &new, &old); - - if (setjmp(cmov_test_return) == 0) { - unsigned long foo = 0; - __asm__ __volatile__("cmovz %0, %1" : "=r" (foo) : "0" (foo)); - printk(UM_KERN_CONT "Yes\n"); - } else - printk(UM_KERN_CONT "No\n"); - - sigaction(SIGILL, &old, &new); -} - -void arch_examine_signal(int sig, struct uml_pt_regs *regs) -{ - unsigned char tmp[2]; - - /* - * This is testing for a cmov (0x0f 0x4x) instruction causing a - * SIGILL in init. - */ - if ((sig != SIGILL) || (TASK_PID(get_current()) != 1)) - return; - - if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) { - printk(UM_KERN_ERR "SIGILL in init, could not read " - "instructions!\n"); - return; - } - - if ((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40)) - return; - - if (host_has_cmov == 0) - printk(UM_KERN_ERR "SIGILL caused by cmov, which this " - "processor doesn't implement. Boot a filesystem " - "compiled for older processors"); - else if (host_has_cmov == 1) - printk(UM_KERN_ERR "SIGILL caused by cmov, which this " - "processor claims to implement"); - else - printk(UM_KERN_ERR "Bad value for host_has_cmov (%d)", - host_has_cmov); -} diff --git a/arch/um/sys-i386/checksum.S b/arch/um/sys-i386/checksum.S deleted file mode 100644 index f058d2f82e1..00000000000 --- a/arch/um/sys-i386/checksum.S +++ /dev/null @@ -1,458 +0,0 @@ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * IP/TCP/UDP checksumming routines - * - * Authors: Jorge Cwik, <jorge@laser.satlink.net> - * Arnt Gulbrandsen, <agulbra@nvg.unit.no> - * Tom May, <ftom@netcom.com> - * Pentium Pro/II routines: - * Alexander Kjeldaas <astor@guardian.no> - * Finn Arne Gangstad <finnag@guardian.no> - * Lots of code moved from tcp.c and ip.c; see those files - * for more names. - * - * Changes: Ingo Molnar, converted csum_partial_copy() to 2.1 exception - * handling. - * Andi Kleen, add zeroing on error - * converted to pure assembler - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include <asm/errno.h> - -/* - * computes a partial checksum, e.g. for TCP/UDP fragments - */ - -/* -unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) - */ - -.text -.align 4 -.globl csum_partial - -#ifndef CONFIG_X86_USE_PPRO_CHECKSUM - - /* - * Experiments with Ethernet and SLIP connections show that buff - * is aligned on either a 2-byte or 4-byte boundary. We get at - * least a twofold speedup on 486 and Pentium if it is 4-byte aligned. - * Fortunately, it is easy to convert 2-byte alignment to 4-byte - * alignment for the unrolled loop. - */ -csum_partial: - pushl %esi - pushl %ebx - movl 20(%esp),%eax # Function arg: unsigned int sum - movl 16(%esp),%ecx # Function arg: int len - movl 12(%esp),%esi # Function arg: unsigned char *buff - testl $2, %esi # Check alignment. - jz 2f # Jump if alignment is ok. - subl $2, %ecx # Alignment uses up two bytes. - jae 1f # Jump if we had at least two bytes. - addl $2, %ecx # ecx was < 2. Deal with it. - jmp 4f -1: movw (%esi), %bx - addl $2, %esi - addw %bx, %ax - adcl $0, %eax -2: - movl %ecx, %edx - shrl $5, %ecx - jz 2f - testl %esi, %esi -1: movl (%esi), %ebx - adcl %ebx, %eax - movl 4(%esi), %ebx - adcl %ebx, %eax - movl 8(%esi), %ebx - adcl %ebx, %eax - movl 12(%esi), %ebx - adcl %ebx, %eax - movl 16(%esi), %ebx - adcl %ebx, %eax - movl 20(%esi), %ebx - adcl %ebx, %eax - movl 24(%esi), %ebx - adcl %ebx, %eax - movl 28(%esi), %ebx - adcl %ebx, %eax - lea 32(%esi), %esi - dec %ecx - jne 1b - adcl $0, %eax -2: movl %edx, %ecx - andl $0x1c, %edx - je 4f - shrl $2, %edx # This clears CF -3: adcl (%esi), %eax - lea 4(%esi), %esi - dec %edx - jne 3b - adcl $0, %eax -4: andl $3, %ecx - jz 7f - cmpl $2, %ecx - jb 5f - movw (%esi),%cx - leal 2(%esi),%esi - je 6f - shll $16,%ecx -5: movb (%esi),%cl -6: addl %ecx,%eax - adcl $0, %eax -7: - popl %ebx - popl %esi - ret - -#else - -/* Version for PentiumII/PPro */ - -csum_partial: - pushl %esi - pushl %ebx - movl 20(%esp),%eax # Function arg: unsigned int sum - movl 16(%esp),%ecx # Function arg: int len - movl 12(%esp),%esi # Function arg: const unsigned char *buf - - testl $2, %esi - jnz 30f -10: - movl %ecx, %edx - movl %ecx, %ebx - andl $0x7c, %ebx - shrl $7, %ecx - addl %ebx,%esi - shrl $2, %ebx - negl %ebx - lea 45f(%ebx,%ebx,2), %ebx - testl %esi, %esi - jmp *%ebx - - # Handle 2-byte-aligned regions -20: addw (%esi), %ax - lea 2(%esi), %esi - adcl $0, %eax - jmp 10b - -30: subl $2, %ecx - ja 20b - je 32f - movzbl (%esi),%ebx # csumming 1 byte, 2-aligned - addl %ebx, %eax - adcl $0, %eax - jmp 80f -32: - addw (%esi), %ax # csumming 2 bytes, 2-aligned - adcl $0, %eax - jmp 80f - -40: - addl -128(%esi), %eax - adcl -124(%esi), %eax - adcl -120(%esi), %eax - adcl -116(%esi), %eax - adcl -112(%esi), %eax - adcl -108(%esi), %eax - adcl -104(%esi), %eax - adcl -100(%esi), %eax - adcl -96(%esi), %eax - adcl -92(%esi), %eax - adcl -88(%esi), %eax - adcl -84(%esi), %eax - adcl -80(%esi), %eax - adcl -76(%esi), %eax - adcl -72(%esi), %eax - adcl -68(%esi), %eax - adcl -64(%esi), %eax - adcl -60(%esi), %eax - adcl -56(%esi), %eax - adcl -52(%esi), %eax - adcl -48(%esi), %eax - adcl -44(%esi), %eax - adcl -40(%esi), %eax - adcl -36(%esi), %eax - adcl -32(%esi), %eax - adcl -28(%esi), %eax - adcl -24(%esi), %eax - adcl -20(%esi), %eax - adcl -16(%esi), %eax - adcl -12(%esi), %eax - adcl -8(%esi), %eax - adcl -4(%esi), %eax -45: - lea 128(%esi), %esi - adcl $0, %eax - dec %ecx - jge 40b - movl %edx, %ecx -50: andl $3, %ecx - jz 80f - - # Handle the last 1-3 bytes without jumping - notl %ecx # 1->2, 2->1, 3->0, higher bits are masked - movl $0xffffff,%ebx # by the shll and shrl instructions - shll $3,%ecx - shrl %cl,%ebx - andl -128(%esi),%ebx # esi is 4-aligned so should be ok - addl %ebx,%eax - adcl $0,%eax -80: - popl %ebx - popl %esi - ret - -#endif - -/* -unsigned int csum_partial_copy_generic (const char *src, char *dst, - int len, int sum, int *src_err_ptr, int *dst_err_ptr) - */ - -/* - * Copy from ds while checksumming, otherwise like csum_partial - * - * The macros SRC and DST specify the type of access for the instruction. - * thus we can call a custom exception handler for all access types. - * - * FIXME: could someone double-check whether I haven't mixed up some SRC and - * DST definitions? It's damn hard to trigger all cases. I hope I got - * them all but there's no guarantee. - */ - -#define SRC(y...) \ - 9999: y; \ - .section __ex_table, "a"; \ - .long 9999b, 6001f ; \ - .previous - -#define DST(y...) \ - 9999: y; \ - .section __ex_table, "a"; \ - .long 9999b, 6002f ; \ - .previous - -.align 4 - -#ifndef CONFIG_X86_USE_PPRO_CHECKSUM - -#define ARGBASE 16 -#define FP 12 - -csum_partial_copy_generic_i386: - subl $4,%esp - pushl %edi - pushl %esi - pushl %ebx - movl ARGBASE+16(%esp),%eax # sum - movl ARGBASE+12(%esp),%ecx # len - movl ARGBASE+4(%esp),%esi # src - movl ARGBASE+8(%esp),%edi # dst - - testl $2, %edi # Check alignment. - jz 2f # Jump if alignment is ok. - subl $2, %ecx # Alignment uses up two bytes. - jae 1f # Jump if we had at least two bytes. - addl $2, %ecx # ecx was < 2. Deal with it. - jmp 4f -SRC(1: movw (%esi), %bx ) - addl $2, %esi -DST( movw %bx, (%edi) ) - addl $2, %edi - addw %bx, %ax - adcl $0, %eax -2: - movl %ecx, FP(%esp) - shrl $5, %ecx - jz 2f - testl %esi, %esi -SRC(1: movl (%esi), %ebx ) -SRC( movl 4(%esi), %edx ) - adcl %ebx, %eax -DST( movl %ebx, (%edi) ) - adcl %edx, %eax -DST( movl %edx, 4(%edi) ) - -SRC( movl 8(%esi), %ebx ) -SRC( movl 12(%esi), %edx ) - adcl %ebx, %eax -DST( movl %ebx, 8(%edi) ) - adcl %edx, %eax -DST( movl %edx, 12(%edi) ) - -SRC( movl 16(%esi), %ebx ) -SRC( movl 20(%esi), %edx ) - adcl %ebx, %eax -DST( movl %ebx, 16(%edi) ) - adcl %edx, %eax -DST( movl %edx, 20(%edi) ) - -SRC( movl 24(%esi), %ebx ) -SRC( movl 28(%esi), %edx ) - adcl %ebx, %eax -DST( movl %ebx, 24(%edi) ) - adcl %edx, %eax -DST( movl %edx, 28(%edi) ) - - lea 32(%esi), %esi - lea 32(%edi), %edi - dec %ecx - jne 1b - adcl $0, %eax -2: movl FP(%esp), %edx - movl %edx, %ecx - andl $0x1c, %edx - je 4f - shrl $2, %edx # This clears CF -SRC(3: movl (%esi), %ebx ) - adcl %ebx, %eax -DST( movl %ebx, (%edi) ) - lea 4(%esi), %esi - lea 4(%edi), %edi - dec %edx - jne 3b - adcl $0, %eax -4: andl $3, %ecx - jz 7f - cmpl $2, %ecx - jb 5f -SRC( movw (%esi), %cx ) - leal 2(%esi), %esi -DST( movw %cx, (%edi) ) - leal 2(%edi), %edi - je 6f - shll $16,%ecx -SRC(5: movb (%esi), %cl ) -DST( movb %cl, (%edi) ) -6: addl %ecx, %eax - adcl $0, %eax -7: -5000: - -# Exception handler: -.section .fixup, "ax" - -6001: - movl ARGBASE+20(%esp), %ebx # src_err_ptr - movl $-EFAULT, (%ebx) - - # zero the complete destination - computing the rest - # is too much work - movl ARGBASE+8(%esp), %edi # dst - movl ARGBASE+12(%esp), %ecx # len - xorl %eax,%eax - rep ; stosb - - jmp 5000b - -6002: - movl ARGBASE+24(%esp), %ebx # dst_err_ptr - movl $-EFAULT,(%ebx) - jmp 5000b - -.previous - - popl %ebx - popl %esi - popl %edi - popl %ecx # equivalent to addl $4,%esp - ret - -#else - -/* Version for PentiumII/PPro */ - -#define ROUND1(x) \ - SRC(movl x(%esi), %ebx ) ; \ - addl %ebx, %eax ; \ - DST(movl %ebx, x(%edi) ) ; - -#define ROUND(x) \ - SRC(movl x(%esi), %ebx ) ; \ - adcl %ebx, %eax ; \ - DST(movl %ebx, x(%edi) ) ; - -#define ARGBASE 12 - -csum_partial_copy_generic_i386: - pushl %ebx - pushl %edi - pushl %esi - movl ARGBASE+4(%esp),%esi #src - movl ARGBASE+8(%esp),%edi #dst - movl ARGBASE+12(%esp),%ecx #len - movl ARGBASE+16(%esp),%eax #sum -# movl %ecx, %edx - movl %ecx, %ebx - movl %esi, %edx - shrl $6, %ecx - andl $0x3c, %ebx - negl %ebx - subl %ebx, %esi - subl %ebx, %edi - lea -1(%esi),%edx - andl $-32,%edx - lea 3f(%ebx,%ebx), %ebx - testl %esi, %esi - jmp *%ebx -1: addl $64,%esi - addl $64,%edi - SRC(movb -32(%edx),%bl) ; SRC(movb (%edx),%bl) - ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52) - ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36) - ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20) - ROUND (-16) ROUND(-12) ROUND(-8) ROUND(-4) -3: adcl $0,%eax - addl $64, %edx - dec %ecx - jge 1b -4: movl ARGBASE+12(%esp),%edx #len - andl $3, %edx - jz 7f - cmpl $2, %edx - jb 5f -SRC( movw (%esi), %dx ) - leal 2(%esi), %esi -DST( movw %dx, (%edi) ) - leal 2(%edi), %edi - je 6f - shll $16,%edx -5: -SRC( movb (%esi), %dl ) -DST( movb %dl, (%edi) ) -6: addl %edx, %eax - adcl $0, %eax -7: -.section .fixup, "ax" -6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr - movl $-EFAULT, (%ebx) - # zero the complete destination (computing the rest is too much work) - movl ARGBASE+8(%esp),%edi # dst - movl ARGBASE+12(%esp),%ecx # len - xorl %eax,%eax - rep; stosb - jmp 7b -6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr - movl $-EFAULT, (%ebx) - jmp 7b -.previous - - popl %esi - popl %edi - popl %ebx - ret - -#undef ROUND -#undef ROUND1 - -#endif diff --git a/arch/um/sys-i386/delay.c b/arch/um/sys-i386/delay.c deleted file mode 100644 index d623e074f41..00000000000 --- a/arch/um/sys-i386/delay.c +++ /dev/null @@ -1,29 +0,0 @@ -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <asm/param.h> - -void __delay(unsigned long time) -{ - /* Stolen from the i386 __loop_delay */ - int d0; - __asm__ __volatile__( - "\tjmp 1f\n" - ".align 16\n" - "1:\tjmp 2f\n" - ".align 16\n" - "2:\tdecl %0\n\tjns 2b" - :"=&a" (d0) - :"0" (time)); -} - -void __udelay(unsigned long usecs) -{ - int i, n; - - n = (loops_per_jiffy * HZ * usecs) / MILLION; - for(i=0;i<n;i++) - cpu_relax(); -} - -EXPORT_SYMBOL(__udelay); diff --git a/arch/um/sys-i386/elfcore.c b/arch/um/sys-i386/elfcore.c deleted file mode 100644 index 6bb49b687c9..00000000000 --- a/arch/um/sys-i386/elfcore.c +++ /dev/null @@ -1,83 +0,0 @@ -#include <linux/elf.h> -#include <linux/coredump.h> -#include <linux/fs.h> -#include <linux/mm.h> - -#include <asm/elf.h> - - -Elf32_Half elf_core_extra_phdrs(void) -{ - return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0; -} - -int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size, - unsigned long limit) -{ - if ( vsyscall_ehdr ) { - const struct elfhdr *const ehdrp = - (struct elfhdr *) vsyscall_ehdr; - const struct elf_phdr *const phdrp = - (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); - int i; - Elf32_Off ofs = 0; - - for (i = 0; i < ehdrp->e_phnum; ++i) { - struct elf_phdr phdr = phdrp[i]; - - if (phdr.p_type == PT_LOAD) { - ofs = phdr.p_offset = offset; - offset += phdr.p_filesz; - } else { - phdr.p_offset += ofs; - } - phdr.p_paddr = 0; /* match other core phdrs */ - *size += sizeof(phdr); - if (*size > limit - || !dump_write(file, &phdr, sizeof(phdr))) - return 0; - } - } - return 1; -} - -int elf_core_write_extra_data(struct file *file, size_t *size, - unsigned long limit) -{ - if ( vsyscall_ehdr ) { - const struct elfhdr *const ehdrp = - (struct elfhdr *) vsyscall_ehdr; - const struct elf_phdr *const phdrp = - (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); - int i; - - for (i = 0; i < ehdrp->e_phnum; ++i) { - if (phdrp[i].p_type == PT_LOAD) { - void *addr = (void *) phdrp[i].p_vaddr; - size_t filesz = phdrp[i].p_filesz; - - *size += filesz; - if (*size > limit - || !dump_write(file, addr, filesz)) - return 0; - } - } - } - return 1; -} - -size_t elf_core_extra_data_size(void) -{ - if ( vsyscall_ehdr ) { - const struct elfhdr *const ehdrp = - (struct elfhdr *)vsyscall_ehdr; - const struct elf_phdr *const phdrp = - (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); - int i; - - for (i = 0; i < ehdrp->e_phnum; ++i) - if (phdrp[i].p_type == PT_LOAD) - return (size_t) phdrp[i].p_filesz; - } - return 0; -} diff --git a/arch/um/sys-i386/fault.c b/arch/um/sys-i386/fault.c deleted file mode 100644 index d670f68532f..00000000000 --- a/arch/um/sys-i386/fault.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include "sysdep/ptrace.h" - -/* These two are from asm-um/uaccess.h and linux/module.h, check them. */ -struct exception_table_entry -{ - unsigned long insn; - unsigned long fixup; -}; - -const struct exception_table_entry *search_exception_tables(unsigned long add); - -/* Compare this to arch/i386/mm/extable.c:fixup_exception() */ -int arch_fixup(unsigned long address, struct uml_pt_regs *regs) -{ - const struct exception_table_entry *fixup; - - fixup = search_exception_tables(address); - if (fixup != 0) { - UPT_IP(regs) = fixup->fixup; - return 1; - } - return 0; -} diff --git a/arch/um/sys-i386/ksyms.c b/arch/um/sys-i386/ksyms.c deleted file mode 100644 index bfbefd30db8..00000000000 --- a/arch/um/sys-i386/ksyms.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "linux/module.h" -#include "asm/checksum.h" - -/* Networking helper routines. */ -EXPORT_SYMBOL(csum_partial); diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c deleted file mode 100644 index 3f2bf208d88..00000000000 --- a/arch/um/sys-i386/ldt.c +++ /dev/null @@ -1,502 +0,0 @@ -/* - * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include <linux/mm.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <asm/unistd.h> -#include "os.h" -#include "proc_mm.h" -#include "skas.h" -#include "skas_ptrace.h" -#include "sysdep/tls.h" - -extern int modify_ldt(int func, void *ptr, unsigned long bytecount); - -static long write_ldt_entry(struct mm_id *mm_idp, int func, - struct user_desc *desc, void **addr, int done) -{ - long res; - - if (proc_mm) { - /* - * This is a special handling for the case, that the mm to - * modify isn't current->active_mm. - * If this is called directly by modify_ldt, - * (current->active_mm->context.skas.u == mm_idp) - * will be true. So no call to __switch_mm(mm_idp) is done. - * If this is called in case of init_new_ldt or PTRACE_LDT, - * mm_idp won't belong to current->active_mm, but child->mm. - * So we need to switch child's mm into our userspace, then - * later switch back. - * - * Note: I'm unsure: should interrupts be disabled here? - */ - if (!current->active_mm || current->active_mm == &init_mm || - mm_idp != ¤t->active_mm->context.id) - __switch_mm(mm_idp); - } - - if (ptrace_ldt) { - struct ptrace_ldt ldt_op = (struct ptrace_ldt) { - .func = func, - .ptr = desc, - .bytecount = sizeof(*desc)}; - u32 cpu; - int pid; - - if (!proc_mm) - pid = mm_idp->u.pid; - else { - cpu = get_cpu(); - pid = userspace_pid[cpu]; - } - - res = os_ptrace_ldt(pid, 0, (unsigned long) &ldt_op); - - if (proc_mm) - put_cpu(); - } - else { - void *stub_addr; - res = syscall_stub_data(mm_idp, (unsigned long *)desc, - (sizeof(*desc) + sizeof(long) - 1) & - ~(sizeof(long) - 1), - addr, &stub_addr); - if (!res) { - unsigned long args[] = { func, - (unsigned long)stub_addr, - sizeof(*desc), - 0, 0, 0 }; - res = run_syscall_stub(mm_idp, __NR_modify_ldt, args, - 0, addr, done); - } - } - - if (proc_mm) { - /* - * This is the second part of special handling, that makes - * PTRACE_LDT possible to implement. - */ - if (current->active_mm && current->active_mm != &init_mm && - mm_idp != ¤t->active_mm->context.id) - __switch_mm(¤t->active_mm->context.id); - } - - return res; -} - -static long read_ldt_from_host(void __user * ptr, unsigned long bytecount) -{ - int res, n; - struct ptrace_ldt ptrace_ldt = (struct ptrace_ldt) { - .func = 0, - .bytecount = bytecount, - .ptr = kmalloc(bytecount, GFP_KERNEL)}; - u32 cpu; - - if (ptrace_ldt.ptr == NULL) - return -ENOMEM; - - /* - * This is called from sys_modify_ldt only, so userspace_pid gives - * us the right number - */ - - cpu = get_cpu(); - res = os_ptrace_ldt(userspace_pid[cpu], 0, (unsigned long) &ptrace_ldt); - put_cpu(); - if (res < 0) - goto out; - - n = copy_to_user(ptr, ptrace_ldt.ptr, res); - if (n != 0) - res = -EFAULT; - - out: - kfree(ptrace_ldt.ptr); - - return res; -} - -/* - * In skas mode, we hold our own ldt data in UML. - * Thus, the code implementing sys_modify_ldt_skas - * is very similar to (and mostly stolen from) sys_modify_ldt - * for arch/i386/kernel/ldt.c - * The routines copied and modified in part are: - * - read_ldt - * - read_default_ldt - * - write_ldt - * - sys_modify_ldt_skas - */ - -static int read_ldt(void __user * ptr, unsigned long bytecount) -{ - int i, err = 0; - unsigned long size; - uml_ldt_t * ldt = ¤t->mm->context.ldt; - - if (!ldt->entry_count) - goto out; - if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES) - bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES; - err = bytecount; - - if (ptrace_ldt) - return read_ldt_from_host(ptr, bytecount); - - mutex_lock(&ldt->lock); - if (ldt->entry_count <= LDT_DIRECT_ENTRIES) { - size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES; - if (size > bytecount) - size = bytecount; - if (copy_to_user(ptr, ldt->u.entries, size)) - err = -EFAULT; - bytecount -= size; - ptr += size; - } - else { - for (i=0; i<ldt->entry_count/LDT_ENTRIES_PER_PAGE && bytecount; - i++) { - size = PAGE_SIZE; - if (size > bytecount) - size = bytecount; - if (copy_to_user(ptr, ldt->u.pages[i], size)) { - err = -EFAULT; - break; - } - bytecount -= size; - ptr += size; - } - } - mutex_unlock(&ldt->lock); - - if (bytecount == 0 || err == -EFAULT) - goto out; - - if (clear_user(ptr, bytecount)) - err = -EFAULT; - -out: - return err; -} - -static int read_default_ldt(void __user * ptr, unsigned long bytecount) -{ - int err; - - if (bytecount > 5*LDT_ENTRY_SIZE) - bytecount = 5*LDT_ENTRY_SIZE; - - err = bytecount; - /* - * UML doesn't support lcall7 and lcall27. - * So, we don't really have a default ldt, but emulate - * an empty ldt of common host default ldt size. - */ - if (clear_user(ptr, bytecount)) - err = -EFAULT; - - return err; -} - -static int write_ldt(void __user * ptr, unsigned long bytecount, int func) -{ - uml_ldt_t * ldt = ¤t->mm->context.ldt; - struct mm_id * mm_idp = ¤t->mm->context.id; - int i, err; - struct user_desc ldt_info; - struct ldt_entry entry0, *ldt_p; - void *addr = NULL; - - err = -EINVAL; - if (bytecount != sizeof(ldt_info)) - goto out; - err = -EFAULT; - if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info))) - goto out; - - err = -EINVAL; - if (ldt_info.entry_number >= LDT_ENTRIES) - goto out; - if (ldt_info.contents == 3) { - if (func == 1) - goto out; - if (ldt_info.seg_not_present == 0) - goto out; - } - - if (!ptrace_ldt) - mutex_lock(&ldt->lock); - - err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1); - if (err) - goto out_unlock; - else if (ptrace_ldt) { - /* With PTRACE_LDT available, this is used as a flag only */ - ldt->entry_count = 1; - goto out; - } - - if (ldt_info.entry_number >= ldt->entry_count && - ldt_info.entry_number >= LDT_DIRECT_ENTRIES) { - for (i=ldt->entry_count/LDT_ENTRIES_PER_PAGE; - i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number; - i++) { - if (i == 0) - memcpy(&entry0, ldt->u.entries, - sizeof(entry0)); - ldt->u.pages[i] = (struct ldt_entry *) - __get_free_page(GFP_KERNEL|__GFP_ZERO); - if (!ldt->u.pages[i]) { - err = -ENOMEM; - /* Undo the change in host */ - memset(&ldt_info, 0, sizeof(ldt_info)); - write_ldt_entry(mm_idp, 1, &ldt_info, &addr, 1); - goto out_unlock; - } - if (i == 0) { - memcpy(ldt->u.pages[0], &entry0, - sizeof(entry0)); - memcpy(ldt->u.pages[0]+1, ldt->u.entries+1, - sizeof(entry0)*(LDT_DIRECT_ENTRIES-1)); - } - ldt->entry_count = (i + 1) * LDT_ENTRIES_PER_PAGE; - } - } - if (ldt->entry_count <= ldt_info.entry_number) - ldt->entry_count = ldt_info.entry_number + 1; - - if (ldt->entry_count <= LDT_DIRECT_ENTRIES) - ldt_p = ldt->u.entries + ldt_info.entry_number; - else - ldt_p = ldt->u.pages[ldt_info.entry_number/LDT_ENTRIES_PER_PAGE] + - ldt_info.entry_number%LDT_ENTRIES_PER_PAGE; - - if (ldt_info.base_addr == 0 && ldt_info.limit == 0 && - (func == 1 || LDT_empty(&ldt_info))) { - ldt_p->a = 0; - ldt_p->b = 0; - } - else{ - if (func == 1) - ldt_info.useable = 0; - ldt_p->a = LDT_entry_a(&ldt_info); - ldt_p->b = LDT_entry_b(&ldt_info); - } - err = 0; - -out_unlock: - mutex_unlock(&ldt->lock); -out: - return err; -} - -static long do_modify_ldt_skas(int func, void __user *ptr, - unsigned long bytecount) -{ - int ret = -ENOSYS; - - switch (func) { - case 0: - ret = read_ldt(ptr, bytecount); - break; - case 1: - case 0x11: - ret = write_ldt(ptr, bytecount, func); - break; - case 2: - ret = read_default_ldt(ptr, bytecount); - break; - } - return ret; -} - -static DEFINE_SPINLOCK(host_ldt_lock); -static short dummy_list[9] = {0, -1}; -static short * host_ldt_entries = NULL; - -static void ldt_get_host_info(void) -{ - long ret; - struct ldt_entry * ldt; - short *tmp; - int i, size, k, order; - - spin_lock(&host_ldt_lock); - - if (host_ldt_entries != NULL) { - spin_unlock(&host_ldt_lock); - return; - } - host_ldt_entries = dummy_list+1; - - spin_unlock(&host_ldt_lock); - - for (i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++) - ; - - ldt = (struct ldt_entry *) - __get_free_pages(GFP_KERNEL|__GFP_ZERO, order); - if (ldt == NULL) { - printk(KERN_ERR "ldt_get_host_info: couldn't allocate buffer " - "for host ldt\n"); - return; - } - - ret = modify_ldt(0, ldt, (1<<order)*PAGE_SIZE); - if (ret < 0) { - printk(KERN_ERR "ldt_get_host_info: couldn't read host ldt\n"); - goto out_free; - } - if (ret == 0) { - /* default_ldt is active, simply write an empty entry 0 */ - host_ldt_entries = dummy_list; - goto out_free; - } - - for (i=0, size=0; i<ret/LDT_ENTRY_SIZE; i++) { - if (ldt[i].a != 0 || ldt[i].b != 0) - size++; - } - - if (size < ARRAY_SIZE(dummy_list)) - host_ldt_entries = dummy_list; - else { - size = (size + 1) * sizeof(dummy_list[0]); - tmp = kmalloc(size, GFP_KERNEL); - if (tmp == NULL) { - printk(KERN_ERR "ldt_get_host_info: couldn't allocate " - "host ldt list\n"); - goto out_free; - } - host_ldt_entries = tmp; - } - - for (i=0, k=0; i<ret/LDT_ENTRY_SIZE; i++) { - if (ldt[i].a != 0 || ldt[i].b != 0) - host_ldt_entries[k++] = i; - } - host_ldt_entries[k] = -1; - -out_free: - free_pages((unsigned long)ldt, order); -} - -long init_new_ldt(struct mm_context *new_mm, struct mm_context *from_mm) -{ - struct user_desc desc; - short * num_p; - int i; - long page, err=0; - void *addr = NULL; - struct proc_mm_op copy; - - - if (!ptrace_ldt) - mutex_init(&new_mm->ldt.lock); - - if (!from_mm) { - memset(&desc, 0, sizeof(desc)); - /* - * We have to initialize a clean ldt. - */ - if (proc_mm) { - /* - * If the new mm was created using proc_mm, host's - * default-ldt currently is assigned, which normally - * contains the call-gates for lcall7 and lcall27. - * To remove these gates, we simply write an empty - * entry as number 0 to the host. - */ - err = write_ldt_entry(&new_mm->id, 1, &desc, &addr, 1); - } - else{ - /* - * Now we try to retrieve info about the ldt, we - * inherited from the host. All ldt-entries found - * will be reset in the following loop - */ - ldt_get_host_info(); - for (num_p=host_ldt_entries; *num_p != -1; num_p++) { - desc.entry_number = *num_p; - err = write_ldt_entry(&new_mm->id, 1, &desc, - &addr, *(num_p + 1) == -1); - if (err) - break; - } - } - new_mm->ldt.entry_count = 0; - - goto out; - } - - if (proc_mm) { - /* - * We have a valid from_mm, so we now have to copy the LDT of - * from_mm to new_mm, because using proc_mm an new mm with - * an empty/default LDT was created in new_mm() - */ - copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS, - .u = - { .copy_segments = - from_mm->id.u.mm_fd } } ); - i = os_write_file(new_mm->id.u.mm_fd, ©, sizeof(copy)); - if (i != sizeof(copy)) - printk(KERN_ERR "new_mm : /proc/mm copy_segments " - "failed, err = %d\n", -i); - } - - if (!ptrace_ldt) { - /* - * Our local LDT is used to supply the data for - * modify_ldt(READLDT), if PTRACE_LDT isn't available, - * i.e., we have to use the stub for modify_ldt, which - * can't handle the big read buffer of up to 64kB. - */ - mutex_lock(&from_mm->ldt.lock); - if (from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES) - memcpy(new_mm->ldt.u.entries, from_mm->ldt.u.entries, - sizeof(new_mm->ldt.u.entries)); - else { - i = from_mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; - while (i-->0) { - page = __get_free_page(GFP_KERNEL|__GFP_ZERO); - if (!page) { - err = -ENOMEM; - break; - } - new_mm->ldt.u.pages[i] = - (struct ldt_entry *) page; - memcpy(new_mm->ldt.u.pages[i], - from_mm->ldt.u.pages[i], PAGE_SIZE); - } - } - new_mm->ldt.entry_count = from_mm->ldt.entry_count; - mutex_unlock(&from_mm->ldt.lock); - } - - out: - return err; -} - - -void free_ldt(struct mm_context *mm) -{ - int i; - - if (!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES) { - i = mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; - while (i-- > 0) - free_page((long) mm->ldt.u.pages[i]); - } - mm->ldt.entry_count = 0; -} - -int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) -{ - return do_modify_ldt_skas(func, ptr, bytecount); -} diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c deleted file mode 100644 index d23b2d3ea38..00000000000 --- a/arch/um/sys-i386/ptrace.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include "linux/mm.h" -#include "linux/sched.h" -#include "asm/uaccess.h" -#include "skas.h" - -extern int arch_switch_tls(struct task_struct *to); - -void arch_switch_to(struct task_struct *to) -{ - int err = arch_switch_tls(to); - if (!err) - return; - - if (err != -EINVAL) - printk(KERN_WARNING "arch_switch_tls failed, errno %d, " - "not EINVAL\n", -err); - else - printk(KERN_WARNING "arch_switch_tls failed, errno = EINVAL\n"); -} - -int is_syscall(unsigned long addr) -{ - unsigned short instr; - int n; - - n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); - if (n) { - /* access_process_vm() grants access to vsyscall and stub, - * while copy_from_user doesn't. Maybe access_process_vm is - * slow, but that doesn't matter, since it will be called only - * in case of singlestepping, if copy_from_user failed. - */ - n = access_process_vm(current, addr, &instr, sizeof(instr), 0); - if (n != sizeof(instr)) { - printk(KERN_ERR "is_syscall : failed to read " - "instruction from 0x%lx\n", addr); - return 1; - } - } - /* int 0x80 or sysenter */ - return (instr == 0x80cd) || (instr == 0x340f); -} - -/* determines which flags the user has access to. */ -/* 1 = access 0 = no access */ -#define FLAG_MASK 0x00044dd5 - -int putreg(struct task_struct *child, int regno, unsigned long value) -{ - regno >>= 2; - switch (regno) { - case FS: - if (value && (value & 3) != 3) - return -EIO; - PT_REGS_FS(&child->thread.regs) = value; - return 0; - case GS: - if (value && (value & 3) != 3) - return -EIO; - PT_REGS_GS(&child->thread.regs) = value; - return 0; - case DS: - case ES: - if (value && (value & 3) != 3) - return -EIO; - value &= 0xffff; - break; - case SS: - case CS: - if ((value & 3) != 3) - return -EIO; - value &= 0xffff; - break; - case EFL: - value &= FLAG_MASK; - value |= PT_REGS_EFLAGS(&child->thread.regs); - break; - } - PT_REGS_SET(&child->thread.regs, regno, 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; - - regno >>= 2; - switch (regno) { - case FS: - case GS: - case DS: - case ES: - case SS: - case CS: - retval = 0xffff; - /* fall through */ - default: - retval &= PT_REG(&child->thread.regs, regno); - } - return retval; -} - -/* read the word at location addr in the USER area. */ -int peek_user(struct task_struct *child, long addr, long data) -{ - 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 __user *) data); -} - -int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) -{ - int err, n, cpu = ((struct thread_info *) child->stack)->cpu; - struct user_i387_struct fpregs; - - err = save_fp_registers(userspace_pid[cpu], (unsigned long *) &fpregs); - if (err) - return err; - - n = copy_to_user(buf, &fpregs, sizeof(fpregs)); - if(n > 0) - return -EFAULT; - - return n; -} - -int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) -{ - int n, cpu = ((struct thread_info *) child->stack)->cpu; - struct user_i387_struct fpregs; - - n = copy_from_user(&fpregs, buf, sizeof(fpregs)); - if (n > 0) - return -EFAULT; - - return restore_fp_registers(userspace_pid[cpu], - (unsigned long *) &fpregs); -} - -int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) -{ - int err, n, cpu = ((struct thread_info *) child->stack)->cpu; - struct user_fxsr_struct fpregs; - - err = save_fpx_registers(userspace_pid[cpu], (unsigned long *) &fpregs); - if (err) - return err; - - n = copy_to_user(buf, &fpregs, sizeof(fpregs)); - if(n > 0) - return -EFAULT; - - return n; -} - -int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) -{ - int n, cpu = ((struct thread_info *) child->stack)->cpu; - struct user_fxsr_struct fpregs; - - n = copy_from_user(&fpregs, buf, sizeof(fpregs)); - if (n > 0) - return -EFAULT; - - return restore_fpx_registers(userspace_pid[cpu], - (unsigned long *) &fpregs); -} - -long subarch_ptrace(struct task_struct *child, long request, - unsigned long addr, unsigned long data) -{ - return -EIO; -} diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c deleted file mode 100644 index 0b10c3e7402..00000000000 --- a/arch/um/sys-i386/ptrace_user.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include <errno.h> -#include <sys/ptrace.h> - -int ptrace_getregs(long pid, unsigned long *regs_out) -{ - if (ptrace(PTRACE_GETREGS, pid, 0, regs_out) < 0) - return -errno; - return 0; -} - -int ptrace_setregs(long pid, unsigned long *regs) -{ - if (ptrace(PTRACE_SETREGS, pid, 0, regs) < 0) - return -errno; - return 0; -} diff --git a/arch/um/sys-i386/setjmp.S b/arch/um/sys-i386/setjmp.S deleted file mode 100644 index b766792c993..00000000000 --- a/arch/um/sys-i386/setjmp.S +++ /dev/null @@ -1,58 +0,0 @@ -# -# arch/i386/setjmp.S -# -# setjmp/longjmp for the i386 architecture -# - -# -# The jmp_buf is assumed to contain the following, in order: -# %ebx -# %esp -# %ebp -# %esi -# %edi -# <return address> -# - - .text - .align 4 - .globl setjmp - .type setjmp, @function -setjmp: -#ifdef _REGPARM - movl %eax,%edx -#else - movl 4(%esp),%edx -#endif - popl %ecx # Return address, and adjust the stack - xorl %eax,%eax # Return value - movl %ebx,(%edx) - movl %esp,4(%edx) # Post-return %esp! - pushl %ecx # Make the call/return stack happy - movl %ebp,8(%edx) - movl %esi,12(%edx) - movl %edi,16(%edx) - movl %ecx,20(%edx) # Return address - ret - - .size setjmp,.-setjmp - - .text - .align 4 - .globl longjmp - .type longjmp, @function -longjmp: -#ifdef _REGPARM - xchgl %eax,%edx -#else - movl 4(%esp),%edx # jmp_ptr address - movl 8(%esp),%eax # Return value -#endif - movl (%edx),%ebx - movl 4(%edx),%esp - movl 8(%edx),%ebp - movl 12(%edx),%esi - movl 16(%edx),%edi - jmp *20(%edx) - - .size longjmp,.-longjmp diff --git a/arch/um/sys-i386/shared/sysdep/archsetjmp.h b/arch/um/sys-i386/shared/sysdep/archsetjmp.h deleted file mode 100644 index 0f312085ce1..00000000000 --- a/arch/um/sys-i386/shared/sysdep/archsetjmp.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * arch/um/include/sysdep-i386/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned int __ebx; - unsigned int __esp; - unsigned int __ebp; - unsigned int __esi; - unsigned int __edi; - unsigned int __eip; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#define JB_IP __eip -#define JB_SP __esp - -#endif /* _SETJMP_H */ diff --git a/arch/um/sys-i386/shared/sysdep/barrier.h b/arch/um/sys-i386/shared/sysdep/barrier.h deleted file mode 100644 index b58d52c5b2f..00000000000 --- a/arch/um/sys-i386/shared/sysdep/barrier.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __SYSDEP_I386_BARRIER_H -#define __SYSDEP_I386_BARRIER_H - -/* Copied from include/asm-i386 for use by userspace. i386 has the option - * of using mfence, but I'm just using this, which works everywhere, for now. - */ -#define mb() asm volatile("lock; addl $0,0(%esp)") - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/checksum.h b/arch/um/sys-i386/shared/sysdep/checksum.h deleted file mode 100644 index ed47445f390..00000000000 --- a/arch/um/sys-i386/shared/sysdep/checksum.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Licensed under the GPL - */ - -#ifndef __UM_SYSDEP_CHECKSUM_H -#define __UM_SYSDEP_CHECKSUM_H - -#include "linux/in6.h" -#include "linux/string.h" - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -__wsum csum_partial(const void *buff, int len, __wsum sum); - -/* - * Note: when you get a NULL pointer exception here this means someone - * passed in an incorrect kernel address to one of these functions. - * - * If you use these functions directly please don't forget the - * access_ok(). - */ - -static __inline__ -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum) -{ - memcpy(dst, src, len); - 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__ -__wsum csum_partial_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *err_ptr) -{ - if (copy_from_user(dst, src, len)) { - *err_ptr = -EFAULT; - return (__force __wsum)-1; - } - - return csum_partial(dst, len, sum); -} - -/* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. - * - * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by - * Arnt Gulbrandsen. - */ -static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) -{ - unsigned int sum; - - __asm__ __volatile__( - "movl (%1), %0 ;\n" - "subl $4, %2 ;\n" - "jbe 2f ;\n" - "addl 4(%1), %0 ;\n" - "adcl 8(%1), %0 ;\n" - "adcl 12(%1), %0 ;\n" -"1: adcl 16(%1), %0 ;\n" - "lea 4(%1), %1 ;\n" - "decl %2 ;\n" - "jne 1b ;\n" - "adcl $0, %0 ;\n" - "movl %0, %2 ;\n" - "shrl $16, %0 ;\n" - "addw %w2, %w0 ;\n" - "adcl $0, %0 ;\n" - "notl %0 ;\n" -"2: ;\n" - /* Since the input registers which are loaded with iph and ipl - are modified, we must also specify them as outputs, or gcc - will assume they contain their original values. */ - : "=r" (sum), "=r" (iph), "=r" (ihl) - : "1" (iph), "2" (ihl) - : "memory"); - return (__force __sum16)sum; -} - -/* - * Fold a partial checksum - */ - -static inline __sum16 csum_fold(__wsum sum) -{ - __asm__( - "addl %1, %0 ;\n" - "adcl $0xffff, %0 ;\n" - : "=r" (sum) - : "r" ((__force u32)sum << 16), - "0" ((__force u32)sum & 0xffff0000) - ); - return (__force __sum16)(~(__force u32)sum >> 16); -} - -static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) -{ - __asm__( - "addl %1, %0 ;\n" - "adcl %2, %0 ;\n" - "adcl %3, %0 ;\n" - "adcl $0, %0 ;\n" - : "=r" (sum) - : "g" (daddr), "g"(saddr), "g"((len + proto) << 8), "0"(sum)); - return sum; -} - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ -static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -} - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ - -static inline __sum16 ip_compute_csum(const void *buff, int len) -{ - return csum_fold (csum_partial(buff, len, 0)); -} - -#define _HAVE_ARCH_IPV6_CSUM -static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, - const struct in6_addr *daddr, - __u32 len, unsigned short proto, - __wsum sum) -{ - __asm__( - "addl 0(%1), %0 ;\n" - "adcl 4(%1), %0 ;\n" - "adcl 8(%1), %0 ;\n" - "adcl 12(%1), %0 ;\n" - "adcl 0(%2), %0 ;\n" - "adcl 4(%2), %0 ;\n" - "adcl 8(%2), %0 ;\n" - "adcl 12(%2), %0 ;\n" - "adcl %3, %0 ;\n" - "adcl %4, %0 ;\n" - "adcl $0, %0 ;\n" - : "=&r" (sum) - : "r" (saddr), "r" (daddr), - "r"(htonl(len)), "r"(htonl(proto)), "0"(sum)); - - return csum_fold(sum); -} - -/* - * Copy and checksum to user - */ -#define HAVE_CSUM_COPY_USER -static __inline__ __wsum csum_and_copy_to_user(const void *src, - void __user *dst, - int len, __wsum sum, int *err_ptr) -{ - if (access_ok(VERIFY_WRITE, dst, len)) { - if (copy_to_user(dst, src, len)) { - *err_ptr = -EFAULT; - return (__force __wsum)-1; - } - - return csum_partial(src, len, sum); - } - - if (len) - *err_ptr = -EFAULT; - - return (__force __wsum)-1; /* invalid checksum */ -} - -#endif - diff --git a/arch/um/sys-i386/shared/sysdep/faultinfo.h b/arch/um/sys-i386/shared/sysdep/faultinfo.h deleted file mode 100644 index db437cc373b..00000000000 --- a/arch/um/sys-i386/shared/sysdep/faultinfo.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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/sys-i386/shared/sysdep/host_ldt.h b/arch/um/sys-i386/shared/sysdep/host_ldt.h deleted file mode 100644 index 0953cc4df65..00000000000 --- a/arch/um/sys-i386/shared/sysdep/host_ldt.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __ASM_HOST_LDT_I386_H -#define __ASM_HOST_LDT_I386_H - -#include <asm/ldt.h> - -/* - * macros stolen from include/asm-i386/desc.h - */ -#define LDT_entry_a(info) \ - ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) - -#define LDT_entry_b(info) \ - (((info)->base_addr & 0xff000000) | \ - (((info)->base_addr & 0x00ff0000) >> 16) | \ - ((info)->limit & 0xf0000) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - 0x7000) - -#define LDT_empty(info) (\ - (info)->base_addr == 0 && \ - (info)->limit == 0 && \ - (info)->contents == 0 && \ - (info)->read_exec_only == 1 && \ - (info)->seg_32bit == 0 && \ - (info)->limit_in_pages == 0 && \ - (info)->seg_not_present == 1 && \ - (info)->useable == 0 ) - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/kernel-offsets.h b/arch/um/sys-i386/shared/sysdep/kernel-offsets.h deleted file mode 100644 index 5868526b5ee..00000000000 --- a/arch/um/sys-i386/shared/sysdep/kernel-offsets.h +++ /dev/null @@ -1,21 +0,0 @@ -#include <linux/stddef.h> -#include <linux/sched.h> -#include <linux/elf.h> -#include <linux/crypto.h> -#include <asm/mman.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) -{ -#include <common-offsets.h> -} diff --git a/arch/um/sys-i386/shared/sysdep/ptrace.h b/arch/um/sys-i386/shared/sysdep/ptrace.h deleted file mode 100644 index d50e62e0707..00000000000 --- a/arch/um/sys-i386/shared/sysdep/ptrace.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_I386_PTRACE_H -#define __SYSDEP_I386_PTRACE_H - -#include "user_constants.h" -#include "sysdep/faultinfo.h" - -#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) -#define MAX_REG_OFFSET (UM_FRAME_SIZE) - -static inline void update_debugregs(int seq) {} - -/* syscall emulation path in ptrace */ - -#ifndef PTRACE_SYSEMU -#define PTRACE_SYSEMU 31 -#endif - -void set_using_sysemu(int value); -int get_using_sysemu(void); -extern int sysemu_supported; - -#include "skas_ptregs.h" - -#define REGS_IP(r) ((r)[HOST_IP]) -#define REGS_SP(r) ((r)[HOST_SP]) -#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS]) -#define REGS_EAX(r) ((r)[HOST_EAX]) -#define REGS_EBX(r) ((r)[HOST_EBX]) -#define REGS_ECX(r) ((r)[HOST_ECX]) -#define REGS_EDX(r) ((r)[HOST_EDX]) -#define REGS_ESI(r) ((r)[HOST_ESI]) -#define REGS_EDI(r) ((r)[HOST_EDI]) -#define REGS_EBP(r) ((r)[HOST_EBP]) -#define REGS_CS(r) ((r)[HOST_CS]) -#define REGS_SS(r) ((r)[HOST_SS]) -#define REGS_DS(r) ((r)[HOST_DS]) -#define REGS_ES(r) ((r)[HOST_ES]) -#define REGS_FS(r) ((r)[HOST_FS]) -#define REGS_GS(r) ((r)[HOST_GS]) - -#define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res) - -#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) - -#ifndef PTRACE_SYSEMU_SINGLESTEP -#define PTRACE_SYSEMU_SINGLESTEP 32 -#endif - -struct uml_pt_regs { - unsigned long gp[MAX_REG_NR]; - struct faultinfo faultinfo; - long syscall; - int is_user; -}; - -#define EMPTY_UML_PT_REGS { } - -#define UPT_IP(r) REGS_IP((r)->gp) -#define UPT_SP(r) REGS_SP((r)->gp) -#define UPT_EFLAGS(r) REGS_EFLAGS((r)->gp) -#define UPT_EAX(r) REGS_EAX((r)->gp) -#define UPT_EBX(r) REGS_EBX((r)->gp) -#define UPT_ECX(r) REGS_ECX((r)->gp) -#define UPT_EDX(r) REGS_EDX((r)->gp) -#define UPT_ESI(r) REGS_ESI((r)->gp) -#define UPT_EDI(r) REGS_EDI((r)->gp) -#define UPT_EBP(r) REGS_EBP((r)->gp) -#define UPT_ORIG_EAX(r) ((r)->syscall) -#define UPT_CS(r) REGS_CS((r)->gp) -#define UPT_SS(r) REGS_SS((r)->gp) -#define UPT_DS(r) REGS_DS((r)->gp) -#define UPT_ES(r) REGS_ES((r)->gp) -#define UPT_FS(r) REGS_FS((r)->gp) -#define UPT_GS(r) REGS_GS((r)->gp) - -#define UPT_SYSCALL_ARG1(r) UPT_EBX(r) -#define UPT_SYSCALL_ARG2(r) UPT_ECX(r) -#define UPT_SYSCALL_ARG3(r) UPT_EDX(r) -#define UPT_SYSCALL_ARG4(r) UPT_ESI(r) -#define UPT_SYSCALL_ARG5(r) UPT_EDI(r) -#define UPT_SYSCALL_ARG6(r) UPT_EBP(r) - -extern int user_context(unsigned long sp); - -#define UPT_IS_USER(r) ((r)->is_user) - -struct syscall_args { - unsigned long args[6]; -}; - -#define SYSCALL_ARGS(r) ((struct syscall_args) \ - { .args = { UPT_SYSCALL_ARG1(r), \ - UPT_SYSCALL_ARG2(r), \ - UPT_SYSCALL_ARG3(r), \ - UPT_SYSCALL_ARG4(r), \ - UPT_SYSCALL_ARG5(r), \ - UPT_SYSCALL_ARG6(r) } } ) - -#define UPT_REG(regs, reg) \ - ({ unsigned long val; \ - switch(reg){ \ - case EIP: val = UPT_IP(regs); break; \ - case UESP: val = UPT_SP(regs); break; \ - case EAX: val = UPT_EAX(regs); break; \ - case EBX: val = UPT_EBX(regs); break; \ - case ECX: val = UPT_ECX(regs); break; \ - case EDX: val = UPT_EDX(regs); break; \ - case ESI: val = UPT_ESI(regs); break; \ - case EDI: val = UPT_EDI(regs); break; \ - case EBP: val = UPT_EBP(regs); break; \ - case ORIG_EAX: val = UPT_ORIG_EAX(regs); break; \ - case CS: val = UPT_CS(regs); break; \ - case SS: val = UPT_SS(regs); break; \ - case DS: val = UPT_DS(regs); break; \ - case ES: val = UPT_ES(regs); break; \ - case FS: val = UPT_FS(regs); break; \ - case GS: val = UPT_GS(regs); break; \ - case EFL: val = UPT_EFLAGS(regs); break; \ - default : \ - panic("Bad register in UPT_REG : %d\n", reg); \ - val = -1; \ - } \ - val; \ - }) - -#define UPT_SET(regs, reg, val) \ - do { \ - switch(reg){ \ - case EIP: UPT_IP(regs) = val; break; \ - case UESP: UPT_SP(regs) = val; break; \ - case EAX: UPT_EAX(regs) = val; break; \ - case EBX: UPT_EBX(regs) = val; break; \ - case ECX: UPT_ECX(regs) = val; break; \ - case EDX: UPT_EDX(regs) = val; break; \ - case ESI: UPT_ESI(regs) = val; break; \ - case EDI: UPT_EDI(regs) = val; break; \ - case EBP: UPT_EBP(regs) = val; break; \ - case ORIG_EAX: UPT_ORIG_EAX(regs) = val; break; \ - case CS: UPT_CS(regs) = val; break; \ - case SS: UPT_SS(regs) = val; break; \ - case DS: UPT_DS(regs) = val; break; \ - case ES: UPT_ES(regs) = val; break; \ - case FS: UPT_FS(regs) = val; break; \ - case GS: UPT_GS(regs) = val; break; \ - case EFL: UPT_EFLAGS(regs) = val; break; \ - default : \ - panic("Bad register in UPT_SET : %d\n", reg); \ - break; \ - } \ - } while (0) - -#define UPT_SET_SYSCALL_RETURN(r, res) \ - REGS_SET_SYSCALL_RETURN((r)->regs, (res)) - -#define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp) - -#define UPT_ORIG_SYSCALL(r) UPT_EAX(r) -#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r) -#define UPT_SYSCALL_RET(r) UPT_EAX(r) - -#define UPT_FAULTINFO(r) (&(r)->faultinfo) - -extern void arch_init_registers(int pid); - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/ptrace_user.h b/arch/um/sys-i386/shared/sysdep/ptrace_user.h deleted file mode 100644 index ef56247e414..00000000000 --- a/arch/um/sys-i386/shared/sysdep/ptrace_user.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_I386_PTRACE_USER_H__ -#define __SYSDEP_I386_PTRACE_USER_H__ - -#include <sys/ptrace.h> -#include <linux/ptrace.h> -#include <asm/ptrace.h> -#include "user_constants.h" - -#define PT_OFFSET(r) ((r) * sizeof(long)) - -#define PT_SYSCALL_NR(regs) ((regs)[ORIG_EAX]) -#define PT_SYSCALL_NR_OFFSET PT_OFFSET(ORIG_EAX) - -#define PT_SYSCALL_ARG1_OFFSET PT_OFFSET(EBX) -#define PT_SYSCALL_ARG2_OFFSET PT_OFFSET(ECX) -#define PT_SYSCALL_ARG3_OFFSET PT_OFFSET(EDX) -#define PT_SYSCALL_ARG4_OFFSET PT_OFFSET(ESI) -#define PT_SYSCALL_ARG5_OFFSET PT_OFFSET(EDI) -#define PT_SYSCALL_ARG6_OFFSET PT_OFFSET(EBP) - -#define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX) - -#define REGS_SYSCALL_NR EAX /* This is used before a system call */ -#define REGS_SYSCALL_ARG1 EBX -#define REGS_SYSCALL_ARG2 ECX -#define REGS_SYSCALL_ARG3 EDX -#define REGS_SYSCALL_ARG4 ESI -#define REGS_SYSCALL_ARG5 EDI -#define REGS_SYSCALL_ARG6 EBP - -#define REGS_IP_INDEX EIP -#define REGS_SP_INDEX UESP - -#define PT_IP_OFFSET PT_OFFSET(EIP) -#define PT_IP(regs) ((regs)[EIP]) -#define PT_SP_OFFSET PT_OFFSET(UESP) -#define PT_SP(regs) ((regs)[UESP]) - -#define FP_SIZE ((HOST_FPX_SIZE > HOST_FP_SIZE) ? HOST_FPX_SIZE : HOST_FP_SIZE) - -#ifndef FRAME_SIZE -#define FRAME_SIZE (17) -#endif - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/sc.h b/arch/um/sys-i386/shared/sysdep/sc.h deleted file mode 100644 index c57d1780ad3..00000000000 --- a/arch/um/sys-i386/shared/sysdep/sc.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef __SYSDEP_I386_SC_H -#define __SYSDEP_I386_SC_H - -#include <user_constants.h> - -#define SC_OFFSET(sc, field) \ - *((unsigned long *) &(((char *) (sc))[HOST_##field])) -#define SC_FP_OFFSET(sc, field) \ - *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[HOST_##field])) -#define SC_FP_OFFSET_PTR(sc, field, type) \ - ((type *) &(((char *) (SC_FPSTATE(sc)))[HOST_##field])) - -#define SC_IP(sc) SC_OFFSET(sc, SC_IP) -#define SC_SP(sc) SC_OFFSET(sc, SC_SP) -#define SC_FS(sc) SC_OFFSET(sc, SC_FS) -#define SC_GS(sc) SC_OFFSET(sc, SC_GS) -#define SC_DS(sc) SC_OFFSET(sc, SC_DS) -#define SC_ES(sc) SC_OFFSET(sc, SC_ES) -#define SC_SS(sc) SC_OFFSET(sc, SC_SS) -#define SC_CS(sc) SC_OFFSET(sc, SC_CS) -#define SC_EFLAGS(sc) SC_OFFSET(sc, SC_EFLAGS) -#define SC_EAX(sc) SC_OFFSET(sc, SC_EAX) -#define SC_EBX(sc) SC_OFFSET(sc, SC_EBX) -#define SC_ECX(sc) SC_OFFSET(sc, SC_ECX) -#define SC_EDX(sc) SC_OFFSET(sc, SC_EDX) -#define SC_EDI(sc) SC_OFFSET(sc, SC_EDI) -#define SC_ESI(sc) SC_OFFSET(sc, SC_ESI) -#define SC_EBP(sc) SC_OFFSET(sc, SC_EBP) -#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) -#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) -#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2) -#define SC_FPSTATE(sc) SC_OFFSET(sc, SC_FPSTATE) -#define SC_SIGMASK(sc) SC_OFFSET(sc, SC_SIGMASK) -#define SC_FP_CW(sc) SC_FP_OFFSET(sc, SC_FP_CW) -#define SC_FP_SW(sc) SC_FP_OFFSET(sc, SC_FP_SW) -#define SC_FP_TAG(sc) SC_FP_OFFSET(sc, SC_FP_TAG) -#define SC_FP_IPOFF(sc) SC_FP_OFFSET(sc, SC_FP_IPOFF) -#define SC_FP_CSSEL(sc) SC_FP_OFFSET(sc, SC_FP_CSSEL) -#define SC_FP_DATAOFF(sc) SC_FP_OFFSET(sc, SC_FP_DATAOFF) -#define SC_FP_DATASEL(sc) SC_FP_OFFSET(sc, SC_FP_DATASEL) -#define SC_FP_ST(sc) SC_FP_OFFSET_PTR(sc, SC_FP_ST, struct _fpstate) -#define SC_FXSR_ENV(sc) SC_FP_OFFSET_PTR(sc, SC_FXSR_ENV, void) - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/sigcontext.h b/arch/um/sys-i386/shared/sysdep/sigcontext.h deleted file mode 100644 index f583c87111a..00000000000 --- a/arch/um/sys-i386/shared/sysdep/sigcontext.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __SYS_SIGCONTEXT_I386_H -#define __SYS_SIGCONTEXT_I386_H - -#include "sysdep/sc.h" - -#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) - -#define GET_FAULTINFO_FROM_SC(fi, sc) \ - { \ - (fi).cr2 = SC_CR2(sc); \ - (fi).error_code = SC_ERR(sc); \ - (fi).trap_no = SC_TRAPNO(sc); \ - } - -/* This is Page Fault */ -#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) - -/* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */ -#define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo) - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/skas_ptrace.h b/arch/um/sys-i386/shared/sysdep/skas_ptrace.h deleted file mode 100644 index e27b8a79177..00000000000 --- a/arch/um/sys-i386/shared/sysdep/skas_ptrace.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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/sys-i386/shared/sysdep/stub.h b/arch/um/sys-i386/shared/sysdep/stub.h deleted file mode 100644 index 977dedd9221..00000000000 --- a/arch/um/sys-i386/shared/sysdep/stub.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_STUB_H -#define __SYSDEP_STUB_H - -#include <sys/mman.h> -#include <asm/ptrace.h> -#include <asm/unistd.h> -#include "as-layout.h" -#include "stub-data.h" -#include "kern_constants.h" - -extern void stub_segv_handler(int sig); -extern void stub_clone_handler(void); - -#define STUB_SYSCALL_RET EAX -#define STUB_MMAP_NR __NR_mmap2 -#define MMAP_OFFSET(o) ((o) >> UM_KERN_PAGE_SHIFT) - -static inline long stub_syscall0(long syscall) -{ - long ret; - - __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall)); - - return ret; -} - -static inline long stub_syscall1(long syscall, long arg1) -{ - long ret; - - __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1)); - - return ret; -} - -static inline long stub_syscall2(long syscall, long arg1, long arg2) -{ - long ret; - - __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), - "c" (arg2)); - - return ret; -} - -static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3) -{ - long ret; - - __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), - "c" (arg2), "d" (arg3)); - - return ret; -} - -static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3, - long arg4) -{ - long ret; - - __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), - "c" (arg2), "d" (arg3), "S" (arg4)); - - return ret; -} - -static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3, - long arg4, long arg5) -{ - long ret; - - __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), - "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)); - - return ret; -} - -static inline void trap_myself(void) -{ - __asm("int3"); -} - -static inline void remap_stack(int fd, unsigned long offset) -{ - __asm__ volatile ("movl %%eax,%%ebp ; movl %0,%%eax ; int $0x80 ;" - "movl %7, %%ebx ; movl %%eax, (%%ebx)" - : : "g" (STUB_MMAP_NR), "b" (STUB_DATA), - "c" (UM_KERN_PAGE_SIZE), - "d" (PROT_READ | PROT_WRITE), - "S" (MAP_FIXED | MAP_SHARED), "D" (fd), - "a" (offset), - "i" (&((struct stub_data *) STUB_DATA)->err) - : "memory"); -} - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/syscalls.h b/arch/um/sys-i386/shared/sysdep/syscalls.h deleted file mode 100644 index 05cb796aecb..00000000000 --- a/arch/um/sys-i386/shared/sysdep/syscalls.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2000 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include "asm/unistd.h" -#include "sysdep/ptrace.h" - -typedef long syscall_handler_t(struct pt_regs); - -/* Not declared on x86, incompatible declarations on x86_64, so these have - * to go here rather than in sys_call_table.c - */ -extern syscall_handler_t sys_rt_sigaction; - -extern syscall_handler_t *sys_call_table[]; - -#define EXECUTE_SYSCALL(syscall, regs) \ - ((long (*)(struct syscall_args)) \ - (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs)) diff --git a/arch/um/sys-i386/shared/sysdep/system.h b/arch/um/sys-i386/shared/sysdep/system.h deleted file mode 100644 index d1b93c43620..00000000000 --- a/arch/um/sys-i386/shared/sysdep/system.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef _ASM_X86_SYSTEM_H_ -#define _ASM_X86_SYSTEM_H_ - -#include <asm/asm.h> -#include <asm/segment.h> -#include <asm/cpufeature.h> -#include <asm/cmpxchg.h> -#include <asm/nops.h> - -#include <linux/kernel.h> -#include <linux/irqflags.h> - -/* entries in ARCH_DLINFO: */ -#ifdef CONFIG_IA32_EMULATION -# define AT_VECTOR_SIZE_ARCH 2 -#else -# define AT_VECTOR_SIZE_ARCH 1 -#endif - -extern unsigned long arch_align_stack(unsigned long sp); - -void default_idle(void); - -/* - * Force strict CPU ordering. - * And yes, this is required on UP too when we're talking - * to devices. - */ -#ifdef CONFIG_X86_32 -/* - * Some non-Intel clones support out of order store. wmb() ceases to be a - * nop for these. - */ -#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) -#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) -#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) -#else -#define mb() asm volatile("mfence":::"memory") -#define rmb() asm volatile("lfence":::"memory") -#define wmb() asm volatile("sfence" ::: "memory") -#endif - -/** - * read_barrier_depends - Flush all pending reads that subsequents reads - * depend on. - * - * No data-dependent reads from memory-like regions are ever reordered - * over this barrier. All reads preceding this primitive are guaranteed - * to access memory (but not necessarily other CPUs' caches) before any - * reads following this primitive that depend on the data return by - * any of the preceding reads. This primitive is much lighter weight than - * rmb() on most CPUs, and is never heavier weight than is - * rmb(). - * - * These ordering constraints are respected by both the local CPU - * and the compiler. - * - * Ordering is not guaranteed by anything other than these primitives, - * not even by data dependencies. See the documentation for - * memory_barrier() for examples and URLs to more information. - * - * For example, the following code would force ordering (the initial - * value of "a" is zero, "b" is one, and "p" is "&a"): - * - * <programlisting> - * CPU 0 CPU 1 - * - * b = 2; - * memory_barrier(); - * p = &b; q = p; - * read_barrier_depends(); - * d = *q; - * </programlisting> - * - * because the read of "*q" depends on the read of "p" and these - * two reads are separated by a read_barrier_depends(). However, - * the following code, with the same initial values for "a" and "b": - * - * <programlisting> - * CPU 0 CPU 1 - * - * a = 2; - * memory_barrier(); - * b = 3; y = b; - * read_barrier_depends(); - * x = a; - * </programlisting> - * - * does not enforce ordering, since there is no data dependency between - * the read of "a" and the read of "b". Therefore, on some CPUs, such - * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() - * in cases like this where there are no data dependencies. - **/ - -#define read_barrier_depends() do { } while (0) - -#ifdef CONFIG_SMP -#define smp_mb() mb() -#ifdef CONFIG_X86_PPRO_FENCE -# define smp_rmb() rmb() -#else -# define smp_rmb() barrier() -#endif -#ifdef CONFIG_X86_OOSTORE -# define smp_wmb() wmb() -#else -# define smp_wmb() barrier() -#endif -#define smp_read_barrier_depends() read_barrier_depends() -#define set_mb(var, value) do { (void)xchg(&var, value); } while (0) -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while (0) -#define set_mb(var, value) do { var = value; barrier(); } while (0) -#endif - -/* - * Stop RDTSC speculation. This is needed when you need to use RDTSC - * (or get_cycles or vread that possibly accesses the TSC) in a defined - * code region. - * - * (Could use an alternative three way for this if there was one.) - */ -static inline void rdtsc_barrier(void) -{ - alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC); - alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); -} - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/tls.h b/arch/um/sys-i386/shared/sysdep/tls.h deleted file mode 100644 index 34550755b2a..00000000000 --- a/arch/um/sys-i386/shared/sysdep/tls.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _SYSDEP_TLS_H -#define _SYSDEP_TLS_H - -# ifndef __KERNEL__ - -/* Change name to avoid conflicts with the original one from <asm/ldt.h>, which - * may be named user_desc (but in 2.4 and in header matching its API was named - * modify_ldt_ldt_s). */ - -typedef struct um_dup_user_desc { - unsigned int entry_number; - unsigned int base_addr; - unsigned int limit; - unsigned int seg_32bit:1; - unsigned int contents:2; - unsigned int read_exec_only:1; - unsigned int limit_in_pages:1; - unsigned int seg_not_present:1; - unsigned int useable:1; -} user_desc_t; - -# else /* __KERNEL__ */ - -# include <ldt.h> -typedef struct user_desc user_desc_t; - -# endif /* __KERNEL__ */ - -#define GDT_ENTRY_TLS_MIN_I386 6 -#define GDT_ENTRY_TLS_MIN_X86_64 12 - -#endif /* _SYSDEP_TLS_H */ diff --git a/arch/um/sys-i386/shared/sysdep/vm-flags.h b/arch/um/sys-i386/shared/sysdep/vm-flags.h deleted file mode 100644 index e0d24c568db..00000000000 --- a/arch/um/sys-i386/shared/sysdep/vm-flags.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#ifndef __VM_FLAGS_I386_H -#define __VM_FLAGS_I386_H - -#define VM_DATA_DEFAULT_FLAGS \ - (VM_READ | VM_WRITE | \ - ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - -#endif diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c deleted file mode 100644 index 129647375a6..00000000000 --- a/arch/um/sys-i386/signal.c +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include <linux/ptrace.h> -#include <asm/unistd.h> -#include <asm/uaccess.h> -#include <asm/ucontext.h> -#include "frame_kern.h" -#include "skas.h" - -void copy_sc(struct uml_pt_regs *regs, void *from) -{ - struct sigcontext *sc = from; - - REGS_GS(regs->gp) = sc->gs; - REGS_FS(regs->gp) = sc->fs; - REGS_ES(regs->gp) = sc->es; - REGS_DS(regs->gp) = sc->ds; - REGS_EDI(regs->gp) = sc->di; - REGS_ESI(regs->gp) = sc->si; - REGS_EBP(regs->gp) = sc->bp; - REGS_SP(regs->gp) = sc->sp; - REGS_EBX(regs->gp) = sc->bx; - REGS_EDX(regs->gp) = sc->dx; - REGS_ECX(regs->gp) = sc->cx; - REGS_EAX(regs->gp) = sc->ax; - REGS_IP(regs->gp) = sc->ip; - REGS_CS(regs->gp) = sc->cs; - REGS_EFLAGS(regs->gp) = sc->flags; - REGS_SS(regs->gp) = sc->ss; -} - -/* - * FPU tag word conversions. - */ - -static inline unsigned short twd_i387_to_fxsr(unsigned short twd) -{ - unsigned int tmp; /* to avoid 16 bit prefixes in the code */ - - /* Transform each pair of bits into 01 (valid) or 00 (empty) */ - tmp = ~twd; - tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */ - /* and move the valid bits to the lower byte. */ - tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */ - tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */ - tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */ - return tmp; -} - -static inline unsigned long twd_fxsr_to_i387(struct user_fxsr_struct *fxsave) -{ - struct _fpxreg *st = NULL; - unsigned long twd = (unsigned long) fxsave->twd; - unsigned long tag; - unsigned long ret = 0xffff0000; - int i; - -#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16); - - for (i = 0; i < 8; i++) { - if (twd & 0x1) { - st = (struct _fpxreg *) FPREG_ADDR(fxsave, i); - - switch (st->exponent & 0x7fff) { - case 0x7fff: - tag = 2; /* Special */ - break; - case 0x0000: - if ( !st->significand[0] && - !st->significand[1] && - !st->significand[2] && - !st->significand[3] ) { - tag = 1; /* Zero */ - } else { - tag = 2; /* Special */ - } - break; - default: - if (st->significand[3] & 0x8000) { - tag = 0; /* Valid */ - } else { - tag = 2; /* Special */ - } - break; - } - } else { - tag = 3; /* Empty */ - } - ret |= (tag << (2 * i)); - twd = twd >> 1; - } - return ret; -} - -static int convert_fxsr_to_user(struct _fpstate __user *buf, - struct user_fxsr_struct *fxsave) -{ - unsigned long env[7]; - struct _fpreg __user *to; - struct _fpxreg *from; - int i; - - env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul; - env[1] = (unsigned long)fxsave->swd | 0xffff0000ul; - env[2] = twd_fxsr_to_i387(fxsave); - env[3] = fxsave->fip; - env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16); - env[5] = fxsave->foo; - env[6] = fxsave->fos; - - if (__copy_to_user(buf, env, 7 * sizeof(unsigned long))) - return 1; - - to = &buf->_st[0]; - from = (struct _fpxreg *) &fxsave->st_space[0]; - for (i = 0; i < 8; i++, to++, from++) { - unsigned long __user *t = (unsigned long __user *)to; - unsigned long *f = (unsigned long *)from; - - if (__put_user(*f, t) || - __put_user(*(f + 1), t + 1) || - __put_user(from->exponent, &to->exponent)) - return 1; - } - return 0; -} - -static int convert_fxsr_from_user(struct user_fxsr_struct *fxsave, - struct _fpstate __user *buf) -{ - unsigned long env[7]; - struct _fpxreg *to; - struct _fpreg __user *from; - int i; - - if (copy_from_user( env, buf, 7 * sizeof(long))) - return 1; - - fxsave->cwd = (unsigned short)(env[0] & 0xffff); - fxsave->swd = (unsigned short)(env[1] & 0xffff); - fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff)); - fxsave->fip = env[3]; - fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16); - fxsave->fcs = (env[4] & 0xffff); - fxsave->foo = env[5]; - fxsave->fos = env[6]; - - to = (struct _fpxreg *) &fxsave->st_space[0]; - from = &buf->_st[0]; - for (i = 0; i < 8; i++, to++, from++) { - unsigned long *t = (unsigned long *)to; - unsigned long __user *f = (unsigned long __user *)from; - - if (__get_user(*t, f) || - __get_user(*(t + 1), f + 1) || - __get_user(to->exponent, &from->exponent)) - return 1; - } - return 0; -} - -extern int have_fpx_regs; - -static int copy_sc_from_user(struct pt_regs *regs, - struct sigcontext __user *from) -{ - struct sigcontext sc; - int err, pid; - - err = copy_from_user(&sc, from, sizeof(sc)); - if (err) - return err; - - pid = userspace_pid[current_thread_info()->cpu]; - copy_sc(®s->regs, &sc); - if (have_fpx_regs) { - struct user_fxsr_struct fpx; - - err = copy_from_user(&fpx, - &((struct _fpstate __user *)sc.fpstate)->_fxsr_env[0], - sizeof(struct user_fxsr_struct)); - if (err) - return 1; - - err = convert_fxsr_from_user(&fpx, sc.fpstate); - if (err) - return 1; - - err = restore_fpx_registers(pid, (unsigned long *) &fpx); - if (err < 0) { - printk(KERN_ERR "copy_sc_from_user - " - "restore_fpx_registers failed, errno = %d\n", - -err); - return 1; - } - } - else { - struct user_i387_struct fp; - - err = copy_from_user(&fp, sc.fpstate, - sizeof(struct user_i387_struct)); - if (err) - return 1; - - err = restore_fp_registers(pid, (unsigned long *) &fp); - if (err < 0) { - printk(KERN_ERR "copy_sc_from_user - " - "restore_fp_registers failed, errno = %d\n", - -err); - return 1; - } - } - - return 0; -} - -static int copy_sc_to_user(struct sigcontext __user *to, - struct _fpstate __user *to_fp, struct pt_regs *regs, - unsigned long sp) -{ - struct sigcontext sc; - struct faultinfo * fi = ¤t->thread.arch.faultinfo; - int err, pid; - - sc.gs = REGS_GS(regs->regs.gp); - sc.fs = REGS_FS(regs->regs.gp); - sc.es = REGS_ES(regs->regs.gp); - sc.ds = REGS_DS(regs->regs.gp); - sc.di = REGS_EDI(regs->regs.gp); - sc.si = REGS_ESI(regs->regs.gp); - sc.bp = REGS_EBP(regs->regs.gp); - sc.sp = sp; - sc.bx = REGS_EBX(regs->regs.gp); - sc.dx = REGS_EDX(regs->regs.gp); - sc.cx = REGS_ECX(regs->regs.gp); - sc.ax = REGS_EAX(regs->regs.gp); - sc.ip = REGS_IP(regs->regs.gp); - sc.cs = REGS_CS(regs->regs.gp); - sc.flags = REGS_EFLAGS(regs->regs.gp); - sc.sp_at_signal = regs->regs.gp[UESP]; - sc.ss = regs->regs.gp[SS]; - sc.cr2 = fi->cr2; - sc.err = fi->error_code; - sc.trapno = fi->trap_no; - - to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1)); - sc.fpstate = to_fp; - - pid = userspace_pid[current_thread_info()->cpu]; - if (have_fpx_regs) { - struct user_fxsr_struct fpx; - - err = save_fpx_registers(pid, (unsigned long *) &fpx); - if (err < 0){ - printk(KERN_ERR "copy_sc_to_user - save_fpx_registers " - "failed, errno = %d\n", err); - return 1; - } - - err = convert_fxsr_to_user(to_fp, &fpx); - if (err) - return 1; - - err |= __put_user(fpx.swd, &to_fp->status); - err |= __put_user(X86_FXSR_MAGIC, &to_fp->magic); - if (err) - return 1; - - if (copy_to_user(&to_fp->_fxsr_env[0], &fpx, - sizeof(struct user_fxsr_struct))) - return 1; - } - else { - struct user_i387_struct fp; - - err = save_fp_registers(pid, (unsigned long *) &fp); - if (copy_to_user(to_fp, &fp, sizeof(struct user_i387_struct))) - return 1; - } - - return copy_to_user(to, &sc, sizeof(sc)); -} - -static int copy_ucontext_to_user(struct ucontext __user *uc, - struct _fpstate __user *fp, sigset_t *set, - unsigned long sp) -{ - int err = 0; - - err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp); - err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags); - err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size); - err |= copy_sc_to_user(&uc->uc_mcontext, fp, ¤t->thread.regs, sp); - err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set)); - return err; -} - -struct sigframe -{ - char __user *pretcode; - int sig; - struct sigcontext sc; - struct _fpstate fpstate; - unsigned long extramask[_NSIG_WORDS-1]; - char retcode[8]; -}; - -struct rt_sigframe -{ - char __user *pretcode; - int sig; - struct siginfo __user *pinfo; - void __user *puc; - struct siginfo info; - struct ucontext uc; - struct _fpstate fpstate; - char retcode[8]; -}; - -int setup_signal_stack_sc(unsigned long stack_top, int sig, - struct k_sigaction *ka, struct pt_regs *regs, - sigset_t *mask) -{ - struct sigframe __user *frame; - void __user *restorer; - unsigned long save_sp = PT_REGS_SP(regs); - int err = 0; - - /* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */ - stack_top = ((stack_top + 4) & -16UL) - 4; - frame = (struct sigframe __user *) stack_top - 1; - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - return 1; - - restorer = frame->retcode; - if (ka->sa.sa_flags & SA_RESTORER) - restorer = ka->sa.sa_restorer; - - /* Update SP now because the page fault handler refuses to extend - * the stack if the faulting address is too far below the current - * SP, which frame now certainly is. If there's an error, the original - * value is restored on the way out. - * When writing the sigcontext to the stack, we have to write the - * original value, so that's passed to copy_sc_to_user, which does - * the right thing with it. - */ - PT_REGS_SP(regs) = (unsigned long) frame; - - err |= __put_user(restorer, &frame->pretcode); - err |= __put_user(sig, &frame->sig); - err |= copy_sc_to_user(&frame->sc, NULL, regs, save_sp); - err |= __put_user(mask->sig[0], &frame->sc.oldmask); - if (_NSIG_WORDS > 1) - err |= __copy_to_user(&frame->extramask, &mask->sig[1], - sizeof(frame->extramask)); - - /* - * This is popl %eax ; movl $,%eax ; int $0x80 - * - * WE DO NOT USE IT ANY MORE! It's only left here for historical - * reasons and because gdb uses it as a signature to notice - * signal handler stack frames. - */ - err |= __put_user(0xb858, (short __user *)(frame->retcode+0)); - err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2)); - err |= __put_user(0x80cd, (short __user *)(frame->retcode+6)); - - if (err) - goto err; - - PT_REGS_SP(regs) = (unsigned long) frame; - PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; - PT_REGS_EAX(regs) = (unsigned long) sig; - PT_REGS_EDX(regs) = (unsigned long) 0; - PT_REGS_ECX(regs) = (unsigned long) 0; - - if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) - ptrace_notify(SIGTRAP); - return 0; - -err: - PT_REGS_SP(regs) = save_sp; - return err; -} - -int setup_signal_stack_si(unsigned long stack_top, int sig, - struct k_sigaction *ka, struct pt_regs *regs, - siginfo_t *info, sigset_t *mask) -{ - struct rt_sigframe __user *frame; - void __user *restorer; - unsigned long save_sp = PT_REGS_SP(regs); - int err = 0; - - stack_top &= -8UL; - frame = (struct rt_sigframe __user *) stack_top - 1; - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - return 1; - - restorer = frame->retcode; - if (ka->sa.sa_flags & SA_RESTORER) - restorer = ka->sa.sa_restorer; - - /* See comment above about why this is here */ - PT_REGS_SP(regs) = (unsigned long) frame; - - err |= __put_user(restorer, &frame->pretcode); - err |= __put_user(sig, &frame->sig); - err |= __put_user(&frame->info, &frame->pinfo); - err |= __put_user(&frame->uc, &frame->puc); - err |= copy_siginfo_to_user(&frame->info, info); - err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask, - save_sp); - - /* - * This is movl $,%eax ; int $0x80 - * - * WE DO NOT USE IT ANY MORE! It's only left here for historical - * reasons and because gdb uses it as a signature to notice - * signal handler stack frames. - */ - err |= __put_user(0xb8, (char __user *)(frame->retcode+0)); - err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1)); - err |= __put_user(0x80cd, (short __user *)(frame->retcode+5)); - - if (err) - goto err; - - PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; - PT_REGS_EAX(regs) = (unsigned long) sig; - PT_REGS_EDX(regs) = (unsigned long) &frame->info; - PT_REGS_ECX(regs) = (unsigned long) &frame->uc; - - if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) - ptrace_notify(SIGTRAP); - return 0; - -err: - PT_REGS_SP(regs) = save_sp; - return err; -} - -long sys_sigreturn(struct pt_regs regs) -{ - unsigned long sp = PT_REGS_SP(¤t->thread.regs); - struct sigframe __user *frame = (struct sigframe __user *)(sp - 8); - sigset_t set; - struct sigcontext __user *sc = &frame->sc; - unsigned long __user *oldmask = &sc->oldmask; - unsigned long __user *extramask = frame->extramask; - int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); - - if (copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) || - copy_from_user(&set.sig[1], extramask, sig_size)) - goto segfault; - - sigdelsetmask(&set, ~_BLOCKABLE); - - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - if (copy_sc_from_user(¤t->thread.regs, sc)) - goto segfault; - - /* Avoid ERESTART handling */ - PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; - return PT_REGS_SYSCALL_RET(¤t->thread.regs); - - segfault: - force_sig(SIGSEGV, current); - return 0; -} - -long sys_rt_sigreturn(struct pt_regs regs) -{ - unsigned long sp = PT_REGS_SP(¤t->thread.regs); - struct rt_sigframe __user *frame = - (struct rt_sigframe __user *) (sp - 4); - sigset_t set; - struct ucontext __user *uc = &frame->uc; - int sig_size = _NSIG_WORDS * sizeof(unsigned long); - - if (copy_from_user(&set, &uc->uc_sigmask, sig_size)) - goto segfault; - - sigdelsetmask(&set, ~_BLOCKABLE); - - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext)) - goto segfault; - - /* Avoid ERESTART handling */ - PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; - return PT_REGS_SYSCALL_RET(¤t->thread.regs); - - segfault: - force_sig(SIGSEGV, current); - return 0; -} diff --git a/arch/um/sys-i386/stub.S b/arch/um/sys-i386/stub.S deleted file mode 100644 index 54a36ec20cb..00000000000 --- a/arch/um/sys-i386/stub.S +++ /dev/null @@ -1,51 +0,0 @@ -#include "as-layout.h" - - .globl syscall_stub -.section .__syscall_stub, "ax" - - .globl batch_syscall_stub -batch_syscall_stub: - /* load pointer to first operation */ - mov $(STUB_DATA+8), %esp - -again: - /* load length of additional data */ - mov 0x0(%esp), %eax - - /* if(length == 0) : end of list */ - /* write possible 0 to header */ - mov %eax, STUB_DATA+4 - cmpl $0, %eax - jz done - - /* save current pointer */ - mov %esp, STUB_DATA+4 - - /* skip additional data */ - add %eax, %esp - - /* load syscall-# */ - pop %eax - - /* load syscall params */ - pop %ebx - pop %ecx - pop %edx - pop %esi - pop %edi - pop %ebp - - /* execute syscall */ - int $0x80 - - /* check return value */ - pop %ebx - cmp %ebx, %eax - je again - -done: - /* save return value */ - mov %eax, STUB_DATA - - /* stop */ - int3 diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c deleted file mode 100644 index 28ccf737a79..00000000000 --- a/arch/um/sys-i386/stub_segv.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include "sysdep/stub.h" -#include "sysdep/sigcontext.h" - -void __attribute__ ((__section__ (".__syscall_stub"))) -stub_segv_handler(int sig) -{ - struct sigcontext *sc = (struct sigcontext *) (&sig + 1); - - GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), sc); - - trap_myself(); -} diff --git a/arch/um/sys-i386/sys_call_table.S b/arch/um/sys-i386/sys_call_table.S deleted file mode 100644 index de274071455..00000000000 --- a/arch/um/sys-i386/sys_call_table.S +++ /dev/null @@ -1,28 +0,0 @@ -#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 old_mmap sys_old_mmap - -#define ptregs_fork sys_fork -#define ptregs_execve sys_execve -#define ptregs_iopl sys_iopl -#define ptregs_vm86old sys_vm86old -#define ptregs_sigreturn sys_sigreturn -#define ptregs_clone sys_clone -#define ptregs_vm86 sys_vm86 -#define ptregs_rt_sigreturn sys_rt_sigreturn -#define ptregs_sigaltstack sys_sigaltstack -#define ptregs_vfork sys_vfork - -.section .rodata,"a" - -#include "../../x86/kernel/syscall_table_32.S" - -ENTRY(syscall_table_size) -.long .-sys_call_table diff --git a/arch/um/sys-i386/syscalls.c b/arch/um/sys-i386/syscalls.c deleted file mode 100644 index 70ca357393b..00000000000 --- a/arch/um/sys-i386/syscalls.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#include "linux/sched.h" -#include "linux/shm.h" -#include "linux/ipc.h" -#include "linux/syscalls.h" -#include "asm/mman.h" -#include "asm/uaccess.h" -#include "asm/unistd.h" - -/* - * The prototype on i386 is: - * - * int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr) - * - * and the "newtls" arg. on i386 is read by copy_thread directly from the - * register saved on the stack. - */ -long sys_clone(unsigned long clone_flags, unsigned long newsp, - int __user *parent_tid, void *newtls, int __user *child_tid) -{ - long ret; - - if (!newsp) - newsp = UPT_SP(¤t->thread.regs.regs); - - current->thread.forking = 1; - ret = do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid, - child_tid); - current->thread.forking = 0; - return ret; -} - -long sys_sigaction(int sig, const struct old_sigaction __user *act, - struct old_sigaction __user *oact) -{ - struct k_sigaction new_ka, old_ka; - int ret; - - if (act) { - old_sigset_t mask; - if (!access_ok(VERIFY_READ, act, sizeof(*act)) || - __get_user(new_ka.sa.sa_handler, &act->sa_handler) || - __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) - return -EFAULT; - __get_user(new_ka.sa.sa_flags, &act->sa_flags); - __get_user(mask, &act->sa_mask); - siginitset(&new_ka.sa.sa_mask, mask); - } - - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); - - if (!ret && oact) { - if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || - __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || - __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) - return -EFAULT; - __put_user(old_ka.sa.sa_flags, &oact->sa_flags); - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); - } - - return ret; -} diff --git a/arch/um/sys-i386/sysrq.c b/arch/um/sys-i386/sysrq.c deleted file mode 100644 index 171b3e9dc86..00000000000 --- a/arch/um/sys-i386/sysrq.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#include "linux/kernel.h" -#include "linux/smp.h" -#include "linux/sched.h" -#include "linux/kallsyms.h" -#include "asm/ptrace.h" -#include "sysrq.h" - -/* This is declared by <linux/sched.h> */ -void show_regs(struct pt_regs *regs) -{ - printk("\n"); - printk("EIP: %04lx:[<%08lx>] CPU: %d %s", - 0xffff & PT_REGS_CS(regs), PT_REGS_IP(regs), - smp_processor_id(), print_tainted()); - if (PT_REGS_CS(regs) & 3) - printk(" ESP: %04lx:%08lx", 0xffff & PT_REGS_SS(regs), - PT_REGS_SP(regs)); - printk(" EFLAGS: %08lx\n %s\n", PT_REGS_EFLAGS(regs), - print_tainted()); - printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", - PT_REGS_EAX(regs), PT_REGS_EBX(regs), - PT_REGS_ECX(regs), - PT_REGS_EDX(regs)); - printk("ESI: %08lx EDI: %08lx EBP: %08lx", - PT_REGS_ESI(regs), PT_REGS_EDI(regs), - PT_REGS_EBP(regs)); - printk(" DS: %04lx ES: %04lx\n", - 0xffff & PT_REGS_DS(regs), - 0xffff & PT_REGS_ES(regs)); - - show_trace(NULL, (unsigned long *) ®s); -} - -/* Copied from i386. */ -static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) -{ - return p > (void *)tinfo && - p < (void *)tinfo + THREAD_SIZE - 3; -} - -/* Adapted from i386 (we also print the address we read from). */ -static inline unsigned long print_context_stack(struct thread_info *tinfo, - unsigned long *stack, unsigned long ebp) -{ - unsigned long addr; - -#ifdef CONFIG_FRAME_POINTER - while (valid_stack_ptr(tinfo, (void *)ebp)) { - addr = *(unsigned long *)(ebp + 4); - printk("%08lx: [<%08lx>]", ebp + 4, addr); - print_symbol(" %s", addr); - printk("\n"); - ebp = *(unsigned long *)ebp; - } -#else - while (valid_stack_ptr(tinfo, stack)) { - addr = *stack; - if (__kernel_text_address(addr)) { - printk("%08lx: [<%08lx>]", (unsigned long) stack, addr); - print_symbol(" %s", addr); - printk("\n"); - } - stack++; - } -#endif - return ebp; -} - -void show_trace(struct task_struct* task, unsigned long * stack) -{ - unsigned long ebp; - struct thread_info *context; - - /* Turn this into BUG_ON if possible. */ - if (!stack) { - stack = (unsigned long*) &stack; - printk("show_trace: got NULL stack, implicit assumption task == current"); - WARN_ON(1); - } - - if (!task) - task = current; - - if (task != current) { - ebp = (unsigned long) KSTK_EBP(task); - } else { - asm ("movl %%ebp, %0" : "=r" (ebp) : ); - } - - context = (struct thread_info *) - ((unsigned long)stack & (~(THREAD_SIZE - 1))); - print_context_stack(context, stack, ebp); - - printk("\n"); -} - diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c deleted file mode 100644 index c6c7131e563..00000000000 --- a/arch/um/sys-i386/tls.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * Copyright (C) 2005 Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> - * Licensed under the GPL - */ - -#include "linux/percpu.h" -#include "linux/sched.h" -#include "asm/uaccess.h" -#include "os.h" -#include "skas.h" -#include "sysdep/tls.h" - -/* - * If needed we can detect when it's uninitialized. - * - * These are initialized in an initcall and unchanged thereafter. - */ -static int host_supports_tls = -1; -int host_gdt_entry_tls_min; - -int do_set_thread_area(struct user_desc *info) -{ - int ret; - u32 cpu; - - cpu = get_cpu(); - ret = os_set_thread_area(info, userspace_pid[cpu]); - put_cpu(); - - if (ret) - printk(KERN_ERR "PTRACE_SET_THREAD_AREA failed, err = %d, " - "index = %d\n", ret, info->entry_number); - - return ret; -} - -int do_get_thread_area(struct user_desc *info) -{ - int ret; - u32 cpu; - - cpu = get_cpu(); - ret = os_get_thread_area(info, userspace_pid[cpu]); - put_cpu(); - - if (ret) - printk(KERN_ERR "PTRACE_GET_THREAD_AREA failed, err = %d, " - "index = %d\n", ret, info->entry_number); - - return ret; -} - -/* - * sys_get_thread_area: get a yet unused TLS descriptor index. - * XXX: Consider leaving one free slot for glibc usage at first place. This must - * be done here (and by changing GDT_ENTRY_TLS_* macros) and nowhere else. - * - * Also, this must be tested when compiling in SKAS mode with dynamic linking - * and running against NPTL. - */ -static int get_free_idx(struct task_struct* task) -{ - struct thread_struct *t = &task->thread; - int idx; - - if (!t->arch.tls_array) - return GDT_ENTRY_TLS_MIN; - - for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++) - if (!t->arch.tls_array[idx].present) - return idx + GDT_ENTRY_TLS_MIN; - return -ESRCH; -} - -static inline void clear_user_desc(struct user_desc* info) -{ - /* Postcondition: LDT_empty(info) returns true. */ - memset(info, 0, sizeof(*info)); - - /* - * Check the LDT_empty or the i386 sys_get_thread_area code - we obtain - * indeed an empty user_desc. - */ - info->read_exec_only = 1; - info->seg_not_present = 1; -} - -#define O_FORCE 1 - -static int load_TLS(int flags, struct task_struct *to) -{ - int ret = 0; - int idx; - - for (idx = GDT_ENTRY_TLS_MIN; idx < GDT_ENTRY_TLS_MAX; idx++) { - struct uml_tls_struct* curr = - &to->thread.arch.tls_array[idx - GDT_ENTRY_TLS_MIN]; - - /* - * Actually, now if it wasn't flushed it gets cleared and - * flushed to the host, which will clear it. - */ - if (!curr->present) { - if (!curr->flushed) { - clear_user_desc(&curr->tls); - curr->tls.entry_number = idx; - } else { - WARN_ON(!LDT_empty(&curr->tls)); - continue; - } - } - - if (!(flags & O_FORCE) && curr->flushed) - continue; - - ret = do_set_thread_area(&curr->tls); - if (ret) - goto out; - - curr->flushed = 1; - } -out: - return ret; -} - -/* - * Verify if we need to do a flush for the new process, i.e. if there are any - * present desc's, only if they haven't been flushed. - */ -static inline int needs_TLS_update(struct task_struct *task) -{ - int i; - int ret = 0; - - for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) { - struct uml_tls_struct* curr = - &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN]; - - /* - * Can't test curr->present, we may need to clear a descriptor - * which had a value. - */ - if (curr->flushed) - continue; - ret = 1; - break; - } - return ret; -} - -/* - * On a newly forked process, the TLS descriptors haven't yet been flushed. So - * we mark them as such and the first switch_to will do the job. - */ -void clear_flushed_tls(struct task_struct *task) -{ - int i; - - for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) { - struct uml_tls_struct* curr = - &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN]; - - /* - * Still correct to do this, if it wasn't present on the host it - * will remain as flushed as it was. - */ - if (!curr->present) - continue; - - curr->flushed = 0; - } -} - -/* - * In SKAS0 mode, currently, multiple guest threads sharing the same ->mm have a - * common host process. So this is needed in SKAS0 too. - * - * However, if each thread had a different host process (and this was discussed - * for SMP support) this won't be needed. - * - * And this will not need be used when (and if) we'll add support to the host - * SKAS patch. - */ - -int arch_switch_tls(struct task_struct *to) -{ - if (!host_supports_tls) - return 0; - - /* - * We have no need whatsoever to switch TLS for kernel threads; beyond - * that, that would also result in us calling os_set_thread_area with - * userspace_pid[cpu] == 0, which gives an error. - */ - if (likely(to->mm)) - return load_TLS(O_FORCE, to); - - return 0; -} - -static int set_tls_entry(struct task_struct* task, struct user_desc *info, - int idx, int flushed) -{ - struct thread_struct *t = &task->thread; - - if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) - return -EINVAL; - - t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls = *info; - t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].present = 1; - t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed = flushed; - - return 0; -} - -int arch_copy_tls(struct task_struct *new) -{ - struct user_desc info; - int idx, ret = -EFAULT; - - if (copy_from_user(&info, - (void __user *) UPT_ESI(&new->thread.regs.regs), - sizeof(info))) - goto out; - - ret = -EINVAL; - if (LDT_empty(&info)) - goto out; - - idx = info.entry_number; - - ret = set_tls_entry(new, &info, idx, 0); -out: - return ret; -} - -/* XXX: use do_get_thread_area to read the host value? I'm not at all sure! */ -static int get_tls_entry(struct task_struct *task, struct user_desc *info, - int idx) -{ - struct thread_struct *t = &task->thread; - - if (!t->arch.tls_array) - goto clear; - - if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) - return -EINVAL; - - if (!t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].present) - goto clear; - - *info = t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls; - -out: - /* - * Temporary debugging check, to make sure that things have been - * flushed. This could be triggered if load_TLS() failed. - */ - if (unlikely(task == current && - !t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed)) { - printk(KERN_ERR "get_tls_entry: task with pid %d got here " - "without flushed TLS.", current->pid); - } - - return 0; -clear: - /* - * When the TLS entry has not been set, the values read to user in the - * tls_array are 0 (because it's cleared at boot, see - * arch/i386/kernel/head.S:cpu_gdt_table). Emulate that. - */ - clear_user_desc(info); - info->entry_number = idx; - goto out; -} - -int sys_set_thread_area(struct user_desc __user *user_desc) -{ - struct user_desc info; - int idx, ret; - - if (!host_supports_tls) - return -ENOSYS; - - if (copy_from_user(&info, user_desc, sizeof(info))) - return -EFAULT; - - idx = info.entry_number; - - if (idx == -1) { - idx = get_free_idx(current); - if (idx < 0) - return idx; - info.entry_number = idx; - /* Tell the user which slot we chose for him.*/ - if (put_user(idx, &user_desc->entry_number)) - return -EFAULT; - } - - ret = do_set_thread_area(&info); - if (ret) - return ret; - return set_tls_entry(current, &info, idx, 1); -} - -/* - * Perform set_thread_area on behalf of the traced child. - * Note: error handling is not done on the deferred load, and this differ from - * i386. However the only possible error are caused by bugs. - */ -int ptrace_set_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc) -{ - struct user_desc info; - - if (!host_supports_tls) - return -EIO; - - if (copy_from_user(&info, user_desc, sizeof(info))) - return -EFAULT; - - return set_tls_entry(child, &info, idx, 0); -} - -int sys_get_thread_area(struct user_desc __user *user_desc) -{ - struct user_desc info; - int idx, ret; - - if (!host_supports_tls) - return -ENOSYS; - - if (get_user(idx, &user_desc->entry_number)) - return -EFAULT; - - ret = get_tls_entry(current, &info, idx); - if (ret < 0) - goto out; - - if (copy_to_user(user_desc, &info, sizeof(info))) - ret = -EFAULT; - -out: - return ret; -} - -/* - * Perform get_thread_area on behalf of the traced child. - */ -int ptrace_get_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc) -{ - struct user_desc info; - int ret; - - if (!host_supports_tls) - return -EIO; - - ret = get_tls_entry(child, &info, idx); - if (ret < 0) - goto out; - - if (copy_to_user(user_desc, &info, sizeof(info))) - ret = -EFAULT; -out: - return ret; -} - -/* - * This code is really i386-only, but it detects and logs x86_64 GDT indexes - * if a 32-bit UML is running on a 64-bit host. - */ -static int __init __setup_host_supports_tls(void) -{ - check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min); - if (host_supports_tls) { - printk(KERN_INFO "Host TLS support detected\n"); - printk(KERN_INFO "Detected host type: "); - switch (host_gdt_entry_tls_min) { - case GDT_ENTRY_TLS_MIN_I386: - printk(KERN_CONT "i386"); - break; - case GDT_ENTRY_TLS_MIN_X86_64: - printk(KERN_CONT "x86_64"); - break; - } - printk(KERN_CONT " (GDT indexes %d to %d)\n", - host_gdt_entry_tls_min, - host_gdt_entry_tls_min + GDT_ENTRY_TLS_ENTRIES); - } else - printk(KERN_ERR " Host TLS support NOT detected! " - "TLS support inside UML will not work\n"); - return 0; -} - -__initcall(__setup_host_supports_tls); diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c deleted file mode 100644 index 5f883bfe773..00000000000 --- a/arch/um/sys-i386/user-offsets.c +++ /dev/null @@ -1,53 +0,0 @@ -#include <stdio.h> -#include <stddef.h> -#include <signal.h> -#include <sys/poll.h> -#include <sys/user.h> -#include <sys/mman.h> -#include <asm/ptrace.h> - -#define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) - -#define DEFINE_LONGS(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long))) - -#define OFFSET(sym, str, mem) \ - DEFINE(sym, offsetof(struct str, mem)); - -void foo(void) -{ - OFFSET(HOST_SC_TRAPNO, sigcontext, trapno); - OFFSET(HOST_SC_ERR, sigcontext, err); - OFFSET(HOST_SC_CR2, sigcontext, cr2); - - DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct)); - DEFINE_LONGS(HOST_FPX_SIZE, sizeof(struct user_fpxregs_struct)); - - 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)); - - /* XXX Duplicated between i386 and x86_64 */ - DEFINE(UM_POLLIN, POLLIN); - DEFINE(UM_POLLPRI, POLLPRI); - DEFINE(UM_POLLOUT, POLLOUT); - - DEFINE(UM_PROT_READ, PROT_READ); - DEFINE(UM_PROT_WRITE, PROT_WRITE); - DEFINE(UM_PROT_EXEC, PROT_EXEC); -} diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile deleted file mode 100644 index c1ea9eb0446..00000000000 --- a/arch/um/sys-x86_64/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright 2003 PathScale, Inc. -# -# Licensed under the GPL -# - -obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \ - setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \ - sysrq.o ksyms.o tls.o - -subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o \ - lib/rwsem_64.o -subarch-obj-$(CONFIG_MODULES) += kernel/module.o - -ldt-y = ../sys-i386/ldt.o - -USER_OBJS := ptrace_user.o - -USER_OBJS += user-offsets.s -extra-y += user-offsets.s - -UNPROFILE_OBJS := stub_segv.o -CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) - -include arch/um/scripts/Makefile.rules diff --git a/arch/um/sys-x86_64/asm/archparam.h b/arch/um/sys-x86_64/asm/archparam.h deleted file mode 100644 index 6c083663b8d..00000000000 --- a/arch/um/sys-x86_64/asm/archparam.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __UM_ARCHPARAM_X86_64_H -#define __UM_ARCHPARAM_X86_64_H - - -/* No user-accessible fixmap addresses, i.e. vsyscall */ -#define FIXADDR_USER_START 0 -#define FIXADDR_USER_END 0 - -#endif - diff --git a/arch/um/sys-x86_64/asm/elf.h b/arch/um/sys-x86_64/asm/elf.h deleted file mode 100644 index d6d5af37625..00000000000 --- a/arch/um/sys-x86_64/asm/elf.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * - * Licensed under the GPL - */ -#ifndef __UM_ELF_X86_64_H -#define __UM_ELF_X86_64_H - -#include <asm/user.h> -#include "skas.h" - -/* x86-64 relocation types, taken from asm-x86_64/elf.h */ -#define R_X86_64_NONE 0 /* No reloc */ -#define R_X86_64_64 1 /* Direct 64 bit */ -#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ -#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ -#define R_X86_64_PLT32 4 /* 32 bit PLT address */ -#define R_X86_64_COPY 5 /* Copy symbol at runtime */ -#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ -#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ -#define R_X86_64_RELATIVE 8 /* Adjust by program base */ -#define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative - offset to GOT */ -#define R_X86_64_32 10 /* Direct 32 bit zero extended */ -#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ -#define R_X86_64_16 12 /* Direct 16 bit zero extended */ -#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ -#define R_X86_64_8 14 /* Direct 8 bit sign extended */ -#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ - -#define R_X86_64_NUM 16 - -typedef unsigned long elf_greg_t; - -#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -typedef struct user_i387_struct elf_fpregset_t; - -/* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(x) \ - ((x)->e_machine == EM_X86_64) - -#define ELF_CLASS ELFCLASS64 -#define ELF_DATA ELFDATA2LSB -#define ELF_ARCH EM_X86_64 - -#define ELF_PLAT_INIT(regs, load_addr) do { \ - PT_REGS_RBX(regs) = 0; \ - PT_REGS_RCX(regs) = 0; \ - PT_REGS_RDX(regs) = 0; \ - PT_REGS_RSI(regs) = 0; \ - PT_REGS_RDI(regs) = 0; \ - PT_REGS_RBP(regs) = 0; \ - PT_REGS_RAX(regs) = 0; \ - PT_REGS_R8(regs) = 0; \ - PT_REGS_R9(regs) = 0; \ - PT_REGS_R10(regs) = 0; \ - PT_REGS_R11(regs) = 0; \ - PT_REGS_R12(regs) = 0; \ - PT_REGS_R13(regs) = 0; \ - PT_REGS_R14(regs) = 0; \ - PT_REGS_R15(regs) = 0; \ -} while (0) - -#define ELF_CORE_COPY_REGS(pr_reg, _regs) \ - (pr_reg)[0] = (_regs)->regs.gp[0]; \ - (pr_reg)[1] = (_regs)->regs.gp[1]; \ - (pr_reg)[2] = (_regs)->regs.gp[2]; \ - (pr_reg)[3] = (_regs)->regs.gp[3]; \ - (pr_reg)[4] = (_regs)->regs.gp[4]; \ - (pr_reg)[5] = (_regs)->regs.gp[5]; \ - (pr_reg)[6] = (_regs)->regs.gp[6]; \ - (pr_reg)[7] = (_regs)->regs.gp[7]; \ - (pr_reg)[8] = (_regs)->regs.gp[8]; \ - (pr_reg)[9] = (_regs)->regs.gp[9]; \ - (pr_reg)[10] = (_regs)->regs.gp[10]; \ - (pr_reg)[11] = (_regs)->regs.gp[11]; \ - (pr_reg)[12] = (_regs)->regs.gp[12]; \ - (pr_reg)[13] = (_regs)->regs.gp[13]; \ - (pr_reg)[14] = (_regs)->regs.gp[14]; \ - (pr_reg)[15] = (_regs)->regs.gp[15]; \ - (pr_reg)[16] = (_regs)->regs.gp[16]; \ - (pr_reg)[17] = (_regs)->regs.gp[17]; \ - (pr_reg)[18] = (_regs)->regs.gp[18]; \ - (pr_reg)[19] = (_regs)->regs.gp[19]; \ - (pr_reg)[20] = (_regs)->regs.gp[20]; \ - (pr_reg)[21] = current->thread.arch.fs; \ - (pr_reg)[22] = 0; \ - (pr_reg)[23] = 0; \ - (pr_reg)[24] = 0; \ - (pr_reg)[25] = 0; \ - (pr_reg)[26] = 0; - -#define task_pt_regs(t) (&(t)->thread.regs) - -struct task_struct; - -extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu); - -#define ELF_CORE_COPY_FPREGS(t, fpu) elf_core_copy_fpregs(t, fpu) - -#ifdef TIF_IA32 /* XXX */ -#error XXX, indeed - clear_thread_flag(TIF_IA32); -#endif - -#define ELF_EXEC_PAGESIZE 4096 - -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) - -extern long elf_aux_hwcap; -#define ELF_HWCAP (elf_aux_hwcap) - -#define ELF_PLATFORM "x86_64" - -#define SET_PERSONALITY(ex) do ; while(0) - -#endif diff --git a/arch/um/sys-x86_64/asm/module.h b/arch/um/sys-x86_64/asm/module.h deleted file mode 100644 index 8eb79c2d07d..00000000000 --- a/arch/um/sys-x86_64/asm/module.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __UM_MODULE_X86_64_H -#define __UM_MODULE_X86_64_H - -/* UML is simple */ -struct mod_arch_specific -{ -}; - -#define Elf_Shdr Elf64_Shdr -#define Elf_Sym Elf64_Sym -#define Elf_Ehdr Elf64_Ehdr - -#endif - diff --git a/arch/um/sys-x86_64/asm/processor.h b/arch/um/sys-x86_64/asm/processor.h deleted file mode 100644 index 875a26a6261..00000000000 --- a/arch/um/sys-x86_64/asm/processor.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __UM_PROCESSOR_X86_64_H -#define __UM_PROCESSOR_X86_64_H - -/* include faultinfo structure */ -#include "sysdep/faultinfo.h" - -struct arch_thread { - unsigned long debugregs[8]; - int debugregs_seq; - unsigned long fs; - struct faultinfo faultinfo; -}; - -/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ -static inline void rep_nop(void) -{ - __asm__ __volatile__("rep;nop": : :"memory"); -} - -#define cpu_relax() rep_nop() - -#define INIT_ARCH_THREAD { .debugregs = { [ 0 ... 7 ] = 0 }, \ - .debugregs_seq = 0, \ - .fs = 0, \ - .faultinfo = { 0, 0, 0 } } - -static inline void arch_flush_thread(struct arch_thread *thread) -{ -} - -static inline void arch_copy_thread(struct arch_thread *from, - struct arch_thread *to) -{ - to->fs = from->fs; -} - -#include <asm/user.h> - -#define current_text_addr() \ - ({ void *pc; __asm__("movq $1f,%0\n1:":"=g" (pc)); pc; }) - -#define ARCH_IS_STACKGROW(address) \ - (address + 128 >= UPT_SP(¤t->thread.regs.regs)) - -#define KSTK_EIP(tsk) KSTK_REG(tsk, RIP) -#define KSTK_ESP(tsk) KSTK_REG(tsk, RSP) - -#include "asm/processor-generic.h" - -#endif diff --git a/arch/um/sys-x86_64/asm/ptrace.h b/arch/um/sys-x86_64/asm/ptrace.h deleted file mode 100644 index 83d8c473b90..00000000000 --- a/arch/um/sys-x86_64/asm/ptrace.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __UM_PTRACE_X86_64_H -#define __UM_PTRACE_X86_64_H - -#include "linux/compiler.h" -#include "asm/errno.h" - -#define __FRAME_OFFSETS /* Needed to get the R* macros */ -#include "asm/ptrace-generic.h" - -#define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64 - -#define PT_REGS_RBX(r) UPT_RBX(&(r)->regs) -#define PT_REGS_RCX(r) UPT_RCX(&(r)->regs) -#define PT_REGS_RDX(r) UPT_RDX(&(r)->regs) -#define PT_REGS_RSI(r) UPT_RSI(&(r)->regs) -#define PT_REGS_RDI(r) UPT_RDI(&(r)->regs) -#define PT_REGS_RBP(r) UPT_RBP(&(r)->regs) -#define PT_REGS_RAX(r) UPT_RAX(&(r)->regs) -#define PT_REGS_R8(r) UPT_R8(&(r)->regs) -#define PT_REGS_R9(r) UPT_R9(&(r)->regs) -#define PT_REGS_R10(r) UPT_R10(&(r)->regs) -#define PT_REGS_R11(r) UPT_R11(&(r)->regs) -#define PT_REGS_R12(r) UPT_R12(&(r)->regs) -#define PT_REGS_R13(r) UPT_R13(&(r)->regs) -#define PT_REGS_R14(r) UPT_R14(&(r)->regs) -#define PT_REGS_R15(r) UPT_R15(&(r)->regs) - -#define PT_REGS_FS(r) UPT_FS(&(r)->regs) -#define PT_REGS_GS(r) UPT_GS(&(r)->regs) -#define PT_REGS_DS(r) UPT_DS(&(r)->regs) -#define PT_REGS_ES(r) UPT_ES(&(r)->regs) -#define PT_REGS_SS(r) UPT_SS(&(r)->regs) -#define PT_REGS_CS(r) UPT_CS(&(r)->regs) - -#define PT_REGS_ORIG_RAX(r) UPT_ORIG_RAX(&(r)->regs) -#define PT_REGS_RIP(r) UPT_IP(&(r)->regs) -#define PT_REGS_RSP(r) UPT_SP(&(r)->regs) - -#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs) - -/* XXX */ -#define user_mode(r) UPT_IS_USER(&(r)->regs) -#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_RAX(r) -#define PT_REGS_SYSCALL_RET(r) PT_REGS_RAX(r) - -#define PT_FIX_EXEC_STACK(sp) do ; while(0) - -#define profile_pc(regs) PT_REGS_IP(regs) - -struct user_desc; - -static inline int ptrace_get_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc) -{ - return -ENOSYS; -} - -static inline int ptrace_set_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc) -{ - return -ENOSYS; -} - -extern long arch_prctl(struct task_struct *task, int code, - unsigned long __user *addr); -#endif diff --git a/arch/um/sys-x86_64/bug.c b/arch/um/sys-x86_64/bug.c deleted file mode 100644 index e8034e363d8..00000000000 --- a/arch/um/sys-x86_64/bug.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL V2 - */ - -#include <linux/uaccess.h> - -/* - * Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because - * that's not relevant in skas mode. - */ - -int is_valid_bugaddr(unsigned long eip) -{ - unsigned short ud2; - - if (probe_kernel_address((unsigned short __user *)eip, ud2)) - return 0; - - return ud2 == 0x0b0f; -} diff --git a/arch/um/sys-x86_64/bugs.c b/arch/um/sys-x86_64/bugs.c deleted file mode 100644 index 44e02ba2a26..00000000000 --- a/arch/um/sys-x86_64/bugs.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include "sysdep/ptrace.h" - -void arch_check_bugs(void) -{ -} - -void arch_examine_signal(int sig, struct uml_pt_regs *regs) -{ -} diff --git a/arch/um/sys-x86_64/delay.c b/arch/um/sys-x86_64/delay.c deleted file mode 100644 index dee5be66da8..00000000000 --- a/arch/um/sys-x86_64/delay.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * Copied from arch/x86_64 - * - * Licensed under the GPL - */ - -#include <linux/module.h> -#include <linux/delay.h> -#include <asm/processor.h> -#include <asm/param.h> - -void __delay(unsigned long loops) -{ - unsigned long i; - - for(i = 0; i < loops; i++) - cpu_relax(); -} - -void __udelay(unsigned long usecs) -{ - unsigned long i, n; - - n = (loops_per_jiffy * HZ * usecs) / MILLION; - for(i=0;i<n;i++) - cpu_relax(); -} - -EXPORT_SYMBOL(__udelay); diff --git a/arch/um/sys-x86_64/fault.c b/arch/um/sys-x86_64/fault.c deleted file mode 100644 index ce85117fc64..00000000000 --- a/arch/um/sys-x86_64/fault.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include "sysdep/ptrace.h" - -/* These two are from asm-um/uaccess.h and linux/module.h, check them. */ -struct exception_table_entry -{ - unsigned long insn; - unsigned long fixup; -}; - -const struct exception_table_entry *search_exception_tables(unsigned long add); - -int arch_fixup(unsigned long address, struct uml_pt_regs *regs) -{ - const struct exception_table_entry *fixup; - - fixup = search_exception_tables(address); - if (fixup != 0) { - UPT_IP(regs) = fixup->fixup; - return 1; - } - return 0; -} diff --git a/arch/um/sys-x86_64/ksyms.c b/arch/um/sys-x86_64/ksyms.c deleted file mode 100644 index 1db2fce0094..00000000000 --- a/arch/um/sys-x86_64/ksyms.c +++ /dev/null @@ -1,11 +0,0 @@ -#include <linux/module.h> -#include <asm/string.h> -#include <asm/checksum.h> - -/*XXX: we need them because they would be exported by x86_64 */ -#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4 -EXPORT_SYMBOL(memcpy); -#else -EXPORT_SYMBOL(__memcpy); -#endif -EXPORT_SYMBOL(csum_partial); diff --git a/arch/um/sys-x86_64/mem.c b/arch/um/sys-x86_64/mem.c deleted file mode 100644 index 3f8df8abf34..00000000000 --- a/arch/um/sys-x86_64/mem.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include "linux/mm.h" -#include "asm/page.h" -#include "asm/mman.h" - -unsigned long vm_stack_flags = __VM_STACK_FLAGS; -unsigned long vm_stack_flags32 = __VM_STACK_FLAGS; -unsigned long vm_data_default_flags = __VM_DATA_DEFAULT_FLAGS; -unsigned long vm_data_default_flags32 = __VM_DATA_DEFAULT_FLAGS; -unsigned long vm_force_exec32 = PROT_EXEC; - diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c deleted file mode 100644 index f43613643cd..00000000000 --- a/arch/um/sys-x86_64/ptrace.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * - * Licensed under the GPL - */ - -#include <linux/mm.h> -#include <linux/sched.h> -#include <linux/errno.h> -#define __FRAME_OFFSETS -#include <asm/ptrace.h> -#include <asm/uaccess.h> - -/* - * determines which flags the user has access to. - * 1 = access 0 = no access - */ -#define FLAG_MASK 0x44dd5UL - -int putreg(struct task_struct *child, int regno, unsigned long value) -{ - unsigned long tmp; - -#ifdef TIF_IA32 - /* - * Some code in the 64bit emulation may not be 64bit clean. - * Don't take any chances. - */ - if (test_tsk_thread_flag(child, TIF_IA32)) - value &= 0xffffffff; -#endif - switch (regno) { - case FS: - case GS: - case DS: - case ES: - case SS: - case CS: - if (value && (value & 3) != 3) - return -EIO; - value &= 0xffff; - break; - - case FS_BASE: - case GS_BASE: - if (!((value >> 48) == 0 || (value >> 48) == 0xffff)) - return -EIO; - break; - - case EFLAGS: - value &= FLAG_MASK; - tmp = PT_REGS_EFLAGS(&child->thread.regs) & ~FLAG_MASK; - value |= tmp; - break; - } - - PT_REGS_SET(&child->thread.regs, regno, 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; - switch (regno) { - case FS: - case GS: - case DS: - case ES: - case SS: - case CS: - retval = 0xffff; - /* fall through */ - default: - retval &= PT_REG(&child->thread.regs, regno); -#ifdef TIF_IA32 - if (test_tsk_thread_flag(child, TIF_IA32)) - retval &= 0xffffffff; -#endif - } - 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); -} - -/* XXX Mostly copied from sys-i386 */ -int is_syscall(unsigned long addr) -{ - unsigned short instr; - int n; - - n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); - if (n) { - /* - * access_process_vm() grants access to vsyscall and stub, - * while copy_from_user doesn't. Maybe access_process_vm is - * slow, but that doesn't matter, since it will be called only - * in case of singlestepping, if copy_from_user failed. - */ - n = access_process_vm(current, addr, &instr, sizeof(instr), 0); - if (n != sizeof(instr)) { - printk("is_syscall : failed to read instruction from " - "0x%lx\n", addr); - return 1; - } - } - /* sysenter */ - return instr == 0x050f; -} - -int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) -{ - int err, n, cpu = ((struct thread_info *) child->stack)->cpu; - long fpregs[HOST_FP_SIZE]; - - BUG_ON(sizeof(*buf) != sizeof(fpregs)); - err = save_fp_registers(userspace_pid[cpu], fpregs); - if (err) - return err; - - n = copy_to_user(buf, fpregs, sizeof(fpregs)); - if (n > 0) - return -EFAULT; - - return n; -} - -int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) -{ - int n, cpu = ((struct thread_info *) child->stack)->cpu; - long fpregs[HOST_FP_SIZE]; - - BUG_ON(sizeof(*buf) != sizeof(fpregs)); - n = copy_from_user(fpregs, buf, sizeof(fpregs)); - if (n > 0) - return -EFAULT; - - return restore_fp_registers(userspace_pid[cpu], fpregs); -} - -long subarch_ptrace(struct task_struct *child, long request, - unsigned long addr, unsigned long data) -{ - int ret = -EIO; - void __user *datap = (void __user *) data; - - switch (request) { - case PTRACE_GETFPXREGS: /* Get the child FPU state. */ - ret = get_fpregs(datap, child); - break; - case PTRACE_SETFPXREGS: /* Set the child FPU state. */ - ret = set_fpregs(datap, child); - break; - } - - return ret; -} diff --git a/arch/um/sys-x86_64/ptrace_user.c b/arch/um/sys-x86_64/ptrace_user.c deleted file mode 100644 index c57a496d3f5..00000000000 --- a/arch/um/sys-x86_64/ptrace_user.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include <errno.h> -#include "ptrace_user.h" - -int ptrace_getregs(long pid, unsigned long *regs_out) -{ - if (ptrace(PTRACE_GETREGS, pid, 0, regs_out) < 0) - return -errno; - return(0); -} - -int ptrace_setregs(long pid, unsigned long *regs_out) -{ - if (ptrace(PTRACE_SETREGS, pid, 0, regs_out) < 0) - return -errno; - return(0); -} diff --git a/arch/um/sys-x86_64/setjmp.S b/arch/um/sys-x86_64/setjmp.S deleted file mode 100644 index 45f547b4043..00000000000 --- a/arch/um/sys-x86_64/setjmp.S +++ /dev/null @@ -1,54 +0,0 @@ -# -# arch/x86_64/setjmp.S -# -# setjmp/longjmp for the x86-64 architecture -# - -# -# The jmp_buf is assumed to contain the following, in order: -# %rbx -# %rsp (post-return) -# %rbp -# %r12 -# %r13 -# %r14 -# %r15 -# <return address> -# - - .text - .align 4 - .globl setjmp - .type setjmp, @function -setjmp: - pop %rsi # Return address, and adjust the stack - xorl %eax,%eax # Return value - movq %rbx,(%rdi) - movq %rsp,8(%rdi) # Post-return %rsp! - push %rsi # Make the call/return stack happy - movq %rbp,16(%rdi) - movq %r12,24(%rdi) - movq %r13,32(%rdi) - movq %r14,40(%rdi) - movq %r15,48(%rdi) - movq %rsi,56(%rdi) # Return address - ret - - .size setjmp,.-setjmp - - .text - .align 4 - .globl longjmp - .type longjmp, @function -longjmp: - movl %esi,%eax # Return value (int) - movq (%rdi),%rbx - movq 8(%rdi),%rsp - movq 16(%rdi),%rbp - movq 24(%rdi),%r12 - movq 32(%rdi),%r13 - movq 40(%rdi),%r14 - movq 48(%rdi),%r15 - jmp *56(%rdi) - - .size longjmp,.-longjmp diff --git a/arch/um/sys-x86_64/shared/sysdep/archsetjmp.h b/arch/um/sys-x86_64/shared/sysdep/archsetjmp.h deleted file mode 100644 index 2af8f12ca16..00000000000 --- a/arch/um/sys-x86_64/shared/sysdep/archsetjmp.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * arch/um/include/sysdep-x86_64/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __rbx; - unsigned long __rsp; - unsigned long __rbp; - unsigned long __r12; - unsigned long __r13; - unsigned long __r14; - unsigned long __r15; - unsigned long __rip; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#define JB_IP __rip -#define JB_SP __rsp - -#endif /* _SETJMP_H */ diff --git a/arch/um/sys-x86_64/shared/sysdep/barrier.h b/arch/um/sys-x86_64/shared/sysdep/barrier.h deleted file mode 100644 index 7b610befdc8..00000000000 --- a/arch/um/sys-x86_64/shared/sysdep/barrier.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __SYSDEP_X86_64_BARRIER_H -#define __SYSDEP_X86_64_BARRIER_H - -/* Copied from include/asm-x86_64 for use by userspace. */ -#define mb() asm volatile("mfence":::"memory") - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/checksum.h b/arch/um/sys-x86_64/shared/sysdep/checksum.h deleted file mode 100644 index a5be9031ea8..00000000000 --- a/arch/um/sys-x86_64/shared/sysdep/checksum.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Licensed under the GPL - */ - -#ifndef __UM_SYSDEP_CHECKSUM_H -#define __UM_SYSDEP_CHECKSUM_H - -#include "linux/string.h" -#include "linux/in6.h" -#include "asm/uaccess.h" - -extern __wsum csum_partial(const void *buff, int len, __wsum sum); - -/* - * Note: when you get a NULL pointer exception here this means someone - * passed in an incorrect kernel address to one of these functions. - * - * If you use these functions directly please don't forget the - * access_ok(). - */ - -static __inline__ -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum) -{ - memcpy(dst, src, len); - return(csum_partial(dst, len, sum)); -} - -static __inline__ -__wsum csum_partial_copy_from_user(const void __user *src, - void *dst, int len, __wsum sum, - int *err_ptr) -{ - if (copy_from_user(dst, src, len)) { - *err_ptr = -EFAULT; - return (__force __wsum)-1; - } - return csum_partial(dst, len, sum); -} - -/** - * csum_fold - Fold and invert a 32bit checksum. - * sum: 32bit unfolded sum - * - * Fold a 32bit running checksum to 16bit and invert it. This is usually - * the last step before putting a checksum into a packet. - * Make sure not to mix with 64bit checksums. - */ -static inline __sum16 csum_fold(__wsum sum) -{ - __asm__( - " addl %1,%0\n" - " adcl $0xffff,%0" - : "=r" (sum) - : "r" ((__force u32)sum << 16), - "0" ((__force u32)sum & 0xffff0000) - ); - return (__force __sum16)(~(__force u32)sum >> 16); -} - -/** - * csum_tcpup_nofold - Compute an IPv4 pseudo header checksum. - * @saddr: source address - * @daddr: destination address - * @len: length of packet - * @proto: ip protocol of packet - * @sum: initial sum to be added in (32bit unfolded) - * - * Returns the pseudo header checksum the input data. Result is - * 32bit unfolded. - */ -static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - asm(" addl %1, %0\n" - " adcl %2, %0\n" - " adcl %3, %0\n" - " adcl $0, %0\n" - : "=r" (sum) - : "g" (daddr), "g" (saddr), "g" ((len + proto) << 8), "0" (sum)); - return sum; -} - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ -static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -} - -/** - * ip_fast_csum - Compute the IPv4 header checksum efficiently. - * iph: ipv4 header - * ihl: length of header / 4 - */ -static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) -{ - unsigned int sum; - - asm( " movl (%1), %0\n" - " subl $4, %2\n" - " jbe 2f\n" - " addl 4(%1), %0\n" - " adcl 8(%1), %0\n" - " adcl 12(%1), %0\n" - "1: adcl 16(%1), %0\n" - " lea 4(%1), %1\n" - " decl %2\n" - " jne 1b\n" - " adcl $0, %0\n" - " movl %0, %2\n" - " shrl $16, %0\n" - " addw %w2, %w0\n" - " adcl $0, %0\n" - " notl %0\n" - "2:" - /* Since the input registers which are loaded with iph and ipl - are modified, we must also specify them as outputs, or gcc - will assume they contain their original values. */ - : "=r" (sum), "=r" (iph), "=r" (ihl) - : "1" (iph), "2" (ihl) - : "memory"); - return (__force __sum16)sum; -} - -static inline unsigned add32_with_carry(unsigned a, unsigned b) -{ - asm("addl %2,%0\n\t" - "adcl $0,%0" - : "=r" (a) - : "0" (a), "r" (b)); - return a; -} - -extern __sum16 ip_compute_csum(const void *buff, int len); - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/faultinfo.h b/arch/um/sys-x86_64/shared/sysdep/faultinfo.h deleted file mode 100644 index cb917b0d566..00000000000 --- a/arch/um/sys-x86_64/shared/sysdep/faultinfo.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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/sys-x86_64/shared/sysdep/host_ldt.h b/arch/um/sys-x86_64/shared/sysdep/host_ldt.h deleted file mode 100644 index e8b1be1e154..00000000000 --- a/arch/um/sys-x86_64/shared/sysdep/host_ldt.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __ASM_HOST_LDT_X86_64_H -#define __ASM_HOST_LDT_X86_64_H - -#include <asm/ldt.h> - -/* - * macros stolen from include/asm-x86_64/desc.h - */ -#define LDT_entry_a(info) \ - ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) - -/* Don't allow setting of the lm bit. It is useless anyways because - * 64bit system calls require __USER_CS. */ -#define LDT_entry_b(info) \ - (((info)->base_addr & 0xff000000) | \ - (((info)->base_addr & 0x00ff0000) >> 16) | \ - ((info)->limit & 0xf0000) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - /* ((info)->lm << 21) | */ \ - 0x7000) - -#define LDT_empty(info) (\ - (info)->base_addr == 0 && \ - (info)->limit == 0 && \ - (info)->contents == 0 && \ - (info)->read_exec_only == 1 && \ - (info)->seg_32bit == 0 && \ - (info)->limit_in_pages == 0 && \ - (info)->seg_not_present == 1 && \ - (info)->useable == 0 && \ - (info)->lm == 0) - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/kernel-offsets.h b/arch/um/sys-x86_64/shared/sysdep/kernel-offsets.h deleted file mode 100644 index a307237b796..00000000000 --- a/arch/um/sys-x86_64/shared/sysdep/kernel-offsets.h +++ /dev/null @@ -1,23 +0,0 @@ -#include <linux/stddef.h> -#include <linux/sched.h> -#include <linux/time.h> -#include <linux/elf.h> -#include <linux/crypto.h> -#include <asm/page.h> -#include <asm/mman.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) -{ -#include <common-offsets.h> -} diff --git a/arch/um/sys-x86_64/shared/sysdep/ptrace.h b/arch/um/sys-x86_64/shared/sysdep/ptrace.h deleted file mode 100644 index fdba5457947..00000000000 --- a/arch/um/sys-x86_64/shared/sysdep/ptrace.h +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_64_PTRACE_H -#define __SYSDEP_X86_64_PTRACE_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)) - -#include "skas_ptregs.h" - -#define REGS_IP(r) ((r)[HOST_IP]) -#define REGS_SP(r) ((r)[HOST_SP]) - -#define REGS_RBX(r) ((r)[HOST_RBX]) -#define REGS_RCX(r) ((r)[HOST_RCX]) -#define REGS_RDX(r) ((r)[HOST_RDX]) -#define REGS_RSI(r) ((r)[HOST_RSI]) -#define REGS_RDI(r) ((r)[HOST_RDI]) -#define REGS_RBP(r) ((r)[HOST_RBP]) -#define REGS_RAX(r) ((r)[HOST_RAX]) -#define REGS_R8(r) ((r)[HOST_R8]) -#define REGS_R9(r) ((r)[HOST_R9]) -#define REGS_R10(r) ((r)[HOST_R10]) -#define REGS_R11(r) ((r)[HOST_R11]) -#define REGS_R12(r) ((r)[HOST_R12]) -#define REGS_R13(r) ((r)[HOST_R13]) -#define REGS_R14(r) ((r)[HOST_R14]) -#define REGS_R15(r) ((r)[HOST_R15]) -#define REGS_CS(r) ((r)[HOST_CS]) -#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS]) -#define REGS_SS(r) ((r)[HOST_SS]) - -#define HOST_FS_BASE 21 -#define HOST_GS_BASE 22 -#define HOST_DS 23 -#define HOST_ES 24 -#define HOST_FS 25 -#define HOST_GS 26 - -/* Also defined in asm/ptrace-x86_64.h, but not in libc headers. So, these - * are already defined for kernel code, but not for userspace code. - */ -#ifndef FS_BASE -/* These aren't defined in ptrace.h, but exist in struct user_regs_struct, - * which is what x86_64 ptrace actually uses. - */ -#define FS_BASE (HOST_FS_BASE * sizeof(long)) -#define GS_BASE (HOST_GS_BASE * sizeof(long)) -#define DS (HOST_DS * sizeof(long)) -#define ES (HOST_ES * sizeof(long)) -#define FS (HOST_FS * sizeof(long)) -#define GS (HOST_GS * sizeof(long)) -#endif - -#define REGS_FS_BASE(r) ((r)[HOST_FS_BASE]) -#define REGS_GS_BASE(r) ((r)[HOST_GS_BASE]) -#define REGS_DS(r) ((r)[HOST_DS]) -#define REGS_ES(r) ((r)[HOST_ES]) -#define REGS_FS(r) ((r)[HOST_FS]) -#define REGS_GS(r) ((r)[HOST_GS]) - -#define REGS_ORIG_RAX(r) ((r)[HOST_ORIG_RAX]) - -#define REGS_SET_SYSCALL_RETURN(r, res) REGS_RAX(r) = (res) - -#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) - -#define REGS_TRAP(r) ((r)->trap_type) - -#define REGS_ERR(r) ((r)->fault_type) - -struct uml_pt_regs { - unsigned long gp[MAX_REG_NR]; - struct faultinfo faultinfo; - long syscall; - int is_user; -}; - -#define EMPTY_UML_PT_REGS { } - -#define UPT_RBX(r) REGS_RBX((r)->gp) -#define UPT_RCX(r) REGS_RCX((r)->gp) -#define UPT_RDX(r) REGS_RDX((r)->gp) -#define UPT_RSI(r) REGS_RSI((r)->gp) -#define UPT_RDI(r) REGS_RDI((r)->gp) -#define UPT_RBP(r) REGS_RBP((r)->gp) -#define UPT_RAX(r) REGS_RAX((r)->gp) -#define UPT_R8(r) REGS_R8((r)->gp) -#define UPT_R9(r) REGS_R9((r)->gp) -#define UPT_R10(r) REGS_R10((r)->gp) -#define UPT_R11(r) REGS_R11((r)->gp) -#define UPT_R12(r) REGS_R12((r)->gp) -#define UPT_R13(r) REGS_R13((r)->gp) -#define UPT_R14(r) REGS_R14((r)->gp) -#define UPT_R15(r) REGS_R15((r)->gp) -#define UPT_CS(r) REGS_CS((r)->gp) -#define UPT_FS_BASE(r) REGS_FS_BASE((r)->gp) -#define UPT_FS(r) REGS_FS((r)->gp) -#define UPT_GS_BASE(r) REGS_GS_BASE((r)->gp) -#define UPT_GS(r) REGS_GS((r)->gp) -#define UPT_DS(r) REGS_DS((r)->gp) -#define UPT_ES(r) REGS_ES((r)->gp) -#define UPT_CS(r) REGS_CS((r)->gp) -#define UPT_SS(r) REGS_SS((r)->gp) -#define UPT_ORIG_RAX(r) REGS_ORIG_RAX((r)->gp) - -#define UPT_IP(r) REGS_IP((r)->gp) -#define UPT_SP(r) REGS_SP((r)->gp) - -#define UPT_EFLAGS(r) REGS_EFLAGS((r)->gp) -#define UPT_SYSCALL_NR(r) ((r)->syscall) -#define UPT_SYSCALL_RET(r) UPT_RAX(r) - -extern int user_context(unsigned long sp); - -#define UPT_IS_USER(r) ((r)->is_user) - -#define UPT_SYSCALL_ARG1(r) UPT_RDI(r) -#define UPT_SYSCALL_ARG2(r) UPT_RSI(r) -#define UPT_SYSCALL_ARG3(r) UPT_RDX(r) -#define UPT_SYSCALL_ARG4(r) UPT_R10(r) -#define UPT_SYSCALL_ARG5(r) UPT_R8(r) -#define UPT_SYSCALL_ARG6(r) UPT_R9(r) - -struct syscall_args { - unsigned long args[6]; -}; - -#define SYSCALL_ARGS(r) ((struct syscall_args) \ - { .args = { UPT_SYSCALL_ARG1(r), \ - UPT_SYSCALL_ARG2(r), \ - UPT_SYSCALL_ARG3(r), \ - UPT_SYSCALL_ARG4(r), \ - UPT_SYSCALL_ARG5(r), \ - UPT_SYSCALL_ARG6(r) } } ) - -#define UPT_REG(regs, reg) \ - ({ unsigned long val; \ - switch(reg){ \ - case R8: val = UPT_R8(regs); break; \ - case R9: val = UPT_R9(regs); break; \ - case R10: val = UPT_R10(regs); break; \ - case R11: val = UPT_R11(regs); break; \ - case R12: val = UPT_R12(regs); break; \ - case R13: val = UPT_R13(regs); break; \ - case R14: val = UPT_R14(regs); break; \ - case R15: val = UPT_R15(regs); break; \ - case RIP: val = UPT_IP(regs); break; \ - case RSP: val = UPT_SP(regs); break; \ - case RAX: val = UPT_RAX(regs); break; \ - case RBX: val = UPT_RBX(regs); break; \ - case RCX: val = UPT_RCX(regs); break; \ - case RDX: val = UPT_RDX(regs); break; \ - case RSI: val = UPT_RSI(regs); break; \ - case RDI: val = UPT_RDI(regs); break; \ - case RBP: val = UPT_RBP(regs); break; \ - case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \ - case CS: val = UPT_CS(regs); break; \ - case SS: val = UPT_SS(regs); break; \ - case FS_BASE: val = UPT_FS_BASE(regs); break; \ - case GS_BASE: val = UPT_GS_BASE(regs); break; \ - case DS: val = UPT_DS(regs); break; \ - case ES: val = UPT_ES(regs); break; \ - case FS : val = UPT_FS (regs); break; \ - case GS: val = UPT_GS(regs); break; \ - case EFLAGS: val = UPT_EFLAGS(regs); break; \ - default : \ - panic("Bad register in UPT_REG : %d\n", reg); \ - val = -1; \ - } \ - val; \ - }) - - -#define UPT_SET(regs, reg, val) \ - ({ unsigned long __upt_val = val; \ - switch(reg){ \ - case R8: UPT_R8(regs) = __upt_val; break; \ - case R9: UPT_R9(regs) = __upt_val; break; \ - case R10: UPT_R10(regs) = __upt_val; break; \ - case R11: UPT_R11(regs) = __upt_val; break; \ - case R12: UPT_R12(regs) = __upt_val; break; \ - case R13: UPT_R13(regs) = __upt_val; break; \ - case R14: UPT_R14(regs) = __upt_val; break; \ - case R15: UPT_R15(regs) = __upt_val; break; \ - case RIP: UPT_IP(regs) = __upt_val; break; \ - case RSP: UPT_SP(regs) = __upt_val; break; \ - case RAX: UPT_RAX(regs) = __upt_val; break; \ - case RBX: UPT_RBX(regs) = __upt_val; break; \ - case RCX: UPT_RCX(regs) = __upt_val; break; \ - case RDX: UPT_RDX(regs) = __upt_val; break; \ - case RSI: UPT_RSI(regs) = __upt_val; break; \ - case RDI: UPT_RDI(regs) = __upt_val; break; \ - case RBP: UPT_RBP(regs) = __upt_val; break; \ - case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \ - case CS: UPT_CS(regs) = __upt_val; break; \ - case SS: UPT_SS(regs) = __upt_val; break; \ - case FS_BASE: UPT_FS_BASE(regs) = __upt_val; break; \ - case GS_BASE: UPT_GS_BASE(regs) = __upt_val; break; \ - case DS: UPT_DS(regs) = __upt_val; break; \ - case ES: UPT_ES(regs) = __upt_val; break; \ - case FS: UPT_FS(regs) = __upt_val; break; \ - case GS: UPT_GS(regs) = __upt_val; break; \ - case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \ - default : \ - panic("Bad register in UPT_SET : %d\n", reg); \ - break; \ - } \ - __upt_val; \ - }) - -#define UPT_SET_SYSCALL_RETURN(r, res) \ - REGS_SET_SYSCALL_RETURN((r)->regs, (res)) - -#define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp) - -#define UPT_SEGV_IS_FIXABLE(r) REGS_SEGV_IS_FIXABLE(&r->skas) - -#define UPT_FAULTINFO(r) (&(r)->faultinfo) - -static inline void arch_init_registers(int pid) -{ -} - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h b/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h deleted file mode 100644 index 4dbccdb58f4..00000000000 --- a/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_64_PTRACE_USER_H__ -#define __SYSDEP_X86_64_PTRACE_USER_H__ - -#define __FRAME_OFFSETS -#include <sys/ptrace.h> -#include <linux/ptrace.h> -#include <asm/ptrace.h> -#undef __FRAME_OFFSETS -#include "user_constants.h" - -#define PT_INDEX(off) ((off) / sizeof(unsigned long)) - -#define PT_SYSCALL_NR(regs) ((regs)[PT_INDEX(ORIG_RAX)]) -#define PT_SYSCALL_NR_OFFSET (ORIG_RAX) - -#define PT_SYSCALL_ARG1(regs) (((unsigned long *) (regs))[PT_INDEX(RDI)]) -#define PT_SYSCALL_ARG1_OFFSET (RDI) - -#define PT_SYSCALL_ARG2(regs) (((unsigned long *) (regs))[PT_INDEX(RSI)]) -#define PT_SYSCALL_ARG2_OFFSET (RSI) - -#define PT_SYSCALL_ARG3(regs) (((unsigned long *) (regs))[PT_INDEX(RDX)]) -#define PT_SYSCALL_ARG3_OFFSET (RDX) - -#define PT_SYSCALL_ARG4(regs) (((unsigned long *) (regs))[PT_INDEX(RCX)]) -#define PT_SYSCALL_ARG4_OFFSET (RCX) - -#define PT_SYSCALL_ARG5(regs) (((unsigned long *) (regs))[PT_INDEX(R8)]) -#define PT_SYSCALL_ARG5_OFFSET (R8) - -#define PT_SYSCALL_ARG6(regs) (((unsigned long *) (regs))[PT_INDEX(R9)]) -#define PT_SYSCALL_ARG6_OFFSET (R9) - -#define PT_SYSCALL_RET_OFFSET (RAX) - -#define PT_IP_OFFSET (RIP) -#define PT_IP(regs) ((regs)[PT_INDEX(RIP)]) - -#define PT_SP_OFFSET (RSP) -#define PT_SP(regs) ((regs)[PT_INDEX(RSP)]) - -#define PT_ORIG_RAX_OFFSET (ORIG_RAX) -#define PT_ORIG_RAX(regs) ((regs)[PT_INDEX(ORIG_RAX)]) - -/* - * x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though - * it's defined in the kernel's include/linux/ptrace.h. Additionally, use the - * 2.4 name and value for 2.4 host compatibility. - */ -#ifndef PTRACE_OLDSETOPTIONS -#define PTRACE_OLDSETOPTIONS 21 -#endif - -/* - * These are before the system call, so the system call number is RAX - * rather than ORIG_RAX, and arg4 is R10 rather than RCX - */ -#define REGS_SYSCALL_NR PT_INDEX(RAX) -#define REGS_SYSCALL_ARG1 PT_INDEX(RDI) -#define REGS_SYSCALL_ARG2 PT_INDEX(RSI) -#define REGS_SYSCALL_ARG3 PT_INDEX(RDX) -#define REGS_SYSCALL_ARG4 PT_INDEX(R10) -#define REGS_SYSCALL_ARG5 PT_INDEX(R8) -#define REGS_SYSCALL_ARG6 PT_INDEX(R9) - -#define REGS_IP_INDEX PT_INDEX(RIP) -#define REGS_SP_INDEX PT_INDEX(RSP) - -#define FP_SIZE (HOST_FP_SIZE) - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/sc.h b/arch/um/sys-x86_64/shared/sysdep/sc.h deleted file mode 100644 index 8aee45b0743..00000000000 --- a/arch/um/sys-x86_64/shared/sysdep/sc.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef __SYSDEP_X86_64_SC_H -#define __SYSDEP_X86_64_SC_H - -/* Copyright (C) 2003 - 2004 PathScale, Inc - * Released under the GPL - */ - -#include <user_constants.h> - -#define SC_OFFSET(sc, field) \ - *((unsigned long *) &(((char *) (sc))[HOST_##field])) - -#define SC_RBX(sc) SC_OFFSET(sc, SC_RBX) -#define SC_RCX(sc) SC_OFFSET(sc, SC_RCX) -#define SC_RDX(sc) SC_OFFSET(sc, SC_RDX) -#define SC_RSI(sc) SC_OFFSET(sc, SC_RSI) -#define SC_RDI(sc) SC_OFFSET(sc, SC_RDI) -#define SC_RBP(sc) SC_OFFSET(sc, SC_RBP) -#define SC_RAX(sc) SC_OFFSET(sc, SC_RAX) -#define SC_R8(sc) SC_OFFSET(sc, SC_R8) -#define SC_R9(sc) SC_OFFSET(sc, SC_R9) -#define SC_R10(sc) SC_OFFSET(sc, SC_R10) -#define SC_R11(sc) SC_OFFSET(sc, SC_R11) -#define SC_R12(sc) SC_OFFSET(sc, SC_R12) -#define SC_R13(sc) SC_OFFSET(sc, SC_R13) -#define SC_R14(sc) SC_OFFSET(sc, SC_R14) -#define SC_R15(sc) SC_OFFSET(sc, SC_R15) -#define SC_IP(sc) SC_OFFSET(sc, SC_IP) -#define SC_SP(sc) SC_OFFSET(sc, SC_SP) -#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2) -#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) -#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) -#define SC_CS(sc) SC_OFFSET(sc, SC_CS) -#define SC_FS(sc) SC_OFFSET(sc, SC_FS) -#define SC_GS(sc) SC_OFFSET(sc, SC_GS) -#define SC_EFLAGS(sc) SC_OFFSET(sc, SC_EFLAGS) -#define SC_SIGMASK(sc) SC_OFFSET(sc, SC_SIGMASK) -#define SC_SS(sc) SC_OFFSET(sc, SC_SS) -#if 0 -#define SC_ORIG_RAX(sc) SC_OFFSET(sc, SC_ORIG_RAX) -#define SC_DS(sc) SC_OFFSET(sc, SC_DS) -#define SC_ES(sc) SC_OFFSET(sc, SC_ES) -#endif - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/sigcontext.h b/arch/um/sys-x86_64/shared/sysdep/sigcontext.h deleted file mode 100644 index 0155133b145..00000000000 --- a/arch/um/sys-x86_64/shared/sysdep/sigcontext.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_64_SIGCONTEXT_H -#define __SYSDEP_X86_64_SIGCONTEXT_H - -#include <sysdep/sc.h> - -#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) - -#define GET_FAULTINFO_FROM_SC(fi, sc) \ - { \ - (fi).cr2 = SC_CR2(sc); \ - (fi).error_code = SC_ERR(sc); \ - (fi).trap_no = SC_TRAPNO(sc); \ - } - -/* This is Page Fault */ -#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) - -/* No broken SKAS API, which doesn't pass trap_no, here. */ -#define SEGV_MAYBE_FIXABLE(fi) 0 - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/skas_ptrace.h b/arch/um/sys-x86_64/shared/sysdep/skas_ptrace.h deleted file mode 100644 index 95db4be786e..00000000000 --- a/arch/um/sys-x86_64/shared/sysdep/skas_ptrace.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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/sys-x86_64/shared/sysdep/stub.h b/arch/um/sys-x86_64/shared/sysdep/stub.h deleted file mode 100644 index 3432aa24997..00000000000 --- a/arch/um/sys-x86_64/shared/sysdep/stub.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_STUB_H -#define __SYSDEP_STUB_H - -#include <sys/mman.h> -#include <asm/unistd.h> -#include <sysdep/ptrace_user.h> -#include "as-layout.h" -#include "stub-data.h" -#include "kern_constants.h" - -extern void stub_segv_handler(int sig); -extern void stub_clone_handler(void); - -#define STUB_SYSCALL_RET PT_INDEX(RAX) -#define STUB_MMAP_NR __NR_mmap -#define MMAP_OFFSET(o) (o) - -#define __syscall_clobber "r11","rcx","memory" -#define __syscall "syscall" - -static inline long stub_syscall0(long syscall) -{ - long ret; - - __asm__ volatile (__syscall - : "=a" (ret) - : "0" (syscall) : __syscall_clobber ); - - return ret; -} - -static inline long stub_syscall2(long syscall, long arg1, long arg2) -{ - long ret; - - __asm__ volatile (__syscall - : "=a" (ret) - : "0" (syscall), "D" (arg1), "S" (arg2) : __syscall_clobber ); - - return ret; -} - -static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3) -{ - long ret; - - __asm__ volatile (__syscall - : "=a" (ret) - : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3) - : __syscall_clobber ); - - return ret; -} - -static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3, - long arg4) -{ - long ret; - - __asm__ volatile ("movq %5,%%r10 ; " __syscall - : "=a" (ret) - : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3), - "g" (arg4) - : __syscall_clobber, "r10" ); - - return ret; -} - -static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3, - long arg4, long arg5) -{ - long ret; - - __asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " __syscall - : "=a" (ret) - : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3), - "g" (arg4), "g" (arg5) - : __syscall_clobber, "r10", "r8" ); - - return ret; -} - -static inline void trap_myself(void) -{ - __asm("int3"); -} - -static inline void remap_stack(long fd, unsigned long offset) -{ - __asm__ volatile ("movq %4,%%r10 ; movq %5,%%r8 ; " - "movq %6, %%r9; " __syscall "; movq %7, %%rbx ; " - "movq %%rax, (%%rbx)": - : "a" (STUB_MMAP_NR), "D" (STUB_DATA), - "S" (UM_KERN_PAGE_SIZE), - "d" (PROT_READ | PROT_WRITE), - "g" (MAP_FIXED | MAP_SHARED), "g" (fd), - "g" (offset), - "i" (&((struct stub_data *) STUB_DATA)->err) - : __syscall_clobber, "r10", "r8", "r9" ); -} - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/syscalls.h b/arch/um/sys-x86_64/shared/sysdep/syscalls.h deleted file mode 100644 index 7cfb0b08565..00000000000 --- a/arch/um/sys-x86_64/shared/sysdep/syscalls.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_64_SYSCALLS_H__ -#define __SYSDEP_X86_64_SYSCALLS_H__ - -#include <linux/msg.h> -#include <linux/shm.h> -#include <kern_constants.h> - -typedef long syscall_handler_t(void); - -extern syscall_handler_t *sys_call_table[]; - -#define EXECUTE_SYSCALL(syscall, regs) \ - (((long (*)(long, long, long, long, long, long)) \ - (*sys_call_table[syscall]))(UPT_SYSCALL_ARG1(®s->regs), \ - UPT_SYSCALL_ARG2(®s->regs), \ - UPT_SYSCALL_ARG3(®s->regs), \ - UPT_SYSCALL_ARG4(®s->regs), \ - UPT_SYSCALL_ARG5(®s->regs), \ - UPT_SYSCALL_ARG6(®s->regs))) - -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 sys_modify_ldt; -extern syscall_handler_t sys_arch_prctl; - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/system.h b/arch/um/sys-x86_64/shared/sysdep/system.h deleted file mode 100644 index d1b93c43620..00000000000 --- a/arch/um/sys-x86_64/shared/sysdep/system.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef _ASM_X86_SYSTEM_H_ -#define _ASM_X86_SYSTEM_H_ - -#include <asm/asm.h> -#include <asm/segment.h> -#include <asm/cpufeature.h> -#include <asm/cmpxchg.h> -#include <asm/nops.h> - -#include <linux/kernel.h> -#include <linux/irqflags.h> - -/* entries in ARCH_DLINFO: */ -#ifdef CONFIG_IA32_EMULATION -# define AT_VECTOR_SIZE_ARCH 2 -#else -# define AT_VECTOR_SIZE_ARCH 1 -#endif - -extern unsigned long arch_align_stack(unsigned long sp); - -void default_idle(void); - -/* - * Force strict CPU ordering. - * And yes, this is required on UP too when we're talking - * to devices. - */ -#ifdef CONFIG_X86_32 -/* - * Some non-Intel clones support out of order store. wmb() ceases to be a - * nop for these. - */ -#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) -#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) -#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) -#else -#define mb() asm volatile("mfence":::"memory") -#define rmb() asm volatile("lfence":::"memory") -#define wmb() asm volatile("sfence" ::: "memory") -#endif - -/** - * read_barrier_depends - Flush all pending reads that subsequents reads - * depend on. - * - * No data-dependent reads from memory-like regions are ever reordered - * over this barrier. All reads preceding this primitive are guaranteed - * to access memory (but not necessarily other CPUs' caches) before any - * reads following this primitive that depend on the data return by - * any of the preceding reads. This primitive is much lighter weight than - * rmb() on most CPUs, and is never heavier weight than is - * rmb(). - * - * These ordering constraints are respected by both the local CPU - * and the compiler. - * - * Ordering is not guaranteed by anything other than these primitives, - * not even by data dependencies. See the documentation for - * memory_barrier() for examples and URLs to more information. - * - * For example, the following code would force ordering (the initial - * value of "a" is zero, "b" is one, and "p" is "&a"): - * - * <programlisting> - * CPU 0 CPU 1 - * - * b = 2; - * memory_barrier(); - * p = &b; q = p; - * read_barrier_depends(); - * d = *q; - * </programlisting> - * - * because the read of "*q" depends on the read of "p" and these - * two reads are separated by a read_barrier_depends(). However, - * the following code, with the same initial values for "a" and "b": - * - * <programlisting> - * CPU 0 CPU 1 - * - * a = 2; - * memory_barrier(); - * b = 3; y = b; - * read_barrier_depends(); - * x = a; - * </programlisting> - * - * does not enforce ordering, since there is no data dependency between - * the read of "a" and the read of "b". Therefore, on some CPUs, such - * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() - * in cases like this where there are no data dependencies. - **/ - -#define read_barrier_depends() do { } while (0) - -#ifdef CONFIG_SMP -#define smp_mb() mb() -#ifdef CONFIG_X86_PPRO_FENCE -# define smp_rmb() rmb() -#else -# define smp_rmb() barrier() -#endif -#ifdef CONFIG_X86_OOSTORE -# define smp_wmb() wmb() -#else -# define smp_wmb() barrier() -#endif -#define smp_read_barrier_depends() read_barrier_depends() -#define set_mb(var, value) do { (void)xchg(&var, value); } while (0) -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while (0) -#define set_mb(var, value) do { var = value; barrier(); } while (0) -#endif - -/* - * Stop RDTSC speculation. This is needed when you need to use RDTSC - * (or get_cycles or vread that possibly accesses the TSC) in a defined - * code region. - * - * (Could use an alternative three way for this if there was one.) - */ -static inline void rdtsc_barrier(void) -{ - alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC); - alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); -} - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/tls.h b/arch/um/sys-x86_64/shared/sysdep/tls.h deleted file mode 100644 index 18c000d0357..00000000000 --- a/arch/um/sys-x86_64/shared/sysdep/tls.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _SYSDEP_TLS_H -#define _SYSDEP_TLS_H - -# ifndef __KERNEL__ - -/* Change name to avoid conflicts with the original one from <asm/ldt.h>, which - * may be named user_desc (but in 2.4 and in header matching its API was named - * modify_ldt_ldt_s). */ - -typedef struct um_dup_user_desc { - unsigned int entry_number; - unsigned int base_addr; - unsigned int limit; - unsigned int seg_32bit:1; - unsigned int contents:2; - unsigned int read_exec_only:1; - unsigned int limit_in_pages:1; - unsigned int seg_not_present:1; - unsigned int useable:1; - unsigned int lm:1; -} user_desc_t; - -# else /* __KERNEL__ */ - -# include <ldt.h> -typedef struct user_desc user_desc_t; - -# endif /* __KERNEL__ */ -#endif /* _SYSDEP_TLS_H */ diff --git a/arch/um/sys-x86_64/shared/sysdep/vm-flags.h b/arch/um/sys-x86_64/shared/sysdep/vm-flags.h deleted file mode 100644 index 3213edfa788..00000000000 --- a/arch/um/sys-x86_64/shared/sysdep/vm-flags.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Copyright 2003 PathScale, Inc. - * Licensed under the GPL - */ - -#ifndef __VM_FLAGS_X86_64_H -#define __VM_FLAGS_X86_64_H - -#define __VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) -#define __VM_STACK_FLAGS (VM_GROWSDOWN | VM_READ | VM_WRITE | \ - VM_EXEC | VM_MAYREAD | VM_MAYWRITE | \ - VM_MAYEXEC) - -extern unsigned long vm_stack_flags, vm_stack_flags32; -extern unsigned long vm_data_default_flags, vm_data_default_flags32; -extern unsigned long vm_force_exec32; - -#ifdef TIF_IA32 -#define VM_DATA_DEFAULT_FLAGS \ - (test_thread_flag(TIF_IA32) ? vm_data_default_flags32 : \ - vm_data_default_flags) - -#define VM_STACK_DEFAULT_FLAGS \ - (test_thread_flag(TIF_IA32) ? vm_stack_flags32 : vm_stack_flags) -#endif - -#define VM_DATA_DEFAULT_FLAGS vm_data_default_flags - -#define VM_STACK_DEFAULT_FLAGS vm_stack_flags - -#endif diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c deleted file mode 100644 index b6b65c7c7a7..00000000000 --- a/arch/um/sys-x86_64/signal.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (C) 2003 PathScale, Inc. - * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include <linux/personality.h> -#include <linux/ptrace.h> -#include <linux/kernel.h> -#include <asm/unistd.h> -#include <asm/uaccess.h> -#include <asm/ucontext.h> -#include "frame_kern.h" -#include "skas.h" - -void copy_sc(struct uml_pt_regs *regs, void *from) -{ - struct sigcontext *sc = from; - -#define GETREG(regs, regno, sc, regname) \ - (regs)->gp[(regno) / sizeof(unsigned long)] = (sc)->regname - - GETREG(regs, R8, sc, r8); - GETREG(regs, R9, sc, r9); - GETREG(regs, R10, sc, r10); - GETREG(regs, R11, sc, r11); - GETREG(regs, R12, sc, r12); - GETREG(regs, R13, sc, r13); - GETREG(regs, R14, sc, r14); - GETREG(regs, R15, sc, r15); - GETREG(regs, RDI, sc, di); - GETREG(regs, RSI, sc, si); - GETREG(regs, RBP, sc, bp); - GETREG(regs, RBX, sc, bx); - GETREG(regs, RDX, sc, dx); - GETREG(regs, RAX, sc, ax); - GETREG(regs, RCX, sc, cx); - GETREG(regs, RSP, sc, sp); - GETREG(regs, RIP, sc, ip); - GETREG(regs, EFLAGS, sc, flags); - GETREG(regs, CS, sc, cs); - -#undef GETREG -} - -static int copy_sc_from_user(struct pt_regs *regs, - struct sigcontext __user *from, - struct _fpstate __user *fpp) -{ - struct user_i387_struct fp; - int err = 0; - -#define GETREG(regs, regno, sc, regname) \ - __get_user((regs)->regs.gp[(regno) / sizeof(unsigned long)], \ - &(sc)->regname) - - err |= GETREG(regs, R8, from, r8); - err |= GETREG(regs, R9, from, r9); - err |= GETREG(regs, R10, from, r10); - err |= GETREG(regs, R11, from, r11); - err |= GETREG(regs, R12, from, r12); - err |= GETREG(regs, R13, from, r13); - err |= GETREG(regs, R14, from, r14); - err |= GETREG(regs, R15, from, r15); - err |= GETREG(regs, RDI, from, di); - err |= GETREG(regs, RSI, from, si); - err |= GETREG(regs, RBP, from, bp); - err |= GETREG(regs, RBX, from, bx); - err |= GETREG(regs, RDX, from, dx); - err |= GETREG(regs, RAX, from, ax); - err |= GETREG(regs, RCX, from, cx); - err |= GETREG(regs, RSP, from, sp); - err |= GETREG(regs, RIP, from, ip); - err |= GETREG(regs, EFLAGS, from, flags); - err |= GETREG(regs, CS, from, cs); - if (err) - return 1; - -#undef GETREG - - err = copy_from_user(&fp, fpp, sizeof(struct user_i387_struct)); - if (err) - return 1; - - err = restore_fp_registers(userspace_pid[current_thread_info()->cpu], - (unsigned long *) &fp); - if (err < 0) { - printk(KERN_ERR "copy_sc_from_user - " - "restore_fp_registers failed, errno = %d\n", - -err); - return 1; - } - - return 0; -} - -static int copy_sc_to_user(struct sigcontext __user *to, - struct _fpstate __user *to_fp, struct pt_regs *regs, - unsigned long mask, unsigned long sp) -{ - struct faultinfo * fi = ¤t->thread.arch.faultinfo; - struct user_i387_struct fp; - int err = 0; - - err |= __put_user(0, &to->gs); - err |= __put_user(0, &to->fs); - -#define PUTREG(regs, regno, sc, regname) \ - __put_user((regs)->regs.gp[(regno) / sizeof(unsigned long)], \ - &(sc)->regname) - - err |= PUTREG(regs, RDI, to, di); - err |= PUTREG(regs, RSI, to, si); - err |= PUTREG(regs, RBP, to, bp); - /* - * Must use original RSP, which is passed in, rather than what's in - * the pt_regs, because that's already been updated to point at the - * signal frame. - */ - err |= __put_user(sp, &to->sp); - err |= PUTREG(regs, RBX, to, bx); - err |= PUTREG(regs, RDX, to, dx); - err |= PUTREG(regs, RCX, to, cx); - err |= PUTREG(regs, RAX, to, ax); - err |= PUTREG(regs, R8, to, r8); - err |= PUTREG(regs, R9, to, r9); - err |= PUTREG(regs, R10, to, r10); - err |= PUTREG(regs, R11, to, r11); - err |= PUTREG(regs, R12, to, r12); - err |= PUTREG(regs, R13, to, r13); - 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(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, ip); - err |= PUTREG(regs, EFLAGS, to, flags); -#undef PUTREG - - err |= __put_user(mask, &to->oldmask); - if (err) - return 1; - - err = save_fp_registers(userspace_pid[current_thread_info()->cpu], - (unsigned long *) &fp); - if (err < 0) { - printk(KERN_ERR "copy_sc_from_user - restore_fp_registers " - "failed, errno = %d\n", -err); - return 1; - } - - if (copy_to_user(to_fp, &fp, sizeof(struct user_i387_struct))) - return 1; - - return err; -} - -struct rt_sigframe -{ - char __user *pretcode; - struct ucontext uc; - struct siginfo info; - struct _fpstate fpstate; -}; - -int setup_signal_stack_si(unsigned long stack_top, int sig, - struct k_sigaction *ka, struct pt_regs * regs, - siginfo_t *info, sigset_t *set) -{ - struct rt_sigframe __user *frame; - unsigned long save_sp = PT_REGS_RSP(regs); - int err = 0; - struct task_struct *me = current; - - frame = (struct rt_sigframe __user *) - round_down(stack_top - sizeof(struct rt_sigframe), 16); - /* Subtract 128 for a red zone and 8 for proper alignment */ - frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8); - - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - goto out; - - if (ka->sa.sa_flags & SA_SIGINFO) { - err |= copy_siginfo_to_user(&frame->info, info); - if (err) - goto out; - } - - /* - * Update SP now because the page fault handler refuses to extend - * the stack if the faulting address is too far below the current - * SP, which frame now certainly is. If there's an error, the original - * value is restored on the way out. - * When writing the sigcontext to the stack, we have to write the - * original value, so that's passed to copy_sc_to_user, which does - * the right thing with it. - */ - PT_REGS_RSP(regs) = (unsigned long) frame; - - /* Create the ucontext. */ - err |= __put_user(0, &frame->uc.uc_flags); - err |= __put_user(0, &frame->uc.uc_link); - err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp); - err |= __put_user(sas_ss_flags(save_sp), - &frame->uc.uc_stack.ss_flags); - err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size); - err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs, - set->sig[0], save_sp); - err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate); - if (sizeof(*set) == 16) { - __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); - __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); - } - else - err |= __copy_to_user(&frame->uc.uc_sigmask, set, - sizeof(*set)); - - /* - * Set up to return from userspace. If provided, use a stub - * already in userspace. - */ - /* x86-64 should always use SA_RESTORER. */ - if (ka->sa.sa_flags & SA_RESTORER) - err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); - else - /* could use a vstub here */ - goto restore_sp; - - if (err) - goto restore_sp; - - /* Set up registers for signal handler */ - { - struct exec_domain *ed = current_thread_info()->exec_domain; - if (unlikely(ed && ed->signal_invmap && sig < 32)) - sig = ed->signal_invmap[sig]; - } - - PT_REGS_RDI(regs) = sig; - /* In case the signal handler was declared without prototypes */ - PT_REGS_RAX(regs) = 0; - - /* - * This also works for non SA_SIGINFO handlers because they expect the - * next argument after the signal number on the stack. - */ - PT_REGS_RSI(regs) = (unsigned long) &frame->info; - PT_REGS_RDX(regs) = (unsigned long) &frame->uc; - PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler; - out: - return err; - -restore_sp: - PT_REGS_RSP(regs) = save_sp; - return err; -} - -long sys_rt_sigreturn(struct pt_regs *regs) -{ - unsigned long sp = PT_REGS_SP(¤t->thread.regs); - struct rt_sigframe __user *frame = - (struct rt_sigframe __user *)(sp - 8); - struct ucontext __user *uc = &frame->uc; - sigset_t set; - - if (copy_from_user(&set, &uc->uc_sigmask, sizeof(set))) - goto segfault; - - sigdelsetmask(&set, ~_BLOCKABLE); - - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext, - &frame->fpstate)) - goto segfault; - - /* Avoid ERESTART handling */ - PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; - return PT_REGS_SYSCALL_RET(¤t->thread.regs); - - segfault: - force_sig(SIGSEGV, current); - return 0; -} diff --git a/arch/um/sys-x86_64/stub.S b/arch/um/sys-x86_64/stub.S deleted file mode 100644 index 20e4a96a6dc..00000000000 --- a/arch/um/sys-x86_64/stub.S +++ /dev/null @@ -1,66 +0,0 @@ -#include "as-layout.h" - - .globl syscall_stub -.section .__syscall_stub, "ax" -syscall_stub: - syscall - /* We don't have 64-bit constants, so this constructs the address - * we need. - */ - movq $(STUB_DATA >> 32), %rbx - salq $32, %rbx - movq $(STUB_DATA & 0xffffffff), %rcx - or %rcx, %rbx - movq %rax, (%rbx) - int3 - - .globl batch_syscall_stub -batch_syscall_stub: - mov $(STUB_DATA >> 32), %rbx - sal $32, %rbx - mov $(STUB_DATA & 0xffffffff), %rax - or %rax, %rbx - /* load pointer to first operation */ - mov %rbx, %rsp - add $0x10, %rsp -again: - /* load length of additional data */ - mov 0x0(%rsp), %rax - - /* if(length == 0) : end of list */ - /* write possible 0 to header */ - mov %rax, 8(%rbx) - cmp $0, %rax - jz done - - /* save current pointer */ - mov %rsp, 8(%rbx) - - /* skip additional data */ - add %rax, %rsp - - /* load syscall-# */ - pop %rax - - /* load syscall params */ - pop %rdi - pop %rsi - pop %rdx - pop %r10 - pop %r8 - pop %r9 - - /* execute syscall */ - syscall - - /* check return value */ - pop %rcx - cmp %rcx, %rax - je again - -done: - /* save return value */ - mov %rax, (%rbx) - - /* stop */ - int3 diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c deleted file mode 100644 index ced051afc70..00000000000 --- a/arch/um/sys-x86_64/stub_segv.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include <signal.h> -#include "as-layout.h" -#include "sysdep/stub.h" -#include "sysdep/faultinfo.h" -#include "sysdep/sigcontext.h" - -void __attribute__ ((__section__ (".__syscall_stub"))) -stub_segv_handler(int sig) -{ - struct ucontext *uc; - - __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :); - GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), - &uc->uc_mcontext); - trap_myself(); -} - diff --git a/arch/um/sys-x86_64/syscall_table.c b/arch/um/sys-x86_64/syscall_table.c deleted file mode 100644 index 47d469e7e7c..00000000000 --- a/arch/um/sys-x86_64/syscall_table.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 <kern_constants.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. - */ - -/* On UML we call it this way ("old" means it's not mmap2) */ -#define sys_mmap old_mmap - -#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_UNISTD_64_H -#include "../../x86/include/asm/unistd_64.h" - -#undef __SYSCALL -#define __SYSCALL(nr, sym) [ nr ] = sym, -#undef _ASM_X86_UNISTD_64_H - -typedef void (*sys_call_ptr_t)(void); - -extern void sys_ni_syscall(void); - -/* - * We used to have a trick here which made sure that holes in the - * x86_64 table were filled in with sys_ni_syscall, but a comment in - * unistd_64.h says that holes aren't allowed, so the trick was - * removed. - * The trick looked like this - * [0 ... UM_NR_syscall_max] = &sys_ni_syscall - * before including unistd_64.h - the later initializations overwrote - * the sys_ni_syscall filler. - */ - -sys_call_ptr_t sys_call_table[] __cacheline_aligned = { -#include "../../x86/include/asm/unistd_64.h" -}; - -int syscall_table_size = sizeof(sys_call_table); diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c deleted file mode 100644 index f3d82bb6e15..00000000000 --- a/arch/um/sys-x86_64/syscalls.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include "linux/linkage.h" -#include "linux/personality.h" -#include "linux/utsname.h" -#include "asm/prctl.h" /* XXX This should get the constants from libc */ -#include "asm/uaccess.h" -#include "os.h" - -long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr) -{ - unsigned long *ptr = addr, tmp; - long ret; - int pid = task->mm->context.id.u.pid; - - /* - * With ARCH_SET_FS (and ARCH_SET_GS is treated similarly to - * be safe), we need to call arch_prctl on the host because - * setting %fs may result in something else happening (like a - * GDT or thread.fs being set instead). So, we let the host - * fiddle the registers and thread struct and restore the - * registers afterwards. - * - * So, the saved registers are stored to the process (this - * needed because a stub may have been the last thing to run), - * arch_prctl is run on the host, then the registers are read - * back. - */ - switch (code) { - case ARCH_SET_FS: - case ARCH_SET_GS: - ret = restore_registers(pid, ¤t->thread.regs.regs); - if (ret) - return ret; - break; - case ARCH_GET_FS: - case ARCH_GET_GS: - /* - * With these two, we read to a local pointer and - * put_user it to the userspace pointer that we were - * given. If addr isn't valid (because it hasn't been - * faulted in or is just bogus), we want put_user to - * fault it in (or return -EFAULT) instead of having - * the host return -EFAULT. - */ - ptr = &tmp; - } - - ret = os_arch_prctl(pid, code, ptr); - if (ret) - return ret; - - switch (code) { - case ARCH_SET_FS: - current->thread.arch.fs = (unsigned long) ptr; - ret = save_registers(pid, ¤t->thread.regs.regs); - break; - case ARCH_SET_GS: - ret = save_registers(pid, ¤t->thread.regs.regs); - break; - case ARCH_GET_FS: - ret = put_user(tmp, addr); - break; - case ARCH_GET_GS: - ret = put_user(tmp, addr); - break; - } - - return ret; -} - -long sys_arch_prctl(int code, unsigned long addr) -{ - return arch_prctl(current, code, (unsigned long __user *) addr); -} - -long sys_clone(unsigned long clone_flags, unsigned long newsp, - void __user *parent_tid, void __user *child_tid) -{ - long ret; - - if (!newsp) - newsp = UPT_SP(¤t->thread.regs.regs); - current->thread.forking = 1; - ret = do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid, - child_tid); - current->thread.forking = 0; - return ret; -} - -void arch_switch_to(struct task_struct *to) -{ - if ((to->thread.arch.fs == 0) || (to->mm == NULL)) - return; - - arch_prctl(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs); -} diff --git a/arch/um/sys-x86_64/sysrq.c b/arch/um/sys-x86_64/sysrq.c deleted file mode 100644 index f4f82beb350..00000000000 --- a/arch/um/sys-x86_64/sysrq.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/sched.h> -#include <linux/utsname.h> -#include <asm/current.h> -#include <asm/ptrace.h> -#include "sysrq.h" - -void __show_regs(struct pt_regs *regs) -{ - printk("\n"); - print_modules(); - printk(KERN_INFO "Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current), - current->comm, print_tainted(), init_utsname()->release); - printk(KERN_INFO "RIP: %04lx:[<%016lx>]\n", PT_REGS_CS(regs) & 0xffff, - PT_REGS_RIP(regs)); - printk(KERN_INFO "RSP: %016lx EFLAGS: %08lx\n", PT_REGS_RSP(regs), - PT_REGS_EFLAGS(regs)); - printk(KERN_INFO "RAX: %016lx RBX: %016lx RCX: %016lx\n", - PT_REGS_RAX(regs), PT_REGS_RBX(regs), PT_REGS_RCX(regs)); - printk(KERN_INFO "RDX: %016lx RSI: %016lx RDI: %016lx\n", - PT_REGS_RDX(regs), PT_REGS_RSI(regs), PT_REGS_RDI(regs)); - printk(KERN_INFO "RBP: %016lx R08: %016lx R09: %016lx\n", - PT_REGS_RBP(regs), PT_REGS_R8(regs), PT_REGS_R9(regs)); - printk(KERN_INFO "R10: %016lx R11: %016lx R12: %016lx\n", - PT_REGS_R10(regs), PT_REGS_R11(regs), PT_REGS_R12(regs)); - printk(KERN_INFO "R13: %016lx R14: %016lx R15: %016lx\n", - PT_REGS_R13(regs), PT_REGS_R14(regs), PT_REGS_R15(regs)); -} - -void show_regs(struct pt_regs *regs) -{ - __show_regs(regs); - show_trace(current, (unsigned long *) ®s); -} diff --git a/arch/um/sys-x86_64/tls.c b/arch/um/sys-x86_64/tls.c deleted file mode 100644 index f7ba46200ec..00000000000 --- a/arch/um/sys-x86_64/tls.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "linux/sched.h" - -void clear_flushed_tls(struct task_struct *task) -{ -} - -int arch_copy_tls(struct task_struct *t) -{ - /* - * If CLONE_SETTLS is set, we need to save the thread id - * (which is argument 5, child_tid, of clone) so it can be set - * during context switches. - */ - t->thread.arch.fs = t->thread.regs.regs.gp[R8 / sizeof(long)]; - - return 0; -} diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c deleted file mode 100644 index 973585414a6..00000000000 --- a/arch/um/sys-x86_64/user-offsets.c +++ /dev/null @@ -1,65 +0,0 @@ -#include <stdio.h> -#include <stddef.h> -#include <signal.h> -#include <sys/poll.h> -#include <sys/mman.h> -#include <sys/user.h> -#define __FRAME_OFFSETS -#include <asm/ptrace.h> -#include <asm/types.h> - -#define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) - -#define DEFINE_LONGS(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long))) - -#define OFFSET(sym, str, mem) \ - DEFINE(sym, offsetof(struct str, mem)); - -void foo(void) -{ - OFFSET(HOST_SC_CR2, sigcontext, cr2); - OFFSET(HOST_SC_ERR, sigcontext, err); - OFFSET(HOST_SC_TRAPNO, sigcontext, trapno); - - DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long)); - DEFINE_LONGS(HOST_RBX, RBX); - DEFINE_LONGS(HOST_RCX, RCX); - DEFINE_LONGS(HOST_RDI, RDI); - DEFINE_LONGS(HOST_RSI, RSI); - DEFINE_LONGS(HOST_RDX, RDX); - DEFINE_LONGS(HOST_RBP, RBP); - DEFINE_LONGS(HOST_RAX, RAX); - DEFINE_LONGS(HOST_R8, R8); - DEFINE_LONGS(HOST_R9, R9); - DEFINE_LONGS(HOST_R10, R10); - DEFINE_LONGS(HOST_R11, R11); - DEFINE_LONGS(HOST_R12, R12); - DEFINE_LONGS(HOST_R13, R13); - DEFINE_LONGS(HOST_R14, R14); - DEFINE_LONGS(HOST_R15, R15); - DEFINE_LONGS(HOST_ORIG_RAX, ORIG_RAX); - DEFINE_LONGS(HOST_CS, CS); - DEFINE_LONGS(HOST_SS, SS); - DEFINE_LONGS(HOST_EFLAGS, EFLAGS); -#if 0 - DEFINE_LONGS(HOST_FS, FS); - DEFINE_LONGS(HOST_GS, GS); - DEFINE_LONGS(HOST_DS, DS); - DEFINE_LONGS(HOST_ES, ES); -#endif - - DEFINE_LONGS(HOST_IP, RIP); - DEFINE_LONGS(HOST_SP, RSP); - DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct)); - - /* XXX Duplicated between i386 and x86_64 */ - DEFINE(UM_POLLIN, POLLIN); - DEFINE(UM_POLLPRI, POLLPRI); - DEFINE(UM_POLLOUT, POLLOUT); - - DEFINE(UM_PROT_READ, PROT_READ); - DEFINE(UM_PROT_WRITE, PROT_WRITE); - DEFINE(UM_PROT_EXEC, PROT_EXEC); -} |