]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 19 Nov 2021 13:37:28 +0000 (14:37 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 19 Nov 2021 13:37:28 +0000 (14:37 +0100)
added patches:
parisc-entry-fix-trace-test-in-syscall-exit-path.patch
tracing-resize-tgid_map-to-pid_max-not-pid_max_default.patch

queue-4.14/parisc-entry-fix-trace-test-in-syscall-exit-path.patch [new file with mode: 0644]
queue-4.14/series
queue-4.14/tracing-resize-tgid_map-to-pid_max-not-pid_max_default.patch [new file with mode: 0644]

diff --git a/queue-4.14/parisc-entry-fix-trace-test-in-syscall-exit-path.patch b/queue-4.14/parisc-entry-fix-trace-test-in-syscall-exit-path.patch
new file mode 100644 (file)
index 0000000..7365c19
--- /dev/null
@@ -0,0 +1,42 @@
+From 3ec18fc7831e7d79e2d536dd1f3bc0d3ba425e8a Mon Sep 17 00:00:00 2001
+From: Sven Schnelle <svens@stackframe.org>
+Date: Sat, 13 Nov 2021 20:41:17 +0100
+Subject: parisc/entry: fix trace test in syscall exit path
+
+From: Sven Schnelle <svens@stackframe.org>
+
+commit 3ec18fc7831e7d79e2d536dd1f3bc0d3ba425e8a upstream.
+
+commit 8779e05ba8aa ("parisc: Fix ptrace check on syscall return")
+fixed testing of TI_FLAGS. This uncovered a bug in the test mask.
+syscall_restore_rfi is only used when the kernel needs to exit to
+usespace with single or block stepping and the recovery counter
+enabled. The test however used _TIF_SYSCALL_TRACE_MASK, which
+includes a lot of bits that shouldn't be tested here.
+
+Fix this by using TIF_SINGLESTEP and TIF_BLOCKSTEP directly.
+
+I encountered this bug by enabling syscall tracepoints. Both in qemu and
+on real hardware. As soon as i enabled the tracepoint (sys_exit_read,
+but i guess it doesn't really matter which one), i got random page
+faults in userspace almost immediately.
+
+Signed-off-by: Sven Schnelle <svens@stackframe.org>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/parisc/kernel/entry.S |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/parisc/kernel/entry.S
++++ b/arch/parisc/kernel/entry.S
+@@ -1850,7 +1850,7 @@ syscall_restore:
+       /* Are we being ptraced? */
+       LDREG   TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19
+-      ldi     _TIF_SYSCALL_TRACE_MASK,%r2
++      ldi     _TIF_SINGLESTEP|_TIF_BLOCKSTEP,%r2
+       and,COND(=)     %r19,%r2,%r0
+       b,n     syscall_restore_rfi
index 21ff64e50aa157b2e086eee7870e637eb0982c93..31df114f2aa57b224a778e9e4ff5b99efdbbd831 100644 (file)
@@ -196,3 +196,5 @@ mm-oom-do-not-trigger-out_of_memory-from-the-pf.patch
 s390-cio-check-the-subchannel-validity-for-dev_busid.patch
 pci-add-pci_exp_devctl_payload_-macros.patch
 ext4-fix-lazy-initialization-next-schedule-time-computation-in-more-granular-unit.patch
+tracing-resize-tgid_map-to-pid_max-not-pid_max_default.patch
+parisc-entry-fix-trace-test-in-syscall-exit-path.patch
diff --git a/queue-4.14/tracing-resize-tgid_map-to-pid_max-not-pid_max_default.patch b/queue-4.14/tracing-resize-tgid_map-to-pid_max-not-pid_max_default.patch
new file mode 100644 (file)
index 0000000..2774cf5
--- /dev/null
@@ -0,0 +1,176 @@
+From 4030a6e6a6a4a42ff8c18414c9e0c93e24cc70b8 Mon Sep 17 00:00:00 2001
+From: Paul Burton <paulburton@google.com>
+Date: Thu, 1 Jul 2021 10:24:07 -0700
+Subject: tracing: Resize tgid_map to pid_max, not PID_MAX_DEFAULT
+
+From: Paul Burton <paulburton@google.com>
+
+commit 4030a6e6a6a4a42ff8c18414c9e0c93e24cc70b8 upstream.
+
+Currently tgid_map is sized at PID_MAX_DEFAULT entries, which means that
+on systems where pid_max is configured higher than PID_MAX_DEFAULT the
+ftrace record-tgid option doesn't work so well. Any tasks with PIDs
+higher than PID_MAX_DEFAULT are simply not recorded in tgid_map, and
+don't show up in the saved_tgids file.
+
+In particular since systemd v243 & above configure pid_max to its
+highest possible 1<<22 value by default on 64 bit systems this renders
+the record-tgids option of little use.
+
+Increase the size of tgid_map to the configured pid_max instead,
+allowing it to cover the full range of PIDs up to the maximum value of
+PID_MAX_LIMIT if the system is configured that way.
+
+On 64 bit systems with pid_max == PID_MAX_LIMIT this will increase the
+size of tgid_map from 256KiB to 16MiB. Whilst this 64x increase in
+memory overhead sounds significant 64 bit systems are presumably best
+placed to accommodate it, and since tgid_map is only allocated when the
+record-tgid option is actually used presumably the user would rather it
+spends sufficient memory to actually record the tgids they expect.
+
+The size of tgid_map could also increase for CONFIG_BASE_SMALL=y
+configurations, but these seem unlikely to be systems upon which people
+are both configuring a large pid_max and running ftrace with record-tgid
+anyway.
+
+Of note is that we only allocate tgid_map once, the first time that the
+record-tgid option is enabled. Therefore its size is only set once, to
+the value of pid_max at the time the record-tgid option is first
+enabled. If a user increases pid_max after that point, the saved_tgids
+file will not contain entries for any tasks with pids beyond the earlier
+value of pid_max.
+
+Link: https://lkml.kernel.org/r/20210701172407.889626-2-paulburton@google.com
+
+Fixes: d914ba37d714 ("tracing: Add support for recording tgid of tasks")
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Joel Fernandes <joelaf@google.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Paul Burton <paulburton@google.com>
+[ Fixed comment coding style ]
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/trace/trace.c |   62 ++++++++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 47 insertions(+), 15 deletions(-)
+
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -1723,8 +1723,15 @@ void tracing_reset_all_online_cpus(void)
+       }
+ }
++/*
++ * The tgid_map array maps from pid to tgid; i.e. the value stored at index i
++ * is the tgid last observed corresponding to pid=i.
++ */
+ static int *tgid_map;
++/* The maximum valid index into tgid_map. */
++static size_t tgid_map_max;
++
+ #define SAVED_CMDLINES_DEFAULT 128
+ #define NO_CMDLINE_MAP UINT_MAX
+ static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;
+@@ -1996,24 +2003,41 @@ void trace_find_cmdline(int pid, char co
+       preempt_enable();
+ }
++static int *trace_find_tgid_ptr(int pid)
++{
++      /*
++       * Pairs with the smp_store_release in set_tracer_flag() to ensure that
++       * if we observe a non-NULL tgid_map then we also observe the correct
++       * tgid_map_max.
++       */
++      int *map = smp_load_acquire(&tgid_map);
++
++      if (unlikely(!map || pid > tgid_map_max))
++              return NULL;
++
++      return &map[pid];
++}
++
+ int trace_find_tgid(int pid)
+ {
+-      if (unlikely(!tgid_map || !pid || pid > PID_MAX_DEFAULT))
+-              return 0;
++      int *ptr = trace_find_tgid_ptr(pid);
+-      return tgid_map[pid];
++      return ptr ? *ptr : 0;
+ }
+ static int trace_save_tgid(struct task_struct *tsk)
+ {
++      int *ptr;
++
+       /* treat recording of idle task as a success */
+       if (!tsk->pid)
+               return 1;
+-      if (unlikely(!tgid_map || tsk->pid > PID_MAX_DEFAULT))
++      ptr = trace_find_tgid_ptr(tsk->pid);
++      if (!ptr)
+               return 0;
+-      tgid_map[tsk->pid] = tsk->tgid;
++      *ptr = tsk->tgid;
+       return 1;
+ }
+@@ -4353,6 +4377,8 @@ int trace_keep_overwrite(struct tracer *
+ int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled)
+ {
++      int *map;
++
+       if ((mask == TRACE_ITER_RECORD_TGID) ||
+           (mask == TRACE_ITER_RECORD_CMD))
+               lockdep_assert_held(&event_mutex);
+@@ -4375,9 +4401,19 @@ int set_tracer_flag(struct trace_array *
+               trace_event_enable_cmd_record(enabled);
+       if (mask == TRACE_ITER_RECORD_TGID) {
+-              if (!tgid_map)
+-                      tgid_map = kzalloc((PID_MAX_DEFAULT + 1) * sizeof(*tgid_map),
+-                                         GFP_KERNEL);
++              if (!tgid_map) {
++                      tgid_map_max = pid_max;
++                      map = kzalloc((tgid_map_max + 1) * sizeof(*tgid_map),
++                                    GFP_KERNEL);
++
++                      /*
++                       * Pairs with smp_load_acquire() in
++                       * trace_find_tgid_ptr() to ensure that if it observes
++                       * the tgid_map we just allocated then it also observes
++                       * the corresponding tgid_map_max value.
++                       */
++                      smp_store_release(&tgid_map, map);
++              }
+               if (!tgid_map) {
+                       tr->trace_flags &= ~TRACE_ITER_RECORD_TGID;
+                       return -ENOMEM;
+@@ -4752,18 +4788,14 @@ static void *saved_tgids_next(struct seq
+ {
+       int pid = ++(*pos);
+-      if (pid > PID_MAX_DEFAULT)
+-              return NULL;
+-
+-      return &tgid_map[pid];
++      return trace_find_tgid_ptr(pid);
+ }
+ static void *saved_tgids_start(struct seq_file *m, loff_t *pos)
+ {
+-      if (!tgid_map || *pos > PID_MAX_DEFAULT)
+-              return NULL;
++      int pid = *pos;
+-      return &tgid_map[*pos];
++      return trace_find_tgid_ptr(pid);
+ }
+ static void saved_tgids_stop(struct seq_file *m, void *v)