summaryrefslogtreecommitdiffstats
path: root/arch/x86/um/setjmp_64.S
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--arch/x86/um/setjmp_64.S55
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..b46acb6a8
--- /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