From: Greg Kroah-Hartman Date: Tue, 4 Jun 2019 12:20:22 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v5.1.8~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=37ddba7016891507e0557d46e8602f99b16fa6b9;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: cifs-cifs_read_allocate_pages-don-t-iterate-through-whole-page-array-on-enomem.patch drm-nouveau-i2c-disable-i2c-bus-access-after-fini.patch kernel-signal.c-trace_signal_deliver-when-signal_group_exit.patch memcg-make-it-work-on-sparse-non-0-node-systems.patch tty-max310x-fix-external-crystal-register-setup.patch tty-serial-msm_serial-fix-xon-xoff.patch --- diff --git a/queue-4.4/cifs-cifs_read_allocate_pages-don-t-iterate-through-whole-page-array-on-enomem.patch b/queue-4.4/cifs-cifs_read_allocate_pages-don-t-iterate-through-whole-page-array-on-enomem.patch new file mode 100644 index 00000000000..c0dfa1fc663 --- /dev/null +++ b/queue-4.4/cifs-cifs_read_allocate_pages-don-t-iterate-through-whole-page-array-on-enomem.patch @@ -0,0 +1,37 @@ +From 31fad7d41e73731f05b8053d17078638cf850fa6 Mon Sep 17 00:00:00 2001 +From: Roberto Bergantinos Corpas +Date: Tue, 28 May 2019 09:38:14 +0200 +Subject: CIFS: cifs_read_allocate_pages: don't iterate through whole page array on ENOMEM + +From: Roberto Bergantinos Corpas + +commit 31fad7d41e73731f05b8053d17078638cf850fa6 upstream. + + In cifs_read_allocate_pages, in case of ENOMEM, we go through +whole rdata->pages array but we have failed the allocation before +nr_pages, therefore we may end up calling put_page with NULL +pointer, causing oops + +Signed-off-by: Roberto Bergantinos Corpas +Acked-by: Pavel Shilovsky +Signed-off-by: Steve French +CC: Stable +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/file.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/fs/cifs/file.c ++++ b/fs/cifs/file.c +@@ -2829,7 +2829,9 @@ cifs_read_allocate_pages(struct cifs_rea + } + + if (rc) { +- for (i = 0; i < nr_pages; i++) { ++ unsigned int nr_page_failed = i; ++ ++ for (i = 0; i < nr_page_failed; i++) { + put_page(rdata->pages[i]); + rdata->pages[i] = NULL; + } diff --git a/queue-4.4/drm-nouveau-i2c-disable-i2c-bus-access-after-fini.patch b/queue-4.4/drm-nouveau-i2c-disable-i2c-bus-access-after-fini.patch new file mode 100644 index 00000000000..9fedd6b56e5 --- /dev/null +++ b/queue-4.4/drm-nouveau-i2c-disable-i2c-bus-access-after-fini.patch @@ -0,0 +1,265 @@ +From 342406e4fbba9a174125fbfe6aeac3d64ef90f76 Mon Sep 17 00:00:00 2001 +From: Lyude Paul +Date: Tue, 9 Apr 2019 16:23:30 -0400 +Subject: drm/nouveau/i2c: Disable i2c bus access after ->fini() + +From: Lyude Paul + +commit 342406e4fbba9a174125fbfe6aeac3d64ef90f76 upstream. + +For a while, we've had the problem of i2c bus access not grabbing +a runtime PM ref when it's being used in userspace by i2c-dev, resulting +in nouveau spamming the kernel log with errors if anything attempts to +access the i2c bus while the GPU is in runtime suspend. An example: + +[ 130.078386] nouveau 0000:01:00.0: i2c: aux 000d: begin idle timeout ffffffff + +Since the GPU is in runtime suspend, the MMIO region that the i2c bus is +on isn't accessible. On x86, the standard behavior for accessing an +unavailable MMIO region is to just return ~0. + +Except, that turned out to be a lie. While computers with a clean +concious will return ~0 in this scenario, some machines will actually +completely hang a CPU on certian bad MMIO accesses. This was witnessed +with someone's Lenovo ThinkPad P50, where sensors-detect attempting to +access the i2c bus while the GPU was suspended would result in a CPU +hang: + + CPU: 5 PID: 12438 Comm: sensors-detect Not tainted 5.0.0-0.rc4.git3.1.fc30.x86_64 #1 + Hardware name: LENOVO 20EQS64N17/20EQS64N17, BIOS N1EET74W (1.47 ) 11/21/2017 + RIP: 0010:ioread32+0x2b/0x30 + Code: 81 ff ff ff 03 00 77 20 48 81 ff 00 00 01 00 76 05 0f b7 d7 ed c3 + 48 c7 c6 e1 0c 36 96 e8 2d ff ff ff b8 ff ff ff ff c3 8b 07 0f 1f + 40 00 49 89 f0 48 81 fe ff ff 03 00 76 04 40 88 3e c3 48 + RSP: 0018:ffffaac3c5007b48 EFLAGS: 00000292 ORIG_RAX: ffffffffffffff13 + RAX: 0000000001111000 RBX: 0000000001111000 RCX: 0000043017a97186 + RDX: 0000000000000aaa RSI: 0000000000000005 RDI: ffffaac3c400e4e4 + RBP: ffff9e6443902c00 R08: ffffaac3c400e4e4 R09: ffffaac3c5007be7 + R10: 0000000000000004 R11: 0000000000000001 R12: ffff9e6445dd0000 + R13: 000000000000e4e4 R14: 00000000000003c4 R15: 0000000000000000 + FS: 00007f253155a740(0000) GS:ffff9e644f600000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 00005630d1500358 CR3: 0000000417c44006 CR4: 00000000003606e0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + Call Trace: + g94_i2c_aux_xfer+0x326/0x850 [nouveau] + nvkm_i2c_aux_i2c_xfer+0x9e/0x140 [nouveau] + __i2c_transfer+0x14b/0x620 + i2c_smbus_xfer_emulated+0x159/0x680 + ? _raw_spin_unlock_irqrestore+0x1/0x60 + ? rt_mutex_slowlock.constprop.0+0x13d/0x1e0 + ? __lock_is_held+0x59/0xa0 + __i2c_smbus_xfer+0x138/0x5a0 + i2c_smbus_xfer+0x4f/0x80 + i2cdev_ioctl_smbus+0x162/0x2d0 [i2c_dev] + i2cdev_ioctl+0x1db/0x2c0 [i2c_dev] + do_vfs_ioctl+0x408/0x750 + ksys_ioctl+0x5e/0x90 + __x64_sys_ioctl+0x16/0x20 + do_syscall_64+0x60/0x1e0 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + RIP: 0033:0x7f25317f546b + Code: 0f 1e fa 48 8b 05 1d da 0c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff + ff ff c3 66 0f 1f 44 00 00 f3 0f 1e fa b8 10 00 00 00 0f 05 <48> 3d 01 + f0 ff ff 73 01 c3 48 8b 0d ed d9 0c 00 f7 d8 64 89 01 48 + RSP: 002b:00007ffc88caab68 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 + RAX: ffffffffffffffda RBX: 00005630d0fe7260 RCX: 00007f25317f546b + RDX: 00005630d1598e80 RSI: 0000000000000720 RDI: 0000000000000003 + RBP: 00005630d155b968 R08: 0000000000000001 R09: 00005630d15a1da0 + R10: 0000000000000070 R11: 0000000000000246 R12: 00005630d1598e80 + R13: 00005630d12f3d28 R14: 0000000000000720 R15: 00005630d12f3ce0 + watchdog: BUG: soft lockup - CPU#5 stuck for 23s! [sensors-detect:12438] + +Yikes! While I wanted to try to make it so that accessing an i2c bus on +nouveau would wake up the GPU as needed, airlied pointed out that pretty +much any usecase for userspace accessing an i2c bus on a GPU (mainly for +the DDC brightness control that some displays have) is going to only be +useful while there's at least one display enabled on the GPU anyway, and +the GPU never sleeps while there's displays running. + +Since teaching the i2c bus to wake up the GPU on userspace accesses is a +good deal more difficult than it might seem, mostly due to the fact that +we have to use the i2c bus during runtime resume of the GPU, we instead +opt for the easiest solution: don't let userspace access i2c busses on +the GPU at all while it's in runtime suspend. + +Changes since v1: +* Also disable i2c busses that run over DP AUX + +Signed-off-by: Lyude Paul +Cc: stable@vger.kernel.org +Signed-off-by: Ben Skeggs +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h | 2 + + drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c | 26 +++++++++++++++++++++- + drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h | 2 + + drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c | 15 ++++++++++++ + drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c | 21 ++++++++++++++++- + drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h | 1 + 6 files changed, 65 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h ++++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h +@@ -37,6 +37,7 @@ struct nvkm_i2c_bus { + struct mutex mutex; + struct list_head head; + struct i2c_adapter i2c; ++ u8 enabled; + }; + + int nvkm_i2c_bus_acquire(struct nvkm_i2c_bus *); +@@ -56,6 +57,7 @@ struct nvkm_i2c_aux { + struct mutex mutex; + struct list_head head; + struct i2c_adapter i2c; ++ u8 enabled; + + u32 intr; + }; +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c +@@ -105,9 +105,15 @@ nvkm_i2c_aux_acquire(struct nvkm_i2c_aux + { + struct nvkm_i2c_pad *pad = aux->pad; + int ret; ++ + AUX_TRACE(aux, "acquire"); + mutex_lock(&aux->mutex); +- ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_AUX); ++ ++ if (aux->enabled) ++ ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_AUX); ++ else ++ ret = -EIO; ++ + if (ret) + mutex_unlock(&aux->mutex); + return ret; +@@ -141,6 +147,24 @@ nvkm_i2c_aux_del(struct nvkm_i2c_aux **p + } + } + ++void ++nvkm_i2c_aux_init(struct nvkm_i2c_aux *aux) ++{ ++ AUX_TRACE(aux, "init"); ++ mutex_lock(&aux->mutex); ++ aux->enabled = true; ++ mutex_unlock(&aux->mutex); ++} ++ ++void ++nvkm_i2c_aux_fini(struct nvkm_i2c_aux *aux) ++{ ++ AUX_TRACE(aux, "fini"); ++ mutex_lock(&aux->mutex); ++ aux->enabled = false; ++ mutex_unlock(&aux->mutex); ++} ++ + int + nvkm_i2c_aux_ctor(const struct nvkm_i2c_aux_func *func, + struct nvkm_i2c_pad *pad, int id, +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h +@@ -14,6 +14,8 @@ int nvkm_i2c_aux_ctor(const struct nvkm_ + int nvkm_i2c_aux_new_(const struct nvkm_i2c_aux_func *, struct nvkm_i2c_pad *, + int id, struct nvkm_i2c_aux **); + void nvkm_i2c_aux_del(struct nvkm_i2c_aux **); ++void nvkm_i2c_aux_init(struct nvkm_i2c_aux *); ++void nvkm_i2c_aux_fini(struct nvkm_i2c_aux *); + int nvkm_i2c_aux_xfer(struct nvkm_i2c_aux *, bool retry, u8 type, + u32 addr, u8 *data, u8 size); + +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c +@@ -160,8 +160,18 @@ nvkm_i2c_fini(struct nvkm_subdev *subdev + { + struct nvkm_i2c *i2c = nvkm_i2c(subdev); + struct nvkm_i2c_pad *pad; ++ struct nvkm_i2c_bus *bus; ++ struct nvkm_i2c_aux *aux; + u32 mask; + ++ list_for_each_entry(aux, &i2c->aux, head) { ++ nvkm_i2c_aux_fini(aux); ++ } ++ ++ list_for_each_entry(bus, &i2c->bus, head) { ++ nvkm_i2c_bus_fini(bus); ++ } ++ + if ((mask = (1 << i2c->func->aux) - 1), i2c->func->aux_stat) { + i2c->func->aux_mask(i2c, NVKM_I2C_ANY, mask, 0); + i2c->func->aux_stat(i2c, &mask, &mask, &mask, &mask); +@@ -180,6 +190,7 @@ nvkm_i2c_init(struct nvkm_subdev *subdev + struct nvkm_i2c *i2c = nvkm_i2c(subdev); + struct nvkm_i2c_bus *bus; + struct nvkm_i2c_pad *pad; ++ struct nvkm_i2c_aux *aux; + + list_for_each_entry(pad, &i2c->pad, head) { + nvkm_i2c_pad_init(pad); +@@ -189,6 +200,10 @@ nvkm_i2c_init(struct nvkm_subdev *subdev + nvkm_i2c_bus_init(bus); + } + ++ list_for_each_entry(aux, &i2c->aux, head) { ++ nvkm_i2c_aux_init(aux); ++ } ++ + return 0; + } + +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c +@@ -110,6 +110,19 @@ nvkm_i2c_bus_init(struct nvkm_i2c_bus *b + BUS_TRACE(bus, "init"); + if (bus->func->init) + bus->func->init(bus); ++ ++ mutex_lock(&bus->mutex); ++ bus->enabled = true; ++ mutex_unlock(&bus->mutex); ++} ++ ++void ++nvkm_i2c_bus_fini(struct nvkm_i2c_bus *bus) ++{ ++ BUS_TRACE(bus, "fini"); ++ mutex_lock(&bus->mutex); ++ bus->enabled = false; ++ mutex_unlock(&bus->mutex); + } + + void +@@ -126,9 +139,15 @@ nvkm_i2c_bus_acquire(struct nvkm_i2c_bus + { + struct nvkm_i2c_pad *pad = bus->pad; + int ret; ++ + BUS_TRACE(bus, "acquire"); + mutex_lock(&bus->mutex); +- ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_I2C); ++ ++ if (bus->enabled) ++ ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_I2C); ++ else ++ ret = -EIO; ++ + if (ret) + mutex_unlock(&bus->mutex); + return ret; +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h +@@ -17,6 +17,7 @@ int nvkm_i2c_bus_new_(const struct nvkm_ + int id, struct nvkm_i2c_bus **); + void nvkm_i2c_bus_del(struct nvkm_i2c_bus **); + void nvkm_i2c_bus_init(struct nvkm_i2c_bus *); ++void nvkm_i2c_bus_fini(struct nvkm_i2c_bus *); + + int nvkm_i2c_bit_xfer(struct nvkm_i2c_bus *, struct i2c_msg *, int); + diff --git a/queue-4.4/kernel-signal.c-trace_signal_deliver-when-signal_group_exit.patch b/queue-4.4/kernel-signal.c-trace_signal_deliver-when-signal_group_exit.patch new file mode 100644 index 00000000000..1af54edc353 --- /dev/null +++ b/queue-4.4/kernel-signal.c-trace_signal_deliver-when-signal_group_exit.patch @@ -0,0 +1,50 @@ +From 98af37d624ed8c83f1953b1b6b2f6866011fc064 Mon Sep 17 00:00:00 2001 +From: Zhenliang Wei +Date: Fri, 31 May 2019 22:30:52 -0700 +Subject: kernel/signal.c: trace_signal_deliver when signal_group_exit + +From: Zhenliang Wei + +commit 98af37d624ed8c83f1953b1b6b2f6866011fc064 upstream. + +In the fixes commit, removing SIGKILL from each thread signal mask and +executing "goto fatal" directly will skip the call to +"trace_signal_deliver". At this point, the delivery tracking of the +SIGKILL signal will be inaccurate. + +Therefore, we need to add trace_signal_deliver before "goto fatal" after +executing sigdelset. + +Note: SEND_SIG_NOINFO matches the fact that SIGKILL doesn't have any info. + +Link: http://lkml.kernel.org/r/20190425025812.91424-1-weizhenliang@huawei.com +Fixes: cf43a757fd4944 ("signal: Restore the stop PTRACE_EVENT_EXIT") +Signed-off-by: Zhenliang Wei +Reviewed-by: Christian Brauner +Reviewed-by: Oleg Nesterov +Cc: Eric W. Biederman +Cc: Ivan Delalande +Cc: Arnd Bergmann +Cc: Thomas Gleixner +Cc: Deepa Dinamani +Cc: Greg Kroah-Hartman +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/signal.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -2244,6 +2244,8 @@ relock: + if (signal_group_exit(signal)) { + ksig->info.si_signo = signr = SIGKILL; + sigdelset(¤t->pending.signal, SIGKILL); ++ trace_signal_deliver(SIGKILL, SEND_SIG_NOINFO, ++ &sighand->action[SIGKILL - 1]); + recalc_sigpending(); + goto fatal; + } diff --git a/queue-4.4/memcg-make-it-work-on-sparse-non-0-node-systems.patch b/queue-4.4/memcg-make-it-work-on-sparse-non-0-node-systems.patch new file mode 100644 index 00000000000..2de063788be --- /dev/null +++ b/queue-4.4/memcg-make-it-work-on-sparse-non-0-node-systems.patch @@ -0,0 +1,97 @@ +From 3e8589963773a5c23e2f1fe4bcad0e9a90b7f471 Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Fri, 31 May 2019 22:30:26 -0700 +Subject: memcg: make it work on sparse non-0-node systems + +From: Jiri Slaby + +commit 3e8589963773a5c23e2f1fe4bcad0e9a90b7f471 upstream. + +We have a single node system with node 0 disabled: + Scanning NUMA topology in Northbridge 24 + Number of physical nodes 2 + Skipping disabled node 0 + Node 1 MemBase 0000000000000000 Limit 00000000fbff0000 + NODE_DATA(1) allocated [mem 0xfbfda000-0xfbfeffff] + +This causes crashes in memcg when system boots: + BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 + #PF error: [normal kernel read fault] +... + RIP: 0010:list_lru_add+0x94/0x170 +... + Call Trace: + d_lru_add+0x44/0x50 + dput.part.34+0xfc/0x110 + __fput+0x108/0x230 + task_work_run+0x9f/0xc0 + exit_to_usermode_loop+0xf5/0x100 + +It is reproducible as far as 4.12. I did not try older kernels. You have +to have a new enough systemd, e.g. 241 (the reason is unknown -- was not +investigated). Cannot be reproduced with systemd 234. + +The system crashes because the size of lru array is never updated in +memcg_update_all_list_lrus and the reads are past the zero-sized array, +causing dereferences of random memory. + +The root cause are list_lru_memcg_aware checks in the list_lru code. The +test in list_lru_memcg_aware is broken: it assumes node 0 is always +present, but it is not true on some systems as can be seen above. + +So fix this by avoiding checks on node 0. Remember the memcg-awareness by +a bool flag in struct list_lru. + +Link: http://lkml.kernel.org/r/20190522091940.3615-1-jslaby@suse.cz +Fixes: 60d3fd32a7a9 ("list_lru: introduce per-memcg lists") +Signed-off-by: Jiri Slaby +Acked-by: Michal Hocko +Suggested-by: Vladimir Davydov +Acked-by: Vladimir Davydov +Reviewed-by: Shakeel Butt +Cc: Johannes Weiner +Cc: Raghavendra K T +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/list_lru.h | 1 + + mm/list_lru.c | 8 +++----- + 2 files changed, 4 insertions(+), 5 deletions(-) + +--- a/include/linux/list_lru.h ++++ b/include/linux/list_lru.h +@@ -51,6 +51,7 @@ struct list_lru { + struct list_lru_node *node; + #ifdef CONFIG_MEMCG_KMEM + struct list_head list; ++ bool memcg_aware; + #endif + }; + +--- a/mm/list_lru.c ++++ b/mm/list_lru.c +@@ -42,11 +42,7 @@ static void list_lru_unregister(struct l + #ifdef CONFIG_MEMCG_KMEM + static inline bool list_lru_memcg_aware(struct list_lru *lru) + { +- /* +- * This needs node 0 to be always present, even +- * in the systems supporting sparse numa ids. +- */ +- return !!lru->node[0].memcg_lrus; ++ return lru->memcg_aware; + } + + static inline struct list_lru_one * +@@ -389,6 +385,8 @@ static int memcg_init_list_lru(struct li + { + int i; + ++ lru->memcg_aware = memcg_aware; ++ + if (!memcg_aware) + return 0; + diff --git a/queue-4.4/series b/queue-4.4/series index 4859c0d3ced..5e070196cbe 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -205,3 +205,9 @@ scsi-zfcp-fix-missing-zfcp_port-reference-put-on-ebusy-from-port_remove.patch scsi-zfcp-fix-to-prevent-port_remove-with-pure-auto-scan-luns-only-sdevs.patch btrfs-fix-race-updating-log-root-item-during-fsync.patch alsa-hda-realtek-set-default-power-save-node-to-0.patch +drm-nouveau-i2c-disable-i2c-bus-access-after-fini.patch +tty-serial-msm_serial-fix-xon-xoff.patch +tty-max310x-fix-external-crystal-register-setup.patch +memcg-make-it-work-on-sparse-non-0-node-systems.patch +kernel-signal.c-trace_signal_deliver-when-signal_group_exit.patch +cifs-cifs_read_allocate_pages-don-t-iterate-through-whole-page-array-on-enomem.patch diff --git a/queue-4.4/tty-max310x-fix-external-crystal-register-setup.patch b/queue-4.4/tty-max310x-fix-external-crystal-register-setup.patch new file mode 100644 index 00000000000..7af7d5d5c79 --- /dev/null +++ b/queue-4.4/tty-max310x-fix-external-crystal-register-setup.patch @@ -0,0 +1,42 @@ +From 5d24f455c182d5116dd5db8e1dc501115ecc9c2c Mon Sep 17 00:00:00 2001 +From: Joe Burmeister +Date: Mon, 13 May 2019 11:23:57 +0100 +Subject: tty: max310x: Fix external crystal register setup + +From: Joe Burmeister + +commit 5d24f455c182d5116dd5db8e1dc501115ecc9c2c upstream. + +The datasheet states: + + Bit 4: ClockEnSet the ClockEn bit high to enable an external clocking +(crystal or clock generator at XIN). Set the ClockEn bit to 0 to disable +clocking + Bit 1: CrystalEnSet the CrystalEn bit high to enable the crystal +oscillator. When using an external clock source at XIN, CrystalEn must +be set low. + +The bit 4, MAX310X_CLKSRC_EXTCLK_BIT, should be set and was not. + +This was required to make the MAX3107 with an external crystal on our +board able to send or receive data. + +Signed-off-by: Joe Burmeister +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/max310x.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/tty/serial/max310x.c ++++ b/drivers/tty/serial/max310x.c +@@ -571,7 +571,7 @@ static int max310x_set_ref_clk(struct ma + } + + /* Configure clock source */ +- clksrc = xtal ? MAX310X_CLKSRC_CRYST_BIT : MAX310X_CLKSRC_EXTCLK_BIT; ++ clksrc = MAX310X_CLKSRC_EXTCLK_BIT | (xtal ? MAX310X_CLKSRC_CRYST_BIT : 0); + + /* Configure PLL */ + if (pllcfg) { diff --git a/queue-4.4/tty-serial-msm_serial-fix-xon-xoff.patch b/queue-4.4/tty-serial-msm_serial-fix-xon-xoff.patch new file mode 100644 index 00000000000..e05a983eaa8 --- /dev/null +++ b/queue-4.4/tty-serial-msm_serial-fix-xon-xoff.patch @@ -0,0 +1,53 @@ +From 61c0e37950b88bad590056286c1d766b1f167f4e Mon Sep 17 00:00:00 2001 +From: Jorge Ramirez-Ortiz +Date: Mon, 20 May 2019 20:38:48 +0200 +Subject: tty: serial: msm_serial: Fix XON/XOFF + +From: Jorge Ramirez-Ortiz + +commit 61c0e37950b88bad590056286c1d766b1f167f4e upstream. + +When the tty layer requests the uart to throttle, the current code +executing in msm_serial will trigger "Bad mode in Error Handler" and +generate an invalid stack frame in pstore before rebooting (that is if +pstore is indeed configured: otherwise the user shall just notice a +reboot with no further information dumped to the console). + +This patch replaces the PIO byte accessor with the word accessor +already used in PIO mode. + +Fixes: 68252424a7c7 ("tty: serial: msm: Support big-endian CPUs") +Cc: stable@vger.kernel.org +Signed-off-by: Jorge Ramirez-Ortiz +Reviewed-by: Bjorn Andersson +Reviewed-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/msm_serial.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/tty/serial/msm_serial.c ++++ b/drivers/tty/serial/msm_serial.c +@@ -703,6 +703,7 @@ static void msm_handle_tx(struct uart_po + struct circ_buf *xmit = &msm_port->uart.state->xmit; + struct msm_dma *dma = &msm_port->tx_dma; + unsigned int pio_count, dma_count, dma_min; ++ char buf[4] = { 0 }; + void __iomem *tf; + int err = 0; + +@@ -712,10 +713,12 @@ static void msm_handle_tx(struct uart_po + else + tf = port->membase + UART_TF; + ++ buf[0] = port->x_char; ++ + if (msm_port->is_uartdm) + msm_reset_dm_count(port, 1); + +- iowrite8_rep(tf, &port->x_char, 1); ++ iowrite32_rep(tf, buf, 1); + port->icount.tx++; + port->x_char = 0; + return;