diff options
Diffstat (limited to 'arch/x86/um/setjmp_64.S')
-rw-r--r-- | arch/x86/um/setjmp_64.S | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/arch/x86/um/setjmp_64.S b/arch/x86/um/setjmp_64.S new file mode 100644 index 000000000..1b5d40d4f --- /dev/null +++ b/arch/x86/um/setjmp_64.S @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +# +# 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 kernel_setjmp + .type kernel_setjmp, @function +kernel_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 kernel_setjmp,.-kernel_setjmp + + .text + .align 4 + .globl kernel_longjmp + .type kernel_longjmp, @function +kernel_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 kernel_longjmp,.-kernel_longjmp |