summaryrefslogtreecommitdiffstats
path: root/arch/um/sys-x86_64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/sys-x86_64')
-rw-r--r--arch/um/sys-x86_64/Makefile13
-rw-r--r--arch/um/sys-x86_64/kernel-offsets.c1
-rw-r--r--arch/um/sys-x86_64/signal.c41
-rw-r--r--arch/um/sys-x86_64/stub.S51
-rw-r--r--arch/um/sys-x86_64/stub_segv.c3
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"
OpenPOWER on IntegriCloud