aboutsummaryrefslogtreecommitdiff
path: root/arch/um
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/Makefile70
-rw-r--r--arch/um/Makefile-i38622
-rw-r--r--arch/um/Makefile-skas2
-rw-r--r--arch/um/Makefile-x86_6421
-rw-r--r--arch/um/drivers/Makefile2
-rw-r--r--arch/um/drivers/cow.h39
-rw-r--r--arch/um/drivers/cow_user.c1
-rw-r--r--arch/um/drivers/mconsole_user.c2
-rw-r--r--arch/um/drivers/port_kern.c1
-rw-r--r--arch/um/drivers/ubd_kern.c556
-rw-r--r--arch/um/drivers/ubd_user.c75
-rw-r--r--arch/um/include/aio.h18
-rw-r--r--arch/um/include/common-offsets.h4
-rw-r--r--arch/um/include/os.h9
-rw-r--r--arch/um/include/registers.h12
-rw-r--r--arch/um/include/skas_ptregs.h6
-rw-r--r--arch/um/include/sysdep-i386/sc.h44
-rw-r--r--arch/um/include/sysdep-i386/sigcontext.h10
-rw-r--r--arch/um/include/sysdep-i386/thread.h11
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace.h8
-rw-r--r--arch/um/include/sysdep-x86_64/sc.h45
-rw-r--r--arch/um/include/sysdep-x86_64/sigcontext.h5
-rw-r--r--arch/um/include/sysdep-x86_64/thread.h10
-rw-r--r--arch/um/include/task.h9
-rw-r--r--arch/um/kernel/irq.c1
-rw-r--r--arch/um/kernel/skas/Makefile2
-rw-r--r--arch/um/kernel/skas/util/Makefile5
-rw-r--r--arch/um/kernel/skas/util/mk_ptregs-i386.c49
-rw-r--r--arch/um/kernel/skas/util/mk_ptregs-x86_64.c66
-rw-r--r--arch/um/kernel/sysrq.c8
-rw-r--r--arch/um/kernel/trap_kern.c5
-rw-r--r--arch/um/kernel/um_arch.c2
-rw-r--r--arch/um/os-Linux/aio.c205
-rw-r--r--arch/um/os-Linux/elf_aux.c2
-rw-r--r--arch/um/os-Linux/start_up.c11
-rw-r--r--arch/um/os-Linux/sys-i386/registers.c19
-rw-r--r--arch/um/os-Linux/sys-x86_64/registers.c19
-rw-r--r--arch/um/os-Linux/util/Makefile4
-rw-r--r--arch/um/os-Linux/util/mk_user_constants.c23
-rw-r--r--arch/um/scripts/Makefile.rules4
-rw-r--r--arch/um/sys-i386/Makefile2
-rw-r--r--arch/um/sys-i386/kernel-offsets.c4
-rw-r--r--arch/um/sys-i386/sysrq.c13
-rw-r--r--arch/um/sys-i386/user-offsets.c71
-rw-r--r--arch/um/sys-i386/util/Makefile5
-rw-r--r--arch/um/sys-i386/util/mk_sc.c51
-rw-r--r--arch/um/sys-i386/util/mk_thread.c22
-rw-r--r--arch/um/sys-x86_64/Makefile2
-rw-r--r--arch/um/sys-x86_64/kernel-offsets.c2
-rw-r--r--arch/um/sys-x86_64/stub_segv.c37
-rw-r--r--arch/um/sys-x86_64/user-offsets.c117
-rw-r--r--arch/um/sys-x86_64/util/Makefile8
-rw-r--r--arch/um/sys-x86_64/util/mk_sc.c47
-rw-r--r--arch/um/sys-x86_64/util/mk_thread.c20
-rw-r--r--arch/um/util/Makefile5
-rw-r--r--arch/um/util/mk_constants.c32
-rw-r--r--arch/um/util/mk_task.c30
57 files changed, 846 insertions, 1029 deletions
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 5b5af95721a..e1ffad22460 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -28,8 +28,6 @@ SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
$(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
-GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
-
um-modes-$(CONFIG_MODE_TT) += tt
um-modes-$(CONFIG_MODE_SKAS) += skas
@@ -45,9 +43,7 @@ endif
ARCH_INCLUDE := -I$(ARCH_DIR)/include
ifneq ($(KBUILD_SRC),)
-ARCH_INCLUDE += -I$(ARCH_DIR)/include2
ARCH_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include
-MRPROPER_DIRS += $(ARCH_DIR)/include2
endif
SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH)
@@ -87,10 +83,6 @@ CONFIG_KERNEL_HALF_GIGS ?= 0
SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
-ifeq ($(CONFIG_MODE_SKAS), y)
-$(SYS_HEADERS) : $(ARCH_DIR)/include/skas_ptregs.h
-endif
-
.PHONY: linux
all: linux
@@ -111,7 +103,8 @@ else
$(shell cd $(ARCH_DIR) && ln -sf Kconfig.$(SUBARCH) Kconfig.arch)
endif
-archprepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS)
+archprepare: $(ARCH_SYMLINKS) $(ARCH_DIR)/include/user_constants.h
+prepare: $(ARCH_DIR)/include/kern_constants.h
LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static
LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib
@@ -146,22 +139,20 @@ 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 $(ARCH_DIR)/include/uml-config.h \
- $(GEN_HEADERS) $(ARCH_DIR)/include/skas_ptregs.h \
- $(ARCH_DIR)/include/user_constants.h $(ARCH_DIR)/Kconfig.arch
+ $(ARCH_DIR)/include/user_constants.h \
+ $(ARCH_DIR)/include/kern_constants.h $(ARCH_DIR)/Kconfig.arch
MRPROPER_FILES += $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) \
$(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS)) $(ARCH_DIR)/os
archclean:
- $(Q)$(MAKE) $(clean)=$(ARCH_DIR)/util
- $(Q)$(MAKE) $(clean)=$(ARCH_DIR)/os-$(OS)/util
@find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
-o -name '*.gcov' \) -type f -print | xargs rm -f
$(SYMLINK_HEADERS):
@echo ' SYMLINK $@'
ifneq ($(KBUILD_SRC),)
- ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@
+ $(Q)ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@
else
$(Q)cd $(TOPDIR)/$(dir $@) ; \
ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@)
@@ -180,9 +171,7 @@ $(ARCH_DIR)/include/sysdep:
@echo ' SYMLINK $@'
ifneq ($(KBUILD_SRC),)
$(Q)mkdir -p $(ARCH_DIR)/include
- $(Q)mkdir -p $(ARCH_DIR)/include2
- $(Q)ln -fsn sysdep-$(SUBARCH) $(ARCH_DIR)/include/sysdep
- $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/include/sysdep-$(SUBARCH) $(ARCH_DIR)/include2/sysdep
+ $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/include/sysdep-$(SUBARCH) $(ARCH_DIR)/include/sysdep
else
$(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep
endif
@@ -202,8 +191,6 @@ endef
define filechk_gen-asm-offsets
(set -e; \
- echo "#ifndef __ASM_OFFSETS_H__"; \
- echo "#define __ASM_OFFSETS_H__"; \
echo "/*"; \
echo " * DO NOT MODIFY."; \
echo " *"; \
@@ -212,8 +199,7 @@ define filechk_gen-asm-offsets
echo " */"; \
echo ""; \
sed -ne "/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}"; \
- echo ""; \
- echo "#endif" )
+ echo ""; )
endef
$(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h
@@ -222,50 +208,18 @@ $(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h
$(ARCH_DIR)/user-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.c
$(CC) $(USER_CFLAGS) -S -o $@ $<
-$(ARCH_DIR)/user-offsets.h: $(ARCH_DIR)/user-offsets.s
+$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/user-offsets.s
$(call filechk,gen-asm-offsets)
-CLEAN_FILES += $(ARCH_DIR)/user-offsets.s $(ARCH_DIR)/user-offsets.h
+CLEAN_FILES += $(ARCH_DIR)/user-offsets.s
$(ARCH_DIR)/kernel-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/kernel-offsets.c \
- $(ARCH_SYMLINKS) \
- $(SYS_DIR)/sc.h \
- include/asm include/linux/version.h \
- include/config/MARKER \
- $(ARCH_DIR)/include/user_constants.h
+ archprepare
$(CC) $(CFLAGS) $(NOSTDINC_FLAGS) $(CPPFLAGS) -S -o $@ $<
-$(ARCH_DIR)/kernel-offsets.h: $(ARCH_DIR)/kernel-offsets.s
+$(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/kernel-offsets.s
$(call filechk,gen-asm-offsets)
-CLEAN_FILES += $(ARCH_DIR)/kernel-offsets.s $(ARCH_DIR)/kernel-offsets.h
-
-$(ARCH_DIR)/include/task.h: $(ARCH_DIR)/util/mk_task
- $(call filechk,gen_header)
-
-$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/os-$(OS)/util/mk_user_constants
- $(call filechk,gen_header)
-
-$(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/util/mk_constants
- $(call filechk,gen_header)
-
-$(ARCH_DIR)/include/skas_ptregs.h: $(ARCH_DIR)/kernel/skas/util/mk_ptregs
- $(call filechk,gen_header)
-
-$(ARCH_DIR)/os-$(OS)/util/mk_user_constants: $(ARCH_DIR)/os-$(OS)/util FORCE ;
-
-$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants: $(ARCH_DIR)/include/user_constants.h $(ARCH_DIR)/util \
- FORCE ;
-
-$(ARCH_DIR)/kernel/skas/util/mk_ptregs: $(ARCH_DIR)/kernel/skas/util FORCE ;
-
-$(ARCH_DIR)/util: scripts_basic $(SYS_DIR)/sc.h $(ARCH_DIR)/kernel-offsets.h FORCE
- $(Q)$(MAKE) $(build)=$@
-
-$(ARCH_DIR)/kernel/skas/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
- $(Q)$(MAKE) $(build)=$@
-
-$(ARCH_DIR)/os-$(OS)/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
- $(Q)$(MAKE) $(build)=$@
+CLEAN_FILES += $(ARCH_DIR)/kernel-offsets.s
export SUBARCH USER_CFLAGS OS
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index 1ab431a53ac..2ee8a285811 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -32,25 +32,3 @@ CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH)
ifneq ($(CONFIG_GPROF),y)
ARCH_CFLAGS += -DUM_FASTCALL
endif
-
-SYS_UTIL_DIR := $(ARCH_DIR)/sys-i386/util
-SYS_HEADERS := $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
-
-prepare: $(SYS_HEADERS)
-
-$(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
- $(call filechk,gen_header)
-
-$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
- $(call filechk,gen_header)
-
-$(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
- $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
-
-$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_DIR)/kernel-offsets.h FORCE
- $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
-
-$(SYS_UTIL_DIR): scripts_basic include/asm FORCE
- $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR)
-
-CLEAN_FILES += $(SYS_HEADERS)
diff --git a/arch/um/Makefile-skas b/arch/um/Makefile-skas
index fd18ec57227..ac35de5316a 100644
--- a/arch/um/Makefile-skas
+++ b/arch/um/Makefile-skas
@@ -10,5 +10,3 @@ CFLAGS-$(CONFIG_GCOV) += $(GCOV_OPT)
CFLAGS-$(CONFIG_GPROF) += $(GPROF_OPT)
LINK-$(CONFIG_GCOV) += $(GCOV_OPT)
LINK-$(CONFIG_GPROF) += $(GPROF_OPT)
-
-GEN_HEADERS += $(ARCH_DIR)/include/skas_ptregs.h
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index 436abbba409..4f118d5cc2e 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -12,24 +12,3 @@ CHECKFLAGS += -m64
ELF_ARCH := i386:x86-64
ELF_FORMAT := elf64-x86-64
-
-SYS_UTIL_DIR := $(ARCH_DIR)/sys-x86_64/util
-SYS_DIR := $(ARCH_DIR)/include/sysdep-x86_64
-
-SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
-
-prepare: $(SYS_HEADERS)
-
-$(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
- $(call filechk,gen_header)
-
-$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
- $(call filechk,gen_header)
-
-$(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
- $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
-
-$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(GEN_HEADERS) $(ARCH_DIR)/kernel-offsets.h FORCE
- $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
-
-CLEAN_FILES += $(SYS_HEADERS)
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index 783e18cae09..de17d4c6e02 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -13,7 +13,7 @@ mcast-objs := mcast_kern.o mcast_user.o
net-objs := net_kern.o net_user.o
mconsole-objs := mconsole_kern.o mconsole_user.o
hostaudio-objs := hostaudio_kern.o
-ubd-objs := ubd_kern.o
+ubd-objs := ubd_kern.o ubd_user.o
port-objs := port_kern.o port_user.o
harddog-objs := harddog_kern.o harddog_user.o
diff --git a/arch/um/drivers/cow.h b/arch/um/drivers/cow.h
index 4fcf3a8d13f..dc36b222100 100644
--- a/arch/um/drivers/cow.h
+++ b/arch/um/drivers/cow.h
@@ -3,15 +3,40 @@
#include <asm/types.h>
-#if defined(__BIG_ENDIAN)
-# define ntohll(x) (x)
-# define htonll(x) (x)
-#elif defined(__LITTLE_ENDIAN)
-# define ntohll(x) bswap_64(x)
-# define htonll(x) bswap_64(x)
+#if defined(__KERNEL__)
+
+# include <asm/byteorder.h>
+
+# if defined(__BIG_ENDIAN)
+# define ntohll(x) (x)
+# define htonll(x) (x)
+# elif defined(__LITTLE_ENDIAN)
+# define ntohll(x) be64_to_cpu(x)
+# define htonll(x) cpu_to_be64(x)
+# else
+# error "Could not determine byte order"
+# endif
+
#else
-#error "__BYTE_ORDER not defined"
+/* For the definition of ntohl, htonl and __BYTE_ORDER */
+#include <endian.h>
+#include <netinet/in.h>
+#if defined(__BYTE_ORDER)
+
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define ntohll(x) (x)
+# define htonll(x) (x)
+# elif __BYTE_ORDER == __LITTLE_ENDIAN
+# define ntohll(x) bswap_64(x)
+# define htonll(x) bswap_64(x)
+# else
+# error "Could not determine byte order: __BYTE_ORDER uncorrectly defined"
+# endif
+
+#else /* ! defined(__BYTE_ORDER) */
+# error "Could not determine byte order: __BYTE_ORDER not defined"
#endif
+#endif /* ! defined(__KERNEL__) */
extern int init_cow_file(int fd, char *cow_file, char *backing_file,
int sectorsize, int alignment, int *bitmap_offset_out,
diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c
index a8ce6fc3ef2..fbe2217db5d 100644
--- a/arch/um/drivers/cow_user.c
+++ b/arch/um/drivers/cow_user.c
@@ -9,7 +9,6 @@
#include <sys/time.h>
#include <sys/param.h>
#include <sys/user.h>
-#include <netinet/in.h>
#include "os.h"
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index 04383f98f4d..310c1f823f2 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -23,7 +23,7 @@ static struct mconsole_command commands[] = {
{ "reboot", mconsole_reboot, MCONSOLE_PROC },
{ "config", mconsole_config, MCONSOLE_PROC },
{ "remove", mconsole_remove, MCONSOLE_PROC },
- { "sysrq", mconsole_sysrq, MCONSOLE_PROC },
+ { "sysrq", mconsole_sysrq, MCONSOLE_INTR },
{ "help", mconsole_help, MCONSOLE_INTR },
{ "cad", mconsole_cad, MCONSOLE_INTR },
{ "stop", mconsole_stop, MCONSOLE_PROC },
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
index c41efd207fc..189839e4f1d 100644
--- a/arch/um/drivers/port_kern.c
+++ b/arch/um/drivers/port_kern.c
@@ -7,7 +7,6 @@
#include "linux/sched.h"
#include "linux/slab.h"
#include "linux/interrupt.h"
-#include "linux/irq.h"
#include "linux/spinlock.h"
#include "linux/errno.h"
#include "asm/atomic.h"
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index e77a38da435..f73134333f6 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -35,7 +35,6 @@
#include "linux/blkpg.h"
#include "linux/genhd.h"
#include "linux/spinlock.h"
-#include "asm/atomic.h"
#include "asm/segment.h"
#include "asm/uaccess.h"
#include "asm/irq.h"
@@ -54,21 +53,20 @@
#include "mem.h"
#include "mem_kern.h"
#include "cow.h"
-#include "aio.h"
enum ubd_req { UBD_READ, UBD_WRITE };
struct io_thread_req {
- enum aio_type op;
+ enum ubd_req op;
int fds[2];
unsigned long offsets[2];
unsigned long long offset;
unsigned long length;
char *buffer;
int sectorsize;
- int bitmap_offset;
- long bitmap_start;
- long bitmap_end;
+ unsigned long sector_mask;
+ unsigned long long cow_offset;
+ unsigned long bitmap_words[2];
int error;
};
@@ -82,31 +80,28 @@ extern int create_cow_file(char *cow_file, char *backing_file,
unsigned long *bitmap_len_out,
int *data_offset_out);
extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
-extern void do_io(struct io_thread_req *req, struct request *r,
- unsigned long *bitmap);
+extern void do_io(struct io_thread_req *req);
-static inline int ubd_test_bit(__u64 bit, void *data)
+static inline int ubd_test_bit(__u64 bit, unsigned char *data)
{
- unsigned char *buffer = data;
__u64 n;
int bits, off;
- bits = sizeof(buffer[0]) * 8;
+ bits = sizeof(data[0]) * 8;
n = bit / bits;
off = bit % bits;
- return((buffer[n] & (1 << off)) != 0);
+ return((data[n] & (1 << off)) != 0);
}
-static inline void ubd_set_bit(__u64 bit, void *data)
+static inline void ubd_set_bit(__u64 bit, unsigned char *data)
{
- unsigned char *buffer = data;
__u64 n;
int bits, off;
- bits = sizeof(buffer[0]) * 8;
+ bits = sizeof(data[0]) * 8;
n = bit / bits;
off = bit % bits;
- buffer[n] |= (1 << off);
+ data[n] |= (1 << off);
}
/*End stuff from ubd_user.h*/
@@ -115,6 +110,8 @@ static inline void ubd_set_bit(__u64 bit, void *data)
static DEFINE_SPINLOCK(ubd_io_lock);
static DEFINE_SPINLOCK(ubd_lock);
+static void (*do_ubd)(void);
+
static int ubd_open(struct inode * inode, struct file * filp);
static int ubd_release(struct inode * inode, struct file * file);
static int ubd_ioctl(struct inode * inode, struct file * file,
@@ -161,8 +158,6 @@ struct cow {
int data_offset;
};
-#define MAX_SG 64
-
struct ubd {
char *file;
int count;
@@ -173,7 +168,6 @@ struct ubd {
int no_cow;
struct cow cow;
struct platform_device pdev;
- struct scatterlist sg[MAX_SG];
};
#define DEFAULT_COW { \
@@ -466,114 +460,81 @@ __uml_help(fakehd,
);
static void do_ubd_request(request_queue_t * q);
-static int in_ubd;
+
+/* Only changed by ubd_init, which is an initcall. */
+int thread_fd = -1;
/* Changed by ubd_handler, which is serialized because interrupts only
* happen on CPU 0.
*/
int intr_count = 0;
-static void ubd_end_request(struct request *req, int bytes, int uptodate)
+/* call ubd_finish if you need to serialize */
+static void __ubd_finish(struct request *req, int error)
{
- if (!end_that_request_first(req, uptodate, bytes >> 9)) {
- add_disk_randomness(req->rq_disk);
- end_that_request_last(req);
+ int nsect;
+
+ if(error){
+ end_request(req, 0);
+ return;
}
+ nsect = req->current_nr_sectors;
+ req->sector += nsect;
+ req->buffer += nsect << 9;
+ req->errors = 0;
+ req->nr_sectors -= nsect;
+ req->current_nr_sectors = 0;
+ end_request(req, 1);
}
-/* call ubd_finish if you need to serialize */
-static void __ubd_finish(struct request *req, int bytes)
+static inline void ubd_finish(struct request *req, int error)
{
- if(bytes < 0){
- ubd_end_request(req, 0, 0);
- return;
- }
-
- ubd_end_request(req, bytes, 1);
+ spin_lock(&ubd_io_lock);
+ __ubd_finish(req, error);
+ spin_unlock(&ubd_io_lock);
}
-static inline void ubd_finish(struct request *req, int bytes)
+/* Called without ubd_io_lock held */
+static void ubd_handler(void)
{
- spin_lock(&ubd_io_lock);
- __ubd_finish(req, bytes);
- spin_unlock(&ubd_io_lock);
+ struct io_thread_req req;
+ struct request *rq = elv_next_request(ubd_queue);
+ int n;
+
+ do_ubd = NULL;
+ intr_count++;
+ n = os_read_file(thread_fd, &req, sizeof(req));
+ if(n != sizeof(req)){
+ printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
+ "err = %d\n", os_getpid(), -n);
+ spin_lock(&ubd_io_lock);
+ end_request(rq, 0);
+ spin_unlock(&ubd_io_lock);
+ return;
+ }
+
+ ubd_finish(rq, req.error);
+ reactivate_fd(thread_fd, UBD_IRQ);
+ do_ubd_request(ubd_queue);
}
-struct bitmap_io {
- atomic_t count;
- struct aio_context aio;
-};
-
-struct ubd_aio {
- struct aio_context aio;
- struct request *req;
- int len;
- struct bitmap_io *bitmap;
- void *bitmap_buf;
-};
-
-static int ubd_reply_fd = -1;
-
static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused)
{
- struct aio_thread_reply reply;
- struct ubd_aio *aio;
- struct request *req;
- int err, n, fd = (int) (long) dev;
-
- while(1){
- err = os_read_file(fd, &reply, sizeof(reply));
- if(err == -EAGAIN)
- break;
- if(err < 0){
- printk("ubd_aio_handler - read returned err %d\n",
- -err);
- break;
- }
-
- aio = container_of(reply.data, struct ubd_aio, aio);
- n = reply.err;
-
- if(n == 0){
- req = aio->req;
- req->nr_sectors -= aio->len >> 9;
-
- if((aio->bitmap != NULL) &&
- (atomic_dec_and_test(&aio->bitmap->count))){
- aio->aio = aio->bitmap->aio;
- aio->len = 0;
- kfree(aio->bitmap);
- aio->bitmap = NULL;
- submit_aio(&aio->aio);
- }
- else {
- if((req->nr_sectors == 0) &&
- (aio->bitmap == NULL)){
- int len = req->hard_nr_sectors << 9;
- ubd_finish(req, len);
- }
-
- if(aio->bitmap_buf != NULL)
- kfree(aio->bitmap_buf);
- kfree(aio);
- }
- }
- else if(n < 0){
- ubd_finish(aio->req, n);
- if(aio->bitmap != NULL)
- kfree(aio->bitmap);
- if(aio->bitmap_buf != NULL)
- kfree(aio->bitmap_buf);
- kfree(aio);
- }
- }
- reactivate_fd(fd, UBD_IRQ);
+ ubd_handler();
+ return(IRQ_HANDLED);
+}
- do_ubd_request(ubd_queue);
+/* Only changed by ubd_init, which is an initcall. */
+static int io_pid = -1;
- return(IRQ_HANDLED);
+void kill_io_thread(void)
+{
+ if(io_pid != -1)
+ os_kill_process(io_pid, 1);
}
+__uml_exitcall(kill_io_thread);
+
static int ubd_file_size(struct ubd *dev, __u64 *size_out)
{
char *file;
@@ -608,7 +569,7 @@ static int ubd_open_dev(struct ubd *dev)
&dev->cow.data_offset, create_ptr);
if((dev->fd == -ENOENT) && create_cow){
- dev->fd = create_cow_file(dev->file, dev->cow.file,
+ dev->fd = create_cow_file(dev->file, dev->cow.file,
dev->openflags, 1 << 9, PAGE_SIZE,
&dev->cow.bitmap_offset,
&dev->cow.bitmap_len,
@@ -870,10 +831,6 @@ int ubd_init(void)
{
int i;
- ubd_reply_fd = init_aio_irq(UBD_IRQ, "ubd", ubd_intr);
- if(ubd_reply_fd < 0)
- printk("Setting up ubd AIO failed, err = %d\n", ubd_reply_fd);
-
devfs_mk_dir("ubd");
if (register_blkdev(MAJOR_NR, "ubd"))
return -1;
@@ -884,7 +841,6 @@ int ubd_init(void)
return -1;
}
- blk_queue_max_hw_segments(ubd_queue, MAX_SG);
if (fake_major != MAJOR_NR) {
char name[sizeof("ubd_nnn\0")];
@@ -896,12 +852,40 @@ int ubd_init(void)
driver_register(&ubd_driver);
for (i = 0; i < MAX_DEV; i++)
ubd_add(i);
-
return 0;
}
late_initcall(ubd_init);
+int ubd_driver_init(void){
+ unsigned long stack;
+ int err;
+
+ /* Set by CONFIG_BLK_DEV_UBD_SYNC or ubd=sync.*/
+ if(global_openflags.s){
+ printk(KERN_INFO "ubd: Synchronous mode\n");
+ /* Letting ubd=sync be like using ubd#s= instead of ubd#= is
+ * enough. So use anyway the io thread. */
+ }
+ stack = alloc_stack(0, 0);
+ io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
+ &thread_fd);
+ if(io_pid < 0){
+ printk(KERN_ERR
+ "ubd : Failed to start I/O thread (errno = %d) - "
+ "falling back to synchronous I/O\n", -io_pid);
+ io_pid = -1;
+ return(0);
+ }
+ err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
+ SA_INTERRUPT, "ubd", ubd_dev);
+ if(err != 0)
+ printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
+ return(err);
+}
+
+device_initcall(ubd_driver_init);
+
static int ubd_open(struct inode *inode, struct file *filp)
{
struct gendisk *disk = inode->i_bdev->bd_disk;
@@ -939,55 +923,105 @@ static int ubd_release(struct inode * inode, struct file * file)
return(0);
}
-static void cowify_bitmap(struct io_thread_req *req, unsigned long *bitmap)
+static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
+ __u64 *cow_offset, unsigned long *bitmap,
+ __u64 bitmap_offset, unsigned long *bitmap_words,
+ __u64 bitmap_len)
{
- __u64 sector = req->offset / req->sectorsize;
- int i;
+ __u64 sector = io_offset >> 9;
+ int i, update_bitmap = 0;
+
+ for(i = 0; i < length >> 9; i++){
+ if(cow_mask != NULL)
+ ubd_set_bit(i, (unsigned char *) cow_mask);
+ if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
+ continue;
- for(i = 0; i < req->length / req->sectorsize; i++){
- if(ubd_test_bit(sector + i, bitmap))
- continue;
+ update_bitmap = 1;
+ ubd_set_bit(sector + i, (unsigned char *) bitmap);
+ }
+
+ if(!update_bitmap)
+ return;
- if(req->bitmap_start == -1)
- req->bitmap_start = sector + i;
- req->bitmap_end = sector + i + 1;
+ *cow_offset = sector / (sizeof(unsigned long) * 8);
- ubd_set_bit(sector + i, bitmap);
- }
+ /* This takes care of the case where we're exactly at the end of the
+ * device, and *cow_offset + 1 is off the end. So, just back it up
+ * by one word. Thanks to Lynn Kerby for the fix and James McMechan
+ * for the original diagnosis.
+ */
+ if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) /
+ sizeof(unsigned long) - 1))
+ (*cow_offset)--;
+
+ bitmap_words[0] = bitmap[*cow_offset];
+ bitmap_words[1] = bitmap[*cow_offset + 1];
+
+ *cow_offset *= sizeof(unsigned long);
+ *cow_offset += bitmap_offset;
+}
+
+static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
+ __u64 bitmap_offset, __u64 bitmap_len)
+{
+ __u64 sector = req->offset >> 9;
+ int i;
+
+ if(req->length > (sizeof(req->sector_mask) * 8) << 9)
+ panic("Operation too long");
+
+ if(req->op == UBD_READ) {
+ for(i = 0; i < req->length >> 9; i++){
+ if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
+ ubd_set_bit(i, (unsigned char *)
+ &req->sector_mask);
+ }
+ }
+ else cowify_bitmap(req->offset, req->length, &req->sector_mask,
+ &req->cow_offset, bitmap, bitmap_offset,
+ req->bitmap_words, bitmap_len);
}
/* Called with ubd_io_lock held */
-static int prepare_request(struct request *req, struct io_thread_req *io_req,
- unsigned long long offset, int page_offset,
- int len, struct page *page)
+static int prepare_request(struct request *req, struct io_thread_req *io_req)
{
struct gendisk *disk = req->rq_disk;
struct ubd *dev = disk->private_data;
+ __u64 offset;
+ int len;
+
+ if(req->rq_status == RQ_INACTIVE) return(1);
/* This should be impossible now */
if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
printk("Write attempted on readonly ubd device %s\n",
disk->disk_name);
- ubd_end_request(req, 0, 0);
+ end_request(req, 0);
return(1);
}
+ offset = ((__u64) req->sector) << 9;
+ len = req->current_nr_sectors << 9;
+
io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
io_req->fds[1] = dev->fd;
+ io_req->cow_offset = -1;
io_req->offset = offset;
io_req->length = len;
io_req->error = 0;
- io_req->op = (rq_data_dir(req) == READ) ? AIO_READ : AIO_WRITE;
+ io_req->sector_mask = 0;
+
+ io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
io_req->offsets[0] = 0;
io_req->offsets[1] = dev->cow.data_offset;
- io_req->buffer = page_address(page) + page_offset;
+ io_req->buffer = req->buffer;
io_req->sectorsize = 1 << 9;
- io_req->bitmap_offset = dev->cow.bitmap_offset;
- io_req->bitmap_start = -1;
- io_req->bitmap_end = -1;
- if((dev->cow.file != NULL) && (io_req->op == UBD_WRITE))
- cowify_bitmap(io_req, dev->cow.bitmap);
+ if(dev->cow.file != NULL)
+ cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset,
+ dev->cow.bitmap_len);
+
return(0);
}
@@ -996,36 +1030,30 @@ static void do_ubd_request(request_queue_t *q)
{
struct io_thread_req io_req;
struct request *req;
- __u64 sector;
- int err;
-
- if(in_ubd)
- return;
- in_ubd = 1;
- while((req = elv_next_request(q)) != NULL){
- struct gendisk *disk = req->rq_disk;
- struct ubd *dev = disk->private_data;
- int n, i;
-
- blkdev_dequeue_request(req);
-
- sector = req->sector;
- n = blk_rq_map_sg(q, req, dev->sg);
-
- for(i = 0; i < n; i++){
- struct scatterlist *sg = &dev->sg[i];
-
- err = prepare_request(req, &io_req, sector << 9,
- sg->offset, sg->length,
- sg->page);
- if(err)
- continue;
-
- sector += sg->length >> 9;
- do_io(&io_req, req, dev->cow.bitmap);
+ int err, n;
+
+ if(thread_fd == -1){
+ while((req = elv_next_request(q)) != NULL){
+ err = prepare_request(req, &io_req);
+ if(!err){
+ do_io(&io_req);
+ __ubd_finish(req, io_req.error);
+ }
+ }
+ }
+ else {
+ if(do_ubd || (req = elv_next_request(q)) == NULL)
+ return;
+ err = prepare_request(req, &io_req);
+ if(!err){
+ do_ubd = ubd_handler;
+ n = os_write_file(thread_fd, (char *) &io_req,
+ sizeof(io_req));
+ if(n != sizeof(io_req))
+ printk("write to io thread failed, "
+ "errno = %d\n", -n);
}
}
- in_ubd = 0;
}
static int ubd_ioctl(struct inode * inode, struct file * file,
@@ -1241,95 +1269,131 @@ int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
return(err);
}
-void do_io(struct io_thread_req *req, struct request *r, unsigned long *bitmap)
+static int update_bitmap(struct io_thread_req *req)
{
- struct ubd_aio *aio;
- struct bitmap_io *bitmap_io = NULL;
- char *buf;
- void *bitmap_buf = NULL;
- unsigned long len, sector;
- int nsectors, start, end, bit, err;
- __u64 off;
-
- if(req->bitmap_start != -1){
- /* Round up to the nearest word */
- int round = sizeof(unsigned long);
- len = (req->bitmap_end - req->bitmap_start +
- round * 8 - 1) / (round * 8);
- len *= round;
-
- off = req->bitmap_start / (8 * round);
- off *= round;
-
- bitmap_io = kmalloc(sizeof(*bitmap_io), GFP_KERNEL);
- if(bitmap_io == NULL){
- printk("Failed to kmalloc bitmap IO\n");
- req->error = 1;
- return;
- }
+ int n;
- bitmap_buf = kmalloc(len, GFP_KERNEL);
- if(bitmap_buf == NULL){
- printk("do_io : kmalloc of bitmap chunk "
- "failed\n");
- kfree(bitmap_io);
- req->error = 1;
- return;
- }
- memcpy(bitmap_buf, &bitmap[off / sizeof(bitmap[0])], len);
-
- *bitmap_io = ((struct bitmap_io)
- { .count = ATOMIC_INIT(0),
- .aio = INIT_AIO(AIO_WRITE, req->fds[1],
- bitmap_buf, len,
- req->bitmap_offset + off,
- ubd_reply_fd) } );
- }
+ if(req->cow_offset == -1)
+ return(0);
- nsectors = req->length / req->sectorsize;
- start = 0;
- end = nsectors;
- bit = 0;
- do {
- if(bitmap != NULL){
- sector = req->offset / req->sectorsize;
- bit = ubd_test_bit(sector + start, bitmap);
- end = start;
- while((end < nsectors) &&
- (ubd_test_bit(sector + end, bitmap) == bit))
- end++;
- }
+ n = os_seek_file(req->fds[1], req->cow_offset);
+ if(n < 0){
+ printk("do_io - bitmap lseek failed : err = %d\n", -n);
+ return(1);
+ }
- off = req->offsets[bit] + req->offset +
- start * req->sectorsize;
- len = (end - start) * req->sectorsize;
- buf = &req->buffer[start * req->sectorsize];
+ n = os_write_file(req->fds[1], &req->bitmap_words,
+ sizeof(req->bitmap_words));
+ if(n != sizeof(req->bitmap_words)){
+ printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
+ req->fds[1]);
+ return(1);
+ }
- aio = kmalloc(sizeof(*aio), GFP_KERNEL);
- if(aio == NULL){
- req->error = 1;
- return;
- }
+ return(0);
+}
- *aio = ((struct ubd_aio)
- { .aio = INIT_AIO(req->op, req->fds[bit], buf,
- len, off, ubd_reply_fd),
- .len = len,
- .req = r,
- .bitmap = bitmap_io,
- .bitmap_buf = bitmap_buf });
-
- if(aio->bitmap != NULL)
- atomic_inc(&aio->bitmap->count);
-
- err = submit_aio(&aio->aio);
- if(err){
- printk("do_io - submit_aio failed, "
- "err = %d\n", err);
- req->error = 1;
- return;
- }
+void do_io(struct io_thread_req *req)
+{
+ char *buf;
+ unsigned long len;
+ int n, nsectors, start, end, bit;
+ int err;
+ __u64 off;
+
+ nsectors = req->length / req->sectorsize;
+ start = 0;
+ do {
+ bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
+ end = start;
+ while((end < nsectors) &&
+ (ubd_test_bit(end, (unsigned char *)
+ &req->sector_mask) == bit))
+ end++;
+
+ off = req->offset + req->offsets[bit] +
+ start * req->sectorsize;
+ len = (end - start) * req->sectorsize;
+ buf = &req->buffer[start * req->sectorsize];
+
+ err = os_seek_file(req->fds[bit], off);
+ if(err < 0){
+ printk("do_io - lseek failed : err = %d\n", -err);
+ req->error = 1;
+ return;
+ }
+ if(req->op == UBD_READ){
+ n = 0;
+ do {
+ buf = &buf[n];
+ len -= n;
+ n = os_read_file(req->fds[bit], buf, len);
+ if (n < 0) {
+ printk("do_io - read failed, err = %d "
+ "fd = %d\n", -n, req->fds[bit]);
+ req->error = 1;
+ return;
+ }
+ } while((n < len) && (n != 0));
+ if (n < len) memset(&buf[n], 0, len - n);
+ } else {
+ n = os_write_file(req->fds[bit], buf, len);
+ if(n != len){
+ printk("do_io - write failed err = %d "
+ "fd = %d\n", -n, req->fds[bit]);
+ req->error = 1;
+ return;
+ }
+ }
+
+ start = end;
+ } while(start < nsectors);
- start = end;
- } while(start < nsectors);
+ req->error = update_bitmap(req);
}
+
+/* Changed in start_io_thread, which is serialized by being called only
+ * from ubd_init, which is an initcall.
+ */
+int kernel_fd = -1;
+
+/* Only changed by the io thread */
+int io_count = 0;
+
+int io_thread(void *arg)
+{
+ struct io_thread_req req;
+ int n;
+
+ ignore_sigwinch_sig();
+ while(1){
+ n = os_read_file(kernel_fd, &req, sizeof(req));
+ if(n != sizeof(req)){
+ if(n < 0)
+ printk("io_thread - read failed, fd = %d, "
+ "err = %d\n", kernel_fd, -n);
+ else {
+ printk("io_thread - short read, fd = %d, "
+ "length = %d\n", kernel_fd, n);
+ }
+ continue;
+ }
+ io_count++;
+ do_io(&req);
+ n = os_write_file(kernel_fd, &req, sizeof(req));
+ if(n != sizeof(req))
+ printk("io_thread - write failed, fd = %d, err = %d\n",
+ kernel_fd, -n);
+ }
+}
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only. This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */
diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
new file mode 100644
index 00000000000..b94d2bc4fe0
--- /dev/null
+++ b/arch/um/drivers/ubd_user.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001 Ridgerun,Inc (glonnon@ridgerun.com)
+ * Licensed under the GPL
+ */
+
+#include <stddef.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sched.h>
+#include <signal.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+#include "asm/types.h"
+#include "user_util.h"
+#include "kern_util.h"
+#include "user.h"
+#include "ubd_user.h"
+#include "os.h"
+#include "cow.h"
+
+#include <endian.h>
+#include <byteswap.h>
+
+void ignore_sigwinch_sig(void)
+{
+ signal(SIGWINCH, SIG_IGN);
+}
+
+int start_io_thread(unsigned long sp, int *fd_out)
+{
+ int pid, fds[2], err;
+
+ err = os_pipe(fds, 1, 1);
+ if(err < 0){
+ printk("start_io_thread - os_pipe failed, err = %d\n", -err);
+ goto out;
+ }
+
+ kernel_fd = fds[0];
+ *fd_out = fds[1];
+
+ pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
+ NULL);
+ if(pid < 0){
+ printk("start_io_thread - clone failed : errno = %d\n", errno);
+ err = -errno;
+ goto out_close;
+ }
+
+ return(pid);
+
+ out_close:
+ os_close_file(fds[0]);
+ os_close_file(fds[1]);
+ kernel_fd = -1;
+ *fd_out = -1;
+ out:
+ return(err);
+}
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only. This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */
diff --git a/arch/um/include/aio.h b/arch/um/include/aio.h
index 83f16877ab0..423bae9153f 100644
--- a/arch/um/include/aio.h
+++ b/arch/um/include/aio.h
@@ -14,27 +14,15 @@ struct aio_thread_reply {
};
struct aio_context {
- enum aio_type type;
- int fd;
- void *data;
- int len;
- unsigned long long offset;
int reply_fd;
struct aio_context *next;
};
-#define INIT_AIO(aio_type, aio_fd, aio_data, aio_len, aio_offset, \
- aio_reply_fd) \
- { .type = aio_type, \
- .fd = aio_fd, \
- .data = aio_data, \
- .len = aio_len, \
- .offset = aio_offset, \
- .reply_fd = aio_reply_fd }
-
#define INIT_AIO_CONTEXT { .reply_fd = -1, \
.next = NULL }
-extern int submit_aio(struct aio_context *aio);
+extern int submit_aio(enum aio_type type, int fd, char *buf, int len,
+ unsigned long long offset, int reply_fd,
+ struct aio_context *aio);
#endif
diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h
index 782ac3a3baf..356390d1f8b 100644
--- a/arch/um/include/common-offsets.h
+++ b/arch/um/include/common-offsets.h
@@ -1,7 +1,7 @@
/* for use by sys-$SUBARCH/kernel-offsets.c */
-OFFSET(TASK_REGS, task_struct, thread.regs);
-OFFSET(TASK_PID, task_struct, pid);
+OFFSET(HOST_TASK_REGS, task_struct, thread.regs);
+OFFSET(HOST_TASK_PID, task_struct, pid);
DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE);
DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
DEFINE_STR(UM_KERN_EMERG, KERN_EMERG);
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 583329d0a53..2e58e304b8b 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -6,6 +6,7 @@
#ifndef __OS_H__
#define __OS_H__
+#include "uml-config.h"
#include "asm/types.h"
#include "../os/include/file.h"
@@ -157,6 +158,14 @@ extern int os_lock_file(int fd, int excl);
extern void os_early_checks(void);
extern int can_do_skas(void);
+/* Make sure they are clear when running in TT mode. Required by
+ * SEGV_MAYBE_FIXABLE */
+#ifdef UML_CONFIG_MODE_SKAS
+#define clear_can_do_skas() do { ptrace_faultinfo = proc_mm = 0; } while (0)
+#else
+#define clear_can_do_skas() do {} while (0)
+#endif
+
/* mem.c */
extern int create_mem_file(unsigned long len);
diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h
index 0a35e6d0baa..4892e5fcef0 100644
--- a/arch/um/include/registers.h
+++ b/arch/um/include/registers.h
@@ -15,16 +15,6 @@ extern void save_registers(int pid, union uml_pt_regs *regs);
extern void restore_registers(int pid, union uml_pt_regs *regs);
extern void init_registers(int pid);
extern void get_safe_registers(unsigned long * regs);
+extern void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer);
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/skas_ptregs.h b/arch/um/include/skas_ptregs.h
new file mode 100644
index 00000000000..73db19e9c07
--- /dev/null
+++ b/arch/um/include/skas_ptregs.h
@@ -0,0 +1,6 @@
+#ifndef __SKAS_PT_REGS_
+#define __SKAS_PT_REGS_
+
+#include <user_constants.h>
+
+#endif
diff --git a/arch/um/include/sysdep-i386/sc.h b/arch/um/include/sysdep-i386/sc.h
new file mode 100644
index 00000000000..c57d1780ad3
--- /dev/null
+++ b/arch/um/include/sysdep-i386/sc.h
@@ -0,0 +1,44 @@
+#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/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
index 1fe72926516..23fd2644d7e 100644
--- a/arch/um/include/sysdep-i386/sigcontext.h
+++ b/arch/um/include/sysdep-i386/sigcontext.h
@@ -6,6 +6,7 @@
#ifndef __SYS_SIGCONTEXT_I386_H
#define __SYS_SIGCONTEXT_I386_H
+#include "uml-config.h"
#include <sysdep/sc.h>
#define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
@@ -26,7 +27,14 @@
#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
/* This is Page Fault */
-#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
+#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
+
+/* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */
+#ifdef UML_CONFIG_MODE_SKAS
+#define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo)
+#else
+#define SEGV_MAYBE_FIXABLE(fi) 0
+#endif
extern unsigned long *sc_sigmask(void *sc_ptr);
extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
diff --git a/arch/um/include/sysdep-i386/thread.h b/arch/um/include/sysdep-i386/thread.h
new file mode 100644
index 00000000000..e2bd6bae8b8
--- /dev/null
+++ b/arch/um/include/sysdep-i386/thread.h
@@ -0,0 +1,11 @@
+#ifndef __UM_THREAD_H
+#define __UM_THREAD_H
+
+#include <kern_constants.h>
+
+#define TASK_DEBUGREGS(task) ((unsigned long *) &(((char *) (task))[HOST_TASK_DEBUGREGS]))
+#ifdef CONFIG_MODE_TT
+#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[HOST_TASK_EXTERN_PID]))
+#endif
+
+#endif
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
index 331aa2d1f3f..8d353f0feec 100644
--- a/arch/um/include/sysdep-x86_64/ptrace.h
+++ b/arch/um/include/sysdep-x86_64/ptrace.h
@@ -183,10 +183,6 @@ struct syscall_args {
case RBP: val = UPT_RBP(regs); break; \
case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \
case CS: val = UPT_CS(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); \
@@ -218,10 +214,6 @@ struct syscall_args {
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 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); \
diff --git a/arch/um/include/sysdep-x86_64/sc.h b/arch/um/include/sysdep-x86_64/sc.h
new file mode 100644
index 00000000000..a160d9fcc59
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/sc.h
@@ -0,0 +1,45 @@
+#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)
+#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)
+#define SC_SS(sc) SC_OFFSET(sc, SC_SS)
+#endif
+
+#endif
diff --git a/arch/um/include/sysdep-x86_64/sigcontext.h b/arch/um/include/sysdep-x86_64/sigcontext.h
index 2a78260d15a..41073235e7a 100644
--- a/arch/um/include/sysdep-x86_64/sigcontext.h
+++ b/arch/um/include/sysdep-x86_64/sigcontext.h
@@ -31,7 +31,10 @@
#define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0)
/* This is Page Fault */
-#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
+#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
extern unsigned long *sc_sigmask(void *sc_ptr);
diff --git a/arch/um/include/sysdep-x86_64/thread.h b/arch/um/include/sysdep-x86_64/thread.h
new file mode 100644
index 00000000000..6a76a7f3683
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/thread.h
@@ -0,0 +1,10 @@
+#ifndef __UM_THREAD_H
+#define __UM_THREAD_H
+
+#include <kern_constants.h>
+
+#ifdef CONFIG_MODE_TT
+#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[HOST_TASK_EXTERN_PID]))
+#endif
+
+#endif
diff --git a/arch/um/include/task.h b/arch/um/include/task.h
new file mode 100644
index 00000000000..6375ba7203c
--- /dev/null
+++ b/arch/um/include/task.h
@@ -0,0 +1,9 @@
+#ifndef __TASK_H
+#define __TASK_H
+
+#include <kern_constants.h>
+
+#define TASK_REGS(task) ((union uml_pt_regs *) &(((char *) (task))[HOST_TASK_REGS]))
+#define TASK_PID(task) *((int *) &(((char *) (task))[HOST_TASK_PID]))
+
+#endif
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index dcd81497199..bbf94bf2921 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -9,7 +9,6 @@
#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/smp.h"
-#include "linux/irq.h"
#include "linux/kernel_stat.h"
#include "linux/interrupt.h"
#include "linux/random.h"
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
index db36c7c9594..8de471b59c1 100644
--- a/arch/um/kernel/skas/Makefile
+++ b/arch/um/kernel/skas/Makefile
@@ -6,8 +6,6 @@
obj-y := clone.o exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \
syscall.o tlb.o trap_user.o uaccess.o
-subdir- := util
-
USER_OBJS := process.o clone.o
include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/skas/util/Makefile b/arch/um/kernel/skas/util/Makefile
deleted file mode 100644
index f7b7eba8334..00000000000
--- a/arch/um/kernel/skas/util/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-hostprogs-y := mk_ptregs
-always := $(hostprogs-y)
-
-mk_ptregs-objs := mk_ptregs-$(SUBARCH).o
-HOSTCFLAGS_mk_ptregs-$(SUBARCH).o := -I$(objtree)/arch/um
diff --git a/arch/um/kernel/skas/util/mk_ptregs-i386.c b/arch/um/kernel/skas/util/mk_ptregs-i386.c
deleted file mode 100644
index 1f96e1eeb8a..00000000000
--- a/arch/um/kernel/skas/util/mk_ptregs-i386.c
+++ /dev/null
@@ -1,49 +0,0 @@
-#include <stdio.h>
-#include <user-offsets.h>
-
-#define SHOW(name) printf("#define %s %d\n", #name, name)
-
-int main(int argc, char **argv)
-{
- printf("/* Automatically generated by "
- "arch/um/kernel/skas/util/mk_ptregs */\n");
- printf("\n");
- printf("#ifndef __SKAS_PT_REGS_\n");
- printf("#define __SKAS_PT_REGS_\n");
- printf("\n");
- SHOW(HOST_FRAME_SIZE);
- SHOW(HOST_FP_SIZE);
- SHOW(HOST_XFP_SIZE);
-
- SHOW(HOST_IP);
- SHOW(HOST_SP);
- SHOW(HOST_EFLAGS);
- SHOW(HOST_EAX);
- SHOW(HOST_EBX);
- SHOW(HOST_ECX);
- SHOW(HOST_EDX);
- SHOW(HOST_ESI);
- SHOW(HOST_EDI);
- SHOW(HOST_EBP);
- SHOW(HOST_CS);
- SHOW(HOST_SS);
- SHOW(HOST_DS);
- SHOW(HOST_FS);
- SHOW(HOST_ES);
- SHOW(HOST_GS);
-
- printf("\n");
- printf("#endif\n");
- return(0);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
deleted file mode 100644
index 5fccbfe35f7..00000000000
--- a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2003 PathScale, Inc.
- *
- * Licensed under the GPL
- */
-
-#include <stdio.h>
-#include <user-offsets.h>
-
-#define SHOW(name) \
- printf("#define %s (%d / sizeof(unsigned long))\n", #name, name)
-
-int main(int argc, char **argv)
-{
- printf("/* Automatically generated by "
- "arch/um/kernel/skas/util/mk_ptregs */\n");
- printf("\n");
- printf("#ifndef __SKAS_PT_REGS_\n");
- printf("#define __SKAS_PT_REGS_\n");
- SHOW(HOST_FRAME_SIZE);
- SHOW(HOST_RBX);
- SHOW(HOST_RCX);
- SHOW(HOST_RDI);
- SHOW(HOST_RSI);
- SHOW(HOST_RDX);
- SHOW(HOST_RBP);
- SHOW(HOST_RAX);
- SHOW(HOST_R8);
- SHOW(HOST_R9);
- SHOW(HOST_R10);
- SHOW(HOST_R11);
- SHOW(HOST_R12);
- SHOW(HOST_R13);
- SHOW(HOST_R14);
- SHOW(HOST_R15);
- SHOW(HOST_ORIG_RAX);
- SHOW(HOST_CS);
- SHOW(HOST_SS);
- SHOW(HOST_EFLAGS);
-#if 0
- SHOW(HOST_FS);
- SHOW(HOST_GS);
- SHOW(HOST_DS);
- SHOW(HOST_ES);
-#endif
-
- SHOW(HOST_IP);
- SHOW(HOST_SP);
- printf("#define HOST_FP_SIZE 0\n");
- printf("#define HOST_XFP_SIZE 0\n");
- printf("\n");
- printf("\n");
- printf("#endif\n");
- return(0);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
index f80850091e7..b331e970002 100644
--- a/arch/um/kernel/sysrq.c
+++ b/arch/um/kernel/sysrq.c
@@ -62,13 +62,7 @@ void show_stack(struct task_struct *task, unsigned long *esp)
if (esp == NULL) {
if (task != current && task != NULL) {
- /* XXX: Isn't this bogus? I.e. isn't this the
- * *userspace* stack of this task? If not so, use this
- * even when task == current (as in i386).
- */
esp = (unsigned long *) KSTK_ESP(task);
- /* Which one? No actual difference - just coding style.*/
- //esp = (unsigned long *) PT_REGS_IP(&task->thread.regs);
} else {
esp = (unsigned long *) &esp;
}
@@ -84,5 +78,5 @@ void show_stack(struct task_struct *task, unsigned long *esp)
}
printk("Call Trace: \n");
- show_trace(current, esp);
+ show_trace(task, esp);
}
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
index d297429ac36..95c8f8733ba 100644
--- a/arch/um/kernel/trap_kern.c
+++ b/arch/um/kernel/trap_kern.c
@@ -26,6 +26,9 @@
#include "mconsole_kern.h"
#include "mem.h"
#include "mem_kern.h"
+#ifdef CONFIG_MODE_SKAS
+#include "skas.h"
+#endif
/* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */
int handle_page_fault(unsigned long address, unsigned long ip,
@@ -134,7 +137,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
else if(current->mm == NULL)
panic("Segfault with no mm");
- if (SEGV_IS_FIXABLE(&fi))
+ if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi))
err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
else {
err = -EFAULT;
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index f0a275947d3..93dc782dc1c 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -334,6 +334,8 @@ int linux_main(int argc, char **argv)
add_arg(DEFAULT_COMMAND_LINE);
os_early_checks();
+ if (force_tt)
+ clear_can_do_skas();
mode_tt = force_tt ? 1 : !can_do_skas();
#ifndef CONFIG_MODE_TT
if (mode_tt) {
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index f6e64026f99..41cfb094420 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -6,7 +6,6 @@
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
-#include <string.h>
#include <errno.h>
#include <sched.h>
#include <sys/syscall.h>
@@ -17,31 +16,18 @@
#include "user.h"
#include "mode.h"
+struct aio_thread_req {
+ enum aio_type type;
+ int io_fd;
+ unsigned long long offset;
+ char *buf;
+ int len;
+ struct aio_context *aio;
+};
+
static int aio_req_fd_r = -1;
static int aio_req_fd_w = -1;
-static int update_aio(struct aio_context *aio, int res)
-{
- if(res < 0)
- aio->len = res;
- else if((res == 0) && (aio->type == AIO_READ)){
- /* This is the EOF case - we have hit the end of the file
- * and it ends in a partial block, so we fill the end of
- * the block with zeros and claim success.
- */
- memset(aio->data, 0, aio->len);
- aio->len = 0;
- }
- else if(res > 0){
- aio->len -= res;
- aio->data += res;
- aio->offset += res;
- return aio->len;
- }
-
- return 0;
-}
-
#if defined(HAVE_AIO_ABI)
#include <linux/aio_abi.h>
@@ -80,7 +66,8 @@ static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
* that it now backs the mmapped area.
*/
-static int do_aio(aio_context_t ctx, struct aio_context *aio)
+static int do_aio(aio_context_t ctx, enum aio_type type, int fd, char *buf,
+ int len, unsigned long long offset, struct aio_context *aio)
{
struct iocb iocb, *iocbp = &iocb;
char c;
@@ -88,39 +75,40 @@ static int do_aio(aio_context_t ctx, struct aio_context *aio)
iocb = ((struct iocb) { .aio_data = (unsigned long) aio,
.aio_reqprio = 0,
- .aio_fildes = aio->fd,
- .aio_buf = (unsigned long) aio->data,
- .aio_nbytes = aio->len,
- .aio_offset = aio->offset,
+ .aio_fildes = fd,
+ .aio_buf = (unsigned long) buf,
+ .aio_nbytes = len,
+ .aio_offset = offset,
.aio_reserved1 = 0,
.aio_reserved2 = 0,
.aio_reserved3 = 0 });
- switch(aio->type){
+ switch(type){
case AIO_READ:
iocb.aio_lio_opcode = IOCB_CMD_PREAD;
+ err = io_submit(ctx, 1, &iocbp);
break;
case AIO_WRITE:
iocb.aio_lio_opcode = IOCB_CMD_PWRITE;
+ err = io_submit(ctx, 1, &iocbp);
break;
case AIO_MMAP:
iocb.aio_lio_opcode = IOCB_CMD_PREAD;
iocb.aio_buf = (unsigned long) &c;
iocb.aio_nbytes = sizeof(c);
+ err = io_submit(ctx, 1, &iocbp);
break;
default:
- printk("Bogus op in do_aio - %d\n", aio->type);
+ printk("Bogus op in do_aio - %d\n", type);
err = -EINVAL;
- goto out;
+ break;
}
- err = io_submit(ctx, 1, &iocbp);
if(err > 0)
err = 0;
else
err = -errno;
- out:
return err;
}
@@ -129,9 +117,8 @@ static aio_context_t ctx = 0;
static int aio_thread(void *arg)
{
struct aio_thread_reply reply;
- struct aio_context *aio;
struct io_event event;
- int err, n;
+ int err, n, reply_fd;
signal(SIGWINCH, SIG_IGN);
@@ -144,22 +131,14 @@ static int aio_thread(void *arg)
"errno = %d\n", errno);
}
else {
- /* This is safe as we've just a pointer here. */
- aio = (struct aio_context *) (long) event.data;
- if(update_aio(aio, event.res)){
- do_aio(ctx, aio);
- continue;
- }
-
reply = ((struct aio_thread_reply)
- { .data = aio,
- .err = aio->len });
- err = os_write_file(aio->reply_fd, &reply,
- sizeof(reply));
+ { .data = (void *) (long) event.data,
+ .err = event.res });
+ reply_fd = ((struct aio_context *) reply.data)->reply_fd;
+ err = os_write_file(reply_fd, &reply, sizeof(reply));
if(err != sizeof(reply))
- printk("aio_thread - write failed, "
- "fd = %d, err = %d\n", aio->reply_fd,
- -err);
+ printk("aio_thread - write failed, fd = %d, "
+ "err = %d\n", aio_req_fd_r, -err);
}
}
return 0;
@@ -167,35 +146,35 @@ static int aio_thread(void *arg)
#endif
-static int do_not_aio(struct aio_context *aio)
+static int do_not_aio(struct aio_thread_req *req)
{
char c;
int err;
- switch(aio->type){
+ switch(req->type){
case AIO_READ:
- err = os_seek_file(aio->fd, aio->offset);
+ err = os_seek_file(req->io_fd, req->offset);
if(err)
goto out;
- err = os_read_file(aio->fd, aio->data, aio->len);
+ err = os_read_file(req->io_fd, req->buf, req->len);
break;
case AIO_WRITE:
- err = os_seek_file(aio->fd, aio->offset);
+ err = os_seek_file(req->io_fd, req->offset);
if(err)
goto out;
- err = os_write_file(aio->fd, aio->data, aio->len);
+ err = os_write_file(req->io_fd, req->buf, req->len);
break;
case AIO_MMAP:
- err = os_seek_file(aio->fd, aio->offset);
+ err = os_seek_file(req->io_fd, req->offset);
if(err)
goto out;
- err = os_read_file(aio->fd, &c, sizeof(c));
+ err = os_read_file(req->io_fd, &c, sizeof(c));
break;
default:
- printk("do_not_aio - bad request type : %d\n", aio->type);
+ printk("do_not_aio - bad request type : %d\n", req->type);
err = -EINVAL;
break;
}
@@ -206,14 +185,14 @@ static int do_not_aio(struct aio_context *aio)
static int not_aio_thread(void *arg)
{
- struct aio_context *aio;
+ struct aio_thread_req req;
struct aio_thread_reply reply;
int err;
signal(SIGWINCH, SIG_IGN);
while(1){
- err = os_read_file(aio_req_fd_r, &aio, sizeof(aio));
- if(err != sizeof(aio)){
+ err = os_read_file(aio_req_fd_r, &req, sizeof(req));
+ if(err != sizeof(req)){
if(err < 0)
printk("not_aio_thread - read failed, "
"fd = %d, err = %d\n", aio_req_fd_r,
@@ -224,34 +203,17 @@ static int not_aio_thread(void *arg)
}
continue;
}
- again:
- err = do_not_aio(aio);
-
- if(update_aio(aio, err))
- goto again;
-
- reply = ((struct aio_thread_reply) { .data = aio,
- .err = aio->len });
- err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
+ err = do_not_aio(&req);
+ reply = ((struct aio_thread_reply) { .data = req.aio,
+ .err = err });
+ err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply));
if(err != sizeof(reply))
printk("not_aio_thread - write failed, fd = %d, "
"err = %d\n", aio_req_fd_r, -err);
}
}
-static int submit_aio_24(struct aio_context *aio)
-{
- int err;
-
- err = os_write_file(aio_req_fd_w, &aio, sizeof(aio));
- if(err == sizeof(aio))
- err = 0;
-
- return err;
-}
-
static int aio_pid = -1;
-static int (*submit_proc)(struct aio_context *aio);
static int init_aio_24(void)
{
@@ -283,33 +245,11 @@ static int init_aio_24(void)
#endif
printk("2.6 host AIO support not used - falling back to I/O "
"thread\n");
-
- submit_proc = submit_aio_24;
-
return 0;
}
#ifdef HAVE_AIO_ABI
#define DEFAULT_24_AIO 0
-static int submit_aio_26(struct aio_context *aio)
-{
- struct aio_thread_reply reply;
- int err;
-
- err = do_aio(ctx, aio);
- if(err){
- reply = ((struct aio_thread_reply) { .data = aio,
- .err = err });
- err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
- if(err != sizeof(reply))
- printk("submit_aio_26 - write failed, "
- "fd = %d, err = %d\n", aio->reply_fd, -err);
- else err = 0;
- }
-
- return err;
-}
-
static int init_aio_26(void)
{
unsigned long stack;
@@ -330,22 +270,39 @@ static int init_aio_26(void)
aio_pid = err;
printk("Using 2.6 host AIO\n");
+ return 0;
+}
+
+static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
+ unsigned long long offset, struct aio_context *aio)
+{
+ struct aio_thread_reply reply;
+ int err;
- submit_proc = submit_aio_26;
+ err = do_aio(ctx, type, io_fd, buf, len, offset, aio);
+ if(err){
+ reply = ((struct aio_thread_reply) { .data = aio,
+ .err = err });
+ err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
+ if(err != sizeof(reply))
+ printk("submit_aio_26 - write failed, "
+ "fd = %d, err = %d\n", aio->reply_fd, -err);
+ else err = 0;
+ }
- return 0;
+ return err;
}
#else
#define DEFAULT_24_AIO 1
-static int submit_aio_26(struct aio_context *aio)
+static int init_aio_26(void)
{
return -ENOSYS;
}
-static int init_aio_26(void)
+static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
+ unsigned long long offset, struct aio_context *aio)
{
- submit_proc = submit_aio_26;
return -ENOSYS;
}
#endif
@@ -412,7 +369,33 @@ static void exit_aio(void)
__uml_exitcall(exit_aio);
-int submit_aio(struct aio_context *aio)
+static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
+ unsigned long long offset, struct aio_context *aio)
{
- return (*submit_proc)(aio);
+ struct aio_thread_req req = { .type = type,
+ .io_fd = io_fd,
+ .offset = offset,
+ .buf = buf,
+ .len = len,
+ .aio = aio,
+ };
+ int err;
+
+ err = os_write_file(aio_req_fd_w, &req, sizeof(req));
+ if(err == sizeof(req))
+ err = 0;
+
+ return err;
+}
+
+int submit_aio(enum aio_type type, int io_fd, char *buf, int len,
+ unsigned long long offset, int reply_fd,
+ struct aio_context *aio)
+{
+ aio->reply_fd = reply_fd;
+ if(aio_24)
+ return submit_aio_24(type, io_fd, buf, len, offset, aio);
+ else {
+ return submit_aio_26(type, io_fd, buf, len, offset, aio);
+ }
}
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c
index ab33cb3c74e..5a99dd3fbed 100644
--- a/arch/um/os-Linux/elf_aux.c
+++ b/arch/um/os-Linux/elf_aux.c
@@ -12,7 +12,7 @@
#include "init.h"
#include "elf_user.h"
#include "mem_user.h"
-#include <kernel-offsets.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
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 6af83171ca4..b99ab414542 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -143,11 +143,22 @@ static int __init skas0_cmd_param(char *str, int* add)
return 0;
}
+/* The two __uml_setup would conflict, without this stupid alias. */
+
+static int __init mode_skas0_cmd_param(char *str, int* add)
+ __attribute__((alias("skas0_cmd_param")));
+
__uml_setup("skas0", skas0_cmd_param,
"skas0\n"
" Disables SKAS3 usage, so that SKAS0 is used, unless \n"
" you specify mode=tt.\n\n");
+__uml_setup("mode=skas0", mode_skas0_cmd_param,
+ "mode=skas0\n"
+ " Disables SKAS3 usage, so that SKAS0 is used, unless you \n"
+ " specify mode=tt. Note that this was recently added - on \n"
+ " older kernels you must use simply \"skas0\".\n\n");
+
static int force_sysemu_disabled = 0;
static int __init nosysemu_cmd_param(char *str, int* add)
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index 3125d320722..aee4812333c 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -5,6 +5,7 @@
#include <errno.h>
#include <string.h>
+#include <setjmp.h>
#include "sysdep/ptrace_user.h"
#include "sysdep/ptrace.h"
#include "uml-config.h"
@@ -126,13 +127,11 @@ void get_safe_registers(unsigned long *regs)
memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
}
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
+{
+ struct __jmp_buf_tag *jmpbuf = buffer;
+
+ UPT_SET(uml_regs, EIP, jmpbuf->__jmpbuf[JB_PC]);
+ UPT_SET(uml_regs, UESP, jmpbuf->__jmpbuf[JB_SP]);
+ UPT_SET(uml_regs, EBP, jmpbuf->__jmpbuf[JB_BP]);
+}
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
index 44438d15c3d..4b638dfb52b 100644
--- a/arch/um/os-Linux/sys-x86_64/registers.c
+++ b/arch/um/os-Linux/sys-x86_64/registers.c
@@ -5,6 +5,7 @@
#include <errno.h>
#include <string.h>
+#include <setjmp.h>
#include "ptrace_user.h"
#include "uml-config.h"
#include "skas_ptregs.h"
@@ -74,13 +75,11 @@ void get_safe_registers(unsigned long *regs)
memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
}
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
+{
+ struct __jmp_buf_tag *jmpbuf = buffer;
+
+ UPT_SET(uml_regs, RIP, jmpbuf->__jmpbuf[JB_PC]);
+ UPT_SET(uml_regs, RSP, jmpbuf->__jmpbuf[JB_RSP]);
+ UPT_SET(uml_regs, RBP, jmpbuf->__jmpbuf[JB_RBP]);
+}
diff --git a/arch/um/os-Linux/util/Makefile b/arch/um/os-Linux/util/Makefile
deleted file mode 100644
index 9778aed0c31..00000000000
--- a/arch/um/os-Linux/util/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-hostprogs-y := mk_user_constants
-always := $(hostprogs-y)
-
-HOSTCFLAGS_mk_user_constants.o := -I$(objtree)/arch/um
diff --git a/arch/um/os-Linux/util/mk_user_constants.c b/arch/um/os-Linux/util/mk_user_constants.c
deleted file mode 100644
index 4838f30eecf..00000000000
--- a/arch/um/os-Linux/util/mk_user_constants.c
+++ /dev/null
@@ -1,23 +0,0 @@
-#include <stdio.h>
-#include <user-offsets.h>
-
-int main(int argc, char **argv)
-{
- printf("/*\n");
- printf(" * Generated by mk_user_constants\n");
- printf(" */\n");
- printf("\n");
- printf("#ifndef __UM_USER_CONSTANTS_H\n");
- printf("#define __UM_USER_CONSTANTS_H\n");
- printf("\n");
- /* I'd like to use FRAME_SIZE from ptrace.h here, but that's wrong on
- * x86_64 (216 vs 168 bytes). user_regs_struct is the correct size on
- * both x86_64 and i386.
- */
- printf("#define UM_FRAME_SIZE %d\n", __UM_FRAME_SIZE);
-
- printf("\n");
- printf("#endif\n");
-
- return(0);
-}
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 59a1291f477..651d9d88b65 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -7,8 +7,8 @@ USER_SINGLE_OBJS := \
USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS))
USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
-$(USER_OBJS) : c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \
- $(CFLAGS_$(notdir $@))
+$(USER_OBJS) $(USER_OBJS:.o=.i) $(USER_OBJS:.o=.s) $(USER_OBJS:.o=.lst): \
+ c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(notdir $@))
$(USER_OBJS): cmd_checksrc =
$(USER_OBJS): quiet_cmd_checksrc =
$(USER_OBJS): cmd_force_checksrc =
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 4ca2a229da4..6dfeb70f695 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -18,6 +18,4 @@ module.c-dir = kernel
$(obj)/stub_segv.o : _c_flags = $(call unprofile,$(CFLAGS))
-subdir- := util
-
include arch/um/scripts/Makefile.unmap
diff --git a/arch/um/sys-i386/kernel-offsets.c b/arch/um/sys-i386/kernel-offsets.c
index a1070af2bcd..35db8505750 100644
--- a/arch/um/sys-i386/kernel-offsets.c
+++ b/arch/um/sys-i386/kernel-offsets.c
@@ -18,9 +18,9 @@
void foo(void)
{
- OFFSET(TASK_DEBUGREGS, task_struct, thread.arch.debugregs);
+ OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs);
#ifdef CONFIG_MODE_TT
- OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
+ OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
#endif
#include <common-offsets.h>
}
diff --git a/arch/um/sys-i386/sysrq.c b/arch/um/sys-i386/sysrq.c
index e3706d15c4f..d5244f07053 100644
--- a/arch/um/sys-i386/sysrq.c
+++ b/arch/um/sys-i386/sysrq.c
@@ -88,9 +88,7 @@ void show_trace(struct task_struct* task, unsigned long * stack)
task = current;
if (task != current) {
- //ebp = (unsigned long) KSTK_EBP(task);
- /* Which one? No actual difference - just coding style.*/
- ebp = (unsigned long) PT_REGS_EBP(&task->thread.regs);
+ ebp = (unsigned long) KSTK_EBP(task);
} else {
asm ("movl %%ebp, %0" : "=r" (ebp) : );
}
@@ -99,15 +97,6 @@ void show_trace(struct task_struct* task, unsigned long * stack)
((unsigned long)stack & (~(THREAD_SIZE - 1)));
print_context_stack(context, stack, ebp);
- /*while (((long) stack & (THREAD_SIZE-1)) != 0) {
- addr = *stack;
- if (__kernel_text_address(addr)) {
- printk("%08lx: [<%08lx>]", (unsigned long) stack, addr);
- print_symbol(" %s", addr);
- printk("\n");
- }
- stack++;
- }*/
printk("\n");
}
diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c
index 3ceaabceb3d..26b68675053 100644
--- a/arch/um/sys-i386/user-offsets.c
+++ b/arch/um/sys-i386/user-offsets.c
@@ -7,47 +7,48 @@
#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(SC_IP, sigcontext, eip);
- OFFSET(SC_SP, sigcontext, esp);
- OFFSET(SC_FS, sigcontext, fs);
- OFFSET(SC_GS, sigcontext, gs);
- OFFSET(SC_DS, sigcontext, ds);
- OFFSET(SC_ES, sigcontext, es);
- OFFSET(SC_SS, sigcontext, ss);
- OFFSET(SC_CS, sigcontext, cs);
- OFFSET(SC_EFLAGS, sigcontext, eflags);
- OFFSET(SC_EAX, sigcontext, eax);
- OFFSET(SC_EBX, sigcontext, ebx);
- OFFSET(SC_ECX, sigcontext, ecx);
- OFFSET(SC_EDX, sigcontext, edx);
- OFFSET(SC_EDI, sigcontext, edi);
- OFFSET(SC_ESI, sigcontext, esi);
- OFFSET(SC_EBP, sigcontext, ebp);
- OFFSET(SC_TRAPNO, sigcontext, trapno);
- OFFSET(SC_ERR, sigcontext, err);
- OFFSET(SC_CR2, sigcontext, cr2);
- OFFSET(SC_FPSTATE, sigcontext, fpstate);
- OFFSET(SC_SIGMASK, sigcontext, oldmask);
- OFFSET(SC_FP_CW, _fpstate, cw);
- OFFSET(SC_FP_SW, _fpstate, sw);
- OFFSET(SC_FP_TAG, _fpstate, tag);
- OFFSET(SC_FP_IPOFF, _fpstate, ipoff);
- OFFSET(SC_FP_CSSEL, _fpstate, cssel);
- OFFSET(SC_FP_DATAOFF, _fpstate, dataoff);
- OFFSET(SC_FP_DATASEL, _fpstate, datasel);
- OFFSET(SC_FP_ST, _fpstate, _st);
- OFFSET(SC_FXSR_ENV, _fpstate, _fxsr_env);
+ OFFSET(HOST_SC_IP, sigcontext, eip);
+ OFFSET(HOST_SC_SP, sigcontext, esp);
+ OFFSET(HOST_SC_FS, sigcontext, fs);
+ OFFSET(HOST_SC_GS, sigcontext, gs);
+ OFFSET(HOST_SC_DS, sigcontext, ds);
+ OFFSET(HOST_SC_ES, sigcontext, es);
+ OFFSET(HOST_SC_SS, sigcontext, ss);
+ OFFSET(HOST_SC_CS, sigcontext, cs);
+ OFFSET(HOST_SC_EFLAGS, sigcontext, eflags);
+ OFFSET(HOST_SC_EAX, sigcontext, eax);
+ OFFSET(HOST_SC_EBX, sigcontext, ebx);
+ OFFSET(HOST_SC_ECX, sigcontext, ecx);
+ OFFSET(HOST_SC_EDX, sigcontext, edx);
+ OFFSET(HOST_SC_EDI, sigcontext, edi);
+ OFFSET(HOST_SC_ESI, sigcontext, esi);
+ OFFSET(HOST_SC_EBP, sigcontext, ebp);
+ OFFSET(HOST_SC_TRAPNO, sigcontext, trapno);
+ OFFSET(HOST_SC_ERR, sigcontext, err);
+ OFFSET(HOST_SC_CR2, sigcontext, cr2);
+ OFFSET(HOST_SC_FPSTATE, sigcontext, fpstate);
+ OFFSET(HOST_SC_SIGMASK, sigcontext, oldmask);
+ OFFSET(HOST_SC_FP_CW, _fpstate, cw);
+ OFFSET(HOST_SC_FP_SW, _fpstate, sw);
+ OFFSET(HOST_SC_FP_TAG, _fpstate, tag);
+ OFFSET(HOST_SC_FP_IPOFF, _fpstate, ipoff);
+ OFFSET(HOST_SC_FP_CSSEL, _fpstate, cssel);
+ OFFSET(HOST_SC_FP_DATAOFF, _fpstate, dataoff);
+ OFFSET(HOST_SC_FP_DATASEL, _fpstate, datasel);
+ OFFSET(HOST_SC_FP_ST, _fpstate, _st);
+ OFFSET(HOST_SC_FXSR_ENV, _fpstate, _fxsr_env);
DEFINE(HOST_FRAME_SIZE, FRAME_SIZE);
- DEFINE(HOST_FP_SIZE,
- sizeof(struct user_i387_struct) / sizeof(unsigned long));
- DEFINE(HOST_XFP_SIZE,
- sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
+ DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_i387_struct));
+ DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fxsr_struct));
DEFINE(HOST_IP, EIP);
DEFINE(HOST_SP, UESP);
@@ -65,5 +66,5 @@ void foo(void)
DEFINE(HOST_FS, FS);
DEFINE(HOST_ES, ES);
DEFINE(HOST_GS, GS);
- DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct));
+ DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct));
}
diff --git a/arch/um/sys-i386/util/Makefile b/arch/um/sys-i386/util/Makefile
deleted file mode 100644
index bf61afd0b04..00000000000
--- a/arch/um/sys-i386/util/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-hostprogs-y := mk_sc mk_thread
-always := $(hostprogs-y)
-
-HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um
-HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um
diff --git a/arch/um/sys-i386/util/mk_sc.c b/arch/um/sys-i386/util/mk_sc.c
deleted file mode 100644
index 04c0d73433a..00000000000
--- a/arch/um/sys-i386/util/mk_sc.c
+++ /dev/null
@@ -1,51 +0,0 @@
-#include <stdio.h>
-#include <user-offsets.h>
-
-#define SC_OFFSET(name, field) \
- printf("#define " #name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
- name)
-
-#define SC_FP_OFFSET(name, field) \
- printf("#define " #name \
- "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
- name)
-
-#define SC_FP_OFFSET_PTR(name, field, type) \
- printf("#define " #name \
- "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
- name)
-
-int main(int argc, char **argv)
-{
- SC_OFFSET(SC_IP, eip);
- SC_OFFSET(SC_SP, esp);
- SC_OFFSET(SC_FS, fs);
- SC_OFFSET(SC_GS, gs);
- SC_OFFSET(SC_DS, ds);
- SC_OFFSET(SC_ES, es);
- SC_OFFSET(SC_SS, ss);
- SC_OFFSET(SC_CS, cs);
- SC_OFFSET(SC_EFLAGS, eflags);
- SC_OFFSET(SC_EAX, eax);
- SC_OFFSET(SC_EBX, ebx);
- SC_OFFSET(SC_ECX, ecx);
- SC_OFFSET(SC_EDX, edx);
- SC_OFFSET(SC_EDI, edi);
- SC_OFFSET(SC_ESI, esi);
- SC_OFFSET(SC_EBP, ebp);
- SC_OFFSET(SC_TRAPNO, trapno);
- SC_OFFSET(SC_ERR, err);
- SC_OFFSET(SC_CR2, cr2);
- SC_OFFSET(SC_FPSTATE, fpstate);
- SC_OFFSET(SC_SIGMASK, oldmask);
- SC_FP_OFFSET(SC_FP_CW, cw);
- SC_FP_OFFSET(SC_FP_SW, sw);
- SC_FP_OFFSET(SC_FP_TAG, tag);
- SC_FP_OFFSET(SC_FP_IPOFF, ipoff);
- SC_FP_OFFSET(SC_FP_CSSEL, cssel);
- SC_FP_OFFSET(SC_FP_DATAOFF, dataoff);
- SC_FP_OFFSET(SC_FP_DATASEL, datasel);
- SC_FP_OFFSET_PTR(SC_FP_ST, _st, "struct _fpstate");
- SC_FP_OFFSET_PTR(SC_FXSR_ENV, _fxsr_env, "void");
- return(0);
-}
diff --git a/arch/um/sys-i386/util/mk_thread.c b/arch/um/sys-i386/util/mk_thread.c
deleted file mode 100644
index 7470d0dda67..00000000000
--- a/arch/um/sys-i386/util/mk_thread.c
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <stdio.h>
-#include <kernel-offsets.h>
-
-int main(int argc, char **argv)
-{
- printf("/*\n");
- printf(" * Generated by mk_thread\n");
- printf(" */\n");
- printf("\n");
- printf("#ifndef __UM_THREAD_H\n");
- printf("#define __UM_THREAD_H\n");
- printf("\n");
- printf("#define TASK_DEBUGREGS(task) ((unsigned long *) "
- "&(((char *) (task))[%d]))\n", TASK_DEBUGREGS);
-#ifdef TASK_EXTERN_PID
- printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n",
- TASK_EXTERN_PID);
-#endif
- printf("\n");
- printf("#endif\n");
- return(0);
-}
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index f0ab574d1e9..06c3633457a 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -29,6 +29,4 @@ module.c-dir = kernel
$(obj)/stub_segv.o: _c_flags = $(call unprofile,$(CFLAGS))
-subdir- := util
-
include arch/um/scripts/Makefile.unmap
diff --git a/arch/um/sys-x86_64/kernel-offsets.c b/arch/um/sys-x86_64/kernel-offsets.c
index 998541eade4..bfcb104b846 100644
--- a/arch/um/sys-x86_64/kernel-offsets.c
+++ b/arch/um/sys-x86_64/kernel-offsets.c
@@ -19,7 +19,7 @@
void foo(void)
{
#ifdef CONFIG_MODE_TT
- OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
+ OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
#endif
#include <common-offsets.h>
}
diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c
index 65a131b362b..d1e53bdf2e8 100644
--- a/arch/um/sys-x86_64/stub_segv.c
+++ b/arch/um/sys-x86_64/stub_segv.c
@@ -10,6 +10,22 @@
#include "uml-config.h"
#include "sysdep/sigcontext.h"
#include "sysdep/faultinfo.h"
+#include <stddef.h>
+
+/* Copied from sys-x86_64/signal.c - Can't find an equivalent definition
+ * in the libc headers anywhere.
+ */
+struct rt_sigframe
+{
+ char *pretcode;
+ struct ucontext uc;
+ struct siginfo info;
+};
+
+/* Copied here from <linux/kernel.h> - we're userspace. */
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
void __attribute__ ((__section__ (".__syscall_stub")))
stub_segv_handler(int sig)
@@ -17,16 +33,19 @@ stub_segv_handler(int sig)
struct ucontext *uc;
__asm__("movq %%rdx, %0" : "=g" (uc) :);
- GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA),
- &uc->uc_mcontext);
+ GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA),
+ &uc->uc_mcontext);
- __asm__("movq %0, %%rax ; syscall": : "g" (__NR_getpid));
+ __asm__("movq %0, %%rax ; syscall": : "g" (__NR_getpid));
__asm__("movq %%rax, %%rdi ; movq %0, %%rax ; movq %1, %%rsi ;"
- "syscall": : "g" (__NR_kill), "g" (SIGUSR1));
- /* Two popqs to restore the stack to the state just before entering
- * the handler, one pops the return address, the other pops the frame
- * pointer.
+ "syscall": : "g" (__NR_kill), "g" (SIGUSR1) :
+ "%rdi", "%rax", "%rsi");
+ /* sys_sigreturn expects that the stack pointer will be 8 bytes into
+ * the signal frame. So, we use the ucontext pointer, which we know
+ * already, to get the signal frame pointer, and add 8 to that.
*/
- __asm__("popq %%rax ; popq %%rax ; movq %0, %%rax ; syscall" : : "g"
- (__NR_rt_sigreturn));
+ __asm__("movq %0, %%rsp": :
+ "g" ((unsigned long) container_of(uc, struct rt_sigframe,
+ uc) + 8));
+ __asm__("movq %0, %%rax ; syscall" : : "g" (__NR_rt_sigreturn));
}
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
index 513d17ceafd..5a585bfbb8c 100644
--- a/arch/um/sys-x86_64/user-offsets.c
+++ b/arch/um/sys-x86_64/user-offsets.c
@@ -16,71 +16,76 @@ typedef __u32 u32;
#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(SC_RBX, sigcontext, rbx);
- OFFSET(SC_RCX, sigcontext, rcx);
- OFFSET(SC_RDX, sigcontext, rdx);
- OFFSET(SC_RSI, sigcontext, rsi);
- OFFSET(SC_RDI, sigcontext, rdi);
- OFFSET(SC_RBP, sigcontext, rbp);
- OFFSET(SC_RAX, sigcontext, rax);
- OFFSET(SC_R8, sigcontext, r8);
- OFFSET(SC_R9, sigcontext, r9);
- OFFSET(SC_R10, sigcontext, r10);
- OFFSET(SC_R11, sigcontext, r11);
- OFFSET(SC_R12, sigcontext, r12);
- OFFSET(SC_R13, sigcontext, r13);
- OFFSET(SC_R14, sigcontext, r14);
- OFFSET(SC_R15, sigcontext, r15);
- OFFSET(SC_IP, sigcontext, rip);
- OFFSET(SC_SP, sigcontext, rsp);
- OFFSET(SC_CR2, sigcontext, cr2);
- OFFSET(SC_ERR, sigcontext, err);
- OFFSET(SC_TRAPNO, sigcontext, trapno);
- OFFSET(SC_CS, sigcontext, cs);
- OFFSET(SC_FS, sigcontext, fs);
- OFFSET(SC_GS, sigcontext, gs);
- OFFSET(SC_EFLAGS, sigcontext, eflags);
- OFFSET(SC_SIGMASK, sigcontext, oldmask);
+ OFFSET(HOST_SC_RBX, sigcontext, rbx);
+ OFFSET(HOST_SC_RCX, sigcontext, rcx);
+ OFFSET(HOST_SC_RDX, sigcontext, rdx);
+ OFFSET(HOST_SC_RSI, sigcontext, rsi);
+ OFFSET(HOST_SC_RDI, sigcontext, rdi);
+ OFFSET(HOST_SC_RBP, sigcontext, rbp);
+ OFFSET(HOST_SC_RAX, sigcontext, rax);
+ OFFSET(HOST_SC_R8, sigcontext, r8);
+ OFFSET(HOST_SC_R9, sigcontext, r9);
+ OFFSET(HOST_SC_R10, sigcontext, r10);
+ OFFSET(HOST_SC_R11, sigcontext, r11);
+ OFFSET(HOST_SC_R12, sigcontext, r12);
+ OFFSET(HOST_SC_R13, sigcontext, r13);
+ OFFSET(HOST_SC_R14, sigcontext, r14);
+ OFFSET(HOST_SC_R15, sigcontext, r15);
+ OFFSET(HOST_SC_IP, sigcontext, rip);
+ OFFSET(HOST_SC_SP, sigcontext, rsp);
+ OFFSET(HOST_SC_CR2, sigcontext, cr2);
+ OFFSET(HOST_SC_ERR, sigcontext, err);
+ OFFSET(HOST_SC_TRAPNO, sigcontext, trapno);
+ OFFSET(HOST_SC_CS, sigcontext, cs);
+ OFFSET(HOST_SC_FS, sigcontext, fs);
+ OFFSET(HOST_SC_GS, sigcontext, gs);
+ OFFSET(HOST_SC_EFLAGS, sigcontext, eflags);
+ OFFSET(HOST_SC_SIGMASK, sigcontext, oldmask);
#if 0
- OFFSET(SC_ORIG_RAX, sigcontext, orig_rax);
- OFFSET(SC_DS, sigcontext, ds);
- OFFSET(SC_ES, sigcontext, es);
- OFFSET(SC_SS, sigcontext, ss);
+ OFFSET(HOST_SC_ORIG_RAX, sigcontext, orig_rax);
+ OFFSET(HOST_SC_DS, sigcontext, ds);
+ OFFSET(HOST_SC_ES, sigcontext, es);
+ OFFSET(HOST_SC_SS, sigcontext, ss);
#endif
- DEFINE(HOST_FRAME_SIZE, FRAME_SIZE);
- DEFINE(HOST_RBX, RBX);
- DEFINE(HOST_RCX, RCX);
- DEFINE(HOST_RDI, RDI);
- DEFINE(HOST_RSI, RSI);
- DEFINE(HOST_RDX, RDX);
- DEFINE(HOST_RBP, RBP);
- DEFINE(HOST_RAX, RAX);
- DEFINE(HOST_R8, R8);
- DEFINE(HOST_R9, R9);
- DEFINE(HOST_R10, R10);
- DEFINE(HOST_R11, R11);
- DEFINE(HOST_R12, R12);
- DEFINE(HOST_R13, R13);
- DEFINE(HOST_R14, R14);
- DEFINE(HOST_R15, R15);
- DEFINE(HOST_ORIG_RAX, ORIG_RAX);
- DEFINE(HOST_CS, CS);
- DEFINE(HOST_SS, SS);
- DEFINE(HOST_EFLAGS, EFLAGS);
+ DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE);
+ DEFINE(HOST_FP_SIZE, 0);
+ DEFINE(HOST_XFP_SIZE, 0);
+ 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(HOST_FS, FS);
- DEFINE(HOST_GS, GS);
- DEFINE(HOST_DS, DS);
- DEFINE(HOST_ES, ES);
+ DEFINE_LONGS(HOST_FS, FS);
+ DEFINE_LONGS(HOST_GS, GS);
+ DEFINE_LONGS(HOST_DS, DS);
+ DEFINE_LONGS(HOST_ES, ES);
#endif
- DEFINE(HOST_IP, RIP);
- DEFINE(HOST_SP, RSP);
- DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct));
+ DEFINE_LONGS(HOST_IP, RIP);
+ DEFINE_LONGS(HOST_SP, RSP);
+ DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct));
}
diff --git a/arch/um/sys-x86_64/util/Makefile b/arch/um/sys-x86_64/util/Makefile
deleted file mode 100644
index 75b052cfc20..00000000000
--- a/arch/um/sys-x86_64/util/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2003 - 2004 Pathscale, Inc
-# Released under the GPL
-
-hostprogs-y := mk_sc mk_thread
-always := $(hostprogs-y)
-
-HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um
-HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um
diff --git a/arch/um/sys-x86_64/util/mk_sc.c b/arch/um/sys-x86_64/util/mk_sc.c
deleted file mode 100644
index 7619bc377c1..00000000000
--- a/arch/um/sys-x86_64/util/mk_sc.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright (C) 2003 - 2004 PathScale, Inc
- * Released under the GPL
- */
-
-#include <stdio.h>
-#include <user-offsets.h>
-
-#define SC_OFFSET(name) \
- printf("#define " #name \
- "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
- name)
-
-int main(int argc, char **argv)
-{
- SC_OFFSET(SC_RBX);
- SC_OFFSET(SC_RCX);
- SC_OFFSET(SC_RDX);
- SC_OFFSET(SC_RSI);
- SC_OFFSET(SC_RDI);
- SC_OFFSET(SC_RBP);
- SC_OFFSET(SC_RAX);
- SC_OFFSET(SC_R8);
- SC_OFFSET(SC_R9);
- SC_OFFSET(SC_R10);
- SC_OFFSET(SC_R11);
- SC_OFFSET(SC_R12);
- SC_OFFSET(SC_R13);
- SC_OFFSET(SC_R14);
- SC_OFFSET(SC_R15);
- SC_OFFSET(SC_IP);
- SC_OFFSET(SC_SP);
- SC_OFFSET(SC_CR2);
- SC_OFFSET(SC_ERR);
- SC_OFFSET(SC_TRAPNO);
- SC_OFFSET(SC_CS);
- SC_OFFSET(SC_FS);
- SC_OFFSET(SC_GS);
- SC_OFFSET(SC_EFLAGS);
- SC_OFFSET(SC_SIGMASK);
-#if 0
- SC_OFFSET(SC_ORIG_RAX);
- SC_OFFSET(SC_DS);
- SC_OFFSET(SC_ES);
- SC_OFFSET(SC_SS);
-#endif
- return(0);
-}
diff --git a/arch/um/sys-x86_64/util/mk_thread.c b/arch/um/sys-x86_64/util/mk_thread.c
deleted file mode 100644
index 15517396e9c..00000000000
--- a/arch/um/sys-x86_64/util/mk_thread.c
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <stdio.h>
-#include <kernel-offsets.h>
-
-int main(int argc, char **argv)
-{
- printf("/*\n");
- printf(" * Generated by mk_thread\n");
- printf(" */\n");
- printf("\n");
- printf("#ifndef __UM_THREAD_H\n");
- printf("#define __UM_THREAD_H\n");
- printf("\n");
-#ifdef TASK_EXTERN_PID
- printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n",
- TASK_EXTERN_PID);
-#endif
- printf("\n");
- printf("#endif\n");
- return(0);
-}
diff --git a/arch/um/util/Makefile b/arch/um/util/Makefile
deleted file mode 100644
index 4c7551c2803..00000000000
--- a/arch/um/util/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-hostprogs-y := mk_task mk_constants
-always := $(hostprogs-y)
-
-HOSTCFLAGS_mk_task.o := -I$(objtree)/arch/um
-HOSTCFLAGS_mk_constants.o := -I$(objtree)/arch/um
diff --git a/arch/um/util/mk_constants.c b/arch/um/util/mk_constants.c
deleted file mode 100644
index ab217becc36..00000000000
--- a/arch/um/util/mk_constants.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <stdio.h>
-#include <kernel-offsets.h>
-
-#define SHOW_INT(sym) printf("#define %s %d\n", #sym, sym)
-#define SHOW_STR(sym) printf("#define %s %s\n", #sym, sym)
-
-int main(int argc, char **argv)
-{
- printf("/*\n");
- printf(" * Generated by mk_constants\n");
- printf(" */\n");
- printf("\n");
- printf("#ifndef __UM_CONSTANTS_H\n");
- printf("#define __UM_CONSTANTS_H\n");
- printf("\n");
-
- SHOW_INT(UM_KERN_PAGE_SIZE);
-
- SHOW_STR(UM_KERN_EMERG);
- SHOW_STR(UM_KERN_ALERT);
- SHOW_STR(UM_KERN_CRIT);
- SHOW_STR(UM_KERN_ERR);
- SHOW_STR(UM_KERN_WARNING);
- SHOW_STR(UM_KERN_NOTICE);
- SHOW_STR(UM_KERN_INFO);
- SHOW_STR(UM_KERN_DEBUG);
-
- SHOW_INT(UM_NSEC_PER_SEC);
- printf("\n");
- printf("#endif\n");
- return(0);
-}
diff --git a/arch/um/util/mk_task.c b/arch/um/util/mk_task.c
deleted file mode 100644
index 36c9606505e..00000000000
--- a/arch/um/util/mk_task.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <stdio.h>
-#include <kernel-offsets.h>
-
-void print_ptr(char *name, char *type, int offset)
-{
- printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
- offset);
-}
-
-void print(char *name, char *type, int offset)
-{
- printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
- offset);
-}
-
-int main(int argc, char **argv)
-{
- printf("/*\n");
- printf(" * Generated by mk_task\n");
- printf(" */\n");
- printf("\n");
- printf("#ifndef __TASK_H\n");
- printf("#define __TASK_H\n");
- printf("\n");
- print_ptr("TASK_REGS", "union uml_pt_regs", TASK_REGS);
- print("TASK_PID", "int", TASK_PID);
- printf("\n");
- printf("#endif\n");
- return(0);
-}