diff options
Diffstat (limited to 'arch/x86/um/shared/sysdep')
-rw-r--r-- | arch/x86/um/shared/sysdep/archsetjmp.h | 7 | ||||
-rw-r--r-- | arch/x86/um/shared/sysdep/faultinfo_32.h | 12 | ||||
-rw-r--r-- | arch/x86/um/shared/sysdep/faultinfo_64.h | 12 | ||||
-rw-r--r-- | arch/x86/um/shared/sysdep/kernel-offsets.h | 3 | ||||
-rw-r--r-- | arch/x86/um/shared/sysdep/ptrace.h | 8 | ||||
-rw-r--r-- | arch/x86/um/shared/sysdep/ptrace_32.h | 4 | ||||
-rw-r--r-- | arch/x86/um/shared/sysdep/ptrace_64.h | 4 | ||||
-rw-r--r-- | arch/x86/um/shared/sysdep/ptrace_user.h | 6 | ||||
-rw-r--r-- | arch/x86/um/shared/sysdep/stub.h | 2 | ||||
-rw-r--r-- | arch/x86/um/shared/sysdep/stub_32.h | 63 | ||||
-rw-r--r-- | arch/x86/um/shared/sysdep/stub_64.h | 68 |
11 files changed, 118 insertions, 71 deletions
diff --git a/arch/x86/um/shared/sysdep/archsetjmp.h b/arch/x86/um/shared/sysdep/archsetjmp.h index 166cedbab926..8c81d1a604a9 100644 --- a/arch/x86/um/shared/sysdep/archsetjmp.h +++ b/arch/x86/um/shared/sysdep/archsetjmp.h @@ -1,6 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __X86_UM_SYSDEP_ARCHSETJMP_H +#define __X86_UM_SYSDEP_ARCHSETJMP_H + #ifdef __i386__ #include "archsetjmp_32.h" #else #include "archsetjmp_64.h" #endif + +unsigned long get_thread_reg(int reg, jmp_buf *buf); + +#endif /* __X86_UM_SYSDEP_ARCHSETJMP_H */ diff --git a/arch/x86/um/shared/sysdep/faultinfo_32.h b/arch/x86/um/shared/sysdep/faultinfo_32.h index b6f2437ec29c..ab5c8e47049c 100644 --- a/arch/x86/um/shared/sysdep/faultinfo_32.h +++ b/arch/x86/um/shared/sysdep/faultinfo_32.h @@ -29,4 +29,16 @@ struct faultinfo { #define PTRACE_FULL_FAULTINFO 0 +#define ___backtrack_faulted(_faulted) \ + asm volatile ( \ + "mov $0, %0\n" \ + "movl $__get_kernel_nofault_faulted_%=,%1\n" \ + "jmp _end_%=\n" \ + "__get_kernel_nofault_faulted_%=:\n" \ + "mov $1, %0;" \ + "_end_%=:" \ + : "=r" (_faulted), \ + "=m" (current->thread.segv_continue) :: \ + ) + #endif diff --git a/arch/x86/um/shared/sysdep/faultinfo_64.h b/arch/x86/um/shared/sysdep/faultinfo_64.h index ee88f88974ea..26fb4835d3e9 100644 --- a/arch/x86/um/shared/sysdep/faultinfo_64.h +++ b/arch/x86/um/shared/sysdep/faultinfo_64.h @@ -29,4 +29,16 @@ struct faultinfo { #define PTRACE_FULL_FAULTINFO 1 +#define ___backtrack_faulted(_faulted) \ + asm volatile ( \ + "mov $0, %0\n" \ + "movq $__get_kernel_nofault_faulted_%=,%1\n" \ + "jmp _end_%=\n" \ + "__get_kernel_nofault_faulted_%=:\n" \ + "mov $1, %0;" \ + "_end_%=:" \ + : "=r" (_faulted), \ + "=m" (current->thread.segv_continue) :: \ + ) + #endif diff --git a/arch/x86/um/shared/sysdep/kernel-offsets.h b/arch/x86/um/shared/sysdep/kernel-offsets.h index a004bffb7b8d..48de3a71f845 100644 --- a/arch/x86/um/shared/sysdep/kernel-offsets.h +++ b/arch/x86/um/shared/sysdep/kernel-offsets.h @@ -6,6 +6,9 @@ #include <linux/kbuild.h> #include <asm/mman.h> +/* workaround for a warning with -Wmissing-prototypes */ +void foo(void); + void foo(void) { #include <common-offsets.h> diff --git a/arch/x86/um/shared/sysdep/ptrace.h b/arch/x86/um/shared/sysdep/ptrace.h index 6ca4ecabc55b..8f7476ff6e95 100644 --- a/arch/x86/um/shared/sysdep/ptrace.h +++ b/arch/x86/um/shared/sysdep/ptrace.h @@ -56,12 +56,16 @@ struct syscall_args { UPT_SYSCALL_ARG5(r), \ UPT_SYSCALL_ARG6(r) } } ) +extern unsigned long host_fp_size; + struct uml_pt_regs { unsigned long gp[MAX_REG_NR]; - unsigned long fp[MAX_FP_NR]; struct faultinfo faultinfo; long syscall; int is_user; + + /* Dynamically sized FP registers (holds an XSTATE) */ + unsigned long fp[]; }; #define EMPTY_UML_PT_REGS { } @@ -70,6 +74,6 @@ struct uml_pt_regs { #define UPT_FAULTINFO(r) (&(r)->faultinfo) #define UPT_IS_USER(r) ((r)->is_user) -extern int user_context(unsigned long sp); +extern int arch_init_registers(int pid); #endif /* __SYSDEP_X86_PTRACE_H */ diff --git a/arch/x86/um/shared/sysdep/ptrace_32.h b/arch/x86/um/shared/sysdep/ptrace_32.h index 0c4989842fbe..2392470cac4d 100644 --- a/arch/x86/um/shared/sysdep/ptrace_32.h +++ b/arch/x86/um/shared/sysdep/ptrace_32.h @@ -6,8 +6,6 @@ #ifndef __SYSDEP_I386_PTRACE_H #define __SYSDEP_I386_PTRACE_H -#define MAX_FP_NR HOST_FPX_SIZE - #define UPT_SYSCALL_ARG1(r) UPT_BX(r) #define UPT_SYSCALL_ARG2(r) UPT_CX(r) #define UPT_SYSCALL_ARG3(r) UPT_DX(r) @@ -15,6 +13,4 @@ #define UPT_SYSCALL_ARG5(r) UPT_DI(r) #define UPT_SYSCALL_ARG6(r) UPT_BP(r) -extern void arch_init_registers(int pid); - #endif diff --git a/arch/x86/um/shared/sysdep/ptrace_64.h b/arch/x86/um/shared/sysdep/ptrace_64.h index 0dc223aa1c2d..e73573ac871f 100644 --- a/arch/x86/um/shared/sysdep/ptrace_64.h +++ b/arch/x86/um/shared/sysdep/ptrace_64.h @@ -8,8 +8,6 @@ #ifndef __SYSDEP_X86_64_PTRACE_H #define __SYSDEP_X86_64_PTRACE_H -#define MAX_FP_NR HOST_FP_SIZE - #define REGS_R8(r) ((r)[HOST_R8]) #define REGS_R9(r) ((r)[HOST_R9]) #define REGS_R10(r) ((r)[HOST_R10]) @@ -57,6 +55,4 @@ #define UPT_SYSCALL_ARG5(r) UPT_R8(r) #define UPT_SYSCALL_ARG6(r) UPT_R9(r) -extern void arch_init_registers(int pid); - #endif diff --git a/arch/x86/um/shared/sysdep/ptrace_user.h b/arch/x86/um/shared/sysdep/ptrace_user.h index 1d1a824fa652..98da23120538 100644 --- a/arch/x86/um/shared/sysdep/ptrace_user.h +++ b/arch/x86/um/shared/sysdep/ptrace_user.h @@ -11,12 +11,6 @@ #define REGS_IP_INDEX HOST_IP #define REGS_SP_INDEX HOST_SP -#ifdef __i386__ -#define FP_SIZE ((HOST_FPX_SIZE > HOST_FP_SIZE) ? HOST_FPX_SIZE : HOST_FP_SIZE) -#else -#define FP_SIZE HOST_FP_SIZE -#endif - /* * glibc before 2.27 does not include PTRACE_SYSEMU_SINGLESTEP in its enum, * ensure we have a definition by (re-)defining it here. diff --git a/arch/x86/um/shared/sysdep/stub.h b/arch/x86/um/shared/sysdep/stub.h index ce0ca46ad383..dc89f4423454 100644 --- a/arch/x86/um/shared/sysdep/stub.h +++ b/arch/x86/um/shared/sysdep/stub.h @@ -12,4 +12,4 @@ #endif extern void stub_segv_handler(int, siginfo_t *, void *); -extern void stub_clone_handler(void); +extern void stub_syscall_handler(void); diff --git a/arch/x86/um/shared/sysdep/stub_32.h b/arch/x86/um/shared/sysdep/stub_32.h index ea8b5a2d67af..390988132c0a 100644 --- a/arch/x86/um/shared/sysdep/stub_32.h +++ b/arch/x86/um/shared/sysdep/stub_32.h @@ -6,6 +6,7 @@ #ifndef __SYSDEP_STUB_H #define __SYSDEP_STUB_H +#include <stddef.h> #include <asm/ptrace.h> #include <generated/asm-offsets.h> @@ -79,33 +80,31 @@ static __always_inline long stub_syscall5(long syscall, long arg1, long arg2, return ret; } -static __always_inline void trap_myself(void) +static __always_inline long stub_syscall6(long syscall, long arg1, long arg2, + long arg3, long arg4, long arg5, + long arg6) { - __asm("int3"); + struct syscall_args { + int ebx, ebp; + } args = { arg1, arg6 }; + long ret; + + __asm__ volatile ("pushl %%ebp;" + "movl 0x4(%%ebx),%%ebp;" + "movl (%%ebx),%%ebx;" + "int $0x80;" + "popl %%ebp" + : "=a" (ret) + : "0" (syscall), "b" (&args), + "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5) + : "memory"); + + return ret; } -static __always_inline void remap_stack_and_trap(void) +static __always_inline void trap_myself(void) { - __asm__ volatile ( - "movl %%esp,%%ebx ;" - "andl %0,%%ebx ;" - "movl %1,%%eax ;" - "movl %%ebx,%%edi ; addl %2,%%edi ; movl (%%edi),%%edi ;" - "movl %%ebx,%%ebp ; addl %3,%%ebp ; movl (%%ebp),%%ebp ;" - "int $0x80 ;" - "addl %4,%%ebx ; movl %%eax, (%%ebx) ;" - "int $3" - : : - "g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)), - "g" (STUB_MMAP_NR), - "g" (UML_STUB_FIELD_FD), - "g" (UML_STUB_FIELD_OFFSET), - "g" (UML_STUB_FIELD_CHILD_ERR), - "c" (STUB_DATA_PAGES * UM_KERN_PAGE_SIZE), - "d" (PROT_READ | PROT_WRITE), - "S" (MAP_FIXED | MAP_SHARED) - : - "memory"); + __asm("int3"); } static __always_inline void *get_stub_data(void) @@ -113,11 +112,23 @@ static __always_inline void *get_stub_data(void) unsigned long ret; asm volatile ( - "movl %%esp,%0 ;" - "andl %1,%0" + "call _here_%=;" + "_here_%=:" + "popl %0;" + "andl %1, %0 ;" + "addl %2, %0 ;" : "=a" (ret) - : "g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1))); + : "g" (~(UM_KERN_PAGE_SIZE - 1)), + "g" (UM_KERN_PAGE_SIZE)); return (void *)ret; } + +#define stub_start(fn) \ + asm volatile ( \ + "subl %0,%%esp ;" \ + "movl %1, %%eax ; " \ + "call *%%eax ;" \ + :: "i" ((1 + STUB_DATA_PAGES) * UM_KERN_PAGE_SIZE), \ + "i" (&fn)) #endif diff --git a/arch/x86/um/shared/sysdep/stub_64.h b/arch/x86/um/shared/sysdep/stub_64.h index b24168ef0ac4..294affbec742 100644 --- a/arch/x86/um/shared/sysdep/stub_64.h +++ b/arch/x86/um/shared/sysdep/stub_64.h @@ -6,6 +6,7 @@ #ifndef __SYSDEP_STUB_H #define __SYSDEP_STUB_H +#include <stddef.h> #include <sysdep/ptrace_user.h> #include <generated/asm-offsets.h> #include <linux/stddef.h> @@ -27,6 +28,17 @@ static __always_inline long stub_syscall0(long syscall) return ret; } +static __always_inline long stub_syscall1(long syscall, long arg1) +{ + long ret; + + __asm__ volatile (__syscall + : "=a" (ret) + : "0" (syscall), "D" (arg1) : __syscall_clobber ); + + return ret; +} + static __always_inline long stub_syscall2(long syscall, long arg1, long arg2) { long ret; @@ -79,35 +91,25 @@ static __always_inline long stub_syscall5(long syscall, long arg1, long arg2, return ret; } -static __always_inline void trap_myself(void) +static __always_inline long stub_syscall6(long syscall, long arg1, long arg2, + long arg3, long arg4, long arg5, + long arg6) { - __asm("int3"); + long ret; + + __asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; movq %7,%%r9 ; " + __syscall + : "=a" (ret) + : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3), + "g" (arg4), "g" (arg5), "g" (arg6) + : __syscall_clobber, "r10", "r8", "r9"); + + return ret; } -static __always_inline void remap_stack_and_trap(void) +static __always_inline void trap_myself(void) { - __asm__ volatile ( - "movq %0,%%rax ;" - "movq %%rsp,%%rdi ;" - "andq %1,%%rdi ;" - "movq %2,%%r10 ;" - "movq %%rdi,%%r8 ; addq %3,%%r8 ; movq (%%r8),%%r8 ;" - "movq %%rdi,%%r9 ; addq %4,%%r9 ; movq (%%r9),%%r9 ;" - __syscall ";" - "movq %%rsp,%%rdi ; andq %1,%%rdi ;" - "addq %5,%%rdi ; movq %%rax, (%%rdi) ;" - "int3" - : : - "g" (STUB_MMAP_NR), - "g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)), - "g" (MAP_FIXED | MAP_SHARED), - "g" (UML_STUB_FIELD_FD), - "g" (UML_STUB_FIELD_OFFSET), - "g" (UML_STUB_FIELD_CHILD_ERR), - "S" (STUB_DATA_PAGES * UM_KERN_PAGE_SIZE), - "d" (PROT_READ | PROT_WRITE) - : - __syscall_clobber, "r10", "r8", "r9"); + __asm("int3"); } static __always_inline void *get_stub_data(void) @@ -115,11 +117,21 @@ static __always_inline void *get_stub_data(void) unsigned long ret; asm volatile ( - "movq %%rsp,%0 ;" - "andq %1,%0" + "lea 0(%%rip), %0;" + "andq %1, %0 ;" + "addq %2, %0 ;" : "=a" (ret) - : "g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1))); + : "g" (~(UM_KERN_PAGE_SIZE - 1)), + "g" (UM_KERN_PAGE_SIZE)); return (void *)ret; } + +#define stub_start(fn) \ + asm volatile ( \ + "subq %0,%%rsp ;" \ + "movq %1,%%rax ;" \ + "call *%%rax ;" \ + :: "i" ((1 + STUB_DATA_PAGES) * UM_KERN_PAGE_SIZE), \ + "i" (&fn)) #endif |