From: Greg Kroah-Hartman Date: Fri, 19 Nov 2021 13:37:28 +0000 (+0100) Subject: 4.14-stable patches X-Git-Tag: v5.4.161~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0a98fa3092f73ab037b31b35a77e90f2fb9ef534;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: parisc-entry-fix-trace-test-in-syscall-exit-path.patch tracing-resize-tgid_map-to-pid_max-not-pid_max_default.patch --- 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 index 00000000000..7365c19a0e9 --- /dev/null +++ b/queue-4.14/parisc-entry-fix-trace-test-in-syscall-exit-path.patch @@ -0,0 +1,42 @@ +From 3ec18fc7831e7d79e2d536dd1f3bc0d3ba425e8a Mon Sep 17 00:00:00 2001 +From: Sven Schnelle +Date: Sat, 13 Nov 2021 20:41:17 +0100 +Subject: parisc/entry: fix trace test in syscall exit path + +From: Sven Schnelle + +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 +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + diff --git a/queue-4.14/series b/queue-4.14/series index 21ff64e50aa..31df114f2aa 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -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 index 00000000000..2774cf5878f --- /dev/null +++ b/queue-4.14/tracing-resize-tgid_map-to-pid_max-not-pid_max_default.patch @@ -0,0 +1,176 @@ +From 4030a6e6a6a4a42ff8c18414c9e0c93e24cc70b8 Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Thu, 1 Jul 2021 10:24:07 -0700 +Subject: tracing: Resize tgid_map to pid_max, not PID_MAX_DEFAULT + +From: Paul Burton + +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 +Cc: Joel Fernandes +Cc: +Signed-off-by: Paul Burton +[ Fixed comment coding style ] +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + 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)