Index: sys/arch/amd64/amd64/netbsd32_machdep.c =================================================================== RCS file: /home/netbsd/src/sys/arch/amd64/amd64/netbsd32_machdep.c,v retrieving revision 1.131 diff -p -u -r1.131 netbsd32_machdep.c --- sys/arch/amd64/amd64/netbsd32_machdep.c 20 Nov 2019 19:37:51 -0000 1.131 +++ sys/arch/amd64/amd64/netbsd32_machdep.c 21 Nov 2019 07:38:48 -0000 @@ -86,6 +86,9 @@ __KERNEL_RCSID(0, "$NetBSD: netbsd32_mac const char machine32[] = "i386"; const char machine_arch32[] = "i386"; +static int netbsd32_process_doxmmregs(struct lwp *, struct lwp *, void *, bool); +static int netbsd32_process_xmmregio(struct lwp *, struct lwp *, struct uio *); + #ifdef USER_LDT static int x86_64_get_ldt32(struct lwp *, void *, register_t *); static int x86_64_set_ldt32(struct lwp *, void *, register_t *); @@ -344,8 +347,8 @@ netbsd32_ptrace_translate_request(int re case PT32_SETREGS: return PT_SETREGS; case PT32_GETFPREGS: return PT_GETFPREGS; case PT32_SETFPREGS: return PT_SETFPREGS; - case PT32_GETXMMREGS: return -1; - case PT32_SETXMMREGS: return -1; + case PT32_GETXMMREGS: return PT_GETXMMREGS; + case PT32_SETXMMREGS: return PT_SETXMMREGS; case PT32_GETDBREGS: return PT_GETDBREGS; case PT32_SETDBREGS: return PT_SETDBREGS; case PT32_SETSTEP: return PT_SETSTEP; @@ -500,6 +503,77 @@ netbsd32_process_write_dbregs(struct lwp return 0; } +static int +netbsd32_process_doxmmregs(struct lwp *curl, struct lwp *l, void *addr, + bool write) + /* curl: tracer */ + /* l: traced */ +{ + struct uio uio; + struct iovec iov; + struct vmspace *vm; + int error; + + if ((curl->l_proc->p_flag & PK_32) == 0 || + (l->l_proc->p_flag & PK_32) == 0) + return EINVAL; + + if (!process_machdep_validfpu(l->l_proc)) + return EINVAL; + + error = proc_vmspace_getref(curl->l_proc, &vm); + if (error) + return error; + + iov.iov_base = addr; + iov.iov_len = sizeof(struct xmmregs32); + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + uio.uio_offset = 0; + uio.uio_resid = sizeof(struct xmmregs32); + uio.uio_rw = write ? UIO_WRITE : UIO_READ; + uio.uio_vmspace = vm; + + error = netbsd32_process_xmmregio(curl, l, &uio); + uvmspace_free(vm); + return error; +} + +static int +netbsd32_process_xmmregio(struct lwp *curl, struct lwp *l, struct uio *uio) + /* curl: tracer */ + /* l: traced */ +{ + struct xmmregs32 regs; + int error; + char *kv; + size_t kl; + + kl = sizeof(regs); + kv = (char *)®s; + + if (uio->uio_offset < 0 || uio->uio_offset > (off_t)kl) + return EINVAL; + + kv += uio->uio_offset; + kl -= uio->uio_offset; + + if (kl > uio->uio_resid) + kl = uio->uio_resid; + + process_read_fpregs_xmm(l, ®s.fxstate); + error = uiomove(kv, kl, uio); + if (error == 0 && uio->uio_rw == UIO_WRITE) { + if (l->l_proc->p_stat != SSTOP) + error = EBUSY; + else + process_write_fpregs_xmm(l, ®s.fxstate); + } + + uio->uio_offset = 0; + return error; +} + int netbsd32_sysarch(struct lwp *l, const struct netbsd32_sysarch_args *uap, register_t *retval) { @@ -959,6 +1033,8 @@ netbsd32_machdep_md_init(void) MODULE_HOOK_SET(netbsd32_machine32_hook, "mach32", netbsd32_machine32); MODULE_HOOK_SET(netbsd32_reg_validate_hook, "mcontext32from64_validate", cpu_mcontext32from64_validate); + MODULE_HOOK_SET(netbsd32_process_doxmmregs_hook, + "netbsd32_process_doxmmregs", netbsd32_process_doxmmregs); } void @@ -967,4 +1043,5 @@ netbsd32_machdep_md_fini(void) MODULE_HOOK_UNSET(netbsd32_machine32_hook); MODULE_HOOK_UNSET(netbsd32_reg_validate_hook); + MODULE_HOOK_UNSET(netbsd32_process_doxmmregs_hook); } Index: sys/arch/amd64/amd64/process_machdep.c =================================================================== RCS file: /home/netbsd/src/sys/arch/amd64/amd64/process_machdep.c,v retrieving revision 1.44 diff -p -u -r1.44 process_machdep.c --- sys/arch/amd64/amd64/process_machdep.c 6 Aug 2019 01:34:29 -0000 1.44 +++ sys/arch/amd64/amd64/process_machdep.c 21 Nov 2019 05:37:41 -0000 @@ -94,6 +94,8 @@ __KERNEL_RCSID(0, "$NetBSD: process_mach #include #include +struct netbsd32_process_doxmmregs_hook_t netbsd32_process_doxmmregs_hook; + static inline struct trapframe *process_frame(struct lwp *); static inline struct trapframe * @@ -315,16 +317,16 @@ ptrace_machdep_dorequest( struct iovec iov; struct vmspace *vm; int error; - int write = 0; + bool write = false; switch (req) { case PT_SETXSTATE: - write = 1; + write = true; /* FALLTHROUGH */ case PT_GETXSTATE: - /* write = 0 done above. */ - if (!process_machdep_validxstate(lt->l_proc)) + /* write = false done above. */ + if (!process_machdep_validfpu(lt->l_proc)) return EINVAL; if (__predict_false(l->l_proc->p_flag & PK_32)) { struct netbsd32_iovec user_iov; @@ -358,6 +360,16 @@ ptrace_machdep_dorequest( error = process_machdep_doxstate(l, lt, &uio); uvmspace_free(vm); return error; + + case PT_SETXMMREGS: /* only for COMPAT_NETBSD32 */ + write = true; + + /* FALLTHROUGH */ + case PT_GETXMMREGS: /* only for COMPAT_NETBSD32 */ + /* write = false done above. */ + MODULE_HOOK_CALL(netbsd32_process_doxmmregs_hook, + (l, lt, addr, write), EINVAL, error); + return error; } #ifdef DIAGNOSTIC @@ -404,7 +416,7 @@ process_machdep_doxstate(struct lwp *cur } int -process_machdep_validxstate(struct proc *p) +process_machdep_validfpu(struct proc *p) { if (p->p_flag & PK_SYSTEM) Index: sys/arch/amd64/include/netbsd32_machdep.h =================================================================== RCS file: /home/netbsd/src/sys/arch/amd64/include/netbsd32_machdep.h,v retrieving revision 1.24 diff -p -u -r1.24 netbsd32_machdep.h --- sys/arch/amd64/include/netbsd32_machdep.h 26 Jun 2019 12:30:12 -0000 1.24 +++ sys/arch/amd64/include/netbsd32_machdep.h 21 Nov 2019 05:20:50 -0000 @@ -7,6 +7,8 @@ #include #include +#include + /* * i386 ptrace constants * Please keep in sync with sys/arch/i386/include/ptrace.h. @@ -136,6 +138,11 @@ struct dbreg32 { int dr[8]; }; +struct xmmregs32 { + struct fxsave fxstate; +}; +__CTASSERT(sizeof(struct xmmregs32) == 512); + struct x86_get_ldt_args32 { int32_t start; uint32_t desc; Index: sys/arch/amd64/include/ptrace.h =================================================================== RCS file: /home/netbsd/src/sys/arch/amd64/include/ptrace.h,v retrieving revision 1.16 diff -p -u -r1.16 ptrace.h --- sys/arch/amd64/include/ptrace.h 26 Jun 2019 12:30:12 -0000 1.16 +++ sys/arch/amd64/include/ptrace.h 21 Nov 2019 05:36:55 -0000 @@ -34,7 +34,7 @@ #ifdef __x86_64__ /* - * i386-dependent ptrace definitions + * amd64-dependent ptrace definitions */ #define PT_STEP (PT_FIRSTMACH + 0) #define PT_GETREGS (PT_FIRSTMACH + 1) @@ -47,6 +47,13 @@ #define PT_CLEARSTEP (PT_FIRSTMACH + 8) #define PT_GETXSTATE (PT_FIRSTMACH + 9) #define PT_SETXSTATE (PT_FIRSTMACH + 10) +#ifdef _KERNEL +/* + * Only for COMPAT_NETBSD32 + */ +#define PT_GETXMMREGS (PT_FIRSTMACH + 11) +#define PT_SETXMMREGS (PT_FIRSTMACH + 12) +#endif /* We have machine-dependent process tracing needs. */ #define __HAVE_PTRACE_MACHDEP @@ -63,6 +70,10 @@ "PT_CLEARSTEP", \ "PT_GETXSTATE", \ "PT_SETXSTATE" +/* + "PT_GETXMMREGS", \ + "PT_SETXMMREGS" + */ #include #define PTRACE_REG_PC(r) (r)->regs[_REG_RIP] @@ -85,10 +96,16 @@ */ #define PTRACE_MACHDEP_REQUEST_CASES \ case PT_GETXSTATE: \ - case PT_SETXSTATE: + case PT_SETXSTATE: \ + case PT_GETXMMREGS: \ + case PT_SETXMMREGS: int process_machdep_doxstate(struct lwp *, struct lwp *, struct uio *); -int process_machdep_validxstate(struct proc *); +int process_machdep_validfpu(struct proc *); + +#include +MODULE_HOOK(netbsd32_process_doxmmregs_hook, int, + (struct lwp *, struct lwp *, void *, bool)); #endif /* _KERNEL */