From: Greg Kroah-Hartman Date: Sun, 18 Jun 2017 01:23:11 +0000 (+0800) Subject: 4.4-stable patches X-Git-Tag: v4.11.7~29 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=757f2e8e57ca4f716cc140672b0c48196e851a4c;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: mm-memory-failure.c-use-compound_head-flags-for-huge-pages.patch swap-cond_resched-in-swap_cgroup_prepare.patch usb-gadgetfs-dummy-hcd-net2280-fix-locking-for-callbacks.patch usb-xhci-asmedia-asm1042a-chipset-need-shorts-tx-quirk.patch --- diff --git a/queue-4.4/mm-memory-failure.c-use-compound_head-flags-for-huge-pages.patch b/queue-4.4/mm-memory-failure.c-use-compound_head-flags-for-huge-pages.patch new file mode 100644 index 00000000000..ef6b97688cd --- /dev/null +++ b/queue-4.4/mm-memory-failure.c-use-compound_head-flags-for-huge-pages.patch @@ -0,0 +1,54 @@ +From 7258ae5c5a2ce2f5969e8b18b881be40ab55433d Mon Sep 17 00:00:00 2001 +From: James Morse +Date: Fri, 16 Jun 2017 14:02:29 -0700 +Subject: mm/memory-failure.c: use compound_head() flags for huge pages + +From: James Morse + +commit 7258ae5c5a2ce2f5969e8b18b881be40ab55433d upstream. + +memory_failure() chooses a recovery action function based on the page +flags. For huge pages it uses the tail page flags which don't have +anything interesting set, resulting in: + +> Memory failure: 0x9be3b4: Unknown page state +> Memory failure: 0x9be3b4: recovery action for unknown page: Failed + +Instead, save a copy of the head page's flags if this is a huge page, +this means if there are no relevant flags for this tail page, we use the +head pages flags instead. This results in the me_huge_page() recovery +action being called: + +> Memory failure: 0x9b7969: recovery action for huge page: Delayed + +For hugepages that have not yet been allocated, this allows the hugepage +to be dequeued. + +Fixes: 524fca1e7356 ("HWPOISON: fix misjudgement of page_action() for errors on mlocked pages") +Link: http://lkml.kernel.org/r/20170524130204.21845-1-james.morse@arm.com +Signed-off-by: James Morse +Tested-by: Punit Agrawal +Acked-by: Punit Agrawal +Acked-by: Naoya Horiguchi +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/memory-failure.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/mm/memory-failure.c ++++ b/mm/memory-failure.c +@@ -1208,7 +1208,10 @@ int memory_failure(unsigned long pfn, in + * page_remove_rmap() in try_to_unmap_one(). So to determine page status + * correctly, we save a copy of the page flags at this time. + */ +- page_flags = p->flags; ++ if (PageHuge(p)) ++ page_flags = hpage->flags; ++ else ++ page_flags = p->flags; + + /* + * unpoison always clear PG_hwpoison inside page lock diff --git a/queue-4.4/series b/queue-4.4/series index 4c3e09c2f5c..0a832497a1e 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -18,3 +18,7 @@ usb-gadget-dummy_hcd-fix-hub-descriptor-removable-fields.patch usb-r8a66597-hcd-select-a-different-endpoint-on-timeout.patch usb-r8a66597-hcd-decrease-timeout.patch drivers-misc-c2port-c2port-duramar2150.c-checking-for-null-instead-of-is_err.patch +usb-xhci-asmedia-asm1042a-chipset-need-shorts-tx-quirk.patch +usb-gadgetfs-dummy-hcd-net2280-fix-locking-for-callbacks.patch +mm-memory-failure.c-use-compound_head-flags-for-huge-pages.patch +swap-cond_resched-in-swap_cgroup_prepare.patch diff --git a/queue-4.4/swap-cond_resched-in-swap_cgroup_prepare.patch b/queue-4.4/swap-cond_resched-in-swap_cgroup_prepare.patch new file mode 100644 index 00000000000..7309390b043 --- /dev/null +++ b/queue-4.4/swap-cond_resched-in-swap_cgroup_prepare.patch @@ -0,0 +1,40 @@ +From ef70762948dde012146926720b70e79736336764 Mon Sep 17 00:00:00 2001 +From: Yu Zhao +Date: Fri, 16 Jun 2017 14:02:31 -0700 +Subject: swap: cond_resched in swap_cgroup_prepare() + +From: Yu Zhao + +commit ef70762948dde012146926720b70e79736336764 upstream. + +I saw need_resched() warnings when swapping on large swapfile (TBs) +because continuously allocating many pages in swap_cgroup_prepare() took +too long. + +We already cond_resched when freeing page in swap_cgroup_swapoff(). Do +the same for the page allocation. + +Link: http://lkml.kernel.org/r/20170604200109.17606-1-yuzhao@google.com +Signed-off-by: Yu Zhao +Acked-by: Michal Hocko +Acked-by: Vladimir Davydov +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/swap_cgroup.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/mm/swap_cgroup.c ++++ b/mm/swap_cgroup.c +@@ -48,6 +48,9 @@ static int swap_cgroup_prepare(int type) + if (!page) + goto not_enough_page; + ctrl->map[idx] = page; ++ ++ if (!(idx % SWAP_CLUSTER_MAX)) ++ cond_resched(); + } + return 0; + not_enough_page: diff --git a/queue-4.4/usb-gadgetfs-dummy-hcd-net2280-fix-locking-for-callbacks.patch b/queue-4.4/usb-gadgetfs-dummy-hcd-net2280-fix-locking-for-callbacks.patch new file mode 100644 index 00000000000..800e24a249f --- /dev/null +++ b/queue-4.4/usb-gadgetfs-dummy-hcd-net2280-fix-locking-for-callbacks.patch @@ -0,0 +1,262 @@ +From f16443a034c7aa359ddf6f0f9bc40d01ca31faea Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 13 Jun 2017 15:23:42 -0400 +Subject: USB: gadgetfs, dummy-hcd, net2280: fix locking for callbacks + +From: Alan Stern + +commit f16443a034c7aa359ddf6f0f9bc40d01ca31faea upstream. + +Using the syzkaller kernel fuzzer, Andrey Konovalov generated the +following error in gadgetfs: + +> BUG: KASAN: use-after-free in __lock_acquire+0x3069/0x3690 +> kernel/locking/lockdep.c:3246 +> Read of size 8 at addr ffff88003a2bdaf8 by task kworker/3:1/903 +> +> CPU: 3 PID: 903 Comm: kworker/3:1 Not tainted 4.12.0-rc4+ #35 +> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 +> Workqueue: usb_hub_wq hub_event +> Call Trace: +> __dump_stack lib/dump_stack.c:16 [inline] +> dump_stack+0x292/0x395 lib/dump_stack.c:52 +> print_address_description+0x78/0x280 mm/kasan/report.c:252 +> kasan_report_error mm/kasan/report.c:351 [inline] +> kasan_report+0x230/0x340 mm/kasan/report.c:408 +> __asan_report_load8_noabort+0x19/0x20 mm/kasan/report.c:429 +> __lock_acquire+0x3069/0x3690 kernel/locking/lockdep.c:3246 +> lock_acquire+0x22d/0x560 kernel/locking/lockdep.c:3855 +> __raw_spin_lock include/linux/spinlock_api_smp.h:142 [inline] +> _raw_spin_lock+0x2f/0x40 kernel/locking/spinlock.c:151 +> spin_lock include/linux/spinlock.h:299 [inline] +> gadgetfs_suspend+0x89/0x130 drivers/usb/gadget/legacy/inode.c:1682 +> set_link_state+0x88e/0xae0 drivers/usb/gadget/udc/dummy_hcd.c:455 +> dummy_hub_control+0xd7e/0x1fb0 drivers/usb/gadget/udc/dummy_hcd.c:2074 +> rh_call_control drivers/usb/core/hcd.c:689 [inline] +> rh_urb_enqueue drivers/usb/core/hcd.c:846 [inline] +> usb_hcd_submit_urb+0x92f/0x20b0 drivers/usb/core/hcd.c:1650 +> usb_submit_urb+0x8b2/0x12c0 drivers/usb/core/urb.c:542 +> usb_start_wait_urb+0x148/0x5b0 drivers/usb/core/message.c:56 +> usb_internal_control_msg drivers/usb/core/message.c:100 [inline] +> usb_control_msg+0x341/0x4d0 drivers/usb/core/message.c:151 +> usb_clear_port_feature+0x74/0xa0 drivers/usb/core/hub.c:412 +> hub_port_disable+0x123/0x510 drivers/usb/core/hub.c:4177 +> hub_port_init+0x1ed/0x2940 drivers/usb/core/hub.c:4648 +> hub_port_connect drivers/usb/core/hub.c:4826 [inline] +> hub_port_connect_change drivers/usb/core/hub.c:4999 [inline] +> port_event drivers/usb/core/hub.c:5105 [inline] +> hub_event+0x1ae1/0x3d40 drivers/usb/core/hub.c:5185 +> process_one_work+0xc08/0x1bd0 kernel/workqueue.c:2097 +> process_scheduled_works kernel/workqueue.c:2157 [inline] +> worker_thread+0xb2b/0x1860 kernel/workqueue.c:2233 +> kthread+0x363/0x440 kernel/kthread.c:231 +> ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:424 +> +> Allocated by task 9958: +> save_stack_trace+0x1b/0x20 arch/x86/kernel/stacktrace.c:59 +> save_stack+0x43/0xd0 mm/kasan/kasan.c:513 +> set_track mm/kasan/kasan.c:525 [inline] +> kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:617 +> kmem_cache_alloc_trace+0x87/0x280 mm/slub.c:2745 +> kmalloc include/linux/slab.h:492 [inline] +> kzalloc include/linux/slab.h:665 [inline] +> dev_new drivers/usb/gadget/legacy/inode.c:170 [inline] +> gadgetfs_fill_super+0x24f/0x540 drivers/usb/gadget/legacy/inode.c:1993 +> mount_single+0xf6/0x160 fs/super.c:1192 +> gadgetfs_mount+0x31/0x40 drivers/usb/gadget/legacy/inode.c:2019 +> mount_fs+0x9c/0x2d0 fs/super.c:1223 +> vfs_kern_mount.part.25+0xcb/0x490 fs/namespace.c:976 +> vfs_kern_mount fs/namespace.c:2509 [inline] +> do_new_mount fs/namespace.c:2512 [inline] +> do_mount+0x41b/0x2d90 fs/namespace.c:2834 +> SYSC_mount fs/namespace.c:3050 [inline] +> SyS_mount+0xb0/0x120 fs/namespace.c:3027 +> entry_SYSCALL_64_fastpath+0x1f/0xbe +> +> Freed by task 9960: +> save_stack_trace+0x1b/0x20 arch/x86/kernel/stacktrace.c:59 +> save_stack+0x43/0xd0 mm/kasan/kasan.c:513 +> set_track mm/kasan/kasan.c:525 [inline] +> kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:590 +> slab_free_hook mm/slub.c:1357 [inline] +> slab_free_freelist_hook mm/slub.c:1379 [inline] +> slab_free mm/slub.c:2961 [inline] +> kfree+0xed/0x2b0 mm/slub.c:3882 +> put_dev+0x124/0x160 drivers/usb/gadget/legacy/inode.c:163 +> gadgetfs_kill_sb+0x33/0x60 drivers/usb/gadget/legacy/inode.c:2027 +> deactivate_locked_super+0x8d/0xd0 fs/super.c:309 +> deactivate_super+0x21e/0x310 fs/super.c:340 +> cleanup_mnt+0xb7/0x150 fs/namespace.c:1112 +> __cleanup_mnt+0x1b/0x20 fs/namespace.c:1119 +> task_work_run+0x1a0/0x280 kernel/task_work.c:116 +> exit_task_work include/linux/task_work.h:21 [inline] +> do_exit+0x18a8/0x2820 kernel/exit.c:878 +> do_group_exit+0x14e/0x420 kernel/exit.c:982 +> get_signal+0x784/0x1780 kernel/signal.c:2318 +> do_signal+0xd7/0x2130 arch/x86/kernel/signal.c:808 +> exit_to_usermode_loop+0x1ac/0x240 arch/x86/entry/common.c:157 +> prepare_exit_to_usermode arch/x86/entry/common.c:194 [inline] +> syscall_return_slowpath+0x3ba/0x410 arch/x86/entry/common.c:263 +> entry_SYSCALL_64_fastpath+0xbc/0xbe +> +> The buggy address belongs to the object at ffff88003a2bdae0 +> which belongs to the cache kmalloc-1024 of size 1024 +> The buggy address is located 24 bytes inside of +> 1024-byte region [ffff88003a2bdae0, ffff88003a2bdee0) +> The buggy address belongs to the page: +> page:ffffea0000e8ae00 count:1 mapcount:0 mapping: (null) +> index:0x0 compound_mapcount: 0 +> flags: 0x100000000008100(slab|head) +> raw: 0100000000008100 0000000000000000 0000000000000000 0000000100170017 +> raw: ffffea0000ed3020 ffffea0000f5f820 ffff88003e80efc0 0000000000000000 +> page dumped because: kasan: bad access detected +> +> Memory state around the buggy address: +> ffff88003a2bd980: fb fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +> ffff88003a2bda00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +> >ffff88003a2bda80: fc fc fc fc fc fc fc fc fc fc fc fc fb fb fb fb +> ^ +> ffff88003a2bdb00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb +> ffff88003a2bdb80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb +> ================================================================== + +What this means is that the gadgetfs_suspend() routine was trying to +access dev->lock after it had been deallocated. The root cause is a +race in the dummy_hcd driver; the dummy_udc_stop() routine can race +with the rest of the driver because it contains no locking. And even +when proper locking is added, it can still race with the +set_link_state() function because that function incorrectly drops the +private spinlock before invoking any gadget driver callbacks. + +The result of this race, as seen above, is that set_link_state() can +invoke a callback in gadgetfs even after gadgetfs has been unbound +from dummy_hcd's UDC and its private data structures have been +deallocated. + +include/linux/usb/gadget.h documents that the ->reset, ->disconnect, +->suspend, and ->resume callbacks may be invoked in interrupt context. +In general this is necessary, to prevent races with gadget driver +removal. This patch fixes dummy_hcd to retain the spinlock across +these calls, and it adds a spinlock acquisition to dummy_udc_stop() to +prevent the race. + +The net2280 driver makes the same mistake of dropping the private +spinlock for its ->disconnect and ->reset callback invocations. The +patch fixes it too. + +Lastly, since gadgetfs_suspend() may be invoked in interrupt context, +it cannot assume that interrupts are enabled when it runs. It must +use spin_lock_irqsave() instead of spin_lock_irq(). The patch fixes +that bug as well. + +Signed-off-by: Alan Stern +Reported-and-tested-by: Andrey Konovalov +Acked-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/legacy/inode.c | 5 +++-- + drivers/usb/gadget/udc/dummy_hcd.c | 13 ++++--------- + drivers/usb/gadget/udc/net2280.c | 9 +-------- + 3 files changed, 8 insertions(+), 19 deletions(-) + +--- a/drivers/usb/gadget/legacy/inode.c ++++ b/drivers/usb/gadget/legacy/inode.c +@@ -1676,9 +1676,10 @@ static void + gadgetfs_suspend (struct usb_gadget *gadget) + { + struct dev_data *dev = get_gadget_data (gadget); ++ unsigned long flags; + + INFO (dev, "suspended from state %d\n", dev->state); +- spin_lock (&dev->lock); ++ spin_lock_irqsave(&dev->lock, flags); + switch (dev->state) { + case STATE_DEV_SETUP: // VERY odd... host died?? + case STATE_DEV_CONNECTED: +@@ -1689,7 +1690,7 @@ gadgetfs_suspend (struct usb_gadget *gad + default: + break; + } +- spin_unlock (&dev->lock); ++ spin_unlock_irqrestore(&dev->lock, flags); + } + + static struct usb_gadget_driver gadgetfs_driver = { +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -442,23 +442,16 @@ static void set_link_state(struct dummy_ + /* Report reset and disconnect events to the driver */ + if (dum->driver && (disconnect || reset)) { + stop_activity(dum); +- spin_unlock(&dum->lock); + if (reset) + usb_gadget_udc_reset(&dum->gadget, dum->driver); + else + dum->driver->disconnect(&dum->gadget); +- spin_lock(&dum->lock); + } + } else if (dum_hcd->active != dum_hcd->old_active) { +- if (dum_hcd->old_active && dum->driver->suspend) { +- spin_unlock(&dum->lock); ++ if (dum_hcd->old_active && dum->driver->suspend) + dum->driver->suspend(&dum->gadget); +- spin_lock(&dum->lock); +- } else if (!dum_hcd->old_active && dum->driver->resume) { +- spin_unlock(&dum->lock); ++ else if (!dum_hcd->old_active && dum->driver->resume) + dum->driver->resume(&dum->gadget); +- spin_lock(&dum->lock); +- } + } + + dum_hcd->old_status = dum_hcd->port_status; +@@ -985,7 +978,9 @@ static int dummy_udc_stop(struct usb_gad + struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); + struct dummy *dum = dum_hcd->dum; + ++ spin_lock_irq(&dum->lock); + dum->driver = NULL; ++ spin_unlock_irq(&dum->lock); + + return 0; + } +--- a/drivers/usb/gadget/udc/net2280.c ++++ b/drivers/usb/gadget/udc/net2280.c +@@ -2425,11 +2425,8 @@ static void stop_activity(struct net2280 + nuke(&dev->ep[i]); + + /* report disconnect; the driver is already quiesced */ +- if (driver) { +- spin_unlock(&dev->lock); ++ if (driver) + driver->disconnect(&dev->gadget); +- spin_lock(&dev->lock); +- } + + usb_reinit(dev); + } +@@ -3275,8 +3272,6 @@ next_endpoints: + BIT(PCI_RETRY_ABORT_INTERRUPT)) + + static void handle_stat1_irqs(struct net2280 *dev, u32 stat) +-__releases(dev->lock) +-__acquires(dev->lock) + { + struct net2280_ep *ep; + u32 tmp, num, mask, scratch; +@@ -3317,14 +3312,12 @@ __acquires(dev->lock) + if (disconnect || reset) { + stop_activity(dev, dev->driver); + ep0_start(dev); +- spin_unlock(&dev->lock); + if (reset) + usb_gadget_udc_reset + (&dev->gadget, dev->driver); + else + (dev->driver->disconnect) + (&dev->gadget); +- spin_lock(&dev->lock); + return; + } + } diff --git a/queue-4.4/usb-xhci-asmedia-asm1042a-chipset-need-shorts-tx-quirk.patch b/queue-4.4/usb-xhci-asmedia-asm1042a-chipset-need-shorts-tx-quirk.patch new file mode 100644 index 00000000000..4a6322bf9d0 --- /dev/null +++ b/queue-4.4/usb-xhci-asmedia-asm1042a-chipset-need-shorts-tx-quirk.patch @@ -0,0 +1,35 @@ +From d2f48f05cd2a2a0a708fbfa45f1a00a87660d937 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Fri, 9 Jun 2017 14:48:41 +0300 +Subject: usb: xhci: ASMedia ASM1042A chipset need shorts TX quirk + +From: Corentin Labbe + +commit d2f48f05cd2a2a0a708fbfa45f1a00a87660d937 upstream. + +When plugging an USB webcam I see the following message: +[106385.615559] xhci_hcd 0000:04:00.0: WARN Successful completion on short TX: needs XHCI_TRUST_TX_LENGTH quirk? +[106390.583860] handle_tx_event: 913 callbacks suppressed + +With this patch applied, I get no more printing of this message. + +Signed-off-by: Corentin Labbe +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-pci.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -198,6 +198,9 @@ static void xhci_pci_quirks(struct devic + if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && + pdev->device == 0x1042) + xhci->quirks |= XHCI_BROKEN_STREAMS; ++ if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && ++ pdev->device == 0x1142) ++ xhci->quirks |= XHCI_TRUST_TX_LENGTH; + + if (xhci->quirks & XHCI_RESET_ON_RESUME) + xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,