diff options
Diffstat (limited to 'arch/um/sys-x86_64')
-rw-r--r-- | arch/um/sys-x86_64/Makefile | 13 | ||||
-rw-r--r-- | arch/um/sys-x86_64/kernel-offsets.c | 1 | ||||
-rw-r--r-- | arch/um/sys-x86_64/signal.c | 41 | ||||
-rw-r--r-- | arch/um/sys-x86_64/stub.S | 51 | ||||
-rw-r--r-- | arch/um/sys-x86_64/stub_segv.c | 3 |
5 files changed, 81 insertions, 28 deletions
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index 7488206..f0ab574d 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile @@ -6,7 +6,7 @@ #XXX: why into lib-y? lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \ - ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o stub.o \ + ptrace.o ptrace_user.o sigcontext.o signal.o stub.o \ stub_segv.o syscalls.o syscall_table.o sysrq.o thunk.o obj-y := ksyms.o @@ -15,7 +15,7 @@ obj-$(CONFIG_MODULES) += module.o um_module.o USER_OBJS := ptrace_user.o sigcontext.o SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \ - semaphore.c thunk.S module.c + thunk.S module.c include arch/um/scripts/Makefile.rules @@ -24,17 +24,10 @@ csum-copy.S-dir = lib csum-partial.c-dir = lib csum-wrappers.c-dir = lib memcpy.S-dir = lib -semaphore.c-dir = kernel thunk.S-dir = lib module.c-dir = kernel -STUB_CFLAGS = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS)) - -# _cflags works with kernel files, not with userspace ones, but c_flags does, -# why ask why? -$(obj)/stub_segv.o : c_flags = $(STUB_CFLAGS) - -$(obj)/stub.o : a_flags = $(STUB_CFLAGS) +$(obj)/stub_segv.o: _c_flags = $(call unprofile,$(CFLAGS)) subdir- := util diff --git a/arch/um/sys-x86_64/kernel-offsets.c b/arch/um/sys-x86_64/kernel-offsets.c index 220e875..998541e 100644 --- a/arch/um/sys-x86_64/kernel-offsets.c +++ b/arch/um/sys-x86_64/kernel-offsets.c @@ -2,6 +2,7 @@ #include <linux/stddef.h> #include <linux/sched.h> #include <linux/time.h> +#include <linux/elf.h> #include <asm/page.h> #define DEFINE(sym, val) \ diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index 8fdaed0..fe1d065 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c @@ -104,28 +104,35 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from, int fpsize) { - struct _fpstate *to_fp, *from_fp; - unsigned long sigs; - int err; - - to_fp = to->fpstate; - from_fp = from->fpstate; - sigs = to->oldmask; - err = copy_from_user(to, from, sizeof(*to)); - to->oldmask = sigs; - return(err); + struct _fpstate *to_fp, *from_fp; + unsigned long sigs; + int err; + + to_fp = to->fpstate; + sigs = to->oldmask; + err = copy_from_user(to, from, sizeof(*to)); + from_fp = to->fpstate; + to->fpstate = to_fp; + to->oldmask = sigs; + if(to_fp != NULL) + err |= copy_from_user(to_fp, from_fp, fpsize); + return(err); } int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp, struct sigcontext *from, int fpsize) { - struct _fpstate *to_fp, *from_fp; - int err; - - to_fp = (fp ? fp : (struct _fpstate *) (to + 1)); - from_fp = from->fpstate; - err = copy_to_user(to, from, sizeof(*to)); - return(err); + struct _fpstate *to_fp, *from_fp; + int err; + + to_fp = (fp ? fp : (struct _fpstate *) (to + 1)); + from_fp = from->fpstate; + err = copy_to_user(to, from, sizeof(*to)); + if(from_fp != NULL){ + err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate)); + err |= copy_to_user(to_fp, from_fp, fpsize); + } + return(err); } #endif diff --git a/arch/um/sys-x86_64/stub.S b/arch/um/sys-x86_64/stub.S index 31c1492..03c2797 100644 --- a/arch/um/sys-x86_64/stub.S +++ b/arch/um/sys-x86_64/stub.S @@ -13,3 +13,54 @@ syscall_stub: or %rcx, %rbx movq %rax, (%rbx) int3 + + .globl batch_syscall_stub +batch_syscall_stub: + mov $(UML_CONFIG_STUB_DATA >> 32), %rbx + sal $32, %rbx + mov $(UML_CONFIG_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 index 161d1fe..65a131b 100644 --- a/arch/um/sys-x86_64/stub_segv.c +++ b/arch/um/sys-x86_64/stub_segv.c @@ -3,9 +3,10 @@ * Licensed under the GPL */ -#include <signal.h> +#include <asm/signal.h> #include <linux/compiler.h> #include <asm/unistd.h> +#include <asm/ucontext.h> #include "uml-config.h" #include "sysdep/sigcontext.h" #include "sysdep/faultinfo.h" |