Source-Changes-HG archive

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

[src/netbsd-9]: src/sys/sys Pull up following revision(s) (requested by kamil...



details:   https://anonhg.NetBSD.org/src/rev/cf6e99df01fe
branches:  netbsd-9
changeset: 941101:cf6e99df01fe
user:      martin <martin%NetBSD.org@localhost>
date:      Sun Oct 18 18:42:10 2020 +0000

description:
Pull up following revision(s) (requested by kamil in ticket #1117):

        sys/arch/sh3/include/ptrace.h: revision 1.19
        sys/arch/amd64/amd64/process_machdep.c: revision 1.48
        sys/arch/sh3/sh3/process_machdep.c: revision 1.23
        sys/arch/sh3/sh3/process_machdep.c: revision 1.24
        sys/arch/i386/i386/process_machdep.c: revision 1.95
        sys/arch/x86/x86/fpu.c (apply patch)
        sys/kern/sys_ptrace_common.c: revision 1.84
        sys/arch/powerpc/powerpc/process_machdep.c: revision 1.40
        sys/sys/ptrace.h: revision 1.71
        sys/arch/powerpc/powerpc/process_machdep.c: revision 1.41
        (all via patch, adapted)

Fix s87_tw reconstruction to correctly indicate register states

Fix the code reconstructing s87_tw (full tag word) from fx_sw (abridged
tag word) to correctly represent all register states.  The previous code
only distinguished between empty/non-empty registers, and assigned
'regular value' to all non-empty registers.  The new code explicitly
distinguishes the two other tag word values: empty and special.

Fix the machine-dependent ptrace register-related requests (e.g.
PT_GETXMMREGS, PT_GETXSTATE on x86) to correctly respect the LWP number
passed as the data argument.  Before this change, these requests
did not operate on the requested LWP of a multithreaded program.
This change required moving ptrace_update_lwp() out of unit scope,
and changing ptrace_machdep_dorequest() function to take a pointer
to pointer as the second argument, consistently with ptrace_regs().

I am planning to extend the ATF ptrace() register tests in the future
to check for regressions in multithreaded programs, as time permits.

Reviewed by kamil.

Add missing 'error' declaration

diffstat:

 sys/arch/amd64/amd64/process_machdep.c     |   98 ++++++++++++++++++++++++-
 sys/arch/i386/i386/process_machdep.c       |  112 ++++++++++++++++++++++++++++-
 sys/arch/powerpc/powerpc/process_machdep.c |   67 ++++++++++++++++-
 sys/arch/sh3/include/ptrace.h              |    3 +-
 sys/arch/sh3/sh3/process_machdep.c         |   67 ++++++++++++++++-
 sys/arch/x86/x86/fpu.c                     |   32 ++++++--
 sys/kern/sys_ptrace_common.c               |    6 +-
 sys/sys/ptrace.h                           |    5 +-
 8 files changed, 369 insertions(+), 21 deletions(-)

diffs (truncated from 552 to 300 lines):

diff -r 912e84358843 -r cf6e99df01fe sys/arch/amd64/amd64/process_machdep.c
--- a/sys/arch/amd64/amd64/process_machdep.c    Sun Oct 18 18:18:44 2020 +0000
+++ b/sys/arch/amd64/amd64/process_machdep.c    Sun Oct 18 18:42:10 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: process_machdep.c,v 1.43.2.1 2019/08/06 16:14:33 martin Exp $  */
+/*     $NetBSD: process_machdep.c,v 1.43.2.2 2020/10/18 18:42:10 martin 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.43.2.1 2019/08/06 16:14:33 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.43.2.2 2020/10/18 18:42:10 martin Exp $");
 
 #include "opt_xen.h"
 #include <sys/param.h>
@@ -367,6 +367,100 @@
        return 0;
 }
 
+static int
+ptrace_update_lwp2(struct proc *t, struct lwp **lt, lwpid_t lid)
+{
+       if (lid == 0 || lid == (*lt)->l_lid || t->p_nlwps == 1)
+               return 0;
+
+       mutex_enter(t->p_lock);
+       lwp_delref2(*lt);
+
+       *lt = lwp_find(t, lid);
+       if (*lt == NULL) {
+               mutex_exit(t->p_lock);
+               return ESRCH;
+       }
+
+       if ((*lt)->l_flag & LW_SYSTEM) {
+               mutex_exit(t->p_lock);
+               *lt = NULL;
+               return EINVAL;
+       }
+
+       lwp_addref(*lt);
+       mutex_exit(t->p_lock);
+
+       return 0;
+}
+
+int
+ptrace_machdep_dorequest2(
+    struct lwp *l,
+    struct lwp **lt,
+    int req,
+    void *addr,
+    int data
+)
+{
+       struct uio uio;
+       struct iovec iov;
+       struct vmspace *vm;
+       int error;
+       int write = 0;
+
+       switch (req) {
+       case PT_SETXSTATE:
+               write = 1;
+
+               /* FALLTHROUGH */
+       case PT_GETXSTATE:
+               /* write = 0 done above. */
+               if ((error = ptrace_update_lwp2((*lt)->l_proc, lt, data)) != 0)
+                       return error;
+               if (!process_machdep_validxstate((*lt)->l_proc))
+                       return EINVAL;
+               if (__predict_false(l->l_proc->p_flag & PK_32)) {
+                       struct netbsd32_iovec user_iov;
+                       if ((error = copyin(addr, &user_iov, sizeof(user_iov)))
+                           != 0)
+                               return error;
+
+                       iov.iov_base = NETBSD32PTR64(user_iov.iov_base);
+                       iov.iov_len = user_iov.iov_len;
+               } else {
+                       struct iovec user_iov;
+                       if ((error = copyin(addr, &user_iov, sizeof(user_iov)))
+                           != 0)
+                               return error;
+
+                       iov.iov_base = user_iov.iov_base;
+                       iov.iov_len = user_iov.iov_len;
+               }
+
+               error = proc_vmspace_getref(l->l_proc, &vm);
+               if (error)
+                       return error;
+               if (iov.iov_len > sizeof(struct xstate))
+                       iov.iov_len = sizeof(struct xstate);
+               uio.uio_iov = &iov;
+               uio.uio_iovcnt = 1;
+               uio.uio_offset = 0;
+               uio.uio_resid = iov.iov_len;
+               uio.uio_rw = write ? UIO_WRITE : UIO_READ;
+               uio.uio_vmspace = vm;
+               error = process_machdep_doxstate(l, *lt, &uio);
+               uvmspace_free(vm);
+               return error;
+       }
+
+#ifdef DIAGNOSTIC
+       panic("ptrace_machdep: impossible");
+#endif
+
+       return 0;
+}
+
 /*
  * The following functions are used by both ptrace(2) and procfs.
  */
