Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/amd64 Add support for PT_[GS]ETXMMREGS requests for...



details:   https://anonhg.NetBSD.org/src/rev/9ae6774271e3
branches:  trunk
changeset: 461459:9ae6774271e3
user:      rin <rin%NetBSD.org@localhost>
date:      Wed Nov 27 09:16:58 2019 +0000

description:
Add support for PT_[GS]ETXMMREGS requests for COMPAT_NETBSD32 on amd64.

For this purpose, PT_[GS]ETXMMREGS are added to amd64/ptrace.h. These
are intended for internal usage for COMPAT_NETBSD32, and therefore not
exposed to userland.

Thanks to kamil, mgorny, and pgoyette for their kind review!

XXX
pullup to netbsd-9

diffstat:

 sys/arch/amd64/amd64/netbsd32_machdep.c   |  85 +++++++++++++++++++++++++++++-
 sys/arch/amd64/amd64/process_machdep.c    |  16 +++++-
 sys/arch/amd64/include/netbsd32_machdep.h |   9 ++-
 sys/arch/amd64/include/ptrace.h           |  17 +++++-
 4 files changed, 118 insertions(+), 9 deletions(-)

diffs (248 lines):

diff -r d60e60173d51 -r 9ae6774271e3 sys/arch/amd64/amd64/netbsd32_machdep.c
--- a/sys/arch/amd64/amd64/netbsd32_machdep.c   Wed Nov 27 09:08:14 2019 +0000
+++ b/sys/arch/amd64/amd64/netbsd32_machdep.c   Wed Nov 27 09:16:58 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: netbsd32_machdep.c,v 1.131 2019/11/20 19:37:51 pgoyette Exp $  */
+/*     $NetBSD: netbsd32_machdep.c,v 1.132 2019/11/27 09:16:58 rin Exp $       */
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.131 2019/11/20 19:37:51 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.132 2019/11/27 09:16:58 rin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -86,6 +86,9 @@
 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 @@
        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 @@
        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 *)&regs;
+
+       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, &regs.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, &regs.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 @@
        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, "xmm32",
+           netbsd32_process_doxmmregs);
 }
 
 void
@@ -967,4 +1043,5 @@
 
        MODULE_HOOK_UNSET(netbsd32_machine32_hook);
        MODULE_HOOK_UNSET(netbsd32_reg_validate_hook);
+       MODULE_HOOK_UNSET(netbsd32_process_doxmmregs_hook);
 }
diff -r d60e60173d51 -r 9ae6774271e3 sys/arch/amd64/amd64/process_machdep.c
--- a/sys/arch/amd64/amd64/process_machdep.c    Wed Nov 27 09:08:14 2019 +0000
+++ b/sys/arch/amd64/amd64/process_machdep.c    Wed Nov 27 09:16:58 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: process_machdep.c,v 1.46 2019/11/27 09:08:14 rin Exp $ */
+/*     $NetBSD: process_machdep.c,v 1.47 2019/11/27 09:16:58 rin Exp $ */
 
 /*
  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -74,7 +74,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.46 2019/11/27 09:08:14 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.47 2019/11/27 09:16:58 rin Exp $");
 
 #include "opt_xen.h"
 #include <sys/param.h>
@@ -94,6 +94,8 @@
 #include <x86/dbregs.h>
 #include <x86/fpu.h>
 
+struct netbsd32_process_doxmmregs_hook_t netbsd32_process_doxmmregs_hook;
+
 static inline struct trapframe *process_frame(struct lwp *);
 
 static inline struct trapframe *
@@ -358,6 +360,16 @@
                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
diff -r d60e60173d51 -r 9ae6774271e3 sys/arch/amd64/include/netbsd32_machdep.h
--- a/sys/arch/amd64/include/netbsd32_machdep.h Wed Nov 27 09:08:14 2019 +0000
+++ b/sys/arch/amd64/include/netbsd32_machdep.h Wed Nov 27 09:16:58 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: netbsd32_machdep.h,v 1.24 2019/06/26 12:30:12 mgorny Exp $     */
+/*     $NetBSD: netbsd32_machdep.h,v 1.25 2019/11/27 09:16:58 rin Exp $        */
 
 #ifndef _MACHINE_NETBSD32_H_
 #define _MACHINE_NETBSD32_H_
@@ -7,6 +7,8 @@
 #include <compat/sys/ucontext.h>
 #include <compat/sys/siginfo.h>
 
+#include <x86/fpu.h>
+
 /*
  * i386 ptrace constants
  * Please keep in sync with sys/arch/i386/include/ptrace.h.
@@ -136,6 +138,11 @@
        int     dr[8];
 };
 
+struct xmmregs32 {
+       struct fxsave fxstate;
+};
+__CTASSERT(sizeof(struct xmmregs32) == 512);
+
 struct x86_get_ldt_args32 {
        int32_t start;
        uint32_t desc;
diff -r d60e60173d51 -r 9ae6774271e3 sys/arch/amd64/include/ptrace.h
--- a/sys/arch/amd64/include/ptrace.h   Wed Nov 27 09:08:14 2019 +0000
+++ b/sys/arch/amd64/include/ptrace.h   Wed Nov 27 09:16:58 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ptrace.h,v 1.18 2019/11/27 09:08:14 rin Exp $  */
+/*     $NetBSD: ptrace.h,v 1.19 2019/11/27 09:16:58 rin Exp $  */
 
 /*
  * Copyright (c) 1993 Christopher G. Demetriou
@@ -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 used internally 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
@@ -85,11 +92,17 @@
  */
 #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_validfpu(struct proc *);
 
+#include <sys/module_hook.h>
+MODULE_HOOK(netbsd32_process_doxmmregs_hook, int,
+    (struct lwp *, struct lwp *, void *, bool));
+
 #endif /* _KERNEL */
 
 #ifdef _KERNEL_OPT



Home | Main Index | Thread Index | Old Index