aboutsummaryrefslogtreecommitdiff
path: root/kernel/arch/x86_64
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/arch/x86_64')
-rw-r--r--kernel/arch/x86_64/contextspfunc.S55
-rw-r--r--kernel/arch/x86_64/execregs.c156
-rw-r--r--kernel/arch/x86_64/execregs.h81
-rw-r--r--kernel/arch/x86_64/execsp.S111
-rw-r--r--kernel/arch/x86_64/h_execregs.S82
-rw-r--r--kernel/arch/x86_64/signalsphandler.S55
-rw-r--r--kernel/arch/x86_64/stack_pointer.h35
-rw-r--r--kernel/arch/x86_64/threadspfunc.S54
8 files changed, 629 insertions, 0 deletions
diff --git a/kernel/arch/x86_64/contextspfunc.S b/kernel/arch/x86_64/contextspfunc.S
new file mode 100644
index 000000000000..d01e1dcdcaf3
--- /dev/null
+++ b/kernel/arch/x86_64/contextspfunc.S
@@ -0,0 +1,55 @@
+/* $NetBSD: contextspfunc.S,v 1.1 2025/04/21 02:33:45 riastradh Exp $ */
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define _LOCORE
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: contextspfunc.S,v 1.1 2025/04/21 02:33:45 riastradh Exp $")
+
+/*
+ * contextspfunc()
+ *
+ * makecontext(3) function. Store the stack pointer on entry at
+ * the global variable contextsp and call contextdone.
+ */
+ENTRY(contextspfunc)
+ /*
+ * `The end of the input argument area shall be aligned on a
+ * [16-byte] boundary. In other words, the value of (%rsp + 8)
+ * is always a multiple of 16 when control is transferred to
+ * the function entry point.'
+ *
+ * To make it convenient for t_signal_and_sp.c, we subtract 8
+ * from %rsp in order to get something congruent to zero modulo
+ * the stack alignemnt.
+ */
+ movq %rsp,_C_LABEL(contextsp)(%rip)
+ addq $-8,_C_LABEL(contextsp)(%rip)
+ call _C_LABEL(contextdone)
+END(contextspfunc)
diff --git a/kernel/arch/x86_64/execregs.c b/kernel/arch/x86_64/execregs.c
new file mode 100644
index 000000000000..fad1b40daa5e
--- /dev/null
+++ b/kernel/arch/x86_64/execregs.c
@@ -0,0 +1,156 @@
+/* $NetBSD: execregs.c,v 1.1 2025/02/27 00:55:32 riastradh Exp $ */
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: execregs.c,v 1.1 2025/02/27 00:55:32 riastradh Exp $");
+
+#include "execregs.h"
+
+#include <errno.h>
+#include <spawn.h>
+#include <stddef.h>
+#include <unistd.h>
+
+extern char **environ;
+
+static unsigned long
+nonnull(unsigned long x)
+{
+
+ x |= x << 8;
+ x |= x << 16;
+ x |= x << 32;
+ return x;
+}
+
+int
+execregschild(char *path)
+{
+ /* rdi: used to pass exec arg0, nonnull anyway (path) */
+ /* rsi: used to pass exec arg1, nonnull anyway (argv) */
+ /* rdx: used to pass exec arg2, nonnull anyway (environ) */
+ register long r10 __asm("r10") = nonnull(10);
+ register long r8 __asm("r8") = nonnull(8);
+ register long r9 __asm("r9") = nonnull(9);
+ register long rcx __asm("rcx") = nonnull('c');
+ register long r11 __asm("r11") = nonnull(11);
+ register long r12 __asm("r12") = nonnull(12);
+ register long r13 __asm("r13") = nonnull(13);
+ register long r14 __asm("r14") = nonnull(14);
+ register long r15 __asm("r15") = nonnull(15);
+ /* rbp: frame pointer, can't touch that here, but it'll be nonnull */
+ /* rbx: ps_strings, passed to child */
+ register long rax __asm("rax") = nonnull('a');
+
+ char *argv[] = {path, NULL};
+ char **envp = environ;
+
+ /*
+ * Not perfect -- compiler might use some registers for
+ * stack/argument transfers, but all the arguments are nonnull
+ * so this is probably a good test anyway.
+ */
+ __asm volatile("" :
+ "+r"(r10),
+ "+r"(r8),
+ "+r"(r9),
+ "+r"(rcx),
+ "+r"(r11),
+ "+r"(r12),
+ "+r"(r13),
+ "+r"(r14),
+ "+r"(r15),
+ "+r"(rax)
+ :: "memory");
+
+ return execve(path, argv, envp);
+}
+
+pid_t
+spawnregschild(char *path, int fd)
+{
+ /* rdi: used to pass posix_spawn arg0, nonnull anyway (&pid) */
+ /* rsi: used to pass posix_spawn arg1, nonnull anyway (path) */
+ /* rdx: used to pass posix_spawn arg2, nonnull anyway (&fileacts) */
+ register long r10 __asm("r10") = nonnull(10);
+ /* r8: used to pass posix_spawn arg4, nonnull anyway (argv) */
+ /* r9: used to pass posix_spawn arg5, nonnull anyway (environ) */
+ /* rcx: used to pass posix_spawn arg3, nonnull anyway (&attr) */
+ register long r11 __asm("r11") = nonnull(11);
+ register long r12 __asm("r12") = nonnull(12);
+ register long r13 __asm("r13") = nonnull(13);
+ register long r14 __asm("r14") = nonnull(14);
+ register long r15 __asm("r15") = nonnull(15);
+ /* rbp: frame pointer, can't touch that here, but it'll be nonnull */
+ /* rbx: ps_strings, passed to child */
+ register long rax __asm("rax") = nonnull('a');
+
+ char *argv[] = {path, NULL};
+ char **envp = environ;
+ posix_spawn_file_actions_t fileacts;
+ posix_spawnattr_t attr;
+ pid_t pid;
+ int error;
+
+ error = posix_spawn_file_actions_init(&fileacts);
+ if (error)
+ goto out;
+ error = posix_spawn_file_actions_adddup2(&fileacts, fd, STDOUT_FILENO);
+ if (error)
+ goto out;
+ error = posix_spawnattr_init(&attr);
+ if (error)
+ goto out;
+
+ /*
+ * Not perfect -- compiler might use some registers for
+ * stack/argument transfers, but all the arguments are nonnull
+ * so this is probably a good test anyway.
+ */
+ __asm volatile("" :
+ "+r"(r10),
+ "+r"(r11),
+ "+r"(r12),
+ "+r"(r13),
+ "+r"(r14),
+ "+r"(r15),
+ "+r"(rax)
+ :: "memory");
+
+ error = posix_spawn(&pid, path, &fileacts, &attr, argv, envp);
+ if (error)
+ goto out;
+
+out: posix_spawnattr_destroy(&attr);
+ posix_spawn_file_actions_destroy(&fileacts);
+ if (error) {
+ errno = error;
+ return -1;
+ }
+ return 0;
+}
diff --git a/kernel/arch/x86_64/execregs.h b/kernel/arch/x86_64/execregs.h
new file mode 100644
index 000000000000..904991777483
--- /dev/null
+++ b/kernel/arch/x86_64/execregs.h
@@ -0,0 +1,81 @@
+/* $NetBSD: execregs.h,v 1.1 2025/02/27 00:55:32 riastradh Exp $ */
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TESTS_KERNEL_ARCH_X86_64_EXECREGS_H
+#define TESTS_KERNEL_ARCH_X86_64_EXECREGS_H
+
+#include <sys/cdefs.h>
+
+#define NEXECREGS 14
+
+#ifndef _LOCORE
+
+#include <unistd.h>
+
+/*
+ * Ordered by _FRAME_REG in sys/arch/amd64/include/frame_regs.h for
+ * convenience of auditing. Must match h_execregs.S.
+ */
+static const char *const regname[] = {
+ "rdi",
+ "rsi",
+ "rdx",
+ "r10",
+ "r8",
+ "r9",
+ /* arg6: syscall arg from stack, not a real register */
+ /* arg7: syscall arg from stack, not a real register */
+ /* arg8: syscall arg from stack, not a real register */
+ /* arg9: syscall arg from stack, not a real register */
+ "rcx",
+ "r11",
+ "r12",
+ "r13",
+ "r14",
+ "r15",
+ "rbp",
+ /* rbx: ps_strings */
+ "rax",
+ /* gs/fs/es/ds: segment registers, not really registers */
+ /* trapno: not a register */
+ /* err: not a register */
+ /* rip: instruction pointer */
+ /* cs: segment register */
+ /* rflags */
+ /* rsp: stack pointer */
+ /* ss: stack selector */
+};
+
+__CTASSERT(NEXECREGS == __arraycount(regname));
+
+int execregschild(char *);
+pid_t spawnregschild(char *, int);
+
+#endif /* _LOCORE */
+
+#endif /* TESTS_KERNEL_ARCH_X86_64_EXECREGS_H */
diff --git a/kernel/arch/x86_64/execsp.S b/kernel/arch/x86_64/execsp.S
new file mode 100644
index 000000000000..d351dfb2d9e8
--- /dev/null
+++ b/kernel/arch/x86_64/execsp.S
@@ -0,0 +1,111 @@
+/* $NetBSD: execsp.S,v 1.2 2025/04/20 22:31:25 riastradh Exp $ */
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define _LOCORE
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: execsp.S,v 1.2 2025/04/20 22:31:25 riastradh Exp $")
+
+/*
+ * void execsp_start(void (*cleanup@rbx)(void), void *obj_main@rcx,
+ * struct ps_strings *ps_strings@rbx)
+ *
+ * ELF entry point. Saves the stack pointer in startsp and defers
+ * to the usual csu __start routine.
+ */
+ENTRY(execsp_start)
+ movq %rsp,_C_LABEL(startsp)(%rip)
+ /*
+ * No adjustment like in main because entry point is special
+ * and the amd64 csu __start routine takes care of it.
+ *
+ * XXX Why don't we just arrange to align it in the kernel
+ * anyway?
+ */
+ jmp _C_LABEL(__start)
+END(execsp_start)
+
+/*
+ * void execsp_ctor(void)
+ *
+ * ELF constructor. Saves the stack pointer in ctorsp and
+ * returns.
+ */
+ENTRY(execsp_ctor)
+ /*
+ * `The end of the input argument area shall be aligned on a
+ * [16-byte] boundary. In other words, the value of (%rsp + 8)
+ * is always a multiple of 16 when control is transferred to
+ * the function entry point.'
+ *
+ * To make it convenient for t_signal_and_sp.c, we subtract 8
+ * from %rsp in order to get something congruent to zero modulo
+ * the stack alignemnt.
+ */
+ movq %rsp,_C_LABEL(ctorsp)(%rip)
+ addq $-8,_C_LABEL(ctorsp)(%rip)
+ ret
+END(execsp_ctor)
+
+ /* Make execsp_ctor a constructor. */
+ .section .ctors,"aw",@progbits
+ .p2align 3
+ .quad _C_LABEL(execsp_ctor)
+
+/*
+ * int main(int argc@rdi, char **argv@rsi, ...)
+ *
+ * Main function. Saves the stack pointer in mainsp and returns
+ * zero. We will call execsp_main in execsp_dtor once dtorsp has
+ * been initialized.
+ */
+ENTRY(main)
+ movq %rsp,_C_LABEL(mainsp)(%rip)
+ addq $-8,_C_LABEL(mainsp)(%rip)
+ xorl %eax,%eax
+ ret
+END(main)
+
+/*
+ * void execsp_dtor(void)
+ *
+ * ELF destructor. Saves the stack pointer in dtorsp and defers
+ * to the C execsp_main in h_execsp.c to report the stack pointers
+ * back to the t_signal_and_sp parent.
+ */
+ENTRY(execsp_dtor)
+ movq %rsp,_C_LABEL(dtorsp)(%rip)
+ addq $-8,_C_LABEL(dtorsp)(%rip)
+ jmp _C_LABEL(execsp_main)
+END(execsp_dtor)
+
+ /* Make execsp_ctor a destructor. */
+ .section .dtors,"aw",@progbits
+ .p2align 3
+ .quad _C_LABEL(execsp_dtor)
diff --git a/kernel/arch/x86_64/h_execregs.S b/kernel/arch/x86_64/h_execregs.S
new file mode 100644
index 000000000000..638f73940f06
--- /dev/null
+++ b/kernel/arch/x86_64/h_execregs.S
@@ -0,0 +1,82 @@
+/* $NetBSD: h_execregs.S,v 1.1 2025/02/27 00:55:32 riastradh Exp $ */
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define _LOCORE
+
+#include <sys/syscall.h>
+
+#include <machine/asm.h>
+
+#include "execregs.h"
+
+ENTRY(execregs_start)
+ andq $-0x10,%rsp /* align stack to 16-byte boundary */
+
+ /* store registers to a buffer on stack */
+ subq $(NEXECREGS*8),%rsp /* space for NEXECREGS registers */
+ movq %rdi,0*8(%rsp) /* order matches execregs.h */
+ movq %rsi,1*8(%rsp)
+ movq %rdx,2*8(%rsp)
+ movq %r10,3*8(%rsp)
+ movq %r8,4*8(%rsp)
+ movq %r9,5*8(%rsp)
+ movq %rcx,6*8(%rsp)
+ movq %r11,7*8(%rsp)
+ movq %r12,8*8(%rsp)
+ movq %r13,9*8(%rsp)
+ movq %r14,10*8(%rsp)
+ movq %r15,11*8(%rsp)
+ movq %rbp,12*8(%rsp)
+ movq %rax,13*8(%rsp)
+
+ /* call write(STDOUT_FILENO, regs, sizeof(regs)) */
+ movl $0x1,%edi /* arg0 := STDOUT_FILENO */
+ movq %rsp,%rsi /* arg1 := regs */
+ movl $(NEXECREGS*8),%edx /* arg2 := sizeof(regs) */
+ movl $SYS_write,%eax /* syscall number */
+ syscall
+
+ jb 2f /* bail if write failed */
+ cmpq $(NEXECREGS*8),%rax /* bail if wrote wrong # of bytes */
+ jne 2f
+
+ /* call exit(0) */
+ xorl %edi,%edi /* arg0 := 0 */
+1: movl $SYS_exit,%eax /* syscall number */
+ syscall
+ hlt /* paranoia */
+
+2: /* call exit(127) */
+ movl $127,%edi /* arg0 := 127 */
+ jmp 1b
+END(execregs_start)
+
+/* main stub to simplify linking */
+ENTRY(main)
+ hlt
+END(main)
diff --git a/kernel/arch/x86_64/signalsphandler.S b/kernel/arch/x86_64/signalsphandler.S
new file mode 100644
index 000000000000..b53cb005d0b0
--- /dev/null
+++ b/kernel/arch/x86_64/signalsphandler.S
@@ -0,0 +1,55 @@
+/* $NetBSD: signalsphandler.S,v 1.1 2025/04/20 22:31:01 riastradh Exp $ */
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define _LOCORE
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: signalsphandler.S,v 1.1 2025/04/20 22:31:01 riastradh Exp $")
+
+/*
+ * signalsphandler(signo@rdi)
+ *
+ * Signal handler. Store the stack pointer on entry at the global
+ * variable signalsp and return.
+ */
+ENTRY(signalsphandler)
+ /*
+ * `The end of the input argument area shall be aligned on a
+ * [16-byte] boundary. In other words, the value of (%rsp + 8)
+ * is always a multiple of 16 when control is transferred to
+ * the function entry point.'
+ *
+ * To make it convenient for t_signal_and_sp.c, we subtract 8
+ * from %rsp in order to get something congruent to zero modulo
+ * the stack alignemnt.
+ */
+ movq %rsp,_C_LABEL(signalsp)(%rip)
+ addq $-8,_C_LABEL(signalsp)(%rip)
+ ret
+END(signalsphandler)
diff --git a/kernel/arch/x86_64/stack_pointer.h b/kernel/arch/x86_64/stack_pointer.h
new file mode 100644
index 000000000000..6ea297cf97d9
--- /dev/null
+++ b/kernel/arch/x86_64/stack_pointer.h
@@ -0,0 +1,35 @@
+/* $NetBSD: stack_pointer.h,v 1.1 2025/04/20 22:31:01 riastradh Exp $ */
+
+/*
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TESTS_KERNEL_ARCH_X86_64_STACK_POINTER_H
+#define TESTS_KERNEL_ARCH_X86_64_STACK_POINTER_H
+
+#define MISALIGN_SP __asm __volatile("addq $-1,%rsp")
+#define FIX_SP __asm __volatile("addq $1,%rsp")
+
+#endif /* TESTS_KERNEL_ARCH_X86_64_STACK_POINTER_H */
diff --git a/kernel/arch/x86_64/threadspfunc.S b/kernel/arch/x86_64/threadspfunc.S
new file mode 100644
index 000000000000..c939f36b408a
--- /dev/null
+++ b/kernel/arch/x86_64/threadspfunc.S
@@ -0,0 +1,54 @@
+/* $NetBSD: threadspfunc.S,v 1.2 2025/04/21 12:06:08 riastradh Exp $ */
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define _LOCORE
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: threadspfunc.S,v 1.2 2025/04/21 12:06:08 riastradh Exp $")
+
+/*
+ * void *threadspfunc(void *cookie@rdi)
+ *
+ * pthread_create(3) function. Return the stack pointer on entry.
+ */
+ENTRY(threadspfunc)
+ /*
+ * `The end of the input argument area shall be aligned on a
+ * [16-byte] boundary. In other words, the value of (%rsp + 8)
+ * is always a multiple of 16 when control is transferred to
+ * the function entry point.'
+ *
+ * To make it convenient for t_signal_and_sp.c, we subtract 8
+ * from %rsp in order to get something congruent to zero modulo
+ * the stack alignemnt.
+ */
+ movq %rsp,%rax
+ addq $-8,%rax
+ ret
+END(threadspfunc)