diff -r 912e84358843 -r cf6e99df01fe sys/arch/i386/i386/process_machdep.c
--- a/sys/arch/i386/i386/process_machdep.c      Sun Oct 18 18:18:44 2020 +0000
+++ b/sys/arch/i386/i386/process_machdep.c      Sun Oct 18 18:42:10 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: process_machdep.c,v 1.93.2.1 2019/08/06 16:20:19 martin Exp $  */
+/*     $NetBSD: process_machdep.c,v 1.93.2.2 2020/10/18 18:42:11 martin Exp $  */
 
 /*-
  * Copyright (c) 1998, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -75,7 +75,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.93.2.1 2019/08/06 16:20:19 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.93.2.2 2020/10/18 18:42:11 martin Exp $");
 
 #include "opt_ptrace.h"
 
@@ -347,6 +347,114 @@
        return 0;
 }
 
+static int
+ptrace_update_lwp2(struct proc *t, struct lwp **lt, lwpid_t lid)
+{
+       if (lid == 0 || lid == (*lt)->l_lid || t->p_nlwps == 1)
+               return 0;
+
+       mutex_enter(t->p_lock);
+       lwp_delref2(*lt);
+
+       *lt = lwp_find(t, lid);
+       if (*lt == NULL) {
+               mutex_exit(t->p_lock);
+               return ESRCH;
+       }
+
+       if ((*lt)->l_flag & LW_SYSTEM) {
+               mutex_exit(t->p_lock);
+               *lt = NULL;
+               return EINVAL;
+       }
+
+       lwp_addref(*lt);
+       mutex_exit(t->p_lock);
+
+       return 0;
+}
+
+int
+ptrace_machdep_dorequest2(
+    struct lwp *l,
+    struct lwp **lt,
+    int req,
+    void *addr,
+    int data
+)
+{
+       struct uio uio;
+       struct iovec iov;
+       struct iovec user_iov;
+       struct vmspace *vm;
+       int error;
+       int write = 0;
+
+       switch (req) {
+       case PT_SETXMMREGS:
+               write = 1;
+
+               /* FALLTHROUGH */
+       case PT_GETXMMREGS:
+               /* write = 0 done above. */
+               if ((error = ptrace_update_lwp2((*lt)->l_proc, lt, data)) != 0)
+                       return error;
+               if (!process_machdep_validxmmregs((*lt)->l_proc))
+                       return (EINVAL);
+               error = proc_vmspace_getref(l->l_proc, &vm);
+               if (error) {
+                       return error;
+               }
+               iov.iov_base = addr;
+               iov.iov_len = sizeof(struct xmmregs);
+               uio.uio_iov = &iov;
+               uio.uio_iovcnt = 1;
+               uio.uio_offset = 0;
+               uio.uio_resid = sizeof(struct xmmregs);
+               uio.uio_rw = write ? UIO_WRITE : UIO_READ;
+               uio.uio_vmspace = vm;
+               error = process_machdep_doxmmregs(l, *lt, &uio);
+               uvmspace_free(vm);
+               return error;
+
+       case PT_SETXSTATE:
+               write = 1;
+
+               /* FALLTHROUGH */
+       case PT_GETXSTATE:
+               /* write = 0 done above. */
+               if ((error = ptrace_update_lwp2((*lt)->l_proc, lt, data)) != 0)
+                       return error;
+               if (!process_machdep_validxstate((*lt)->l_proc))
+                       return EINVAL;
+               if ((error = copyin(addr, &user_iov, sizeof(user_iov))) != 0)
+                       return error;
+               error = proc_vmspace_getref(l->l_proc, &vm);
+               if (error) {
+                       return error;
+               }
+               iov.iov_base = user_iov.iov_base;
+               iov.iov_len = user_iov.iov_len;
+               if (iov.iov_len > sizeof(struct xstate))
+                       iov.iov_len = sizeof(struct xstate);
+               uio.uio_iov = &iov;
+               uio.uio_iovcnt = 1;
+               uio.uio_offset = 0;
+               uio.uio_resid = iov.iov_len;
+               uio.uio_rw = write ? UIO_WRITE : UIO_READ;
+               uio.uio_vmspace = vm;
+               error = process_machdep_doxstate(l, *lt, &uio);
+               uvmspace_free(vm);
+               return error;
+       }
+
+#ifdef DIAGNOSTIC
+       panic("ptrace_machdep: impossible");
+#endif
+
+       return 0;
+}
+
 /*
  * The following functions are used by both ptrace(2) and procfs.
  */
