From: Greg Kroah-Hartman Date: Mon, 17 Jun 2019 09:29:57 +0000 (+0200) Subject: 5.1-stable patches X-Git-Tag: v5.1.11~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=452f9198525ba6acc47bc0d94730c5772c998873;p=thirdparty%2Fkernel%2Fstable-queue.git 5.1-stable patches added patches: ras-cec-convert-the-timer-callback-to-a-workqueue.patch ras-cec-fix-binary-search-function.patch timekeeping-repair-ktime_get_coarse-granularity.patch tracing-uprobe-fix-null-pointer-dereference-in-trace_uprobe_create.patch --- diff --git a/queue-5.1/ras-cec-convert-the-timer-callback-to-a-workqueue.patch b/queue-5.1/ras-cec-convert-the-timer-callback-to-a-workqueue.patch new file mode 100644 index 00000000000..259ba9e44b6 --- /dev/null +++ b/queue-5.1/ras-cec-convert-the-timer-callback-to-a-workqueue.patch @@ -0,0 +1,142 @@ +From 0ade0b6240c4853cf9725924c46c10f4251639d7 Mon Sep 17 00:00:00 2001 +From: Cong Wang +Date: Tue, 16 Apr 2019 14:33:51 -0700 +Subject: RAS/CEC: Convert the timer callback to a workqueue + +From: Cong Wang + +commit 0ade0b6240c4853cf9725924c46c10f4251639d7 upstream. + +cec_timer_fn() is a timer callback which reads ce_arr.array[] and +updates its decay values. However, it runs in interrupt context and the +mutex protection the CEC uses for that array, is inadequate. Convert the +used timer to a workqueue to keep the tasks the CEC performs preemptible +and thus low-prio. + + [ bp: Rewrite commit message. + s/timer/decay/gi to make it agnostic as to what facility is used. ] + +Fixes: 011d82611172 ("RAS: Add a Corrected Errors Collector") +Signed-off-by: Cong Wang +Signed-off-by: Borislav Petkov +Cc: Thomas Gleixner +Cc: Tony Luck +Cc: linux-edac +Cc: +Link: https://lkml.kernel.org/r/20190416213351.28999-2-xiyou.wangcong@gmail.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ras/cec.c | 46 ++++++++++++++++++++++------------------------ + 1 file changed, 22 insertions(+), 24 deletions(-) + +--- a/drivers/ras/cec.c ++++ b/drivers/ras/cec.c +@@ -2,6 +2,7 @@ + #include + #include + #include ++#include + + #include + +@@ -123,16 +124,12 @@ static u64 dfs_pfn; + /* Amount of errors after which we offline */ + static unsigned int count_threshold = COUNT_MASK; + +-/* +- * The timer "decays" element count each timer_interval which is 24hrs by +- * default. +- */ +- +-#define CEC_TIMER_DEFAULT_INTERVAL 24 * 60 * 60 /* 24 hrs */ +-#define CEC_TIMER_MIN_INTERVAL 1 * 60 * 60 /* 1h */ +-#define CEC_TIMER_MAX_INTERVAL 30 * 24 * 60 * 60 /* one month */ +-static struct timer_list cec_timer; +-static u64 timer_interval = CEC_TIMER_DEFAULT_INTERVAL; ++/* Each element "decays" each decay_interval which is 24hrs by default. */ ++#define CEC_DECAY_DEFAULT_INTERVAL 24 * 60 * 60 /* 24 hrs */ ++#define CEC_DECAY_MIN_INTERVAL 1 * 60 * 60 /* 1h */ ++#define CEC_DECAY_MAX_INTERVAL 30 * 24 * 60 * 60 /* one month */ ++static struct delayed_work cec_work; ++static u64 decay_interval = CEC_DECAY_DEFAULT_INTERVAL; + + /* + * Decrement decay value. We're using DECAY_BITS bits to denote decay of an +@@ -160,20 +157,21 @@ static void do_spring_cleaning(struct ce + /* + * @interval in seconds + */ +-static void cec_mod_timer(struct timer_list *t, unsigned long interval) ++static void cec_mod_work(unsigned long interval) + { + unsigned long iv; + +- iv = interval * HZ + jiffies; +- +- mod_timer(t, round_jiffies(iv)); ++ iv = interval * HZ; ++ mod_delayed_work(system_wq, &cec_work, round_jiffies(iv)); + } + +-static void cec_timer_fn(struct timer_list *unused) ++static void cec_work_fn(struct work_struct *work) + { ++ mutex_lock(&ce_mutex); + do_spring_cleaning(&ce_arr); ++ mutex_unlock(&ce_mutex); + +- cec_mod_timer(&cec_timer, timer_interval); ++ cec_mod_work(decay_interval); + } + + /* +@@ -374,15 +372,15 @@ static int decay_interval_set(void *data + { + *(u64 *)data = val; + +- if (val < CEC_TIMER_MIN_INTERVAL) ++ if (val < CEC_DECAY_MIN_INTERVAL) + return -EINVAL; + +- if (val > CEC_TIMER_MAX_INTERVAL) ++ if (val > CEC_DECAY_MAX_INTERVAL) + return -EINVAL; + +- timer_interval = val; ++ decay_interval = val; + +- cec_mod_timer(&cec_timer, timer_interval); ++ cec_mod_work(decay_interval); + return 0; + } + DEFINE_DEBUGFS_ATTRIBUTE(decay_interval_ops, u64_get, decay_interval_set, "%lld\n"); +@@ -426,7 +424,7 @@ static int array_dump(struct seq_file *m + + seq_printf(m, "Flags: 0x%x\n", ca->flags); + +- seq_printf(m, "Timer interval: %lld seconds\n", timer_interval); ++ seq_printf(m, "Decay interval: %lld seconds\n", decay_interval); + seq_printf(m, "Decays: %lld\n", ca->decays_done); + + seq_printf(m, "Action threshold: %d\n", count_threshold); +@@ -472,7 +470,7 @@ static int __init create_debugfs_nodes(v + } + + decay = debugfs_create_file("decay_interval", S_IRUSR | S_IWUSR, d, +- &timer_interval, &decay_interval_ops); ++ &decay_interval, &decay_interval_ops); + if (!decay) { + pr_warn("Error creating decay_interval debugfs node!\n"); + goto err; +@@ -508,8 +506,8 @@ void __init cec_init(void) + if (create_debugfs_nodes()) + return; + +- timer_setup(&cec_timer, cec_timer_fn, 0); +- cec_mod_timer(&cec_timer, CEC_TIMER_DEFAULT_INTERVAL); ++ INIT_DELAYED_WORK(&cec_work, cec_work_fn); ++ schedule_delayed_work(&cec_work, CEC_DECAY_DEFAULT_INTERVAL); + + pr_info("Correctable Errors collector initialized.\n"); + } diff --git a/queue-5.1/ras-cec-fix-binary-search-function.patch b/queue-5.1/ras-cec-fix-binary-search-function.patch new file mode 100644 index 00000000000..2c4e4170d56 --- /dev/null +++ b/queue-5.1/ras-cec-fix-binary-search-function.patch @@ -0,0 +1,91 @@ +From f3c74b38a55aefe1004200d15a83f109b510068c Mon Sep 17 00:00:00 2001 +From: Borislav Petkov +Date: Sat, 20 Apr 2019 13:27:51 +0200 +Subject: RAS/CEC: Fix binary search function + +From: Borislav Petkov + +commit f3c74b38a55aefe1004200d15a83f109b510068c upstream. + +Switch to using Donald Knuth's binary search algorithm (The Art of +Computer Programming, vol. 3, section 6.2.1). This should've been done +from the very beginning but the author must've been smoking something +very potent at the time. + +The problem with the current one was that it would return the wrong +element index in certain situations: + + https://lkml.kernel.org/r/CAM_iQpVd02zkVJ846cj-Fg1yUNuz6tY5q1Vpj4LrXmE06dPYYg@mail.gmail.com + +and the noodling code after the loop was fishy at best. + +So switch to using Knuth's binary search. The final result is much +cleaner and straightforward. + +Fixes: 011d82611172 ("RAS: Add a Corrected Errors Collector") +Reported-by: Cong Wang +Signed-off-by: Borislav Petkov +Cc: Tony Luck +Cc: linux-edac +Cc: +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ras/cec.c | 34 ++++++++++++++++++++-------------- + 1 file changed, 20 insertions(+), 14 deletions(-) + +--- a/drivers/ras/cec.c ++++ b/drivers/ras/cec.c +@@ -181,32 +181,38 @@ static void cec_work_fn(struct work_stru + */ + static int __find_elem(struct ce_array *ca, u64 pfn, unsigned int *to) + { ++ int min = 0, max = ca->n - 1; + u64 this_pfn; +- int min = 0, max = ca->n; + +- while (min < max) { +- int tmp = (max + min) >> 1; ++ while (min <= max) { ++ int i = (min + max) >> 1; + +- this_pfn = PFN(ca->array[tmp]); ++ this_pfn = PFN(ca->array[i]); + + if (this_pfn < pfn) +- min = tmp + 1; ++ min = i + 1; + else if (this_pfn > pfn) +- max = tmp; +- else { +- min = tmp; +- break; ++ max = i - 1; ++ else if (this_pfn == pfn) { ++ if (to) ++ *to = i; ++ ++ return i; + } + } + ++ /* ++ * When the loop terminates without finding @pfn, min has the index of ++ * the element slot where the new @pfn should be inserted. The loop ++ * terminates when min > max, which means the min index points to the ++ * bigger element while the max index to the smaller element, in-between ++ * which the new @pfn belongs to. ++ * ++ * For more details, see exercise 1, Section 6.2.1 in TAOCP, vol. 3. ++ */ + if (to) + *to = min; + +- this_pfn = PFN(ca->array[min]); +- +- if (this_pfn == pfn) +- return min; +- + return -ENOKEY; + } + diff --git a/queue-5.1/series b/queue-5.1/series index 5311ed195a9..889f34ed76e 100644 --- a/queue-5.1/series +++ b/queue-5.1/series @@ -101,3 +101,7 @@ usb-usb-storage-add-new-id-to-ums-realtek.patch usb-serial-pl2303-add-allied-telesis-vt-kit3.patch usb-serial-option-add-support-for-simcom-sim7500-sim7600-rndis-mode.patch usb-serial-option-add-telit-0x1260-and-0x1261-compositions.patch +tracing-uprobe-fix-null-pointer-dereference-in-trace_uprobe_create.patch +timekeeping-repair-ktime_get_coarse-granularity.patch +ras-cec-convert-the-timer-callback-to-a-workqueue.patch +ras-cec-fix-binary-search-function.patch diff --git a/queue-5.1/timekeeping-repair-ktime_get_coarse-granularity.patch b/queue-5.1/timekeeping-repair-ktime_get_coarse-granularity.patch new file mode 100644 index 00000000000..1ce1b35155a --- /dev/null +++ b/queue-5.1/timekeeping-repair-ktime_get_coarse-granularity.patch @@ -0,0 +1,60 @@ +From e3ff9c3678b4d80e22d2557b68726174578eaf52 Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Thu, 13 Jun 2019 21:40:45 +0200 +Subject: timekeeping: Repair ktime_get_coarse*() granularity + +From: Thomas Gleixner + +commit e3ff9c3678b4d80e22d2557b68726174578eaf52 upstream. + +Jason reported that the coarse ktime based time getters advance only once +per second and not once per tick as advertised. + +The code reads only the monotonic base time, which advances once per +second. The nanoseconds are accumulated on every tick in xtime_nsec up to +a second and the regular time getters take this nanoseconds offset into +account, but the ktime_get_coarse*() implementation fails to do so. + +Add the accumulated xtime_nsec value to the monotonic base time to get the +proper per tick advancing coarse tinme. + +Fixes: b9ff604cff11 ("timekeeping: Add ktime_get_coarse_with_offset") +Reported-by: Jason A. Donenfeld +Signed-off-by: Thomas Gleixner +Tested-by: Jason A. Donenfeld +Cc: Arnd Bergmann +Cc: Peter Zijlstra +Cc: Clemens Ladisch +Cc: Sultan Alsawaf +Cc: Waiman Long +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/alpine.DEB.2.21.1906132136280.1791@nanos.tec.linutronix.de +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/timekeeping.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -807,17 +807,18 @@ ktime_t ktime_get_coarse_with_offset(enu + struct timekeeper *tk = &tk_core.timekeeper; + unsigned int seq; + ktime_t base, *offset = offsets[offs]; ++ u64 nsecs; + + WARN_ON(timekeeping_suspended); + + do { + seq = read_seqcount_begin(&tk_core.seq); + base = ktime_add(tk->tkr_mono.base, *offset); ++ nsecs = tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift; + + } while (read_seqcount_retry(&tk_core.seq, seq)); + +- return base; +- ++ return base + nsecs; + } + EXPORT_SYMBOL_GPL(ktime_get_coarse_with_offset); + diff --git a/queue-5.1/tracing-uprobe-fix-null-pointer-dereference-in-trace_uprobe_create.patch b/queue-5.1/tracing-uprobe-fix-null-pointer-dereference-in-trace_uprobe_create.patch new file mode 100644 index 00000000000..4634794d714 --- /dev/null +++ b/queue-5.1/tracing-uprobe-fix-null-pointer-dereference-in-trace_uprobe_create.patch @@ -0,0 +1,90 @@ +From f01098c74b5219f3969d4750eeed1a36bfc038e3 Mon Sep 17 00:00:00 2001 +From: Eiichi Tsukata +Date: Fri, 14 Jun 2019 16:40:25 +0900 +Subject: tracing/uprobe: Fix NULL pointer dereference in trace_uprobe_create() + +From: Eiichi Tsukata + +commit f01098c74b5219f3969d4750eeed1a36bfc038e3 upstream. + +Just like the case of commit 8b05a3a7503c ("tracing/kprobes: Fix NULL +pointer dereference in trace_kprobe_create()"), writing an incorrectly +formatted string to uprobe_events can trigger NULL pointer dereference. + +Reporeducer: + + # echo r > /sys/kernel/debug/tracing/uprobe_events + +dmesg: + + BUG: kernel NULL pointer dereference, address: 0000000000000000 + #PF: supervisor read access in kernel mode + #PF: error_code(0x0000) - not-present page + PGD 8000000079d12067 P4D 8000000079d12067 PUD 7b7ab067 PMD 0 + Oops: 0000 [#1] PREEMPT SMP PTI + CPU: 0 PID: 1903 Comm: bash Not tainted 5.2.0-rc3+ #15 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-2.fc30 04/01/2014 + RIP: 0010:strchr+0x0/0x30 + Code: c0 eb 0d 84 c9 74 18 48 83 c0 01 48 39 d0 74 0f 0f b6 0c 07 3a 0c 06 74 ea 19 c0 83 c8 01 c3 31 c0 c3 0f 1f 84 00 00 00 00 00 <0f> b6 07 89 f2 40 38 f0 75 0e eb 13 0f b6 47 01 48 83 c + RSP: 0018:ffffb55fc0403d10 EFLAGS: 00010293 + + RAX: ffff993ffb793400 RBX: 0000000000000000 RCX: ffffffffa4852625 + RDX: 0000000000000000 RSI: 000000000000002f RDI: 0000000000000000 + RBP: ffffb55fc0403dd0 R08: ffff993ffb793400 R09: 0000000000000000 + R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 + R13: ffff993ff9cc1668 R14: 0000000000000001 R15: 0000000000000000 + FS: 00007f30c5147700(0000) GS:ffff993ffda00000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000000 CR3: 000000007b628000 CR4: 00000000000006f0 + Call Trace: + trace_uprobe_create+0xe6/0xb10 + ? __kmalloc_track_caller+0xe6/0x1c0 + ? __kmalloc+0xf0/0x1d0 + ? trace_uprobe_create+0xb10/0xb10 + create_or_delete_trace_uprobe+0x35/0x90 + ? trace_uprobe_create+0xb10/0xb10 + trace_run_command+0x9c/0xb0 + trace_parse_run_command+0xf9/0x1eb + ? probes_open+0x80/0x80 + __vfs_write+0x43/0x90 + vfs_write+0x14a/0x2a0 + ksys_write+0xa2/0x170 + do_syscall_64+0x7f/0x200 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +Link: http://lkml.kernel.org/r/20190614074026.8045-1-devel@etsukata.com + +Cc: stable@vger.kernel.org +Fixes: 0597c49c69d5 ("tracing/uprobes: Use dyn_event framework for uprobe events") +Reviewed-by: Srikar Dronamraju +Signed-off-by: Eiichi Tsukata +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/trace_uprobe.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +--- a/kernel/trace/trace_uprobe.c ++++ b/kernel/trace/trace_uprobe.c +@@ -434,10 +434,17 @@ static int trace_uprobe_create(int argc, + ret = 0; + ref_ctr_offset = 0; + +- /* argc must be >= 1 */ +- if (argv[0][0] == 'r') ++ switch (argv[0][0]) { ++ case 'r': + is_return = true; +- else if (argv[0][0] != 'p' || argc < 2) ++ break; ++ case 'p': ++ break; ++ default: ++ return -ECANCELED; ++ } ++ ++ if (argc < 2) + return -ECANCELED; + + if (argv[0][1] == ':')