goto err_context;
        }
  
-               err = mutex_lock_interruptible(&task->signal->exec_update_mutex);
 +      if (task) {
-                * We must hold exec_update_mutex across this and any potential
++              err = down_read_interruptible(&task->signal->exec_update_lock);
 +              if (err)
 +                      goto err_file;
 +
 +              /*
 +               * Preserve ptrace permission check for backwards compatibility.
 +               *
++               * We must hold exec_update_lock across this and any potential
 +               * perf_install_in_context() call for this new event to
 +               * serialize against exec() altering our credentials (and the
 +               * perf_event_exit_task() that could imply).
 +               */
 +              err = -EACCES;
 +              if (!perfmon_capable() && !ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS))
 +                      goto err_cred;
 +      }
 +
        if (move_group) {
                gctx = __perf_event_ctx_lock_double(group_leader, ctx);
  
        if (move_group)
                perf_event_ctx_unlock(group_leader, gctx);
        mutex_unlock(&ctx->mutex);
 -/* err_file: */
 +err_cred:
 +      if (task)
-               mutex_unlock(&task->signal->exec_update_mutex);
++              up_read(&task->signal->exec_update_lock);
 +err_file:
        fput(event_file);
  err_context:
        perf_unpin_context(ctx);