diff -r 912e84358843 -r cf6e99df01fe sys/arch/powerpc/powerpc/process_machdep.c
--- a/sys/arch/powerpc/powerpc/process_machdep.c        Sun Oct 18 18:18:44 2020 +0000
+++ b/sys/arch/powerpc/powerpc/process_machdep.c        Sun Oct 18 18:42:10 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: process_machdep.c,v 1.38 2017/03/16 16:13:20 chs Exp $ */
+/*     $NetBSD: process_machdep.c,v 1.38.18.1 2020/10/18 18:42:11 martin Exp $ */
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.38 2017/03/16 16:13:20 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.38.18.1 2020/10/18 18:42:11 martin Exp $");
 
 #include "opt_altivec.h"
 
@@ -219,6 +219,69 @@
        return (0);
 }
 
+static int
+ptrace_update_lwp2(struct proc *t, struct lwp **lt, lwpid_t lid)
+{
+       if (lid == 0 || lid == (*lt)->l_lid || t->p_nlwps == 1)
+               return 0;
+
+       mutex_enter(t->p_lock);
+       lwp_delref2(*lt);
+
+       *lt = lwp_find(t, lid);
+       if (*lt == NULL) {
+               mutex_exit(t->p_lock);
+               return ESRCH;
+       }
+
+       if ((*lt)->l_flag & LW_SYSTEM) {
+               mutex_exit(t->p_lock);
+               *lt = NULL;
+               return EINVAL;
+       }
+
+       lwp_addref(*lt);
+       mutex_exit(t->p_lock);
+
+       return 0;
+}



Home | Main Index | Thread Index | Old Index