Message ID | 1a39a239b4a34d2f613ab1ffc62c80967a2f57fb.1729770373.git.thehajime@gmail.com |
---|---|
State | RFC |
Headers | show |
Series | [RFC,01/13] fs: binfmt_elf_efpic: add architecture hook elf_arch_finalize_exec | expand |
On Thu, 2024-10-24 at 21:09 +0900, Hajime Tazaki wrote: > > +++ b/arch/x86/um/do_syscall_64.c > @@ -0,0 +1,42 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +#include <linux/kernel.h> > +#include <linux/ptrace.h> > +#include <kern_util.h> > +#include <sysdep/syscalls.h> > +#include <os.h> > + > +#ifndef CONFIG_MMU This seems unnecessary, you don't build the file with CONFIG_MMU in the first place. > +++ b/arch/x86/um/entry_64.S > @@ -0,0 +1,88 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +#include <asm/errno.h> > + > +#include <linux/linkage.h> > +#include <asm/percpu.h> > +#include <asm/desc.h> > + > +#include "../entry/calling.h" > + > +#ifdef CONFIG_SMP > +#error need to stash these variables somewhere else > +#endif > + > +#ifndef CONFIG_MMU same here. > +++ b/arch/x86/um/shared/sysdep/syscalls_64.h > @@ -25,4 +25,8 @@ extern syscall_handler_t *sys_call_table[]; > extern syscall_handler_t sys_modify_ldt; > extern syscall_handler_t sys_arch_prctl; > > +__visible void do_syscall_64(struct pt_regs *regs); > +extern long __kernel_vsyscall(int64_t a0, int64_t a1, int64_t a2, int64_t a3, > + int64_t a4, int64_t a5, int64_t a6); > + > but maybe that should be ifdef'ed? johannes
On Fri, 25 Oct 2024 18:14:19 +0900, Johannes Berg wrote: > > On Thu, 2024-10-24 at 21:09 +0900, Hajime Tazaki wrote: > > > > +++ b/arch/x86/um/do_syscall_64.c > > @@ -0,0 +1,42 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > + > > +#include <linux/kernel.h> > > +#include <linux/ptrace.h> > > +#include <kern_util.h> > > +#include <sysdep/syscalls.h> > > +#include <os.h> > > + > > +#ifndef CONFIG_MMU > > This seems unnecessary, you don't build the file with CONFIG_MMU in the > first place. will fix it. > > +++ b/arch/x86/um/entry_64.S > > @@ -0,0 +1,88 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +#include <asm/errno.h> > > + > > +#include <linux/linkage.h> > > +#include <asm/percpu.h> > > +#include <asm/desc.h> > > + > > +#include "../entry/calling.h" > > + > > +#ifdef CONFIG_SMP > > +#error need to stash these variables somewhere else > > +#endif > > + > > +#ifndef CONFIG_MMU > > same here. will fix it too. > > +++ b/arch/x86/um/shared/sysdep/syscalls_64.h > > @@ -25,4 +25,8 @@ extern syscall_handler_t *sys_call_table[]; > > extern syscall_handler_t sys_modify_ldt; > > extern syscall_handler_t sys_arch_prctl; > > > > +__visible void do_syscall_64(struct pt_regs *regs); > > +extern long __kernel_vsyscall(int64_t a0, int64_t a1, int64_t a2, int64_t a3, > > + int64_t a4, int64_t a5, int64_t a6); > > + > > > > but maybe that should be ifdef'ed? thanks, will fix it too. -- Hajime
diff --git a/arch/x86/um/do_syscall_64.c b/arch/x86/um/do_syscall_64.c new file mode 100644 index 000000000000..7af6e881ad58 --- /dev/null +++ b/arch/x86/um/do_syscall_64.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/kernel.h> +#include <linux/ptrace.h> +#include <kern_util.h> +#include <sysdep/syscalls.h> +#include <os.h> + +#ifndef CONFIG_MMU + +__visible void do_syscall_64(struct pt_regs *regs) +{ + int syscall; + + syscall = PT_SYSCALL_NR(regs->regs.gp); + UPT_SYSCALL_NR(®s->regs) = syscall; + + pr_debug("syscall(%d) (current=%lx) (fn=%lx)\n", + syscall, (unsigned long)current, + (unsigned long)sys_call_table[syscall]); + + if (likely(syscall < NR_syscalls)) { + PT_REGS_SET_SYSCALL_RETURN(regs, + EXECUTE_SYSCALL(syscall, regs)); + } + + pr_debug("syscall(%d) --> %lx\n", syscall, + regs->regs.gp[HOST_AX]); + + PT_REGS_SYSCALL_RET(regs) = regs->regs.gp[HOST_AX]; + + /* force do_signal() --> is_syscall() */ + set_thread_flag(TIF_SIGPENDING); + interrupt_end(); + + /* execve succeeded */ + if (syscall == __NR_execve && regs->regs.gp[HOST_AX] == 0) { + userspace(¤t->thread.regs.regs, + current_thread_info()->aux_fp_regs); + } +} +#endif diff --git a/arch/x86/um/entry_64.S b/arch/x86/um/entry_64.S new file mode 100644 index 000000000000..12e11ac03543 --- /dev/null +++ b/arch/x86/um/entry_64.S @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include <asm/errno.h> + +#include <linux/linkage.h> +#include <asm/percpu.h> +#include <asm/desc.h> + +#include "../entry/calling.h" + +#ifdef CONFIG_SMP +#error need to stash these variables somewhere else +#endif + +#ifndef CONFIG_MMU +#define UM_GLOBAL_VAR(x) .data; .align 8; .globl x; x:; .long 0 + +UM_GLOBAL_VAR(current_top_of_stack) +UM_GLOBAL_VAR(current_ptregs) + +.code64 +.section .entry.text, "ax" + +.align 8 +#undef ENTRY +#define ENTRY(x) .text; .globl x; .type x,%function; x: +#undef END +#define END(x) .size x, . - x + +/* + * %rcx has the return address (we set it like that in zpoline trampoline). + * + * Registers on entry: + * rax system call number + * rcx return address + * rdi arg0 + * rsi arg1 + * rdx arg2 + * r10 arg3 + * r8 arg4 + * r9 arg5 + * + * (note: we are allowed to mess with r11: r11 is callee-clobbered + * register in C ABI) + */ +ENTRY(__kernel_vsyscall) + + movq %rsp, %r11 + + /* Point rsp to the top of the ptregs array, so we can + just fill it with a bunch of push'es. */ + movq current_ptregs, %rsp + + /* 8 bytes * 20 registers (plus 8 for the push) */ + addq $168, %rsp + + /* Construct struct pt_regs on stack */ + pushq $0 /* pt_regs->ss (index 20) */ + pushq %r11 /* pt_regs->sp */ + pushfq /* pt_regs->flags */ + pushq $0 /* pt_regs->cs */ + pushq %rcx /* pt_regs->ip */ + pushq %rax /* pt_regs->orig_ax */ + + PUSH_AND_CLEAR_REGS rax=$-ENOSYS + + mov %rsp, %rdi + + /* + * Switch to current top of stack, so "current->" points + * to the right task. + */ + movq current_top_of_stack, %rsp + + call do_syscall_64 + + movq current_ptregs, %rsp + + POP_REGS + + addq $8, %rsp /* skip orig_ax */ + addq $8, %rsp /* skip ip */ + addq $8, %rsp /* skip cs */ + addq $8, %rsp /* skip flags */ + popq %rsp + + ret + +END(__kernel_vsyscall) diff --git a/arch/x86/um/shared/sysdep/syscalls_64.h b/arch/x86/um/shared/sysdep/syscalls_64.h index b6b997225841..31aa0694cec0 100644 --- a/arch/x86/um/shared/sysdep/syscalls_64.h +++ b/arch/x86/um/shared/sysdep/syscalls_64.h @@ -25,4 +25,8 @@ extern syscall_handler_t *sys_call_table[]; extern syscall_handler_t sys_modify_ldt; extern syscall_handler_t sys_arch_prctl; +__visible void do_syscall_64(struct pt_regs *regs); +extern long __kernel_vsyscall(int64_t a0, int64_t a1, int64_t a2, int64_t a3, + int64_t a4, int64_t a5, int64_t a6); + #endif