]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
FreeBSD only: fix 445743
authorPaul Floyd <pjfloyd@wanadoo.fr>
Sun, 25 Dec 2022 09:18:51 +0000 (10:18 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Sun, 25 Dec 2022 09:18:51 +0000 (10:18 +0100)
Restart 3 of the umtx_op mutex operations if they are interrupted.

coregrind/m_signals.c
coregrind/m_syswrap/priv_types_n_macros.h
coregrind/m_syswrap/syswrap-freebsd.c
coregrind/m_syswrap/syswrap-main.c
coregrind/pub_core_syswrap.h

index bfddbe392a1b4ee34e2ce9b067035033d939b880..b3c94fcc90d825c1950e0aa04404104c92d2450d 100644 (file)
@@ -2604,7 +2604,7 @@ void async_signalhandler ( Int sigNo,
       tid, 
       VG_UCONTEXT_INSTR_PTR(uc), 
       sres,  
-      !!(scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART),
+      !!(scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART) || VG_(is_in_kernel_restart_syscall)(tid),
       uc
    );
 
index 3966cfa604f6aac8ae6fbfcee3d5be1f42add0c7..461019ad7b9f38afa13f65105af6a11b8b5bdadd 100644 (file)
@@ -185,6 +185,7 @@ typedef
 #define SfPollAfter     (1 << 3) /* poll for signals on completion    */
 #define SfYieldAfter    (1 << 4) /* yield on completion               */
 #define SfNoWriteResult (1 << 5) /* don't write result to guest state */
+#define SfKernelRestart (1 << 6) /* needs a manual restart            */
 
 
 /* ---------------------------------------------------------------------
index 53d09f89f0427b0deef2a5b4c590c42ad41e6fd6..71443e399b7775afd1c3ede62c6123c7cc771556 100644 (file)
@@ -4253,8 +4253,9 @@ PRE(sys__umtx_op)
                     struct umtx *, obj, int, op, unsigned long, id,
                     size_t, timeout_size, struct vki_timespec *, timeout);
       PRE_MEM_READ( "_umtx_op_lock(mtx)", ARG1, sizeof(struct vki_umtx) );
-      if (ARG5)
+      if (ARG5) {
          PRE_MEM_READ( "_umtx_op_lock(timespec)", ARG5, ARG4 );
+      }
       PRE_MEM_WRITE( "_umtx_op_lock(mtx)", ARG1, sizeof(struct vki_umtx) );
       *flags |= SfMayBlock;
       break;
@@ -4279,6 +4280,8 @@ PRE(sys__umtx_op)
 
       if (ARG5) {
          PRE_MEM_READ( "_umtx_op_wait(timeout)", ARG5, ARG4 );
+      } else {
+         *flags |= SfKernelRestart;
       }
 
       break;
@@ -4294,9 +4297,11 @@ PRE(sys__umtx_op)
                     struct umutex *, obj, int, op, unsigned long, noid,
                     size_t, timeout_size, struct vki_timespec *, timeout);
       PRE_MEM_READ( "_umtx_op_mutex_trylock(mutex)", ARG1, sizeof(struct vki_umutex) );
-      if (ARG5)
+      if (ARG5) {
          PRE_MEM_READ( "_umtx_op_mutex_trylock(timespec)", ARG5, ARG4 );
+      }
       PRE_MEM_WRITE( "_umtx_op_mutex_trylock(mutex)", ARG1, sizeof(struct vki_umutex) );
+      *flags |= SfMayBlock | SfKernelRestart;
       break;
    case VKI_UMTX_OP_MUTEX_LOCK:
       PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, MUTEX_LOCK, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
@@ -4304,10 +4309,11 @@ PRE(sys__umtx_op)
                     struct umutex *, obj, int, op, unsigned long, noid,
                     size_t, timeout_size, struct vki_timespec *, timeout);
       PRE_MEM_READ( "_umtx_op_mutex_lock(mutex)", ARG1, sizeof(struct vki_umutex) );
-      if (ARG5)
+      if (ARG5) {
          PRE_MEM_READ( "_umtx_op_mutex_lock(timespec)", ARG5, ARG4 );
+      }
       PRE_MEM_WRITE( "_umtx_op_mutex_lock(mutex)", ARG1, sizeof(struct vki_umutex) );
-      *flags |= SfMayBlock;
+      *flags |= SfMayBlock | SfKernelRestart;
       break;
    case VKI_UMTX_OP_MUTEX_UNLOCK:
       PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, MUTEX_UNLOCK)", ARG1);
@@ -4323,8 +4329,9 @@ PRE(sys__umtx_op)
                     unsigned int *, old_ceiling);
       PRE_MEM_READ( "_umtx_op_set_ceiling(mutex)", ARG1, sizeof(struct vki_umutex) );
       PRE_MEM_WRITE( "_umtx_op_set_ceiling(mutex)", ARG1, sizeof(struct vki_umutex) );
-      if (ARG4)
+      if (ARG4) {
          PRE_MEM_WRITE( "_umtx_op_set_ceiling(old_ceiling)", ARG4, sizeof(vki_uint32_t) );
+      }
       break;
    case VKI_UMTX_OP_CV_WAIT:
       PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, CV_WAIT, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
@@ -4335,8 +4342,9 @@ PRE(sys__umtx_op)
       PRE_MEM_WRITE( "_umtx_op_cv_wait(cond)", ARG1, sizeof(struct vki_ucond) );
       PRE_MEM_READ( "_umtx_op_cv_wait(mutex)", ARG4, sizeof(struct vki_umutex) );
       PRE_MEM_WRITE( "_umtx_op_cv_wait(mutex)", ARG4, sizeof(struct vki_umutex) );
-      if (ARG5)
+      if (ARG5) {
          PRE_MEM_READ( "_umtx_op_cv_wait(timespec)", ARG5, sizeof(struct vki_timespec) );
+      }
       *flags |= SfMayBlock;
       break;
    case VKI_UMTX_OP_CV_SIGNAL:
@@ -4359,8 +4367,9 @@ PRE(sys__umtx_op)
                     int *, obj, int, op, unsigned long, id,
                     size_t, timeout_wait, struct vki_timespec *, timeout);
       PRE_MEM_READ( "_umtx_op_wait(uint)", ARG1, sizeof(int) );
-      if (ARG5)
+      if (ARG5) {
          PRE_MEM_READ( "_umtx_op_wait(timespec)", ARG5, ARG4 );
+      }
       *flags |= SfMayBlock;
       break;
    case VKI_UMTX_OP_RW_RDLOCK:
@@ -4394,8 +4403,9 @@ PRE(sys__umtx_op)
                     int *, obj, int, op, unsigned long, id,
                     size_t, timeout_size, struct vki_timespec *, timeout);
       PRE_MEM_READ( "_umtx_op_wait_private(uint)", ARG1, sizeof(int) );
-      if (ARG5)
+      if (ARG5) {
          PRE_MEM_READ( "_umtx_op_wait_private(umtx_time)", ARG5, ARG4 );
+      }
       *flags |= SfMayBlock;
       break;
    case VKI_UMTX_OP_WAKE_PRIVATE:
@@ -4426,8 +4436,9 @@ PRE(sys__umtx_op)
                     size_t, timeout_size, struct vki_timespec *, timeout);
       PRE_MEM_READ( "_umtx_op_sem_wait(usem)", ARG1, sizeof(struct vki_usem) );
       PRE_MEM_WRITE( "_umtx_op_sem_wait(usem)", ARG1, sizeof(struct vki_usem) );
-      if (ARG5)
+      if (ARG5) {
          PRE_MEM_READ( "_umtx_op_sem_wait(umtx_time)", ARG5, ARG4 );
+      }
       *flags |= SfMayBlock;
       break;
    case VKI_UMTX_OP_SEM_WAKE:
@@ -4474,8 +4485,9 @@ PRE(sys__umtx_op)
    case VKI_UMTX_OP_ROBUST_LISTS:
       // val (ARG2) ought to be the same as sizeof(struct vki_umtx_robust_lists_params)
       // then the structure contains a pointer to mutex structures
-      if (ARG1 != sizeof(struct vki_umtx_robust_lists_params))
+      if (ARG1 != sizeof(struct vki_umtx_robust_lists_params)) {
          SET_STATUS_Failure( VKI_ENOSYS );
+      }
       PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, ROBUST_LISTS, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG3, ARG4, ARG5);
       PRE_REG_READ3(long, "_umtx_op_robust_lists",
                     struct umtx_robust_lists_params *, obj, int, op, unsigned long, flags);
index 5077a7da73f706cbbd2ff7b6b050596bdc2b518f..abd8472e925af4dd1e148bcb8dd79ca076db74ce 100644 (file)
@@ -2000,6 +2000,12 @@ Bool VG_(is_in_syscall) ( ThreadId tid )
    return (syscallInfo && syscallInfo[tid].status.what != SsIdle);
 }
 
+Bool VG_(is_in_kernel_restart_syscall) ( ThreadId tid )
+{
+   vg_assert(tid >= 0 && tid < VG_N_THREADS);
+   return (syscallInfo && ((syscallInfo[tid].flags & SfKernelRestart) != 0));
+}
+
 Word VG_(is_in_syscall_no) (ThreadId tid )
 {
    vg_assert(tid >= 0 && tid < VG_N_THREADS);
@@ -2302,7 +2308,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc )
 
       /* Check that the given flags are allowable: MayBlock, PollAfter
          and PostOnFail are ok. */
-      vg_assert(0 == (sci->flags & ~(SfMayBlock | SfPostOnFail | SfPollAfter)));
+      vg_assert(0 == (sci->flags & ~(SfMayBlock | SfPostOnFail | SfPollAfter | SfKernelRestart)));
 
       if (sci->flags & SfMayBlock) {
 
index a17620afc2576ce91968fb42dd005a4cd4053d31..0b40b501d6d62e94f759fce1a899f1852cfface1 100644 (file)
@@ -52,6 +52,8 @@ extern void VG_(clear_syscallInfo) ( ThreadId tid );
 // Returns True if the given thread is currently in a system call
 extern Bool VG_(is_in_syscall) ( ThreadId tid );
 
+extern Bool VG_(is_in_kernel_restart_syscall) ( ThreadId tid );
+
 // If VG_(is_in_syscall) (tid), returns the sysno the given thread is in
 extern Word VG_(is_in_syscall_no) (ThreadId tid );