Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[PATCH] uml: fix x86_64 with !CONFIG_FRAME_POINTER

UML/x86_64 doesn't run when built with frame pointers disabled. There
was an implicit frame pointer assumption in the stub segfault handler.
With frame pointers disabled, UML dies on handling its first page fault.

The container-of part of this is from Paolo Giarrusso <blaisorblade@yahoo.it>.

Signed-off-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Jeff Dike and committed by
Linus Torvalds
50f72b57 3dd08325

+28 -9
+28 -9
arch/um/sys-x86_64/stub_segv.c
··· 10 10 #include "uml-config.h" 11 11 #include "sysdep/sigcontext.h" 12 12 #include "sysdep/faultinfo.h" 13 + #include <stddef.h> 14 + 15 + /* Copied from sys-x86_64/signal.c - Can't find an equivalent definition 16 + * in the libc headers anywhere. 17 + */ 18 + struct rt_sigframe 19 + { 20 + char *pretcode; 21 + struct ucontext uc; 22 + struct siginfo info; 23 + }; 24 + 25 + /* Copied here from <linux/kernel.h> - we're userspace. */ 26 + #define container_of(ptr, type, member) ({ \ 27 + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 28 + (type *)( (char *)__mptr - offsetof(type,member) );}) 13 29 14 30 void __attribute__ ((__section__ (".__syscall_stub"))) 15 31 stub_segv_handler(int sig) ··· 33 17 struct ucontext *uc; 34 18 35 19 __asm__("movq %%rdx, %0" : "=g" (uc) :); 36 - GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), 37 - &uc->uc_mcontext); 20 + GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), 21 + &uc->uc_mcontext); 38 22 39 - __asm__("movq %0, %%rax ; syscall": : "g" (__NR_getpid)); 23 + __asm__("movq %0, %%rax ; syscall": : "g" (__NR_getpid)); 40 24 __asm__("movq %%rax, %%rdi ; movq %0, %%rax ; movq %1, %%rsi ;" 41 - "syscall": : "g" (__NR_kill), "g" (SIGUSR1)); 42 - /* Two popqs to restore the stack to the state just before entering 43 - * the handler, one pops the return address, the other pops the frame 44 - * pointer. 25 + "syscall": : "g" (__NR_kill), "g" (SIGUSR1) : 26 + "%rdi", "%rax", "%rsi"); 27 + /* sys_sigreturn expects that the stack pointer will be 8 bytes into 28 + * the signal frame. So, we use the ucontext pointer, which we know 29 + * already, to get the signal frame pointer, and add 8 to that. 45 30 */ 46 - __asm__("popq %%rax ; popq %%rax ; movq %0, %%rax ; syscall" : : "g" 47 - (__NR_rt_sigreturn)); 31 + __asm__("movq %0, %%rsp": : 32 + "g" ((unsigned long) container_of(uc, struct rt_sigframe, 33 + uc) + 8)); 34 + __asm__("movq %0, %%rax ; syscall" : : "g" (__NR_rt_sigreturn)); 48 35 }