The patch titled uml: Use klibc setjmp/longjmp has been removed from the -mm tree. Its filename is uml-use-klibc-setjmp-longjmp.patch This patch was dropped because it was merged into mainline or a subsystem tree ------------------------------------------------------ Subject: uml: Use klibc setjmp/longjmp From: Jeff Dike <jdike@xxxxxxxxxxx> This patch adds an implementation of setjmp and longjmp to UML, allowing access to the inside of a jmpbuf without needing the access macros formerly provided by libc. The implementation is stolen from klibc. I copy the relevant files into arch/um. I have another patch which avoids the copying, but requires klibc be in the tree. setjmp and longjmp users required some tweaking. Includes of <setjmp.h> were removed and includes of the UML longjmp.h were added where necessary. There are also replacements of siglongjmp with UML_LONGJMP which I somehow missed earlier. Signed-off-by: Jeff Dike <jdike@xxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- arch/um/include/longjmp.h | 5 + arch/um/include/sysdep-i386/archsetjmp.h | 19 ++++++ arch/um/include/sysdep-x86_64/archsetjmp.h | 21 ++++++ arch/um/os-Linux/process.c | 1 arch/um/os-Linux/skas/process.c | 3 arch/um/os-Linux/sys-i386/registers.c | 10 +-- arch/um/os-Linux/sys-x86_64/registers.c | 10 +-- arch/um/os-Linux/trap.c | 1 arch/um/os-Linux/uaccess.c | 3 arch/um/os-Linux/util.c | 5 - arch/um/sys-i386/Makefile | 2 arch/um/sys-i386/setjmp.S | 58 +++++++++++++++++++ arch/um/sys-x86_64/Makefile | 4 - arch/um/sys-x86_64/setjmp.S | 54 +++++++++++++++++ 14 files changed, 173 insertions(+), 23 deletions(-) diff -puN arch/um/include/longjmp.h~uml-use-klibc-setjmp-longjmp arch/um/include/longjmp.h --- a/arch/um/include/longjmp.h~uml-use-klibc-setjmp-longjmp +++ a/arch/um/include/longjmp.h @@ -1,9 +1,12 @@ #ifndef __UML_LONGJMP_H #define __UML_LONGJMP_H -#include <setjmp.h> +#include "sysdep/archsetjmp.h" #include "os.h" +extern int setjmp(jmp_buf); +extern void longjmp(jmp_buf, int); + #define UML_LONGJMP(buf, val) do { \ longjmp(*buf, val); \ } while(0) diff -puN /dev/null arch/um/include/sysdep-i386/archsetjmp.h --- /dev/null +++ a/arch/um/include/sysdep-i386/archsetjmp.h @@ -0,0 +1,19 @@ +/* + * arch/i386/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned int __ebx; + unsigned int __esp; + unsigned int __ebp; + unsigned int __esi; + unsigned int __edi; + unsigned int __eip; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff -puN /dev/null arch/um/include/sysdep-x86_64/archsetjmp.h --- /dev/null +++ a/arch/um/include/sysdep-x86_64/archsetjmp.h @@ -0,0 +1,21 @@ +/* + * arch/x86_64/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __rbx; + unsigned long __rsp; + unsigned long __rbp; + unsigned long __r12; + unsigned long __r13; + unsigned long __r14; + unsigned long __r15; + unsigned long __rip; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff -puN arch/um/os-Linux/process.c~uml-use-klibc-setjmp-longjmp arch/um/os-Linux/process.c --- a/arch/um/os-Linux/process.c~uml-use-klibc-setjmp-longjmp +++ a/arch/um/os-Linux/process.c @@ -7,7 +7,6 @@ #include <stdio.h> #include <errno.h> #include <signal.h> -#include <setjmp.h> #include <linux/unistd.h> #include <sys/mman.h> #include <sys/wait.h> diff -puN arch/um/os-Linux/skas/process.c~uml-use-klibc-setjmp-longjmp arch/um/os-Linux/skas/process.c --- a/arch/um/os-Linux/skas/process.c~uml-use-klibc-setjmp-longjmp +++ a/arch/um/os-Linux/skas/process.c @@ -8,7 +8,6 @@ #include <unistd.h> #include <errno.h> #include <signal.h> -#include <setjmp.h> #include <sched.h> #include "ptrace_user.h" #include <sys/wait.h> @@ -470,7 +469,7 @@ void thread_wait(void *sw, void *fb) *switch_buf = &buf; fork_buf = fb; if(UML_SETJMP(&buf) == 0) - siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); + UML_LONGJMP(fork_buf, INIT_JMP_REMOVE_SIGSTACK); } void switch_threads(void *me, void *next) diff -puN arch/um/os-Linux/sys-i386/registers.c~uml-use-klibc-setjmp-longjmp arch/um/os-Linux/sys-i386/registers.c --- a/arch/um/os-Linux/sys-i386/registers.c~uml-use-klibc-setjmp-longjmp +++ a/arch/um/os-Linux/sys-i386/registers.c @@ -5,12 +5,12 @@ #include <errno.h> #include <string.h> -#include <setjmp.h> #include "sysdep/ptrace_user.h" #include "sysdep/ptrace.h" #include "uml-config.h" #include "skas_ptregs.h" #include "registers.h" +#include "longjmp.h" #include "user.h" /* These are set once at boot time and not changed thereafter */ @@ -132,9 +132,9 @@ void get_safe_registers(unsigned long *r void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer) { - struct __jmp_buf_tag *jmpbuf = buffer; + struct __jmp_buf *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]); + UPT_SET(uml_regs, EIP, jmpbuf->__eip); + UPT_SET(uml_regs, UESP, jmpbuf->__esp); + UPT_SET(uml_regs, EBP, jmpbuf->__ebp); } diff -puN arch/um/os-Linux/sys-x86_64/registers.c~uml-use-klibc-setjmp-longjmp arch/um/os-Linux/sys-x86_64/registers.c --- a/arch/um/os-Linux/sys-x86_64/registers.c~uml-use-klibc-setjmp-longjmp +++ a/arch/um/os-Linux/sys-x86_64/registers.c @@ -5,11 +5,11 @@ #include <errno.h> #include <string.h> -#include <setjmp.h> #include "ptrace_user.h" #include "uml-config.h" #include "skas_ptregs.h" #include "registers.h" +#include "longjmp.h" #include "user.h" /* These are set once at boot time and not changed thereafter */ @@ -80,9 +80,9 @@ void get_safe_registers(unsigned long *r void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer) { - struct __jmp_buf_tag *jmpbuf = buffer; + struct __jmp_buf *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]); + UPT_SET(uml_regs, RIP, jmpbuf->__rip); + UPT_SET(uml_regs, RSP, jmpbuf->__rsp); + UPT_SET(uml_regs, RBP, jmpbuf->__rbp); } diff -puN arch/um/os-Linux/trap.c~uml-use-klibc-setjmp-longjmp arch/um/os-Linux/trap.c --- a/arch/um/os-Linux/trap.c~uml-use-klibc-setjmp-longjmp +++ a/arch/um/os-Linux/trap.c @@ -5,7 +5,6 @@ #include <stdlib.h> #include <signal.h> -#include <setjmp.h> #include "kern_util.h" #include "user_util.h" #include "os.h" diff -puN arch/um/os-Linux/uaccess.c~uml-use-klibc-setjmp-longjmp arch/um/os-Linux/uaccess.c --- a/arch/um/os-Linux/uaccess.c~uml-use-klibc-setjmp-longjmp +++ a/arch/um/os-Linux/uaccess.c @@ -4,8 +4,7 @@ * Licensed under the GPL */ -#include <setjmp.h> -#include <string.h> +#include <stddef.h> #include "longjmp.h" unsigned long __do_user_copy(void *to, const void *from, int n, diff -puN arch/um/os-Linux/util.c~uml-use-klibc-setjmp-longjmp arch/um/os-Linux/util.c --- a/arch/um/os-Linux/util.c~uml-use-klibc-setjmp-longjmp +++ a/arch/um/os-Linux/util.c @@ -7,7 +7,6 @@ #include <stdlib.h> #include <unistd.h> #include <limits.h> -#include <setjmp.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/utsname.h> @@ -107,11 +106,11 @@ int setjmp_wrapper(void (*proc)(void *, jmp_buf buf; int n; - n = sigsetjmp(buf, 1); + n = UML_SETJMP(&buf); if(n == 0){ va_start(args, proc); (*proc)(&buf, &args); } va_end(args); - return(n); + return n; } diff -puN arch/um/sys-i386/Makefile~uml-use-klibc-setjmp-longjmp arch/um/sys-i386/Makefile --- a/arch/um/sys-i386/Makefile~uml-use-klibc-setjmp-longjmp +++ a/arch/um/sys-i386/Makefile @@ -1,5 +1,5 @@ obj-y = bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ - ptrace_user.o signal.o sigcontext.o syscalls.o sysrq.o \ + ptrace_user.o setjmp.o signal.o sigcontext.o syscalls.o sysrq.o \ sys_call_table.o tls.o obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o diff -puN /dev/null arch/um/sys-i386/setjmp.S --- /dev/null +++ a/arch/um/sys-i386/setjmp.S @@ -0,0 +1,58 @@ +# +# arch/i386/setjmp.S +# +# setjmp/longjmp for the i386 architecture +# + +# +# The jmp_buf is assumed to contain the following, in order: +# %ebx +# %esp +# %ebp +# %esi +# %edi +# <return address> +# + + .text + .align 4 + .globl setjmp + .type setjmp, @function +setjmp: +#ifdef _REGPARM + movl %eax,%edx +#else + movl 4(%esp),%edx +#endif + popl %ecx # Return address, and adjust the stack + xorl %eax,%eax # Return value + movl %ebx,(%edx) + movl %esp,4(%edx) # Post-return %esp! + pushl %ecx # Make the call/return stack happy + movl %ebp,8(%edx) + movl %esi,12(%edx) + movl %edi,16(%edx) + movl %ecx,20(%edx) # Return address + ret + + .size setjmp,.-setjmp + + .text + .align 4 + .globl longjmp + .type longjmp, @function +longjmp: +#ifdef _REGPARM + xchgl %eax,%edx +#else + movl 4(%esp),%edx # jmp_ptr address + movl 8(%esp),%eax # Return value +#endif + movl (%edx),%ebx + movl 4(%edx),%esp + movl 8(%edx),%ebp + movl 12(%edx),%esi + movl 16(%edx),%edi + jmp *20(%edx) + + .size longjmp,.-longjmp diff -puN arch/um/sys-x86_64/Makefile~uml-use-klibc-setjmp-longjmp arch/um/sys-x86_64/Makefile --- a/arch/um/sys-x86_64/Makefile~uml-use-klibc-setjmp-longjmp +++ a/arch/um/sys-x86_64/Makefile @@ -5,8 +5,8 @@ # obj-y = bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \ - sigcontext.o signal.o syscalls.o syscall_table.o sysrq.o ksyms.o \ - tls.o + setjmp.o sigcontext.o signal.o syscalls.o syscall_table.o sysrq.o \ + ksyms.o tls.o obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o obj-$(CONFIG_MODULES) += um_module.o diff -puN /dev/null arch/um/sys-x86_64/setjmp.S --- /dev/null +++ a/arch/um/sys-x86_64/setjmp.S @@ -0,0 +1,54 @@ +# +# arch/x86_64/setjmp.S +# +# setjmp/longjmp for the x86-64 architecture +# + +# +# The jmp_buf is assumed to contain the following, in order: +# %rbx +# %rsp (post-return) +# %rbp +# %r12 +# %r13 +# %r14 +# %r15 +# <return address> +# + + .text + .align 4 + .globl setjmp + .type setjmp, @function +setjmp: + pop %rsi # Return address, and adjust the stack + xorl %eax,%eax # Return value + movq %rbx,(%rdi) + movq %rsp,8(%rdi) # Post-return %rsp! + push %rsi # Make the call/return stack happy + movq %rbp,16(%rdi) + movq %r12,24(%rdi) + movq %r13,32(%rdi) + movq %r14,40(%rdi) + movq %r15,48(%rdi) + movq %rsi,56(%rdi) # Return address + ret + + .size setjmp,.-setjmp + + .text + .align 4 + .globl longjmp + .type longjmp, @function +longjmp: + movl %esi,%eax # Return value (int) + movq (%rdi),%rbx + movq 8(%rdi),%rsp + movq 16(%rdi),%rbp + movq 24(%rdi),%r12 + movq 32(%rdi),%r13 + movq 40(%rdi),%r14 + movq 48(%rdi),%r15 + jmp *56(%rdi) + + .size longjmp,.-longjmp _ Patches currently in -mm which might be from jdike@xxxxxxxxxxx are origin.patch uml-use-mcmodel=kernel-for-x86_64.patch uml-fix-proc-vs-interrupt-context-spinlock-deadlock.patch uml-const-more-data.patch uml-get-rid-of-zone_dma-use.patch uml-fix-missing-x86_64-register-definitions.patch uml-fix-gcov-support.patch uml-use-correct-sigbus-handler.patch uml-add-checkstack-support.patch uml-mark-some-tt-mode-code.patch uml-thread-creation-tidying.patch uml-file-renaming.patch uml-add-an-export.patch uml-fix-sleep-length-bug.patch uml-fix-allocation-size.patch uml-remove-pte_mkexec.patch simplify-update_times-avoid-jiffies-jiffies_64-aliasing-problem-2.patch kill-wall_jiffies.patch const-struct-tty_operations.patch namespaces-utsname-switch-to-using-uts-namespaces.patch introduce-kernel_execve.patch rename-the-provided-execve-functions-to-kernel_execve.patch provide-kernel_execve-on-all-architectures.patch provide-kernel_execve-on-all-architectures-fix.patch remove-the-use-of-_syscallx-macros-in-uml.patch sh64-remove-the-use-of-kernel-syscalls.patch remove-remaining-errno-and-__kernel_syscalls__-references.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html