diff options
Diffstat (limited to 'arch/um/sys-x86_64')
-rw-r--r-- | arch/um/sys-x86_64/Makefile | 12 | ||||
-rw-r--r-- | arch/um/sys-x86_64/stub.S | 15 | ||||
-rw-r--r-- | arch/um/sys-x86_64/stub_segv.c | 31 |
3 files changed, 56 insertions, 2 deletions
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index 2bc6f6849010..7488206ce6f4 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile | |||
@@ -6,8 +6,8 @@ | |||
6 | 6 | ||
7 | #XXX: why into lib-y? | 7 | #XXX: why into lib-y? |
8 | lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \ | 8 | lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \ |
9 | ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \ | 9 | ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o stub.o \ |
10 | syscalls.o sysrq.o thunk.o syscall_table.o | 10 | stub_segv.o syscalls.o syscall_table.o sysrq.o thunk.o |
11 | 11 | ||
12 | obj-y := ksyms.o | 12 | obj-y := ksyms.o |
13 | obj-$(CONFIG_MODULES) += module.o um_module.o | 13 | obj-$(CONFIG_MODULES) += module.o um_module.o |
@@ -28,6 +28,14 @@ semaphore.c-dir = kernel | |||
28 | thunk.S-dir = lib | 28 | thunk.S-dir = lib |
29 | module.c-dir = kernel | 29 | module.c-dir = kernel |
30 | 30 | ||
31 | STUB_CFLAGS = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS)) | ||
32 | |||
33 | # _cflags works with kernel files, not with userspace ones, but c_flags does, | ||
34 | # why ask why? | ||
35 | $(obj)/stub_segv.o : c_flags = $(STUB_CFLAGS) | ||
36 | |||
37 | $(obj)/stub.o : a_flags = $(STUB_CFLAGS) | ||
38 | |||
31 | subdir- := util | 39 | subdir- := util |
32 | 40 | ||
33 | include arch/um/scripts/Makefile.unmap | 41 | include arch/um/scripts/Makefile.unmap |
diff --git a/arch/um/sys-x86_64/stub.S b/arch/um/sys-x86_64/stub.S new file mode 100644 index 000000000000..31c14925716b --- /dev/null +++ b/arch/um/sys-x86_64/stub.S | |||
@@ -0,0 +1,15 @@ | |||
1 | #include "uml-config.h" | ||
2 | |||
3 | .globl syscall_stub | ||
4 | .section .__syscall_stub, "x" | ||
5 | syscall_stub: | ||
6 | syscall | ||
7 | /* We don't have 64-bit constants, so this constructs the address | ||
8 | * we need. | ||
9 | */ | ||
10 | movq $(UML_CONFIG_STUB_DATA >> 32), %rbx | ||
11 | salq $32, %rbx | ||
12 | movq $(UML_CONFIG_STUB_DATA & 0xffffffff), %rcx | ||
13 | or %rcx, %rbx | ||
14 | movq %rax, (%rbx) | ||
15 | int3 | ||
diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c new file mode 100644 index 000000000000..161d1fe9c034 --- /dev/null +++ b/arch/um/sys-x86_64/stub_segv.c | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #include <signal.h> | ||
7 | #include <linux/compiler.h> | ||
8 | #include <asm/unistd.h> | ||
9 | #include "uml-config.h" | ||
10 | #include "sysdep/sigcontext.h" | ||
11 | #include "sysdep/faultinfo.h" | ||
12 | |||
13 | void __attribute__ ((__section__ (".__syscall_stub"))) | ||
14 | stub_segv_handler(int sig) | ||
15 | { | ||
16 | struct ucontext *uc; | ||
17 | |||
18 | __asm__("movq %%rdx, %0" : "=g" (uc) :); | ||
19 | GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), | ||
20 | &uc->uc_mcontext); | ||
21 | |||
22 | __asm__("movq %0, %%rax ; syscall": : "g" (__NR_getpid)); | ||
23 | __asm__("movq %%rax, %%rdi ; movq %0, %%rax ; movq %1, %%rsi ;" | ||
24 | "syscall": : "g" (__NR_kill), "g" (SIGUSR1)); | ||
25 | /* Two popqs to restore the stack to the state just before entering | ||
26 | * the handler, one pops the return address, the other pops the frame | ||
27 | * pointer. | ||
28 | */ | ||
29 | __asm__("popq %%rax ; popq %%rax ; movq %0, %%rax ; syscall" : : "g" | ||
30 | (__NR_rt_sigreturn)); | ||
31 | } | ||