diff options
author | Paul Gortmaker <paul.gortmaker@windriver.com> | 2017-10-30 22:36:55 -0400 |
---|---|---|
committer | Paul Gortmaker <paul.gortmaker@windriver.com> | 2017-10-30 22:36:55 -0400 |
commit | 1bfade240c583d5e787f1d48ca93848b1a3cf176 (patch) | |
tree | 8d7f7f13c8fcf823941e9fcf439e142d6838a405 | |
parent | c34ba8c52db7eb258ad369ed013038c52f60f25c (diff) | |
download | longterm-queue-4.8-1bfade240c583d5e787f1d48ca93848b1a3cf176.tar.gz |
raw import of mainline commits used in 4.9.25 --> 4.9.29
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
265 files changed, 19002 insertions, 0 deletions
diff --git a/queue/8250_pci-Fix-potential-use-after-free-in-error-path.patch b/queue/8250_pci-Fix-potential-use-after-free-in-error-path.patch new file mode 100644 index 0000000..6a7ca16 --- /dev/null +++ b/queue/8250_pci-Fix-potential-use-after-free-in-error-path.patch @@ -0,0 +1,56 @@ +From c130b666a9a711f985a0a44b58699ebe14bb7245 Mon Sep 17 00:00:00 2001 +From: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com> +Date: Wed, 28 Dec 2016 16:42:00 -0200 +Subject: [PATCH] 8250_pci: Fix potential use-after-free in error path + +commit c130b666a9a711f985a0a44b58699ebe14bb7245 upstream. + +Commit f209fa03fc9d ("serial: 8250_pci: Detach low-level driver during +PCI error recovery") introduces a potential use-after-free in case the +pciserial_init_ports call in serial8250_io_resume fails, which may +happen if a memory allocation fails or if the .init quirk failed for +whatever reason). If this happen, further pci_get_drvdata will return a +pointer to freed memory. + +This patch reworks the PCI recovery resume hook to restore the old priv +structure in this case, which should be ok, since the ports were already +detached. Such error during recovery causes us to give up on the +recovery. + +Fixes: f209fa03fc9d ("serial: 8250_pci: Detach low-level driver during + PCI error recovery") +Reported-by: Michal Suchanek <msuchanek@suse.com> +Signed-off-by: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com> +Signed-off-by: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c +index aa0166b6d450..116436b7fa52 100644 +--- a/drivers/tty/serial/8250/8250_pci.c ++++ b/drivers/tty/serial/8250/8250_pci.c +@@ -5642,17 +5642,15 @@ static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev) + static void serial8250_io_resume(struct pci_dev *dev) + { + struct serial_private *priv = pci_get_drvdata(dev); +- const struct pciserial_board *board; ++ struct serial_private *new; + + if (!priv) + return; + +- board = priv->board; +- kfree(priv); +- priv = pciserial_init_ports(dev, board); +- +- if (!IS_ERR(priv)) { +- pci_set_drvdata(dev, priv); ++ new = pciserial_init_ports(dev, priv->board); ++ if (!IS_ERR(new)) { ++ pci_set_drvdata(dev, new); ++ kfree(priv); + } + } + +-- +2.12.0 + diff --git a/queue/9p-fix-a-potential-acl-leak.patch b/queue/9p-fix-a-potential-acl-leak.patch new file mode 100644 index 0000000..7ff116a --- /dev/null +++ b/queue/9p-fix-a-potential-acl-leak.patch @@ -0,0 +1,46 @@ +From b5c66bab72a6a65edb15beb60b90d3cb84c5763b Mon Sep 17 00:00:00 2001 +From: Cong Wang <xiyou.wangcong@gmail.com> +Date: Wed, 22 Feb 2017 15:40:53 -0800 +Subject: [PATCH] 9p: fix a potential acl leak + +commit b5c66bab72a6a65edb15beb60b90d3cb84c5763b upstream. + +posix_acl_update_mode() could possibly clear 'acl', if so we leak the +memory pointed by 'acl'. Save this pointer before calling +posix_acl_update_mode() and release the memory if 'acl' really gets +cleared. + +Link: http://lkml.kernel.org/r/1486678332-2430-1-git-send-email-xiyou.wangcong@gmail.com +Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> +Reported-by: Mark Salyzyn <salyzyn@android.com> +Reviewed-by: Jan Kara <jack@suse.cz> +Reviewed-by: Greg Kurz <groug@kaod.org> +Cc: Eric Van Hensbergen <ericvh@gmail.com> +Cc: Ron Minnich <rminnich@sandia.gov> +Cc: Latchesar Ionkov <lucho@ionkov.net> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> + +diff --git a/fs/9p/acl.c b/fs/9p/acl.c +index b3c2cc79c20d..082d227fa56b 100644 +--- a/fs/9p/acl.c ++++ b/fs/9p/acl.c +@@ -277,6 +277,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler, + case ACL_TYPE_ACCESS: + if (acl) { + struct iattr iattr; ++ struct posix_acl *old_acl = acl; + + retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl); + if (retval) +@@ -287,6 +288,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler, + * by the mode bits. So don't + * update ACL. + */ ++ posix_acl_release(old_acl); + value = NULL; + size = 0; + } +-- +2.12.0 + diff --git a/queue/ACPI-power-Avoid-maybe-uninitialized-warning.patch b/queue/ACPI-power-Avoid-maybe-uninitialized-warning.patch new file mode 100644 index 0000000..b11cd48 --- /dev/null +++ b/queue/ACPI-power-Avoid-maybe-uninitialized-warning.patch @@ -0,0 +1,44 @@ +From fe8c470ab87d90e4b5115902dd94eced7e3305c3 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann <arnd@arndb.de> +Date: Wed, 19 Apr 2017 19:47:04 +0200 +Subject: [PATCH] ACPI / power: Avoid maybe-uninitialized warning + +commit fe8c470ab87d90e4b5115902dd94eced7e3305c3 upstream. + +gcc -O2 cannot always prove that the loop in acpi_power_get_inferred_state() +is enterered at least once, so it assumes that cur_state might not get +initialized: + +drivers/acpi/power.c: In function 'acpi_power_get_inferred_state': +drivers/acpi/power.c:222:9: error: 'cur_state' may be used uninitialized in this function [-Werror=maybe-uninitialized] + +This sets the variable to zero at the start of the loop, to ensure that +there is well-defined behavior even for an empty list. This gets rid of +the warning. + +The warning first showed up when the -Os flag got removed in a bug fix +patch in linux-4.11-rc5. + +I would suggest merging this addon patch on top of that bug fix to avoid +introducing a new warning in the stable kernels. + +Fixes: 61b79e16c68d (ACPI: Fix incompatibility with mcount-based function graph tracing) +Cc: All applicable <stable@vger.kernel.org> +Signed-off-by: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> + +diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c +index fcd4ce6f78d5..1c2b846c5776 100644 +--- a/drivers/acpi/power.c ++++ b/drivers/acpi/power.c +@@ -200,6 +200,7 @@ static int acpi_power_get_list_state(struct list_head *list, int *state) + return -EINVAL; + + /* The state of the list is 'on' IFF all resources are 'on'. */ ++ cur_state = 0; + list_for_each_entry(entry, list, node) { + struct acpi_power_resource *resource = entry->resource; + acpi_handle handle = resource->device.handle; +-- +2.12.0 + diff --git a/queue/ALSA-firewire-lib-fix-inappropriate-assignment-betwe.patch b/queue/ALSA-firewire-lib-fix-inappropriate-assignment-betwe.patch new file mode 100644 index 0000000..b9c9f07 --- /dev/null +++ b/queue/ALSA-firewire-lib-fix-inappropriate-assignment-betwe.patch @@ -0,0 +1,40 @@ +From dfb00a56935186171abb5280b3407c3f910011f1 Mon Sep 17 00:00:00 2001 +From: Takashi Sakamoto <o-takashi@sakamocchi.jp> +Date: Fri, 14 Apr 2017 12:43:01 +0900 +Subject: [PATCH] ALSA: firewire-lib: fix inappropriate assignment between + signed/unsigned type + +commit dfb00a56935186171abb5280b3407c3f910011f1 upstream. + +An abstraction of asynchronous transaction for transmission of MIDI +messages was introduced in Linux v4.4. Each driver can utilize this +abstraction to transfer MIDI messages via fixed-length payload of +transaction to a certain unit address. Filling payload of the transaction +is done by callback. In this callback, each driver can return negative +error code, however current implementation assigns the return value to +unsigned variable. + +This commit changes type of the variable to fix the bug. + +Reported-by: Julia Lawall <Julia.Lawall@lip6.fr> +Cc: <stable@vger.kernel.org> # 4.4+ +Fixes: 585d7cba5e1f ("ALSA: firewire-lib: add helper functions for asynchronous transactions to transfer MIDI messages") +Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> +Signed-off-by: Takashi Iwai <tiwai@suse.de> + +diff --git a/sound/firewire/lib.h b/sound/firewire/lib.h +index f6769312ebfc..c3768cd494a5 100644 +--- a/sound/firewire/lib.h ++++ b/sound/firewire/lib.h +@@ -45,7 +45,7 @@ struct snd_fw_async_midi_port { + + struct snd_rawmidi_substream *substream; + snd_fw_async_midi_port_fill fill; +- unsigned int consume_bytes; ++ int consume_bytes; + }; + + int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port, +-- +2.12.0 + diff --git a/queue/ALSA-hda-Fix-deadlock-of-controller-device-lock-at-u.patch b/queue/ALSA-hda-Fix-deadlock-of-controller-device-lock-at-u.patch new file mode 100644 index 0000000..9ac1eee --- /dev/null +++ b/queue/ALSA-hda-Fix-deadlock-of-controller-device-lock-at-u.patch @@ -0,0 +1,70 @@ +From ab949d519601880fd46e8bc1445d6a453bf2dc09 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai <tiwai@suse.de> +Date: Mon, 2 Jan 2017 11:37:04 +0100 +Subject: [PATCH] ALSA: hda - Fix deadlock of controller device lock at + unbinding + +commit ab949d519601880fd46e8bc1445d6a453bf2dc09 upstream. + +Imre Deak reported a deadlock of HD-audio driver at unbinding while +it's still in probing. Since we probe the codecs asynchronously in a +work, the codec driver probe may still be kicked off while the +controller itself is being unbound. And, azx_remove() tries to +process all pending tasks via cancel_work_sync() for fixing the other +races (see commit [0b8c82190c12: ALSA: hda - Cancel probe work instead +of flush at remove]), now we may meet a bizarre deadlock: + +Unbind snd_hda_intel via sysfs: + device_release_driver() -> + device_lock(snd_hda_intel) -> + azx_remove() -> + cancel_work_sync(azx_probe_work) + +azx_probe_work(): + codec driver probe() -> + __driver_attach() -> + device_lock(snd_hda_intel) + +This deadlock is caused by the fact that both device_release_driver() +and driver_probe_device() take both the device and its parent locks at +the same time. The codec device sets the controller device as its +parent, and this lock is taken before the probe() callback is called, +while the controller remove() callback gets called also with the same +lock. + +In this patch, as an ugly workaround, we unlock the controller device +temporarily during cancel_work_sync() call. The race against another +bind call should be still suppressed by the parent's device lock. + +Reported-by: Imre Deak <imre.deak@intel.com> +Fixes: 0b8c82190c12 ("ALSA: hda - Cancel probe work instead of flush at remove") +Signed-off-by: Takashi Iwai <tiwai@suse.de> + +diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c +index c64d986009a9..2587c197e353 100644 +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -2155,7 +2155,20 @@ static void azx_remove(struct pci_dev *pci) + /* cancel the pending probing work */ + chip = card->private_data; + hda = container_of(chip, struct hda_intel, chip); ++ /* FIXME: below is an ugly workaround. ++ * Both device_release_driver() and driver_probe_device() ++ * take *both* the device's and its parent's lock before ++ * calling the remove() and probe() callbacks. The codec ++ * probe takes the locks of both the codec itself and its ++ * parent, i.e. the PCI controller dev. Meanwhile, when ++ * the PCI controller is unbound, it takes its lock, too ++ * ==> ouch, a deadlock! ++ * As a workaround, we unlock temporarily here the controller ++ * device during cancel_work_sync() call. ++ */ ++ device_unlock(&pci->dev); + cancel_work_sync(&hda->probe_work); ++ device_lock(&pci->dev); + + snd_card_free(card); + } +-- +2.12.0 + diff --git a/queue/ALSA-oxfw-fix-regression-to-handle-Stanton-SCS.1m-1d.patch b/queue/ALSA-oxfw-fix-regression-to-handle-Stanton-SCS.1m-1d.patch new file mode 100644 index 0000000..8873a50 --- /dev/null +++ b/queue/ALSA-oxfw-fix-regression-to-handle-Stanton-SCS.1m-1d.patch @@ -0,0 +1,42 @@ +From 3d016d57fdc5e6caa4cd67896f4b081bccad6e2c Mon Sep 17 00:00:00 2001 +From: Takashi Sakamoto <o-takashi@sakamocchi.jp> +Date: Mon, 3 Apr 2017 21:13:40 +0900 +Subject: [PATCH] ALSA: oxfw: fix regression to handle Stanton SCS.1m/1d + +commit 3d016d57fdc5e6caa4cd67896f4b081bccad6e2c upstream. + +At a commit 6c29230e2a5f ("ALSA: oxfw: delayed registration of sound +card"), ALSA oxfw driver fails to handle SCS.1m/1d, due to -EBUSY at a call +of snd_card_register(). The cause is that the driver manages to register +two rawmidi instances with the same device number 0. This is a regression +introduced since kernel 4.7. + +This commit fixes the regression, by fixing up device property after +discovering stream formats. + +Fixes: 6c29230e2a5f ("ALSA: oxfw: delayed registration of sound card") +Cc: <stable@vger.kernel.org> # 4.7+ +Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> +Signed-off-by: Takashi Iwai <tiwai@suse.de> + +diff --git a/sound/firewire/oxfw/oxfw.c b/sound/firewire/oxfw/oxfw.c +index 74d7fb6efce6..413ab6313bb6 100644 +--- a/sound/firewire/oxfw/oxfw.c ++++ b/sound/firewire/oxfw/oxfw.c +@@ -227,11 +227,11 @@ static void do_registration(struct work_struct *work) + if (err < 0) + goto error; + +- err = detect_quirks(oxfw); ++ err = snd_oxfw_stream_discover(oxfw); + if (err < 0) + goto error; + +- err = snd_oxfw_stream_discover(oxfw); ++ err = detect_quirks(oxfw); + if (err < 0) + goto error; + +-- +2.12.0 + diff --git a/queue/ALSA-seq-Don-t-break-snd_use_lock_sync-loop-by-timeo.patch b/queue/ALSA-seq-Don-t-break-snd_use_lock_sync-loop-by-timeo.patch new file mode 100644 index 0000000..7dd33a9 --- /dev/null +++ b/queue/ALSA-seq-Don-t-break-snd_use_lock_sync-loop-by-timeo.patch @@ -0,0 +1,56 @@ +From 4e7655fd4f47c23e5249ea260dc802f909a64611 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai <tiwai@suse.de> +Date: Sun, 9 Apr 2017 10:41:27 +0200 +Subject: [PATCH] ALSA: seq: Don't break snd_use_lock_sync() loop by timeout + +commit 4e7655fd4f47c23e5249ea260dc802f909a64611 upstream. + +The snd_use_lock_sync() (thus its implementation +snd_use_lock_sync_helper()) has the 5 seconds timeout to break out of +the sync loop. It was introduced from the beginning, just to be +"safer", in terms of avoiding the stupid bugs. + +However, as Ben Hutchings suggested, this timeout rather introduces a +potential leak or use-after-free that was apparently fixed by the +commit 2d7d54002e39 ("ALSA: seq: Fix race during FIFO resize"): +for example, snd_seq_fifo_event_in() -> snd_seq_event_dup() -> +copy_from_user() could block for a long time, and snd_use_lock_sync() +goes timeout and still leaves the cell at releasing the pool. + +For fixing such a problem, we remove the break by the timeout while +still keeping the warning. + +Suggested-by: Ben Hutchings <ben.hutchings@codethink.co.uk> +Cc: <stable@vger.kernel.org> +Signed-off-by: Takashi Iwai <tiwai@suse.de> + +diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c +index 3b693e924db7..12ba83367b1b 100644 +--- a/sound/core/seq/seq_lock.c ++++ b/sound/core/seq/seq_lock.c +@@ -28,19 +28,16 @@ + /* wait until all locks are released */ + void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line) + { +- int max_count = 5 * HZ; ++ int warn_count = 5 * HZ; + + if (atomic_read(lockp) < 0) { + pr_warn("ALSA: seq_lock: lock trouble [counter = %d] in %s:%d\n", atomic_read(lockp), file, line); + return; + } + while (atomic_read(lockp) > 0) { +- if (max_count == 0) { +- pr_warn("ALSA: seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line); +- break; +- } ++ if (warn_count-- == 0) ++ pr_warn("ALSA: seq_lock: waiting [%d left] in %s:%d\n", atomic_read(lockp), file, line); + schedule_timeout_uninterruptible(1); +- max_count--; + } + } + +-- +2.12.0 + diff --git a/queue/ARC-plat-eznps-Fix-build-error.patch b/queue/ARC-plat-eznps-Fix-build-error.patch new file mode 100644 index 0000000..479efc6 --- /dev/null +++ b/queue/ARC-plat-eznps-Fix-build-error.patch @@ -0,0 +1,33 @@ +From 6492f09e864417d382e22b922ae30693a7ce2982 Mon Sep 17 00:00:00 2001 +From: Noam Camus <noamca@mellanox.com> +Date: Tue, 4 Apr 2017 11:00:41 +0300 +Subject: [PATCH] ARC: [plat-eznps] Fix build error + +commit 6492f09e864417d382e22b922ae30693a7ce2982 upstream. + +Make ATOMIC_INIT available for all ARC platforms (including plat-eznps) + +Cc: <stable@vger.kernel.org> # 4.9+ +Signed-off-by: Noam Camus <noamca@mellanox.com> +Signed-off-by: Vineet Gupta <vgupta@synopsys.com> + +diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h +index b65930a49589..54b54da6384c 100644 +--- a/arch/arc/include/asm/atomic.h ++++ b/arch/arc/include/asm/atomic.h +@@ -17,10 +17,11 @@ + #include <asm/barrier.h> + #include <asm/smp.h> + ++#define ATOMIC_INIT(i) { (i) } ++ + #ifndef CONFIG_ARC_PLAT_EZNPS + + #define atomic_read(v) READ_ONCE((v)->counter) +-#define ATOMIC_INIT(i) { (i) } + + #ifdef CONFIG_ARC_HAS_LLSC + +-- +2.12.0 + diff --git a/queue/ARCv2-save-r30-on-kernel-entry-as-gcc-uses-it-for-co.patch b/queue/ARCv2-save-r30-on-kernel-entry-as-gcc-uses-it-for-co.patch new file mode 100644 index 0000000..7218d60 --- /dev/null +++ b/queue/ARCv2-save-r30-on-kernel-entry-as-gcc-uses-it-for-co.patch @@ -0,0 +1,48 @@ +From ecd43afdbe72017aefe48080631eb625e177ef4d Mon Sep 17 00:00:00 2001 +From: Vineet Gupta <vgupta@synopsys.com> +Date: Sun, 8 Jan 2017 19:45:48 -0800 +Subject: [PATCH] ARCv2: save r30 on kernel entry as gcc uses it for code-gen + +commit ecd43afdbe72017aefe48080631eb625e177ef4d upstream. + +This is not exposed to userspace debugers yet, which can be done +independently as a seperate patch ! + +Signed-off-by: Vineet Gupta <vgupta@synopsys.com> + +diff --git a/arch/arc/include/asm/entry-arcv2.h b/arch/arc/include/asm/entry-arcv2.h +index b5ff87e6f4b7..aee1a77934cf 100644 +--- a/arch/arc/include/asm/entry-arcv2.h ++++ b/arch/arc/include/asm/entry-arcv2.h +@@ -16,6 +16,7 @@ + ; + ; Now manually save: r12, sp, fp, gp, r25 + ++ PUSH r30 + PUSH r12 + + ; Saving pt_regs->sp correctly requires some extra work due to the way +@@ -72,6 +73,7 @@ + POPAX AUX_USER_SP + 1: + POP r12 ++ POP r30 + + .endm + +diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h +index 69095da1fcfd..47111d565a95 100644 +--- a/arch/arc/include/asm/ptrace.h ++++ b/arch/arc/include/asm/ptrace.h +@@ -84,7 +84,7 @@ struct pt_regs { + unsigned long fp; + unsigned long sp; /* user/kernel sp depending on where we came from */ + +- unsigned long r12; ++ unsigned long r12, r30; + + /*------- Below list auto saved by h/w -----------*/ + unsigned long r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11; +-- +2.12.0 + diff --git a/queue/ARM-OMAP5-DRA7-Fix-HYP-mode-boot-for-thumb2-build.patch b/queue/ARM-OMAP5-DRA7-Fix-HYP-mode-boot-for-thumb2-build.patch new file mode 100644 index 0000000..ee91bcc --- /dev/null +++ b/queue/ARM-OMAP5-DRA7-Fix-HYP-mode-boot-for-thumb2-build.patch @@ -0,0 +1,38 @@ +From 448c077eeb02240c430db2a2c3bf5285a4c65d66 Mon Sep 17 00:00:00 2001 +From: Matthijs van Duin <matthijsvanduin@gmail.com> +Date: Thu, 16 Feb 2017 01:05:04 +0100 +Subject: [PATCH] ARM: OMAP5 / DRA7: Fix HYP mode boot for thumb2 build + +commit 448c077eeb02240c430db2a2c3bf5285a4c65d66 upstream. + +'adr' yields a data-pointer, not a function-pointer. + +Fixes: 999f934de195 ("ARM: omap5/dra7xx: Enable booting secondary +CPU in HYP mode") +Signed-off-by: Matthijs van Duin <matthijsvanduin@gmail.com> +Signed-off-by: Tony Lindgren <tony@atomide.com> + +diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S +index fe36ce2734d4..4c6f14cf92a8 100644 +--- a/arch/arm/mach-omap2/omap-headsmp.S ++++ b/arch/arm/mach-omap2/omap-headsmp.S +@@ -17,6 +17,7 @@ + + #include <linux/linkage.h> + #include <linux/init.h> ++#include <asm/assembler.h> + + #include "omap44xx.h" + +@@ -66,7 +67,7 @@ wait_2: ldr r2, =AUX_CORE_BOOT0_PA @ read from AuxCoreBoot0 + cmp r0, r4 + bne wait_2 + ldr r12, =API_HYP_ENTRY +- adr r0, hyp_boot ++ badr r0, hyp_boot + smc #0 + hyp_boot: + b omap_secondary_startup +-- +2.12.0 + diff --git a/queue/ARM-dts-NSP-GPIO-reboot-open-source.patch b/queue/ARM-dts-NSP-GPIO-reboot-open-source.patch new file mode 100644 index 0000000..cafab45 --- /dev/null +++ b/queue/ARM-dts-NSP-GPIO-reboot-open-source.patch @@ -0,0 +1,109 @@ +From acfa28b3649ec07775efaac0c00de2db39d71634 Mon Sep 17 00:00:00 2001 +From: Jon Mason <jon.mason@broadcom.com> +Date: Wed, 1 Mar 2017 18:02:28 -0500 +Subject: [PATCH] ARM: dts: NSP: GPIO reboot open-source + +commit acfa28b3649ec07775efaac0c00de2db39d71634 upstream. + +The libgpio code pre-sets the GPIO values for the gpio-reset in the +device tree. This results in the device being reset during bringup. +To prevent this pre-setting, use the "open-source" flag in the device +tree. + +Signed-off-by: Jon Mason <jon.mason@broadcom.com> +Fixes: b1aaf88 ("ARM: dts: NSP: Add GPIO reboot method to bcm958625hr DTS file") +Fixes: 10baed1 ("ARM: dts: NSP: Add GPIO reboot method to bcm958625xmc DTS file") +Fixes: 088e3148 ("ARM: dts: NSP: Add new DT file for bcm958522er") +Fixes: e3227c1 ("ARM: dts: NSP: Add new DT file for bcm958525er") +Fixes: 2f8bc00 ("ARM: dts: NSP: Add new DT file for bcm958622hr") +Fixes: d454c37 ("ARM: dts: NSP: Add new DT file for bcm958623hr") +Fixes: f27eacf ("ARM: dts: NSP: Add new DT file for bcm988312hr") +Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> + +diff --git a/arch/arm/boot/dts/bcm958522er.dts b/arch/arm/boot/dts/bcm958522er.dts +index 3f04a40eb90c..df05e7f568af 100644 +--- a/arch/arm/boot/dts/bcm958522er.dts ++++ b/arch/arm/boot/dts/bcm958522er.dts +@@ -55,6 +55,7 @@ + gpio-restart { + compatible = "gpio-restart"; + gpios = <&gpioa 15 GPIO_ACTIVE_LOW>; ++ open-source; + priority = <200>; + }; + }; +diff --git a/arch/arm/boot/dts/bcm958525er.dts b/arch/arm/boot/dts/bcm958525er.dts +index 9fd542200d3d..4a3ab19c6281 100644 +--- a/arch/arm/boot/dts/bcm958525er.dts ++++ b/arch/arm/boot/dts/bcm958525er.dts +@@ -55,6 +55,7 @@ + gpio-restart { + compatible = "gpio-restart"; + gpios = <&gpioa 15 GPIO_ACTIVE_LOW>; ++ open-source; + priority = <200>; + }; + }; +diff --git a/arch/arm/boot/dts/bcm958525xmc.dts b/arch/arm/boot/dts/bcm958525xmc.dts +index 41e7fd350fcd..81f78435d8c7 100644 +--- a/arch/arm/boot/dts/bcm958525xmc.dts ++++ b/arch/arm/boot/dts/bcm958525xmc.dts +@@ -55,6 +55,7 @@ + gpio-restart { + compatible = "gpio-restart"; + gpios = <&gpioa 31 GPIO_ACTIVE_LOW>; ++ open-source; + priority = <200>; + }; + }; +diff --git a/arch/arm/boot/dts/bcm958622hr.dts b/arch/arm/boot/dts/bcm958622hr.dts +index 477c4860db52..c88b8fefcb2f 100644 +--- a/arch/arm/boot/dts/bcm958622hr.dts ++++ b/arch/arm/boot/dts/bcm958622hr.dts +@@ -55,6 +55,7 @@ + gpio-restart { + compatible = "gpio-restart"; + gpios = <&gpioa 15 GPIO_ACTIVE_LOW>; ++ open-source; + priority = <200>; + }; + }; +diff --git a/arch/arm/boot/dts/bcm958623hr.dts b/arch/arm/boot/dts/bcm958623hr.dts +index c0a499d5ba44..d503fa0dde31 100644 +--- a/arch/arm/boot/dts/bcm958623hr.dts ++++ b/arch/arm/boot/dts/bcm958623hr.dts +@@ -55,6 +55,7 @@ + gpio-restart { + compatible = "gpio-restart"; + gpios = <&gpioa 15 GPIO_ACTIVE_LOW>; ++ open-source; + priority = <200>; + }; + }; +diff --git a/arch/arm/boot/dts/bcm958625hr.dts b/arch/arm/boot/dts/bcm958625hr.dts +index f7eb5854a224..cc0363b843c1 100644 +--- a/arch/arm/boot/dts/bcm958625hr.dts ++++ b/arch/arm/boot/dts/bcm958625hr.dts +@@ -55,6 +55,7 @@ + gpio-restart { + compatible = "gpio-restart"; + gpios = <&gpioa 15 GPIO_ACTIVE_LOW>; ++ open-source; + priority = <200>; + }; + }; +diff --git a/arch/arm/boot/dts/bcm988312hr.dts b/arch/arm/boot/dts/bcm988312hr.dts +index 16666324fda8..74e15a3cd9f8 100644 +--- a/arch/arm/boot/dts/bcm988312hr.dts ++++ b/arch/arm/boot/dts/bcm988312hr.dts +@@ -55,6 +55,7 @@ + gpio-restart { + compatible = "gpio-restart"; + gpios = <&gpioa 15 GPIO_ACTIVE_LOW>; ++ open-source; + priority = <200>; + }; + }; +-- +2.12.0 + diff --git a/queue/ARM-dts-sun7i-lamobo-r1-Fix-CPU-port-RGMII-settings.patch b/queue/ARM-dts-sun7i-lamobo-r1-Fix-CPU-port-RGMII-settings.patch new file mode 100644 index 0000000..7dd8bab --- /dev/null +++ b/queue/ARM-dts-sun7i-lamobo-r1-Fix-CPU-port-RGMII-settings.patch @@ -0,0 +1,33 @@ +From 0cdefd5b5485ee6eb3512a75739d09a4090176ed Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <f.fainelli@gmail.com> +Date: Sat, 18 Mar 2017 21:53:20 -0700 +Subject: [PATCH] ARM: dts: sun7i: lamobo-r1: Fix CPU port RGMII settings + +commit 0cdefd5b5485ee6eb3512a75739d09a4090176ed upstream. + +The CPU port of the BCM53125 is configured with RGMII (no delays) but +this should actually be RGMII with transmit delay (rgmii-txid) because +STMMAC takes care of inserting the transmitter delay. This fixes +occasional packet loss encountered. + +Fixes: d7b9eaff5f0c ("ARM: dts: sun7i: Add BCM53125 switch nodes to the lamobo-r1 board") +Reported-by: Hartmut Knaack <knaack.h@gmx.de> +Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> +Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> + +diff --git a/arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts b/arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts +index 72ec0d5ae052..bbf1c8cbaac6 100644 +--- a/arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts ++++ b/arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts +@@ -167,7 +167,7 @@ + reg = <8>; + label = "cpu"; + ethernet = <&gmac>; +- phy-mode = "rgmii"; ++ phy-mode = "rgmii-txid"; + fixed-link { + speed = <1000>; + full-duplex; +-- +2.12.0 + diff --git a/queue/ASoC-intel-Fix-PM-and-non-atomic-crash-in-bytcr-driv.patch b/queue/ASoC-intel-Fix-PM-and-non-atomic-crash-in-bytcr-driv.patch new file mode 100644 index 0000000..4ee8da4 --- /dev/null +++ b/queue/ASoC-intel-Fix-PM-and-non-atomic-crash-in-bytcr-driv.patch @@ -0,0 +1,90 @@ +From 6e4cac23c5a648d50b107d1b53e9c4e1120c7943 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai <tiwai@suse.de> +Date: Mon, 24 Apr 2017 14:09:55 +0200 +Subject: [PATCH] ASoC: intel: Fix PM and non-atomic crash in bytcr drivers + +commit 6e4cac23c5a648d50b107d1b53e9c4e1120c7943 upstream. + +The FE setups of Intel SST bytcr_rt5640 and bytcr_rt5651 drivers carry +the ignore_suspend flag, and this prevents the suspend/resume working +properly while the stream is running, since SST core code has the +check of the running streams and returns -EBUSY. Drop these +superfluous flags for fixing the behavior. + +Also, the bytcr_rt5640 driver lacks of nonatomic flag in some FE +definitions, which leads to the kernel Oops at suspend/resume like: + + BUG: scheduling while atomic: systemd-sleep/3144/0x00000003 + Call Trace: + dump_stack+0x5c/0x7a + __schedule_bug+0x55/0x70 + __schedule+0x63c/0x8c0 + schedule+0x3d/0x90 + schedule_timeout+0x16b/0x320 + ? del_timer_sync+0x50/0x50 + ? sst_wait_timeout+0xa9/0x170 [snd_intel_sst_core] + ? sst_wait_timeout+0xa9/0x170 [snd_intel_sst_core] + ? remove_wait_queue+0x60/0x60 + ? sst_prepare_and_post_msg+0x275/0x960 [snd_intel_sst_core] + ? sst_pause_stream+0x9b/0x110 [snd_intel_sst_core] + .... + +This patch addresses these appropriately, too. + +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Acked-by: Vinod Koul <vinod.koul@intel.com> +Signed-off-by: Mark Brown <broonie@kernel.org> +Cc: <stable@vger.kernel.org> # v4.1+ + +diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c +index 5c7219fb3aa8..9e2a3404a836 100644 +--- a/sound/soc/intel/boards/bytcr_rt5640.c ++++ b/sound/soc/intel/boards/bytcr_rt5640.c +@@ -621,7 +621,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = { + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .platform_name = "sst-mfld-platform", +- .ignore_suspend = 1, ++ .nonatomic = true, + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, +@@ -634,7 +634,6 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = { + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .platform_name = "sst-mfld-platform", +- .ignore_suspend = 1, + .nonatomic = true, + .dynamic = 1, + .dpcm_playback = 1, +@@ -661,6 +660,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = { + | SND_SOC_DAIFMT_CBS_CFS, + .be_hw_params_fixup = byt_rt5640_codec_fixup, + .ignore_suspend = 1, ++ .nonatomic = true, + .dpcm_playback = 1, + .dpcm_capture = 1, + .init = byt_rt5640_init, +diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c +index 3186f015939f..8164bec63bf1 100644 +--- a/sound/soc/intel/boards/bytcr_rt5651.c ++++ b/sound/soc/intel/boards/bytcr_rt5651.c +@@ -235,7 +235,6 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = { + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .platform_name = "sst-mfld-platform", +- .ignore_suspend = 1, + .nonatomic = true, + .dynamic = 1, + .dpcm_playback = 1, +@@ -249,7 +248,6 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = { + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .platform_name = "sst-mfld-platform", +- .ignore_suspend = 1, + .nonatomic = true, + .dynamic = 1, + .dpcm_playback = 1, +-- +2.12.0 + diff --git a/queue/Bluetooth-Fix-user-channel-for-32bit-userspace-on-64.patch b/queue/Bluetooth-Fix-user-channel-for-32bit-userspace-on-64.patch new file mode 100644 index 0000000..e4cee28 --- /dev/null +++ b/queue/Bluetooth-Fix-user-channel-for-32bit-userspace-on-64.patch @@ -0,0 +1,35 @@ +From ab89f0bdd63a3721f7cd3f064f39fc4ac7ca14d4 Mon Sep 17 00:00:00 2001 +From: Szymon Janc <szymon.janc@codecoup.pl> +Date: Mon, 24 Apr 2017 18:25:04 -0700 +Subject: [PATCH] Bluetooth: Fix user channel for 32bit userspace on 64bit + kernel + +commit ab89f0bdd63a3721f7cd3f064f39fc4ac7ca14d4 upstream. + +Running 32bit userspace on 64bit kernel results in MSG_CMSG_COMPAT being +defined as 0x80000000. This results in sendmsg failure if used from 32bit +userspace running on 64bit kernel. Fix this by accounting for MSG_CMSG_COMPAT +in flags check in hci_sock_sendmsg. + +Signed-off-by: Szymon Janc <szymon.janc@codecoup.pl> +Signed-off-by: Marko Kiiskila <marko@runtime.io> +Signed-off-by: Marcel Holtmann <marcel@holtmann.org> +Cc: stable@vger.kernel.org + +diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c +index f64d6566021f..638bf0e1a2e3 100644 +--- a/net/bluetooth/hci_sock.c ++++ b/net/bluetooth/hci_sock.c +@@ -1680,7 +1680,8 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, + if (msg->msg_flags & MSG_OOB) + return -EOPNOTSUPP; + +- if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE)) ++ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE| ++ MSG_CMSG_COMPAT)) + return -EINVAL; + + if (len < 4 || len > HCI_MAX_FRAME_SIZE) +-- +2.12.0 + diff --git a/queue/Bluetooth-hci_bcm-add-missing-tty-device-sanity-chec.patch b/queue/Bluetooth-hci_bcm-add-missing-tty-device-sanity-chec.patch new file mode 100644 index 0000000..6c68a7d --- /dev/null +++ b/queue/Bluetooth-hci_bcm-add-missing-tty-device-sanity-chec.patch @@ -0,0 +1,43 @@ +From 95065a61e9bf25fb85295127fba893200c2bbbd8 Mon Sep 17 00:00:00 2001 +From: Johan Hovold <johan@kernel.org> +Date: Wed, 29 Mar 2017 18:15:27 +0200 +Subject: [PATCH] Bluetooth: hci_bcm: add missing tty-device sanity check + +commit 95065a61e9bf25fb85295127fba893200c2bbbd8 upstream. + +Make sure to check the tty-device pointer before looking up the sibling +platform device to avoid dereferencing a NULL-pointer when the tty is +one end of a Unix98 pty. + +Fixes: 0395ffc1ee05 ("Bluetooth: hci_bcm: Add PM for BCM devices") +Cc: stable <stable@vger.kernel.org> # 4.3 +Cc: Frederic Danis <frederic.danis@linux.intel.com> +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Marcel Holtmann <marcel@holtmann.org> + +diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c +index 04fe5535a153..f87bfdfee4ff 100644 +--- a/drivers/bluetooth/hci_bcm.c ++++ b/drivers/bluetooth/hci_bcm.c +@@ -287,6 +287,9 @@ static int bcm_open(struct hci_uart *hu) + + hu->priv = bcm; + ++ if (!hu->tty->dev) ++ goto out; ++ + mutex_lock(&bcm_device_lock); + list_for_each(p, &bcm_device_list) { + struct bcm_device *dev = list_entry(p, struct bcm_device, list); +@@ -307,7 +310,7 @@ static int bcm_open(struct hci_uart *hu) + } + + mutex_unlock(&bcm_device_lock); +- ++out: + return 0; + } + +-- +2.12.0 + diff --git a/queue/Bluetooth-hci_intel-add-missing-tty-device-sanity-ch.patch b/queue/Bluetooth-hci_intel-add-missing-tty-device-sanity-ch.patch new file mode 100644 index 0000000..f73aae4 --- /dev/null +++ b/queue/Bluetooth-hci_intel-add-missing-tty-device-sanity-ch.patch @@ -0,0 +1,73 @@ +From dcb9cfaa5ea9aa0ec08aeb92582ccfe3e4c719a9 Mon Sep 17 00:00:00 2001 +From: Johan Hovold <johan@kernel.org> +Date: Wed, 29 Mar 2017 18:15:28 +0200 +Subject: [PATCH] Bluetooth: hci_intel: add missing tty-device sanity check + +commit dcb9cfaa5ea9aa0ec08aeb92582ccfe3e4c719a9 upstream. + +Make sure to check the tty-device pointer before looking up the sibling +platform device to avoid dereferencing a NULL-pointer when the tty is +one end of a Unix98 pty. + +Fixes: 74cdad37cd24 ("Bluetooth: hci_intel: Add runtime PM support") +Fixes: 1ab1f239bf17 ("Bluetooth: hci_intel: Add support for platform driver") +Cc: stable <stable@vger.kernel.org> # 4.3 +Cc: Loic Poulain <loic.poulain@intel.com> +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Marcel Holtmann <marcel@holtmann.org> + +diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c +index d915e7eee233..fa5099986f1b 100644 +--- a/drivers/bluetooth/hci_intel.c ++++ b/drivers/bluetooth/hci_intel.c +@@ -307,6 +307,9 @@ static int intel_set_power(struct hci_uart *hu, bool powered) + struct list_head *p; + int err = -ENODEV; + ++ if (!hu->tty->dev) ++ return err; ++ + mutex_lock(&intel_device_list_lock); + + list_for_each(p, &intel_device_list) { +@@ -379,6 +382,9 @@ static void intel_busy_work(struct work_struct *work) + struct intel_data *intel = container_of(work, struct intel_data, + busy_work); + ++ if (!intel->hu->tty->dev) ++ return; ++ + /* Link is busy, delay the suspend */ + mutex_lock(&intel_device_list_lock); + list_for_each(p, &intel_device_list) { +@@ -899,6 +905,8 @@ done: + list_for_each(p, &intel_device_list) { + struct intel_device *dev = list_entry(p, struct intel_device, + list); ++ if (!hu->tty->dev) ++ break; + if (hu->tty->dev->parent == dev->pdev->dev.parent) { + if (device_may_wakeup(&dev->pdev->dev)) { + set_bit(STATE_LPM_ENABLED, &intel->flags); +@@ -1066,6 +1074,9 @@ static int intel_enqueue(struct hci_uart *hu, struct sk_buff *skb) + + BT_DBG("hu %p skb %p", hu, skb); + ++ if (!hu->tty->dev) ++ goto out_enqueue; ++ + /* Be sure our controller is resumed and potential LPM transaction + * completed before enqueuing any packet. + */ +@@ -1082,7 +1093,7 @@ static int intel_enqueue(struct hci_uart *hu, struct sk_buff *skb) + } + } + mutex_unlock(&intel_device_list_lock); +- ++out_enqueue: + skb_queue_tail(&intel->txq, skb); + + return 0; +-- +2.12.0 + diff --git a/queue/CIFS-add-misssing-SFM-mapping-for-doublequote.patch b/queue/CIFS-add-misssing-SFM-mapping-for-doublequote.patch new file mode 100644 index 0000000..aba0846 --- /dev/null +++ b/queue/CIFS-add-misssing-SFM-mapping-for-doublequote.patch @@ -0,0 +1,54 @@ +From 85435d7a15294f9f7ef23469e6aaf7c5dfcc54f0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= <bj@sernet.de> +Date: Fri, 5 May 2017 04:36:16 +0200 +Subject: [PATCH] CIFS: add misssing SFM mapping for doublequote + +commit 85435d7a15294f9f7ef23469e6aaf7c5dfcc54f0 upstream. + +SFM is mapping doublequote to 0xF020 + +Without this patch creating files with doublequote fails to Windows/Mac + +Signed-off-by: Bjoern Jacke <bjacke@samba.org> +Signed-off-by: Steve French <smfrench@gmail.com> +CC: stable <stable@vger.kernel.org> + +diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c +index 02b071bf3732..a0b3e7d1be48 100644 +--- a/fs/cifs/cifs_unicode.c ++++ b/fs/cifs/cifs_unicode.c +@@ -83,6 +83,9 @@ convert_sfm_char(const __u16 src_char, char *target) + case SFM_COLON: + *target = ':'; + break; ++ case SFM_DOUBLEQUOTE: ++ *target = '"'; ++ break; + case SFM_ASTERISK: + *target = '*'; + break; +@@ -418,6 +421,9 @@ static __le16 convert_to_sfm_char(char src_char, bool end_of_string) + case ':': + dest_char = cpu_to_le16(SFM_COLON); + break; ++ case '"': ++ dest_char = cpu_to_le16(SFM_DOUBLEQUOTE); ++ break; + case '*': + dest_char = cpu_to_le16(SFM_ASTERISK); + break; +diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h +index 7bfb76e60401..8a79a34e66b8 100644 +--- a/fs/cifs/cifs_unicode.h ++++ b/fs/cifs/cifs_unicode.h +@@ -57,6 +57,7 @@ + * not conflict (although almost does) with the mapping above. + */ + ++#define SFM_DOUBLEQUOTE ((__u16) 0xF020) + #define SFM_ASTERISK ((__u16) 0xF021) + #define SFM_QUESTION ((__u16) 0xF025) + #define SFM_COLON ((__u16) 0xF022) +-- +2.12.0 + diff --git a/queue/CIFS-fix-mapping-of-SFM_SPACE-and-SFM_PERIOD.patch b/queue/CIFS-fix-mapping-of-SFM_SPACE-and-SFM_PERIOD.patch new file mode 100644 index 0000000..d921388 --- /dev/null +++ b/queue/CIFS-fix-mapping-of-SFM_SPACE-and-SFM_PERIOD.patch @@ -0,0 +1,35 @@ +From b704e70b7cf48f9b67c07d585168e102dfa30bb4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= <bj@sernet.de> +Date: Wed, 3 May 2017 23:47:44 +0200 +Subject: [PATCH] CIFS: fix mapping of SFM_SPACE and SFM_PERIOD + +commit b704e70b7cf48f9b67c07d585168e102dfa30bb4 upstream. + +- trailing space maps to 0xF028 +- trailing period maps to 0xF029 + +This fix corrects the mapping of file names which have a trailing character +that would otherwise be illegal (period or space) but is allowed by POSIX. + +Signed-off-by: Bjoern Jacke <bjacke@samba.org> +CC: Stable <stable@vger.kernel.org> +Signed-off-by: Steve French <smfrench@gmail.com> + +diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h +index 3d7298cc0aeb..7bfb76e60401 100644 +--- a/fs/cifs/cifs_unicode.h ++++ b/fs/cifs/cifs_unicode.h +@@ -64,8 +64,8 @@ + #define SFM_LESSTHAN ((__u16) 0xF023) + #define SFM_PIPE ((__u16) 0xF027) + #define SFM_SLASH ((__u16) 0xF026) +-#define SFM_PERIOD ((__u16) 0xF028) +-#define SFM_SPACE ((__u16) 0xF029) ++#define SFM_SPACE ((__u16) 0xF028) ++#define SFM_PERIOD ((__u16) 0xF029) + + /* + * Mapping mechanism to use when one of the seven reserved characters is +-- +2.12.0 + diff --git a/queue/CIFS-fix-oplock-break-deadlocks.patch b/queue/CIFS-fix-oplock-break-deadlocks.patch new file mode 100644 index 0000000..4d73cee --- /dev/null +++ b/queue/CIFS-fix-oplock-break-deadlocks.patch @@ -0,0 +1,239 @@ +From 3998e6b87d4258a70df358296d6f1c7234012bfe Mon Sep 17 00:00:00 2001 +From: Rabin Vincent <rabinv@axis.com> +Date: Wed, 3 May 2017 17:54:01 +0200 +Subject: [PATCH] CIFS: fix oplock break deadlocks + +commit 3998e6b87d4258a70df358296d6f1c7234012bfe upstream. + +When the final cifsFileInfo_put() is called from cifsiod and an oplock +break work is queued, lockdep complains loudly: + + ============================================= + [ INFO: possible recursive locking detected ] + 4.11.0+ #21 Not tainted + --------------------------------------------- + kworker/0:2/78 is trying to acquire lock: + ("cifsiod"){++++.+}, at: flush_work+0x215/0x350 + + but task is already holding lock: + ("cifsiod"){++++.+}, at: process_one_work+0x255/0x8e0 + + other info that might help us debug this: + Possible unsafe locking scenario: + + CPU0 + ---- + lock("cifsiod"); + lock("cifsiod"); + + *** DEADLOCK *** + + May be due to missing lock nesting notation + + 2 locks held by kworker/0:2/78: + #0: ("cifsiod"){++++.+}, at: process_one_work+0x255/0x8e0 + #1: ((&wdata->work)){+.+...}, at: process_one_work+0x255/0x8e0 + + stack backtrace: + CPU: 0 PID: 78 Comm: kworker/0:2 Not tainted 4.11.0+ #21 + Workqueue: cifsiod cifs_writev_complete + Call Trace: + dump_stack+0x85/0xc2 + __lock_acquire+0x17dd/0x2260 + ? match_held_lock+0x20/0x2b0 + ? trace_hardirqs_off_caller+0x86/0x130 + ? mark_lock+0xa6/0x920 + lock_acquire+0xcc/0x260 + ? lock_acquire+0xcc/0x260 + ? flush_work+0x215/0x350 + flush_work+0x236/0x350 + ? flush_work+0x215/0x350 + ? destroy_worker+0x170/0x170 + __cancel_work_timer+0x17d/0x210 + ? ___preempt_schedule+0x16/0x18 + cancel_work_sync+0x10/0x20 + cifsFileInfo_put+0x338/0x7f0 + cifs_writedata_release+0x2a/0x40 + ? cifs_writedata_release+0x2a/0x40 + cifs_writev_complete+0x29d/0x850 + ? preempt_count_sub+0x18/0xd0 + process_one_work+0x304/0x8e0 + worker_thread+0x9b/0x6a0 + kthread+0x1b2/0x200 + ? process_one_work+0x8e0/0x8e0 + ? kthread_create_on_node+0x40/0x40 + ret_from_fork+0x31/0x40 + +This is a real warning. Since the oplock is queued on the same +workqueue this can deadlock if there is only one worker thread active +for the workqueue (which will be the case during memory pressure when +the rescuer thread is handling it). + +Furthermore, there is at least one other kind of hang possible due to +the oplock break handling if there is only worker. (This can be +reproduced without introducing memory pressure by having passing 1 for +the max_active parameter of cifsiod.) cifs_oplock_break() can wait +indefintely in the filemap_fdatawait() while the cifs_writev_complete() +work is blocked: + + sysrq: SysRq : Show Blocked State + task PC stack pid father + kworker/0:1 D 0 16 2 0x00000000 + Workqueue: cifsiod cifs_oplock_break + Call Trace: + __schedule+0x562/0xf40 + ? mark_held_locks+0x4a/0xb0 + schedule+0x57/0xe0 + io_schedule+0x21/0x50 + wait_on_page_bit+0x143/0x190 + ? add_to_page_cache_lru+0x150/0x150 + __filemap_fdatawait_range+0x134/0x190 + ? do_writepages+0x51/0x70 + filemap_fdatawait_range+0x14/0x30 + filemap_fdatawait+0x3b/0x40 + cifs_oplock_break+0x651/0x710 + ? preempt_count_sub+0x18/0xd0 + process_one_work+0x304/0x8e0 + worker_thread+0x9b/0x6a0 + kthread+0x1b2/0x200 + ? process_one_work+0x8e0/0x8e0 + ? kthread_create_on_node+0x40/0x40 + ret_from_fork+0x31/0x40 + dd D 0 683 171 0x00000000 + Call Trace: + __schedule+0x562/0xf40 + ? mark_held_locks+0x29/0xb0 + schedule+0x57/0xe0 + io_schedule+0x21/0x50 + wait_on_page_bit+0x143/0x190 + ? add_to_page_cache_lru+0x150/0x150 + __filemap_fdatawait_range+0x134/0x190 + ? do_writepages+0x51/0x70 + filemap_fdatawait_range+0x14/0x30 + filemap_fdatawait+0x3b/0x40 + filemap_write_and_wait+0x4e/0x70 + cifs_flush+0x6a/0xb0 + filp_close+0x52/0xa0 + __close_fd+0xdc/0x150 + SyS_close+0x33/0x60 + entry_SYSCALL_64_fastpath+0x1f/0xbe + + Showing all locks held in the system: + 2 locks held by kworker/0:1/16: + #0: ("cifsiod"){.+.+.+}, at: process_one_work+0x255/0x8e0 + #1: ((&cfile->oplock_break)){+.+.+.}, at: process_one_work+0x255/0x8e0 + + Showing busy workqueues and worker pools: + workqueue cifsiod: flags=0xc + pwq 0: cpus=0 node=0 flags=0x0 nice=0 active=1/1 + in-flight: 16:cifs_oplock_break + delayed: cifs_writev_complete, cifs_echo_request + pool 0: cpus=0 node=0 flags=0x0 nice=0 hung=0s workers=3 idle: 750 3 + +Fix these problems by creating a a new workqueue (with a rescuer) for +the oplock break work. + +Signed-off-by: Rabin Vincent <rabinv@axis.com> +Signed-off-by: Steve French <smfrench@gmail.com> +CC: Stable <stable@vger.kernel.org> + +diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c +index 34fee9fb7e4f..5c52c8f56102 100644 +--- a/fs/cifs/cifsfs.c ++++ b/fs/cifs/cifsfs.c +@@ -87,6 +87,7 @@ extern mempool_t *cifs_req_poolp; + extern mempool_t *cifs_mid_poolp; + + struct workqueue_struct *cifsiod_wq; ++struct workqueue_struct *cifsoplockd_wq; + __u32 cifs_lock_secret; + + /* +@@ -1374,9 +1375,16 @@ init_cifs(void) + goto out_clean_proc; + } + ++ cifsoplockd_wq = alloc_workqueue("cifsoplockd", ++ WQ_FREEZABLE|WQ_MEM_RECLAIM, 0); ++ if (!cifsoplockd_wq) { ++ rc = -ENOMEM; ++ goto out_destroy_cifsiod_wq; ++ } ++ + rc = cifs_fscache_register(); + if (rc) +- goto out_destroy_wq; ++ goto out_destroy_cifsoplockd_wq; + + rc = cifs_init_inodecache(); + if (rc) +@@ -1424,7 +1432,9 @@ out_destroy_inodecache: + cifs_destroy_inodecache(); + out_unreg_fscache: + cifs_fscache_unregister(); +-out_destroy_wq: ++out_destroy_cifsoplockd_wq: ++ destroy_workqueue(cifsoplockd_wq); ++out_destroy_cifsiod_wq: + destroy_workqueue(cifsiod_wq); + out_clean_proc: + cifs_proc_clean(); +@@ -1447,6 +1457,7 @@ exit_cifs(void) + cifs_destroy_mids(); + cifs_destroy_inodecache(); + cifs_fscache_unregister(); ++ destroy_workqueue(cifsoplockd_wq); + destroy_workqueue(cifsiod_wq); + cifs_proc_clean(); + } +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h +index 5c0e11a166ff..8be55be70faf 100644 +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -1702,6 +1702,7 @@ void cifs_oplock_break(struct work_struct *work); + + extern const struct slow_work_ops cifs_oplock_break_ops; + extern struct workqueue_struct *cifsiod_wq; ++extern struct workqueue_struct *cifsoplockd_wq; + extern __u32 cifs_lock_secret; + + extern mempool_t *cifs_mid_poolp; +diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c +index d8f8ddcdd57c..b08531977daa 100644 +--- a/fs/cifs/misc.c ++++ b/fs/cifs/misc.c +@@ -489,7 +489,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv) + CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, + &pCifsInode->flags); + +- queue_work(cifsiod_wq, ++ queue_work(cifsoplockd_wq, + &netfile->oplock_break); + netfile->oplock_break_cancelled = false; + +diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c +index 1a04b3a5beb1..7b08a1446a7f 100644 +--- a/fs/cifs/smb2misc.c ++++ b/fs/cifs/smb2misc.c +@@ -499,7 +499,7 @@ smb2_tcon_has_lease(struct cifs_tcon *tcon, struct smb2_lease_break *rsp, + else + cfile->oplock_break_cancelled = true; + +- queue_work(cifsiod_wq, &cfile->oplock_break); ++ queue_work(cifsoplockd_wq, &cfile->oplock_break); + kfree(lw); + return true; + } +@@ -643,7 +643,8 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) + CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, + &cinode->flags); + spin_unlock(&cfile->file_info_lock); +- queue_work(cifsiod_wq, &cfile->oplock_break); ++ queue_work(cifsoplockd_wq, ++ &cfile->oplock_break); + + spin_unlock(&tcon->open_file_lock); + spin_unlock(&cifs_tcp_ses_lock); +-- +2.12.0 + diff --git a/queue/CIFS-remove-bad_network_name-flag.patch b/queue/CIFS-remove-bad_network_name-flag.patch new file mode 100644 index 0000000..4951873 --- /dev/null +++ b/queue/CIFS-remove-bad_network_name-flag.patch @@ -0,0 +1,63 @@ +From a0918f1ce6a43ac980b42b300ec443c154970979 Mon Sep 17 00:00:00 2001 +From: Germano Percossi <germano.percossi@citrix.com> +Date: Fri, 7 Apr 2017 12:29:37 +0100 +Subject: [PATCH] CIFS: remove bad_network_name flag + +commit a0918f1ce6a43ac980b42b300ec443c154970979 upstream. + +STATUS_BAD_NETWORK_NAME can be received during node failover, +causing the flag to be set and making the reconnect thread +always unsuccessful, thereafter. + +Once the only place where it is set is removed, the remaining +bits are rendered moot. + +Removing it does not prevent "mount" from failing when a non +existent share is passed. + +What happens when the share really ceases to exist while the +share is mounted is undefined now as much as it was before. + +Signed-off-by: Germano Percossi <germano.percossi@citrix.com> +Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com> +CC: Stable <stable@vger.kernel.org> +Signed-off-by: Steve French <smfrench@gmail.com> + +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h +index d07f13a63369..37f5a41cc50c 100644 +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -948,7 +948,6 @@ struct cifs_tcon { + bool use_persistent:1; /* use persistent instead of durable handles */ + #ifdef CONFIG_CIFS_SMB2 + bool print:1; /* set if connection to printer share */ +- bool bad_network_name:1; /* set if ret status STATUS_BAD_NETWORK_NAME */ + __le32 capabilities; + __u32 share_flags; + __u32 maximal_access; +diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c +index d09e98bb8584..1bd5d3033fc8 100644 +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -1171,9 +1171,6 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, + else + return -EIO; + +- if (tcon && tcon->bad_network_name) +- return -ENOENT; +- + unc_path = kmalloc(MAX_SHARENAME_LENGTH * 2, GFP_KERNEL); + if (unc_path == NULL) + return -ENOMEM; +@@ -1277,8 +1274,6 @@ tcon_exit: + tcon_error_exit: + if (rsp->hdr.sync_hdr.Status == STATUS_BAD_NETWORK_NAME) { + cifs_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree); +- if (tcon) +- tcon->bad_network_name = true; + } + goto tcon_exit; + } +-- +2.12.0 + diff --git a/queue/Fix-match_prepath.patch b/queue/Fix-match_prepath.patch new file mode 100644 index 0000000..140954c --- /dev/null +++ b/queue/Fix-match_prepath.patch @@ -0,0 +1,46 @@ +From cd8c42968ee651b69e00f8661caff32b0086e82d Mon Sep 17 00:00:00 2001 +From: Sachin Prabhu <sprabhu@redhat.com> +Date: Wed, 26 Apr 2017 14:05:46 +0100 +Subject: [PATCH] Fix match_prepath() + +commit cd8c42968ee651b69e00f8661caff32b0086e82d upstream. + +Incorrect return value for shares not using the prefix path means that +we will never match superblocks for these shares. + +Fixes: commit c1d8b24d1819 ("Compare prepaths when comparing superblocks") +Cc: stable@vger.kernel.org +Signed-off-by: Sachin Prabhu <sprabhu@redhat.com> +Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com> +Signed-off-by: Steve French <smfrench@gmail.com> + +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index d82467cfb0e2..d95744d8b8ab 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -2912,16 +2912,14 @@ match_prepath(struct super_block *sb, struct cifs_mnt_data *mnt_data) + { + struct cifs_sb_info *old = CIFS_SB(sb); + struct cifs_sb_info *new = mnt_data->cifs_sb; ++ bool old_set = old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH; ++ bool new_set = new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH; + +- if (old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) { +- if (!(new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH)) +- return 0; +- /* The prepath should be null terminated strings */ +- if (strcmp(new->prepath, old->prepath)) +- return 0; +- ++ if (old_set && new_set && !strcmp(new->prepath, old->prepath)) + return 1; +- } ++ else if (!old_set && !new_set) ++ return 1; ++ + return 0; + } + +-- +2.12.0 + diff --git a/queue/Handle-mismatched-open-calls.patch b/queue/Handle-mismatched-open-calls.patch new file mode 100644 index 0000000..1502671 --- /dev/null +++ b/queue/Handle-mismatched-open-calls.patch @@ -0,0 +1,381 @@ +From 38bd49064a1ecb67baad33598e3d824448ab11ec Mon Sep 17 00:00:00 2001 +From: Sachin Prabhu <sprabhu@redhat.com> +Date: Fri, 3 Mar 2017 15:41:38 -0800 +Subject: [PATCH] Handle mismatched open calls + +commit 38bd49064a1ecb67baad33598e3d824448ab11ec upstream. + +A signal can interrupt a SendReceive call which result in incoming +responses to the call being ignored. This is a problem for calls such as +open which results in the successful response being ignored. This +results in an open file resource on the server. + +The patch looks into responses which were cancelled after being sent and +in case of successful open closes the open fids. + +For this patch, the check is only done in SendReceive2() + +RH-bz: 1403319 + +Signed-off-by: Sachin Prabhu <sprabhu@redhat.com> +Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com> +Cc: Stable <stable@vger.kernel.org> + +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h +index d42dd3288647..c34bdb12c8e6 100644 +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -243,6 +243,7 @@ struct smb_version_operations { + /* verify the message */ + int (*check_message)(char *, unsigned int, struct TCP_Server_Info *); + bool (*is_oplock_break)(char *, struct TCP_Server_Info *); ++ int (*handle_cancelled_mid)(char *, struct TCP_Server_Info *); + void (*downgrade_oplock)(struct TCP_Server_Info *, + struct cifsInodeInfo *, bool); + /* process transaction2 response */ +@@ -1343,6 +1344,7 @@ struct mid_q_entry { + void *callback_data; /* general purpose pointer for callback */ + void *resp_buf; /* pointer to received SMB header */ + int mid_state; /* wish this were enum but can not pass to wait_event */ ++ unsigned int mid_flags; + __le16 command; /* smb command code */ + bool large_buf:1; /* if valid response, is pointer to large buf */ + bool multiRsp:1; /* multiple trans2 responses for one request */ +@@ -1350,6 +1352,12 @@ struct mid_q_entry { + bool decrypted:1; /* decrypted entry */ + }; + ++struct close_cancelled_open { ++ struct cifs_fid fid; ++ struct cifs_tcon *tcon; ++ struct work_struct work; ++}; ++ + /* Make code in transport.c a little cleaner by moving + update of optional stats into function below */ + #ifdef CONFIG_CIFS_STATS2 +@@ -1481,6 +1489,9 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param, + #define MID_RESPONSE_MALFORMED 0x10 + #define MID_SHUTDOWN 0x20 + ++/* Flags */ ++#define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */ ++ + /* Types of response buffer returned from SendReceive2 */ + #define CIFS_NO_BUFFER 0 /* Response buffer not returned */ + #define CIFS_SMALL_BUFFER 1 +diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h +index 97e5d236d265..ec5e5e514fdd 100644 +--- a/fs/cifs/cifsproto.h ++++ b/fs/cifs/cifsproto.h +@@ -79,7 +79,8 @@ extern void cifs_delete_mid(struct mid_q_entry *mid); + extern void cifs_wake_up_task(struct mid_q_entry *mid); + extern int cifs_handle_standard(struct TCP_Server_Info *server, + struct mid_q_entry *mid); +-extern int cifs_discard_remaining_data(struct TCP_Server_Info *server); ++extern int cifs_discard_remaining_data(struct TCP_Server_Info *server, ++ char *buf); + extern int cifs_call_async(struct TCP_Server_Info *server, + struct smb_rqst *rqst, + mid_receive_t *receive, mid_callback_t *callback, +diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c +index 066950671929..967b92631807 100644 +--- a/fs/cifs/cifssmb.c ++++ b/fs/cifs/cifssmb.c +@@ -1400,9 +1400,9 @@ openRetry: + * current bigbuf. + */ + int +-cifs_discard_remaining_data(struct TCP_Server_Info *server) ++cifs_discard_remaining_data(struct TCP_Server_Info *server, char *buf) + { +- unsigned int rfclen = get_rfc1002_length(server->smallbuf); ++ unsigned int rfclen = get_rfc1002_length(buf); + int remaining = rfclen + 4 - server->total_read; + + while (remaining > 0) { +@@ -1426,7 +1426,7 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) + int length; + struct cifs_readdata *rdata = mid->callback_data; + +- length = cifs_discard_remaining_data(server); ++ length = cifs_discard_remaining_data(server, mid->resp_buf); + dequeue_mid(mid, rdata->result); + return length; + } +@@ -1459,7 +1459,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) + + if (server->ops->is_status_pending && + server->ops->is_status_pending(buf, server, 0)) { +- cifs_discard_remaining_data(server); ++ cifs_discard_remaining_data(server, buf); + return -1; + } + +@@ -1519,6 +1519,9 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) + cifs_dbg(FYI, "0: iov_base=%p iov_len=%u\n", + rdata->iov[0].iov_base, server->total_read); + ++ mid->resp_buf = server->smallbuf; ++ server->smallbuf = NULL; ++ + /* how much data is in the response? */ + data_len = server->ops->read_data_length(buf); + if (data_offset + data_len > buflen) { +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index 9ae695ae3ed7..0c7596cef4b8 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -904,10 +904,19 @@ cifs_demultiplex_thread(void *p) + + server->lstrp = jiffies; + if (mid_entry != NULL) { ++ if ((mid_entry->mid_flags & MID_WAIT_CANCELLED) && ++ mid_entry->mid_state == MID_RESPONSE_RECEIVED && ++ server->ops->handle_cancelled_mid) ++ server->ops->handle_cancelled_mid( ++ mid_entry->resp_buf, ++ server); ++ + if (!mid_entry->multiRsp || mid_entry->multiEnd) + mid_entry->callback(mid_entry); +- } else if (!server->ops->is_oplock_break || +- !server->ops->is_oplock_break(buf, server)) { ++ } else if (server->ops->is_oplock_break && ++ server->ops->is_oplock_break(buf, server)) { ++ cifs_dbg(FYI, "Received oplock break\n"); ++ } else { + cifs_dbg(VFS, "No task to wake, unknown frame received! NumMids %d\n", + atomic_read(&midCount)); + cifs_dump_mem("Received Data is: ", buf, +diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c +index fd516ea8b8f8..1a04b3a5beb1 100644 +--- a/fs/cifs/smb2misc.c ++++ b/fs/cifs/smb2misc.c +@@ -659,3 +659,49 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) + cifs_dbg(FYI, "Can not process oplock break for non-existent connection\n"); + return false; + } ++ ++void ++smb2_cancelled_close_fid(struct work_struct *work) ++{ ++ struct close_cancelled_open *cancelled = container_of(work, ++ struct close_cancelled_open, work); ++ ++ cifs_dbg(VFS, "Close unmatched open\n"); ++ ++ SMB2_close(0, cancelled->tcon, cancelled->fid.persistent_fid, ++ cancelled->fid.volatile_fid); ++ cifs_put_tcon(cancelled->tcon); ++ kfree(cancelled); ++} ++ ++int ++smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server) ++{ ++ struct smb2_sync_hdr *sync_hdr = get_sync_hdr(buffer); ++ struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer; ++ struct cifs_tcon *tcon; ++ struct close_cancelled_open *cancelled; ++ ++ if (sync_hdr->Command != SMB2_CREATE || ++ sync_hdr->Status != STATUS_SUCCESS) ++ return 0; ++ ++ cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL); ++ if (!cancelled) ++ return -ENOMEM; ++ ++ tcon = smb2_find_smb_tcon(server, sync_hdr->SessionId, ++ sync_hdr->TreeId); ++ if (!tcon) { ++ kfree(cancelled); ++ return -ENOENT; ++ } ++ ++ cancelled->fid.persistent_fid = rsp->PersistentFileId; ++ cancelled->fid.volatile_fid = rsp->VolatileFileId; ++ cancelled->tcon = tcon; ++ INIT_WORK(&cancelled->work, smb2_cancelled_close_fid); ++ queue_work(cifsiod_wq, &cancelled->work); ++ ++ return 0; ++} +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index 0231108d9387..b6bdf93042eb 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -2188,7 +2188,7 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid) + if (rc) + goto free_pages; + +- rc = cifs_discard_remaining_data(server); ++ rc = cifs_discard_remaining_data(server, buf); + if (rc) + goto free_pages; + +@@ -2214,7 +2214,7 @@ free_pages: + kfree(pages); + return rc; + discard_data: +- cifs_discard_remaining_data(server); ++ cifs_discard_remaining_data(server, buf); + goto free_pages; + } + +@@ -2322,6 +2322,7 @@ struct smb_version_operations smb20_operations = { + .clear_stats = smb2_clear_stats, + .print_stats = smb2_print_stats, + .is_oplock_break = smb2_is_valid_oplock_break, ++ .handle_cancelled_mid = smb2_handle_cancelled_mid, + .downgrade_oplock = smb2_downgrade_oplock, + .need_neg = smb2_need_neg, + .negotiate = smb2_negotiate, +@@ -2404,6 +2405,7 @@ struct smb_version_operations smb21_operations = { + .clear_stats = smb2_clear_stats, + .print_stats = smb2_print_stats, + .is_oplock_break = smb2_is_valid_oplock_break, ++ .handle_cancelled_mid = smb2_handle_cancelled_mid, + .downgrade_oplock = smb2_downgrade_oplock, + .need_neg = smb2_need_neg, + .negotiate = smb2_negotiate, +@@ -2488,6 +2490,7 @@ struct smb_version_operations smb30_operations = { + .print_stats = smb2_print_stats, + .dump_share_caps = smb2_dump_share_caps, + .is_oplock_break = smb2_is_valid_oplock_break, ++ .handle_cancelled_mid = smb2_handle_cancelled_mid, + .downgrade_oplock = smb2_downgrade_oplock, + .need_neg = smb2_need_neg, + .negotiate = smb2_negotiate, +@@ -2582,6 +2585,7 @@ struct smb_version_operations smb311_operations = { + .print_stats = smb2_print_stats, + .dump_share_caps = smb2_dump_share_caps, + .is_oplock_break = smb2_is_valid_oplock_break, ++ .handle_cancelled_mid = smb2_handle_cancelled_mid, + .downgrade_oplock = smb2_downgrade_oplock, + .need_neg = smb2_need_neg, + .negotiate = smb2_negotiate, +diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h +index 69e35873b1de..6853454fc871 100644 +--- a/fs/cifs/smb2proto.h ++++ b/fs/cifs/smb2proto.h +@@ -48,6 +48,10 @@ extern struct mid_q_entry *smb2_setup_request(struct cifs_ses *ses, + struct smb_rqst *rqst); + extern struct mid_q_entry *smb2_setup_async_request( + struct TCP_Server_Info *server, struct smb_rqst *rqst); ++extern struct cifs_ses *smb2_find_smb_ses(struct TCP_Server_Info *server, ++ __u64 ses_id); ++extern struct cifs_tcon *smb2_find_smb_tcon(struct TCP_Server_Info *server, ++ __u64 ses_id, __u32 tid); + extern int smb2_calc_signature(struct smb_rqst *rqst, + struct TCP_Server_Info *server); + extern int smb3_calc_signature(struct smb_rqst *rqst, +@@ -164,6 +168,9 @@ extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, + extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, + const u64 persistent_fid, const u64 volatile_fid, + const __u8 oplock_level); ++extern int smb2_handle_cancelled_mid(char *buffer, ++ struct TCP_Server_Info *server); ++void smb2_cancelled_close_fid(struct work_struct *work); + extern int SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_file_id, u64 volatile_file_id, + struct kstatfs *FSData); +diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c +index 7c3bb1bd7eed..506b67fc93d9 100644 +--- a/fs/cifs/smb2transport.c ++++ b/fs/cifs/smb2transport.c +@@ -115,23 +115,70 @@ smb3_crypto_shash_allocate(struct TCP_Server_Info *server) + return 0; + } + +-struct cifs_ses * +-smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id) ++static struct cifs_ses * ++smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id) + { + struct cifs_ses *ses; + +- spin_lock(&cifs_tcp_ses_lock); + list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { + if (ses->Suid != ses_id) + continue; +- spin_unlock(&cifs_tcp_ses_lock); + return ses; + } ++ ++ return NULL; ++} ++ ++struct cifs_ses * ++smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id) ++{ ++ struct cifs_ses *ses; ++ ++ spin_lock(&cifs_tcp_ses_lock); ++ ses = smb2_find_smb_ses_unlocked(server, ses_id); + spin_unlock(&cifs_tcp_ses_lock); + ++ return ses; ++} ++ ++static struct cifs_tcon * ++smb2_find_smb_sess_tcon_unlocked(struct cifs_ses *ses, __u32 tid) ++{ ++ struct cifs_tcon *tcon; ++ ++ list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { ++ if (tcon->tid != tid) ++ continue; ++ ++tcon->tc_count; ++ return tcon; ++ } ++ + return NULL; + } + ++/* ++ * Obtain tcon corresponding to the tid in the given ++ * cifs_ses ++ */ ++ ++struct cifs_tcon * ++smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32 tid) ++{ ++ struct cifs_ses *ses; ++ struct cifs_tcon *tcon; ++ ++ spin_lock(&cifs_tcp_ses_lock); ++ ses = smb2_find_smb_ses_unlocked(server, ses_id); ++ if (!ses) { ++ spin_unlock(&cifs_tcp_ses_lock); ++ return NULL; ++ } ++ tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid); ++ spin_unlock(&cifs_tcp_ses_lock); ++ ++ return tcon; ++} ++ + int + smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) + { +diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c +index 526f0533cb4e..f6e13a977fc8 100644 +--- a/fs/cifs/transport.c ++++ b/fs/cifs/transport.c +@@ -752,9 +752,11 @@ cifs_send_recv(const unsigned int xid, struct cifs_ses *ses, + + rc = wait_for_response(ses->server, midQ); + if (rc != 0) { ++ cifs_dbg(FYI, "Cancelling wait for mid %llu\n", midQ->mid); + send_cancel(ses->server, rqst, midQ); + spin_lock(&GlobalMid_Lock); + if (midQ->mid_state == MID_REQUEST_SUBMITTED) { ++ midQ->mid_flags |= MID_WAIT_CANCELLED; + midQ->callback = DeleteMidQEntry; + spin_unlock(&GlobalMid_Lock); + add_credits(ses->server, 1, optype); +-- +2.12.0 + diff --git a/queue/IB-IPoIB-ibX-failed-to-create-mcg-debug-file.patch b/queue/IB-IPoIB-ibX-failed-to-create-mcg-debug-file.patch new file mode 100644 index 0000000..eb7d22f --- /dev/null +++ b/queue/IB-IPoIB-ibX-failed-to-create-mcg-debug-file.patch @@ -0,0 +1,158 @@ +From 771a52584096c45e4565e8aabb596eece9d73d61 Mon Sep 17 00:00:00 2001 +From: Shamir Rabinovitch <shamir.rabinovitch@oracle.com> +Date: Wed, 29 Mar 2017 06:21:59 -0400 +Subject: [PATCH] IB/IPoIB: ibX: failed to create mcg debug file + +commit 771a52584096c45e4565e8aabb596eece9d73d61 upstream. + +When udev renames the netdev devices, ipoib debugfs entries does not +get renamed. As a result, if subsequent probe of ipoib device reuse the +name then creating a debugfs entry for the new device would fail. + +Also, moved ipoib_create_debug_files and ipoib_delete_debug_files as part +of ipoib event handling in order to avoid any race condition between these. + +Fixes: 1732b0ef3b3a ([IPoIB] add path record information in debugfs) +Cc: stable@vger.kernel.org # 2.6.15+ +Signed-off-by: Vijay Kumar <vijay.ac.kumar@oracle.com> +Signed-off-by: Shamir Rabinovitch <shamir.rabinovitch@oracle.com> +Reviewed-by: Mark Bloch <markb@mellanox.com> +Signed-off-by: Doug Ledford <dledford@redhat.com> + +diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c +index 6bd5740e2691..09396bd7b02d 100644 +--- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c ++++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c +@@ -281,8 +281,11 @@ void ipoib_delete_debug_files(struct net_device *dev) + { + struct ipoib_dev_priv *priv = netdev_priv(dev); + ++ WARN_ONCE(!priv->mcg_dentry, "null mcg debug file\n"); ++ WARN_ONCE(!priv->path_dentry, "null path debug file\n"); + debugfs_remove(priv->mcg_dentry); + debugfs_remove(priv->path_dentry); ++ priv->mcg_dentry = priv->path_dentry = NULL; + } + + int ipoib_register_debugfs(void) +diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c +index d1d3fb7a6127..b319cc26c9a7 100644 +--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c ++++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c +@@ -108,6 +108,33 @@ static struct ib_client ipoib_client = { + .get_net_dev_by_params = ipoib_get_net_dev_by_params, + }; + ++#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG ++static int ipoib_netdev_event(struct notifier_block *this, ++ unsigned long event, void *ptr) ++{ ++ struct netdev_notifier_info *ni = ptr; ++ struct net_device *dev = ni->dev; ++ ++ if (dev->netdev_ops->ndo_open != ipoib_open) ++ return NOTIFY_DONE; ++ ++ switch (event) { ++ case NETDEV_REGISTER: ++ ipoib_create_debug_files(dev); ++ break; ++ case NETDEV_CHANGENAME: ++ ipoib_delete_debug_files(dev); ++ ipoib_create_debug_files(dev); ++ break; ++ case NETDEV_UNREGISTER: ++ ipoib_delete_debug_files(dev); ++ break; ++ } ++ ++ return NOTIFY_DONE; ++} ++#endif ++ + int ipoib_open(struct net_device *dev) + { + struct ipoib_dev_priv *priv = netdev_priv(dev); +@@ -1674,8 +1701,6 @@ void ipoib_dev_cleanup(struct net_device *dev) + + ASSERT_RTNL(); + +- ipoib_delete_debug_files(dev); +- + /* Delete any child interfaces first */ + list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) { + /* Stop GC on child */ +@@ -2090,8 +2115,6 @@ static struct net_device *ipoib_add_port(const char *format, + goto register_failed; + } + +- ipoib_create_debug_files(priv->dev); +- + if (ipoib_cm_add_mode_attr(priv->dev)) + goto sysfs_failed; + if (ipoib_add_pkey_attr(priv->dev)) +@@ -2106,7 +2129,6 @@ static struct net_device *ipoib_add_port(const char *format, + return priv->dev; + + sysfs_failed: +- ipoib_delete_debug_files(priv->dev); + unregister_netdev(priv->dev); + + register_failed: +@@ -2191,6 +2213,12 @@ static void ipoib_remove_one(struct ib_device *device, void *client_data) + kfree(dev_list); + } + ++#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG ++static struct notifier_block ipoib_netdev_notifier = { ++ .notifier_call = ipoib_netdev_event, ++}; ++#endif ++ + static int __init ipoib_init_module(void) + { + int ret; +@@ -2243,6 +2271,9 @@ static int __init ipoib_init_module(void) + if (ret) + goto err_client; + ++#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG ++ register_netdevice_notifier(&ipoib_netdev_notifier); ++#endif + return 0; + + err_client: +@@ -2260,6 +2291,9 @@ err_fs: + + static void __exit ipoib_cleanup_module(void) + { ++#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG ++ unregister_netdevice_notifier(&ipoib_netdev_notifier); ++#endif + ipoib_netlink_fini(); + ib_unregister_client(&ipoib_client); + ib_sa_unregister_client(&ipoib_sa_client); +diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +index 3e10e3dac2e7..e543bc745f34 100644 +--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c ++++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +@@ -86,8 +86,6 @@ int __ipoib_vlan_add(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv, + goto register_failed; + } + +- ipoib_create_debug_files(priv->dev); +- + /* RTNL childs don't need proprietary sysfs entries */ + if (type == IPOIB_LEGACY_CHILD) { + if (ipoib_cm_add_mode_attr(priv->dev)) +@@ -108,7 +106,6 @@ int __ipoib_vlan_add(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv, + + sysfs_failed: + result = -ENOMEM; +- ipoib_delete_debug_files(priv->dev); + unregister_netdevice(priv->dev); + + register_failed: +-- +2.12.0 + diff --git a/queue/IB-core-Fix-sysfs-registration-error-flow.patch b/queue/IB-core-Fix-sysfs-registration-error-flow.patch new file mode 100644 index 0000000..1c2e97c --- /dev/null +++ b/queue/IB-core-Fix-sysfs-registration-error-flow.patch @@ -0,0 +1,49 @@ +From b312be3d87e4c80872cbea869e569175c5eb0f9a Mon Sep 17 00:00:00 2001 +From: Jack Morgenstein <jackm@dev.mellanox.co.il> +Date: Sun, 19 Mar 2017 10:55:57 +0200 +Subject: [PATCH] IB/core: Fix sysfs registration error flow + +commit b312be3d87e4c80872cbea869e569175c5eb0f9a upstream. + +The kernel commit cited below restructured ib device management +so that the device kobject is initialized in ib_alloc_device. + +As part of the restructuring, the kobject is now initialized in +procedure ib_alloc_device, and is later added to the device hierarchy +in the ib_register_device call stack, in procedure +ib_device_register_sysfs (which calls device_add). + +However, in the ib_device_register_sysfs error flow, if an error +occurs following the call to device_add, the cleanup procedure +device_unregister is called. This call results in the device object +being deleted -- which results in various use-after-free crashes. + +The correct cleanup call is device_del -- which undoes device_add +without deleting the device object. + +The device object will then (correctly) be deleted in the +ib_register_device caller's error cleanup flow, when the caller invokes +ib_dealloc_device. + +Fixes: 55aeed06544f6 ("IB/core: Make ib_alloc_device init the kobject") +Cc: <stable@vger.kernel.org> # v4.2+ +Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> +Signed-off-by: Leon Romanovsky <leon@kernel.org> +Signed-off-by: Doug Ledford <dledford@redhat.com> + +diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c +index daadf3130c9f..48bb75503255 100644 +--- a/drivers/infiniband/core/sysfs.c ++++ b/drivers/infiniband/core/sysfs.c +@@ -1301,7 +1301,7 @@ err_put: + free_port_list_attributes(device); + + err_unregister: +- device_unregister(class_dev); ++ device_del(class_dev); + + err: + return ret; +-- +2.12.0 + diff --git a/queue/IB-core-For-multicast-functions-verify-that-LIDs-are.patch b/queue/IB-core-For-multicast-functions-verify-that-LIDs-are.patch new file mode 100644 index 0000000..2b9c94f --- /dev/null +++ b/queue/IB-core-For-multicast-functions-verify-that-LIDs-are.patch @@ -0,0 +1,53 @@ +From 8561eae60ff9417a50fa1fb2b83ae950dc5c1e21 Mon Sep 17 00:00:00 2001 +From: "Michael J. Ruhl" <michael.j.ruhl@intel.com> +Date: Sun, 9 Apr 2017 10:15:51 -0700 +Subject: [PATCH] IB/core: For multicast functions, verify that LIDs are + multicast LIDs + +commit 8561eae60ff9417a50fa1fb2b83ae950dc5c1e21 upstream. + +The Infiniband spec defines "A multicast address is defined by a +MGID and a MLID" (section 10.5). Currently the MLID value is not +validated. + +Add check to verify that the MLID value is in the correct address +range. + +Fixes: 0c33aeedb2cf ("[IB] Add checks to multicast attach and detach") +Cc: stable@vger.kernel.org +Reviewed-by: Ira Weiny <ira.weiny@intel.com> +Reviewed-by: Dasaratharaman Chandramouli <dasaratharaman.chandramouli@intel.com> +Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com> +Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> +Reviewed-by: Leon Romanovsky <leonro@mellanox.com> +Signed-off-by: Doug Ledford <dledford@redhat.com> + +diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c +index 85ed5051fdfd..207e5c2457cc 100644 +--- a/drivers/infiniband/core/verbs.c ++++ b/drivers/infiniband/core/verbs.c +@@ -1519,7 +1519,9 @@ int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid) + + if (!qp->device->attach_mcast) + return -ENOSYS; +- if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD) ++ if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD || ++ lid < be16_to_cpu(IB_MULTICAST_LID_BASE) || ++ lid == be16_to_cpu(IB_LID_PERMISSIVE)) + return -EINVAL; + + ret = qp->device->attach_mcast(qp, gid, lid); +@@ -1535,7 +1537,9 @@ int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid) + + if (!qp->device->detach_mcast) + return -ENOSYS; +- if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD) ++ if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD || ++ lid < be16_to_cpu(IB_MULTICAST_LID_BASE) || ++ lid == be16_to_cpu(IB_LID_PERMISSIVE)) + return -EINVAL; + + ret = qp->device->detach_mcast(qp, gid, lid); +-- +2.12.0 + diff --git a/queue/IB-hfi1-Prevent-kernel-QP-post-send-hard-lockups.patch b/queue/IB-hfi1-Prevent-kernel-QP-post-send-hard-lockups.patch new file mode 100644 index 0000000..fa342e5 --- /dev/null +++ b/queue/IB-hfi1-Prevent-kernel-QP-post-send-hard-lockups.patch @@ -0,0 +1,143 @@ +From b6eac931b9bb2bce4db7032c35b41e5e34ec22a5 Mon Sep 17 00:00:00 2001 +From: Mike Marciniszyn <mike.marciniszyn@intel.com> +Date: Sun, 9 Apr 2017 10:16:35 -0700 +Subject: [PATCH] IB/hfi1: Prevent kernel QP post send hard lockups + +commit b6eac931b9bb2bce4db7032c35b41e5e34ec22a5 upstream. + +The driver progress routines can call cond_resched() when +a timeslice is exhausted and irqs are enabled. + +If the ULP had been holding a spin lock without disabling irqs and +the post send directly called the progress routine, the cond_resched() +could yield allowing another thread from the same ULP to deadlock +on that same lock. + +Correct by replacing the current hfi1_do_send() calldown with a unique +one for post send and adding an argument to hfi1_do_send() to indicate +that the send engine is running in a thread. If the routine is not +running in a thread, avoid calling cond_resched(). + +CC: <stable@vger.kernel.org> # 4.7.x- +Fixes: Commit 831464ce4b74 ("IB/hfi1: Don't call cond_resched in atomic mode when sending packets") +Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com> +Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com> +Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> +Signed-off-by: Doug Ledford <dledford@redhat.com> + +diff --git a/drivers/infiniband/hw/hfi1/ruc.c b/drivers/infiniband/hw/hfi1/ruc.c +index 879eb9b31954..ccf8d8037355 100644 +--- a/drivers/infiniband/hw/hfi1/ruc.c ++++ b/drivers/infiniband/hw/hfi1/ruc.c +@@ -1,5 +1,5 @@ + /* +- * Copyright(c) 2015, 2016 Intel Corporation. ++ * Copyright(c) 2015 - 2017 Intel Corporation. + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. +@@ -784,23 +784,29 @@ void hfi1_make_ruc_header(struct rvt_qp *qp, struct ib_other_headers *ohdr, + /* when sending, force a reschedule every one of these periods */ + #define SEND_RESCHED_TIMEOUT (5 * HZ) /* 5s in jiffies */ + ++void hfi1_do_send_from_rvt(struct rvt_qp *qp) ++{ ++ hfi1_do_send(qp, false); ++} ++ + void _hfi1_do_send(struct work_struct *work) + { + struct iowait *wait = container_of(work, struct iowait, iowork); + struct rvt_qp *qp = iowait_to_qp(wait); + +- hfi1_do_send(qp); ++ hfi1_do_send(qp, true); + } + + /** + * hfi1_do_send - perform a send on a QP + * @work: contains a pointer to the QP ++ * @in_thread: true if in a workqueue thread + * + * Process entries in the send work queue until credit or queue is + * exhausted. Only allow one CPU to send a packet per QP. + * Otherwise, two threads could send packets out of order. + */ +-void hfi1_do_send(struct rvt_qp *qp) ++void hfi1_do_send(struct rvt_qp *qp, bool in_thread) + { + struct hfi1_pkt_state ps; + struct hfi1_qp_priv *priv = qp->priv; +@@ -868,8 +874,10 @@ void hfi1_do_send(struct rvt_qp *qp) + qp->s_hdrwords = 0; + /* allow other tasks to run */ + if (unlikely(time_after(jiffies, timeout))) { +- if (workqueue_congested(cpu, +- ps.ppd->hfi1_wq)) { ++ if (!in_thread || ++ workqueue_congested( ++ cpu, ++ ps.ppd->hfi1_wq)) { + spin_lock_irqsave( + &qp->s_lock, + ps.flags); +@@ -882,11 +890,9 @@ void hfi1_do_send(struct rvt_qp *qp) + *ps.ppd->dd->send_schedule); + return; + } +- if (!irqs_disabled()) { +- cond_resched(); +- this_cpu_inc( +- *ps.ppd->dd->send_schedule); +- } ++ cond_resched(); ++ this_cpu_inc( ++ *ps.ppd->dd->send_schedule); + timeout = jiffies + (timeout_int) / 8; + } + spin_lock_irqsave(&qp->s_lock, ps.flags); +diff --git a/drivers/infiniband/hw/hfi1/verbs.c b/drivers/infiniband/hw/hfi1/verbs.c +index 57036e545bdb..7174a18ebaac 100644 +--- a/drivers/infiniband/hw/hfi1/verbs.c ++++ b/drivers/infiniband/hw/hfi1/verbs.c +@@ -1,5 +1,5 @@ + /* +- * Copyright(c) 2015, 2016 Intel Corporation. ++ * Copyright(c) 2015 - 2017 Intel Corporation. + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. +@@ -1820,7 +1820,7 @@ int hfi1_register_ib_device(struct hfi1_devdata *dd) + dd->verbs_dev.rdi.driver_f.qp_priv_free = qp_priv_free; + dd->verbs_dev.rdi.driver_f.free_all_qps = free_all_qps; + dd->verbs_dev.rdi.driver_f.notify_qp_reset = notify_qp_reset; +- dd->verbs_dev.rdi.driver_f.do_send = hfi1_do_send; ++ dd->verbs_dev.rdi.driver_f.do_send = hfi1_do_send_from_rvt; + dd->verbs_dev.rdi.driver_f.schedule_send = hfi1_schedule_send; + dd->verbs_dev.rdi.driver_f.schedule_send_no_lock = _hfi1_schedule_send; + dd->verbs_dev.rdi.driver_f.get_pmtu_from_attr = get_pmtu_from_attr; +diff --git a/drivers/infiniband/hw/hfi1/verbs.h b/drivers/infiniband/hw/hfi1/verbs.h +index 6c549e7a25e7..46b00ed9f2dc 100644 +--- a/drivers/infiniband/hw/hfi1/verbs.h ++++ b/drivers/infiniband/hw/hfi1/verbs.h +@@ -1,5 +1,5 @@ + /* +- * Copyright(c) 2015, 2016 Intel Corporation. ++ * Copyright(c) 2015 - 2017 Intel Corporation. + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. +@@ -355,7 +355,9 @@ void hfi1_make_ruc_header(struct rvt_qp *qp, struct ib_other_headers *ohdr, + + void _hfi1_do_send(struct work_struct *work); + +-void hfi1_do_send(struct rvt_qp *qp); ++void hfi1_do_send_from_rvt(struct rvt_qp *qp); ++ ++void hfi1_do_send(struct rvt_qp *qp, bool in_thread); + + void hfi1_send_complete(struct rvt_qp *qp, struct rvt_swqe *wqe, + enum ib_wc_status status); +-- +2.12.0 + diff --git a/queue/IB-mlx4-Fix-ib-device-initialization-error-flow.patch b/queue/IB-mlx4-Fix-ib-device-initialization-error-flow.patch new file mode 100644 index 0000000..da92655 --- /dev/null +++ b/queue/IB-mlx4-Fix-ib-device-initialization-error-flow.patch @@ -0,0 +1,33 @@ +From 99e68909d5aba1861897fe7afc3306c3c81b6de0 Mon Sep 17 00:00:00 2001 +From: Jack Morgenstein <jackm@dev.mellanox.co.il> +Date: Tue, 21 Mar 2017 12:57:05 +0200 +Subject: [PATCH] IB/mlx4: Fix ib device initialization error flow + +commit 99e68909d5aba1861897fe7afc3306c3c81b6de0 upstream. + +In mlx4_ib_add, procedure mlx4_ib_alloc_eqs is called to allocate EQs. + +However, in the mlx4_ib_add error flow, procedure mlx4_ib_free_eqs is not +called to free the allocated EQs. + +Fixes: e605b743f33d ("IB/mlx4: Increase the number of vectors (EQs) available for ULPs") +Cc: <stable@vger.kernel.org> # v3.4+ +Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> +Signed-off-by: Leon Romanovsky <leon@kernel.org> +Signed-off-by: Doug Ledford <dledford@redhat.com> + +diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c +index 2cc6f21baea1..7a1b345b6aa9 100644 +--- a/drivers/infiniband/hw/mlx4/main.c ++++ b/drivers/infiniband/hw/mlx4/main.c +@@ -2937,6 +2937,7 @@ err_counter: + mlx4_ib_delete_counters_table(ibdev, &ibdev->counters_table[i]); + + err_map: ++ mlx4_ib_free_eqs(dev, ibdev); + iounmap(ibdev->uar_map); + + err_uar: +-- +2.12.0 + diff --git a/queue/IB-mlx4-Reduce-SRIOV-multicast-cleanup-warning-messa.patch b/queue/IB-mlx4-Reduce-SRIOV-multicast-cleanup-warning-messa.patch new file mode 100644 index 0000000..867b195 --- /dev/null +++ b/queue/IB-mlx4-Reduce-SRIOV-multicast-cleanup-warning-messa.patch @@ -0,0 +1,97 @@ +From fb7a91746af18b2ebf596778b38a709cdbc488d3 Mon Sep 17 00:00:00 2001 +From: Jack Morgenstein <jackm@dev.mellanox.co.il> +Date: Tue, 21 Mar 2017 12:57:06 +0200 +Subject: [PATCH] IB/mlx4: Reduce SRIOV multicast cleanup warning message to + debug level + +commit fb7a91746af18b2ebf596778b38a709cdbc488d3 upstream. + +A warning message during SRIOV multicast cleanup should have actually been +a debug level message. The condition generating the warning does no harm +and can fill the message log. + +In some cases, during testing, some tests were so intense as to swamp the +message log with these warning messages, causing a stall in the console +message log output task. This stall caused an NMI to be sent to all CPUs +(so that they all dumped their stacks into the message log). +Aside from the message flood causing an NMI, the tests all passed. + +Once the message flood which caused the NMI is removed (by reducing the +warning message to debug level), the NMI no longer occurs. + +Sample message log (console log) output illustrating the flood and +resultant NMI (snippets with comments and modified with ... instead +of hex digits, to satisfy checkpatch.pl): + + <mlx4_ib> _mlx4_ib_mcg_port_cleanup: ... WARNING: group refcount 1!!!... + *** About 4000 almost identical lines in less than one second *** + <mlx4_ib> _mlx4_ib_mcg_port_cleanup: ... WARNING: group refcount 1!!!... + INFO: rcu_sched detected stalls on CPUs/tasks: { 17} (...) + *** { 17} above indicates that CPU 17 was the one that stalled *** + sending NMI to all CPUs: + ... + NMI backtrace for cpu 17 + CPU: 17 PID: 45909 Comm: kworker/17:2 + Hardware name: HP ProLiant DL360p Gen8, BIOS P71 09/08/2013 + Workqueue: events fb_flashcursor + task: ffff880478...... ti: ffff88064e...... task.ti: ffff88064e...... + RIP: 0010:[ffffffff81......] [ffffffff81......] io_serial_in+0x15/0x20 + RSP: 0018:ffff88064e257cb0 EFLAGS: 00000002 + RAX: 0000000000...... RBX: ffffffff81...... RCX: 0000000000...... + RDX: 0000000000...... RSI: 0000000000...... RDI: ffffffff81...... + RBP: ffff88064e...... R08: ffffffff81...... R09: 0000000000...... + R10: 0000000000...... R11: ffff88064e...... R12: 0000000000...... + R13: 0000000000...... R14: ffffffff81...... R15: 0000000000...... + FS: 0000000000......(0000) GS:ffff8804af......(0000) knlGS:000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080...... + CR2: 00007f2a2f...... CR3: 0000000001...... CR4: 0000000000...... + DR0: 0000000000...... DR1: 0000000000...... DR2: 0000000000...... + DR3: 0000000000...... DR6: 00000000ff...... DR7: 0000000000...... + Stack: + ffff88064e...... ffffffff81...... ffffffff81...... 0000000000...... + ffffffff81...... ffff88064e...... ffffffff81...... ffffffff81...... + ffffffff81...... ffff88064e...... ffffffff81...... 0000000000...... + Call Trace: +[<ffffffff813d099b>] wait_for_xmitr+0x3b/0xa0 +[<ffffffff813d0b5c>] serial8250_console_putchar+0x1c/0x30 +[<ffffffff813d0b40>] ? serial8250_console_write+0x140/0x140 +[<ffffffff813cb5fa>] uart_console_write+0x3a/0x80 +[<ffffffff813d0aae>] serial8250_console_write+0xae/0x140 +[<ffffffff8107c4d1>] call_console_drivers.constprop.15+0x91/0xf0 +[<ffffffff8107d6cf>] console_unlock+0x3bf/0x400 +[<ffffffff813503cd>] fb_flashcursor+0x5d/0x140 +[<ffffffff81355c30>] ? bit_clear+0x120/0x120 +[<ffffffff8109d5fb>] process_one_work+0x17b/0x470 +[<ffffffff8109e3cb>] worker_thread+0x11b/0x400 +[<ffffffff8109e2b0>] ? rescuer_thread+0x400/0x400 +[<ffffffff810a5aef>] kthread+0xcf/0xe0 +[<ffffffff810a5a20>] ? kthread_create_on_node+0x140/0x140 +[<ffffffff81645858>] ret_from_fork+0x58/0x90 +[<ffffffff810a5a20>] ? kthread_create_on_node+0x140/0x140 +Code: 48 89 e5 d3 e6 48 63 f6 48 03 77 10 8b 06 5d c3 66 0f 1f 44 00 00 66 66 66 6 + +As indicated in the stack trace above, the console output task got swamped. + +Fixes: b9c5d6a64358 ("IB/mlx4: Add multicast group (MCG) paravirtualization for SR-IOV") +Cc: <stable@vger.kernel.org> # v3.6+ +Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> +Signed-off-by: Leon Romanovsky <leon@kernel.org> +Signed-off-by: Doug Ledford <dledford@redhat.com> + +diff --git a/drivers/infiniband/hw/mlx4/mcg.c b/drivers/infiniband/hw/mlx4/mcg.c +index e010fe459e67..8772d88d324d 100644 +--- a/drivers/infiniband/hw/mlx4/mcg.c ++++ b/drivers/infiniband/hw/mlx4/mcg.c +@@ -1102,7 +1102,8 @@ static void _mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy + while ((p = rb_first(&ctx->mcg_table)) != NULL) { + group = rb_entry(p, struct mcast_group, node); + if (atomic_read(&group->refcount)) +- mcg_warn_group(group, "group refcount %d!!! (pointer %p)\n", atomic_read(&group->refcount), group); ++ mcg_debug_group(group, "group refcount %d!!! (pointer %p)\n", ++ atomic_read(&group->refcount), group); + + force_clean_group(group); + } +-- +2.12.0 + diff --git a/queue/Input-elantech-add-Fujitsu-Lifebook-E547-to-force-cr.patch b/queue/Input-elantech-add-Fujitsu-Lifebook-E547-to-force-cr.patch new file mode 100644 index 0000000..0671fea --- /dev/null +++ b/queue/Input-elantech-add-Fujitsu-Lifebook-E547-to-force-cr.patch @@ -0,0 +1,49 @@ +From 704de489e0e3640a2ee2d0daf173e9f7375582ba Mon Sep 17 00:00:00 2001 +From: Thorsten Leemhuis <linux@leemhuis.info> +Date: Tue, 18 Apr 2017 11:14:28 -0700 +Subject: [PATCH] Input: elantech - add Fujitsu Lifebook E547 to force + crc_enabled + +commit 704de489e0e3640a2ee2d0daf173e9f7375582ba upstream. + +Temporary got a Lifebook E547 into my hands and noticed the touchpad +only works after running: + + echo "1" > /sys/devices/platform/i8042/serio2/crc_enabled + +Add it to the list of machines that need this workaround. + +Cc: stable@vger.kernel.org +Signed-off-by: Thorsten Leemhuis <linux@leemhuis.info> +Reviewed-by: Ulrik De Bie <ulrik.debie-os@e2big.org> +Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> + +diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c +index efc8ec342351..e73d968023f7 100644 +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -1118,6 +1118,7 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse, + * Asus UX32VD 0x361f02 00, 15, 0e clickpad + * Avatar AVIU-145A2 0x361f00 ? clickpad + * Fujitsu LIFEBOOK E544 0x470f00 d0, 12, 09 2 hw buttons ++ * Fujitsu LIFEBOOK E547 0x470f00 50, 12, 09 2 hw buttons + * Fujitsu LIFEBOOK E554 0x570f01 40, 14, 0c 2 hw buttons + * Fujitsu T725 0x470f01 05, 12, 09 2 hw buttons + * Fujitsu H730 0x570f00 c0, 14, 0c 3 hw buttons (**) +@@ -1524,6 +1525,13 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = { + }, + }, + { ++ /* Fujitsu LIFEBOOK E547 does not work with crc_enabled == 0 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E547"), ++ }, ++ }, ++ { + /* Fujitsu LIFEBOOK E554 does not work with crc_enabled == 0 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +-- +2.12.0 + diff --git a/queue/Input-i8042-add-Clevo-P650RS-to-the-i8042-reset-list.patch b/queue/Input-i8042-add-Clevo-P650RS-to-the-i8042-reset-list.patch new file mode 100644 index 0000000..c79853d --- /dev/null +++ b/queue/Input-i8042-add-Clevo-P650RS-to-the-i8042-reset-list.patch @@ -0,0 +1,40 @@ +From 7c5bb4ac2b76d2a09256aec8a7d584bf3e2b0466 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov <dmitry.torokhov@gmail.com> +Date: Thu, 13 Apr 2017 15:36:31 -0700 +Subject: [PATCH] Input: i8042 - add Clevo P650RS to the i8042 reset list +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 7c5bb4ac2b76d2a09256aec8a7d584bf3e2b0466 upstream. + +Clevo P650RS and other similar devices require i8042 to be reset in order +to detect Synaptics touchpad. + +Reported-by: Paweł Bylica <chfast@gmail.com> +Tested-by: Ed Bordin <edbordin@gmail.com> +Cc: stable@vger.kernel.org +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=190301 +Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> + +diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h +index 312bd6ca9198..09720d950686 100644 +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ b/drivers/input/serio/i8042-x86ia64io.h +@@ -620,6 +620,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "20046"), + }, + }, ++ { ++ /* Clevo P650RS, 650RP6, Sager NP8152-S, and others */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"), ++ }, ++ }, + { } + }; + +-- +2.12.0 + diff --git a/queue/KEYS-Change-the-name-of-the-dead-type-to-.dead-to-pr.patch b/queue/KEYS-Change-the-name-of-the-dead-type-to-.dead-to-pr.patch new file mode 100644 index 0000000..a69e2f4 --- /dev/null +++ b/queue/KEYS-Change-the-name-of-the-dead-type-to-.dead-to-pr.patch @@ -0,0 +1,46 @@ +From c1644fe041ebaf6519f6809146a77c3ead9193af Mon Sep 17 00:00:00 2001 +From: David Howells <dhowells@redhat.com> +Date: Tue, 18 Apr 2017 15:31:08 +0100 +Subject: [PATCH] KEYS: Change the name of the dead type to ".dead" to prevent + user access + +commit c1644fe041ebaf6519f6809146a77c3ead9193af upstream. + +This fixes CVE-2017-6951. + +Userspace should not be able to do things with the "dead" key type as it +doesn't have some of the helper functions set upon it that the kernel +needs. Attempting to use it may cause the kernel to crash. + +Fix this by changing the name of the type to ".dead" so that it's rejected +up front on userspace syscalls by key_get_type_from_user(). + +Though this doesn't seem to affect recent kernels, it does affect older +ones, certainly those prior to: + + commit c06cfb08b88dfbe13be44a69ae2fdc3a7c902d81 + Author: David Howells <dhowells@redhat.com> + Date: Tue Sep 16 17:36:06 2014 +0100 + KEYS: Remove key_type::match in favour of overriding default by match_preparse + +which went in before 3.18-rc1. + +Signed-off-by: David Howells <dhowells@redhat.com> +cc: stable@vger.kernel.org + +diff --git a/security/keys/gc.c b/security/keys/gc.c +index addf060399e0..9cb4fe4478a1 100644 +--- a/security/keys/gc.c ++++ b/security/keys/gc.c +@@ -46,7 +46,7 @@ static unsigned long key_gc_flags; + * immediately unlinked. + */ + struct key_type key_type_dead = { +- .name = "dead", ++ .name = ".dead", + }; + + /* +-- +2.12.0 + diff --git a/queue/KEYS-Disallow-keyrings-beginning-with-.-to-be-joined.patch b/queue/KEYS-Disallow-keyrings-beginning-with-.-to-be-joined.patch new file mode 100644 index 0000000..5919e09 --- /dev/null +++ b/queue/KEYS-Disallow-keyrings-beginning-with-.-to-be-joined.patch @@ -0,0 +1,79 @@ +From ee8f844e3c5a73b999edf733df1c529d6503ec2f Mon Sep 17 00:00:00 2001 +From: David Howells <dhowells@redhat.com> +Date: Tue, 18 Apr 2017 15:31:07 +0100 +Subject: [PATCH] KEYS: Disallow keyrings beginning with '.' to be joined as + session keyrings + +commit ee8f844e3c5a73b999edf733df1c529d6503ec2f upstream. + +This fixes CVE-2016-9604. + +Keyrings whose name begin with a '.' are special internal keyrings and so +userspace isn't allowed to create keyrings by this name to prevent +shadowing. However, the patch that added the guard didn't fix +KEYCTL_JOIN_SESSION_KEYRING. Not only can that create dot-named keyrings, +it can also subscribe to them as a session keyring if they grant SEARCH +permission to the user. + +This, for example, allows a root process to set .builtin_trusted_keys as +its session keyring, at which point it has full access because now the +possessor permissions are added. This permits root to add extra public +keys, thereby bypassing module verification. + +This also affects kexec and IMA. + +This can be tested by (as root): + + keyctl session .builtin_trusted_keys + keyctl add user a a @s + keyctl list @s + +which on my test box gives me: + + 2 keys in keyring: + 180010936: ---lswrv 0 0 asymmetric: Build time autogenerated kernel key: ae3d4a31b82daa8e1a75b49dc2bba949fd992a05 + 801382539: --alswrv 0 0 user: a + + +Fix this by rejecting names beginning with a '.' in the keyctl. + +Signed-off-by: David Howells <dhowells@redhat.com> +Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com> +cc: linux-ima-devel@lists.sourceforge.net +cc: stable@vger.kernel.org + +diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c +index 52c34532c785..ab082a2e8fdd 100644 +--- a/security/keys/keyctl.c ++++ b/security/keys/keyctl.c +@@ -273,7 +273,8 @@ error: + * Create and join an anonymous session keyring or join a named session + * keyring, creating it if necessary. A named session keyring must have Search + * permission for it to be joined. Session keyrings without this permit will +- * be skipped over. ++ * be skipped over. It is not permitted for userspace to create or join ++ * keyrings whose name begin with a dot. + * + * If successful, the ID of the joined session keyring will be returned. + */ +@@ -290,12 +291,16 @@ long keyctl_join_session_keyring(const char __user *_name) + ret = PTR_ERR(name); + goto error; + } ++ ++ ret = -EPERM; ++ if (name[0] == '.') ++ goto error_name; + } + + /* join the session */ + ret = join_session_keyring(name); ++error_name: + kfree(name); +- + error: + return ret; + } +-- +2.12.0 + diff --git a/queue/KEYS-fix-keyctl_set_reqkey_keyring-to-not-leak-threa.patch b/queue/KEYS-fix-keyctl_set_reqkey_keyring-to-not-leak-threa.patch new file mode 100644 index 0000000..2ede87b --- /dev/null +++ b/queue/KEYS-fix-keyctl_set_reqkey_keyring-to-not-leak-threa.patch @@ -0,0 +1,179 @@ +From c9f838d104fed6f2f61d68164712e3204bf5271b Mon Sep 17 00:00:00 2001 +From: Eric Biggers <ebiggers@google.com> +Date: Tue, 18 Apr 2017 15:31:09 +0100 +Subject: [PATCH] KEYS: fix keyctl_set_reqkey_keyring() to not leak thread + keyrings + +commit c9f838d104fed6f2f61d68164712e3204bf5271b upstream. + +This fixes CVE-2017-7472. + +Running the following program as an unprivileged user exhausts kernel +memory by leaking thread keyrings: + + #include <keyutils.h> + + int main() + { + for (;;) + keyctl_set_reqkey_keyring(KEY_REQKEY_DEFL_THREAD_KEYRING); + } + +Fix it by only creating a new thread keyring if there wasn't one before. +To make things more consistent, make install_thread_keyring_to_cred() +and install_process_keyring_to_cred() both return 0 if the corresponding +keyring is already present. + +Fixes: d84f4f992cbd ("CRED: Inaugurate COW credentials") +Cc: stable@vger.kernel.org # 2.6.29+ +Signed-off-by: Eric Biggers <ebiggers@google.com> +Signed-off-by: David Howells <dhowells@redhat.com> + +diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c +index ab082a2e8fdd..4ad3212adebe 100644 +--- a/security/keys/keyctl.c ++++ b/security/keys/keyctl.c +@@ -1258,8 +1258,8 @@ error: + * Read or set the default keyring in which request_key() will cache keys and + * return the old setting. + * +- * If a process keyring is specified then this will be created if it doesn't +- * yet exist. The old setting will be returned if successful. ++ * If a thread or process keyring is specified then it will be created if it ++ * doesn't yet exist. The old setting will be returned if successful. + */ + long keyctl_set_reqkey_keyring(int reqkey_defl) + { +@@ -1284,11 +1284,8 @@ long keyctl_set_reqkey_keyring(int reqkey_defl) + + case KEY_REQKEY_DEFL_PROCESS_KEYRING: + ret = install_process_keyring_to_cred(new); +- if (ret < 0) { +- if (ret != -EEXIST) +- goto error; +- ret = 0; +- } ++ if (ret < 0) ++ goto error; + goto set; + + case KEY_REQKEY_DEFL_DEFAULT: +diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c +index b6fdd22205b1..9139b18fc863 100644 +--- a/security/keys/process_keys.c ++++ b/security/keys/process_keys.c +@@ -128,13 +128,18 @@ error: + } + + /* +- * Install a fresh thread keyring directly to new credentials. This keyring is +- * allowed to overrun the quota. ++ * Install a thread keyring to the given credentials struct if it didn't have ++ * one already. This is allowed to overrun the quota. ++ * ++ * Return: 0 if a thread keyring is now present; -errno on failure. + */ + int install_thread_keyring_to_cred(struct cred *new) + { + struct key *keyring; + ++ if (new->thread_keyring) ++ return 0; ++ + keyring = keyring_alloc("_tid", new->uid, new->gid, new, + KEY_POS_ALL | KEY_USR_VIEW, + KEY_ALLOC_QUOTA_OVERRUN, +@@ -147,7 +152,9 @@ int install_thread_keyring_to_cred(struct cred *new) + } + + /* +- * Install a fresh thread keyring, discarding the old one. ++ * Install a thread keyring to the current task if it didn't have one already. ++ * ++ * Return: 0 if a thread keyring is now present; -errno on failure. + */ + static int install_thread_keyring(void) + { +@@ -158,8 +165,6 @@ static int install_thread_keyring(void) + if (!new) + return -ENOMEM; + +- BUG_ON(new->thread_keyring); +- + ret = install_thread_keyring_to_cred(new); + if (ret < 0) { + abort_creds(new); +@@ -170,17 +175,17 @@ static int install_thread_keyring(void) + } + + /* +- * Install a process keyring directly to a credentials struct. ++ * Install a process keyring to the given credentials struct if it didn't have ++ * one already. This is allowed to overrun the quota. + * +- * Returns -EEXIST if there was already a process keyring, 0 if one installed, +- * and other value on any other error ++ * Return: 0 if a process keyring is now present; -errno on failure. + */ + int install_process_keyring_to_cred(struct cred *new) + { + struct key *keyring; + + if (new->process_keyring) +- return -EEXIST; ++ return 0; + + keyring = keyring_alloc("_pid", new->uid, new->gid, new, + KEY_POS_ALL | KEY_USR_VIEW, +@@ -194,11 +199,9 @@ int install_process_keyring_to_cred(struct cred *new) + } + + /* +- * Make sure a process keyring is installed for the current process. The +- * existing process keyring is not replaced. ++ * Install a process keyring to the current task if it didn't have one already. + * +- * Returns 0 if there is a process keyring by the end of this function, some +- * error otherwise. ++ * Return: 0 if a process keyring is now present; -errno on failure. + */ + static int install_process_keyring(void) + { +@@ -212,14 +215,18 @@ static int install_process_keyring(void) + ret = install_process_keyring_to_cred(new); + if (ret < 0) { + abort_creds(new); +- return ret != -EEXIST ? ret : 0; ++ return ret; + } + + return commit_creds(new); + } + + /* +- * Install a session keyring directly to a credentials struct. ++ * Install the given keyring as the session keyring of the given credentials ++ * struct, replacing the existing one if any. If the given keyring is NULL, ++ * then install a new anonymous session keyring. ++ * ++ * Return: 0 on success; -errno on failure. + */ + int install_session_keyring_to_cred(struct cred *cred, struct key *keyring) + { +@@ -254,8 +261,11 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring) + } + + /* +- * Install a session keyring, discarding the old one. If a keyring is not +- * supplied, an empty one is invented. ++ * Install the given keyring as the session keyring of the current task, ++ * replacing the existing one if any. If the given keyring is NULL, then ++ * install a new anonymous session keyring. ++ * ++ * Return: 0 on success; -errno on failure. + */ + static int install_session_keyring(struct key *keyring) + { +-- +2.12.0 + diff --git a/queue/KVM-arm-arm64-fix-races-in-kvm_psci_vcpu_on.patch b/queue/KVM-arm-arm64-fix-races-in-kvm_psci_vcpu_on.patch new file mode 100644 index 0000000..65b1546 --- /dev/null +++ b/queue/KVM-arm-arm64-fix-races-in-kvm_psci_vcpu_on.patch @@ -0,0 +1,71 @@ +From 6c7a5dce22b3f3cc44be098e2837fa6797edb8b8 Mon Sep 17 00:00:00 2001 +From: Andrew Jones <drjones@redhat.com> +Date: Tue, 18 Apr 2017 17:59:58 +0200 +Subject: [PATCH] KVM: arm/arm64: fix races in kvm_psci_vcpu_on + +commit 6c7a5dce22b3f3cc44be098e2837fa6797edb8b8 upstream. + +Fix potential races in kvm_psci_vcpu_on() by taking the kvm->lock +mutex. In general, it's a bad idea to allow more than one PSCI_CPU_ON +to process the same target VCPU at the same time. One such problem +that may arise is that one PSCI_CPU_ON could be resetting the target +vcpu, which fills the entire sys_regs array with a temporary value +including the MPIDR register, while another looks up the VCPU based +on the MPIDR value, resulting in no target VCPU found. Resolves both +races found with the kvm-unit-tests/arm/psci unit test. + +Reviewed-by: Marc Zyngier <marc.zyngier@arm.com> +Reviewed-by: Christoffer Dall <cdall@linaro.org> +Reported-by: Levente Kurusa <lkurusa@redhat.com> +Suggested-by: Christoffer Dall <cdall@linaro.org> +Signed-off-by: Andrew Jones <drjones@redhat.com> +Cc: stable@vger.kernel.org +Signed-off-by: Christoffer Dall <cdall@linaro.org> + +diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c +index c2b131527a64..a08d7a93aebb 100644 +--- a/arch/arm/kvm/psci.c ++++ b/arch/arm/kvm/psci.c +@@ -208,9 +208,10 @@ int kvm_psci_version(struct kvm_vcpu *vcpu) + + static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu) + { +- int ret = 1; ++ struct kvm *kvm = vcpu->kvm; + unsigned long psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0); + unsigned long val; ++ int ret = 1; + + switch (psci_fn) { + case PSCI_0_2_FN_PSCI_VERSION: +@@ -230,7 +231,9 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu) + break; + case PSCI_0_2_FN_CPU_ON: + case PSCI_0_2_FN64_CPU_ON: ++ mutex_lock(&kvm->lock); + val = kvm_psci_vcpu_on(vcpu); ++ mutex_unlock(&kvm->lock); + break; + case PSCI_0_2_FN_AFFINITY_INFO: + case PSCI_0_2_FN64_AFFINITY_INFO: +@@ -279,6 +282,7 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu) + + static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu) + { ++ struct kvm *kvm = vcpu->kvm; + unsigned long psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0); + unsigned long val; + +@@ -288,7 +292,9 @@ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu) + val = PSCI_RET_SUCCESS; + break; + case KVM_PSCI_FN_CPU_ON: ++ mutex_lock(&kvm->lock); + val = kvm_psci_vcpu_on(vcpu); ++ mutex_unlock(&kvm->lock); + break; + default: + val = PSCI_RET_NOT_SUPPORTED; +-- +2.12.0 + diff --git a/queue/KVM-nVMX-do-not-leak-PML-full-vmexit-to-L1.patch b/queue/KVM-nVMX-do-not-leak-PML-full-vmexit-to-L1.patch new file mode 100644 index 0000000..5a11d33 --- /dev/null +++ b/queue/KVM-nVMX-do-not-leak-PML-full-vmexit-to-L1.patch @@ -0,0 +1,38 @@ +From ab007cc94ff9d82f5a8db8363b3becbd946e58cf Mon Sep 17 00:00:00 2001 +From: Ladi Prosek <lprosek@redhat.com> +Date: Fri, 31 Mar 2017 10:19:26 +0200 +Subject: [PATCH] KVM: nVMX: do not leak PML full vmexit to L1 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit ab007cc94ff9d82f5a8db8363b3becbd946e58cf upstream. + +The PML feature is not exposed to guests so we should not be forwarding +the vmexit either. + +This commit fixes BSOD 0x20001 (HYPERVISOR_ERROR) when running Hyper-V +enabled Windows Server 2016 in L1 on hardware that supports PML. + +Fixes: 843e4330573c ("KVM: VMX: Add PML support in VMX") +Signed-off-by: Ladi Prosek <lprosek@redhat.com> +Reviewed-by: David Hildenbrand <david@redhat.com> +Signed-off-by: Radim Krčmář <rkrcmar@redhat.com> + +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index 2ee00dbbbd51..605183291069 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -8198,6 +8198,9 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) + return nested_cpu_has2(vmcs12, SECONDARY_EXEC_XSAVES); + case EXIT_REASON_PREEMPTION_TIMER: + return false; ++ case EXIT_REASON_PML_FULL: ++ /* We don't expose PML support to L1. */ ++ return false; + default: + return true; + } +-- +2.12.0 + diff --git a/queue/KVM-nVMX-initialize-PML-fields-in-vmcs02.patch b/queue/KVM-nVMX-initialize-PML-fields-in-vmcs02.patch new file mode 100644 index 0000000..cc3283e --- /dev/null +++ b/queue/KVM-nVMX-initialize-PML-fields-in-vmcs02.patch @@ -0,0 +1,44 @@ +From 1fb883bb827ee8efc1cc9ea0154f953f8a219d38 Mon Sep 17 00:00:00 2001 +From: Ladi Prosek <lprosek@redhat.com> +Date: Tue, 4 Apr 2017 14:18:53 +0200 +Subject: [PATCH] KVM: nVMX: initialize PML fields in vmcs02 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 1fb883bb827ee8efc1cc9ea0154f953f8a219d38 upstream. + +L2 was running with uninitialized PML fields which led to incomplete +dirty bitmap logging. This manifested as all kinds of subtle erratic +behavior of the nested guest. + +Fixes: 843e4330573c ("KVM: VMX: Add PML support in VMX") +Signed-off-by: Ladi Prosek <lprosek@redhat.com> +Signed-off-by: Radim Krčmář <rkrcmar@redhat.com> + +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index 605183291069..259e9b28ccf8 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -10270,6 +10270,18 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, + + } + ++ if (enable_pml) { ++ /* ++ * Conceptually we want to copy the PML address and index from ++ * vmcs01 here, and then back to vmcs01 on nested vmexit. But, ++ * since we always flush the log on each vmexit, this happens ++ * to be equivalent to simply resetting the fields in vmcs02. ++ */ ++ ASSERT(vmx->pml_pg); ++ vmcs_write64(PML_ADDRESS, page_to_phys(vmx->pml_pg)); ++ vmcs_write16(GUEST_PML_INDEX, PML_ENTITY_NUM - 1); ++ } ++ + if (nested_cpu_has_ept(vmcs12)) { + kvm_mmu_unload(vcpu); + nested_ept_init_mmu_context(vcpu); +-- +2.12.0 + diff --git a/queue/KVM-x86-fix-user-triggerable-warning-in-kvm_apic_acc.patch b/queue/KVM-x86-fix-user-triggerable-warning-in-kvm_apic_acc.patch new file mode 100644 index 0000000..6f66080 --- /dev/null +++ b/queue/KVM-x86-fix-user-triggerable-warning-in-kvm_apic_acc.patch @@ -0,0 +1,57 @@ +From 28bf28887976d8881a3a59491896c718fade7355 Mon Sep 17 00:00:00 2001 +From: David Hildenbrand <david@redhat.com> +Date: Thu, 23 Mar 2017 11:46:03 +0100 +Subject: [PATCH] KVM: x86: fix user triggerable warning in + kvm_apic_accept_events() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 28bf28887976d8881a3a59491896c718fade7355 upstream. + +If we already entered/are about to enter SMM, don't allow switching to +INIT/SIPI_RECEIVED, otherwise the next call to kvm_apic_accept_events() +will report a warning. + +Same applies if we are already in MP state INIT_RECEIVED and SMM is +requested to be turned on. Refuse to set the VCPU events in this case. + +Fixes: cd7764fe9f73 ("KVM: x86: latch INITs while in system management mode") +Cc: stable@vger.kernel.org # 4.2+ +Reported-by: Dmitry Vyukov <dvyukov@google.com> +Signed-off-by: David Hildenbrand <david@redhat.com> +Signed-off-by: Radim Krčmář <rkrcmar@redhat.com> + +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index bb3a1531b249..722fe854985e 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -3114,6 +3114,12 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, + (events->exception.nr > 31 || events->exception.nr == NMI_VECTOR)) + return -EINVAL; + ++ /* INITs are latched while in SMM */ ++ if (events->flags & KVM_VCPUEVENT_VALID_SMM && ++ (events->smi.smm || events->smi.pending) && ++ vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED) ++ return -EINVAL; ++ + process_nmi(vcpu); + vcpu->arch.exception.pending = events->exception.injected; + vcpu->arch.exception.nr = events->exception.nr; +@@ -7342,6 +7348,12 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, + mp_state->mp_state != KVM_MP_STATE_RUNNABLE) + return -EINVAL; + ++ /* INITs are latched while in SMM */ ++ if ((is_smm(vcpu) || vcpu->arch.smi_pending) && ++ (mp_state->mp_state == KVM_MP_STATE_SIPI_RECEIVED || ++ mp_state->mp_state == KVM_MP_STATE_INIT_RECEIVED)) ++ return -EINVAL; ++ + if (mp_state->mp_state == KVM_MP_STATE_SIPI_RECEIVED) { + vcpu->arch.mp_state = KVM_MP_STATE_INIT_RECEIVED; + set_bit(KVM_APIC_SIPI, &vcpu->arch.apic->pending_events); +-- +2.12.0 + diff --git a/queue/MIPS-Avoid-BUG-warning-in-arch_check_elf.patch b/queue/MIPS-Avoid-BUG-warning-in-arch_check_elf.patch new file mode 100644 index 0000000..8f3d4fd --- /dev/null +++ b/queue/MIPS-Avoid-BUG-warning-in-arch_check_elf.patch @@ -0,0 +1,45 @@ +From c46f59e90226fa5bfcc83650edebe84ae47d454b Mon Sep 17 00:00:00 2001 +From: James Cowgill <James.Cowgill@imgtec.com> +Date: Tue, 11 Apr 2017 13:51:07 +0100 +Subject: [PATCH] MIPS: Avoid BUG warning in arch_check_elf + +commit c46f59e90226fa5bfcc83650edebe84ae47d454b upstream. + +arch_check_elf contains a usage of current_cpu_data that will call +smp_processor_id() with preemption enabled and therefore triggers a +"BUG: using smp_processor_id() in preemptible" warning when an fpxx +executable is loaded. + +As a follow-up to commit b244614a60ab ("MIPS: Avoid a BUG warning during +prctl(PR_SET_FP_MODE, ...)"), apply the same fix to arch_check_elf by +using raw_current_cpu_data instead. The rationale quoted from the previous +commit: + +"It is assumed throughout the kernel that if any CPU has an FPU, then +all CPUs would have an FPU as well, so it is safe to perform the check +with preemption enabled - change the code to use raw_ variant of the +check to avoid the warning." + +Fixes: 46490b572544 ("MIPS: kernel: elf: Improve the overall ABI and FPU mode checks") +Signed-off-by: James Cowgill <James.Cowgill@imgtec.com> +CC: <stable@vger.kernel.org> # 4.0+ +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/15951/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> + +diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c +index 6430bff21fff..5c429d70e17f 100644 +--- a/arch/mips/kernel/elf.c ++++ b/arch/mips/kernel/elf.c +@@ -257,7 +257,7 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, void *_interp_ehdr, + else if ((prog_req.fr1 && prog_req.frdefault) || + (prog_req.single && !prog_req.frdefault)) + /* Make sure 64-bit MIPS III/IV/64R1 will not pick FR1 */ +- state->overall_fp_mode = ((current_cpu_data.fpu_id & MIPS_FPIR_F64) && ++ state->overall_fp_mode = ((raw_current_cpu_data.fpu_id & MIPS_FPIR_F64) && + cpu_has_mips_r2_r6) ? + FP_FR1 : FP_FR0; + else if (prog_req.fr1) +-- +2.12.0 + diff --git a/queue/MIPS-KGDB-Use-kernel-context-for-sleeping-threads.patch b/queue/MIPS-KGDB-Use-kernel-context-for-sleeping-threads.patch new file mode 100644 index 0000000..d698f0e --- /dev/null +++ b/queue/MIPS-KGDB-Use-kernel-context-for-sleeping-threads.patch @@ -0,0 +1,124 @@ +From 162b270c664dca2e0944308e92f9fcc887151a72 Mon Sep 17 00:00:00 2001 +From: James Hogan <james.hogan@imgtec.com> +Date: Thu, 30 Mar 2017 16:06:02 +0100 +Subject: [PATCH] MIPS: KGDB: Use kernel context for sleeping threads + +commit 162b270c664dca2e0944308e92f9fcc887151a72 upstream. + +KGDB is a kernel debug stub and it can't be used to debug userland as it +can only safely access kernel memory. + +On MIPS however KGDB has always got the register state of sleeping +processes from the userland register context at the beginning of the +kernel stack. This is meaningless for kernel threads (which never enter +userland), and for user threads it prevents the user seeing what it is +doing while in the kernel: + +(gdb) info threads + Id Target Id Frame + ... + 3 Thread 2 (kthreadd) 0x0000000000000000 in ?? () + 2 Thread 1 (init) 0x000000007705c4b4 in ?? () + 1 Thread -2 (shadowCPU0) 0xffffffff8012524c in arch_kgdb_breakpoint () at arch/mips/kernel/kgdb.c:201 + +Get the register state instead from the (partial) kernel register +context stored in the task's thread_struct for resume() to restore. All +threads now correctly appear to be in context_switch(): + +(gdb) info threads + Id Target Id Frame + ... + 3 Thread 2 (kthreadd) context_switch (rq=<optimized out>, cookie=..., next=<optimized out>, prev=0x0) at kernel/sched/core.c:2903 + 2 Thread 1 (init) context_switch (rq=<optimized out>, cookie=..., next=<optimized out>, prev=0x0) at kernel/sched/core.c:2903 + 1 Thread -2 (shadowCPU0) 0xffffffff8012524c in arch_kgdb_breakpoint () at arch/mips/kernel/kgdb.c:201 + +Call clobbered registers which aren't saved and exception registers +(BadVAddr & Cause) which can't be easily determined without stack +unwinding are reported as 0. The PC is taken from the return address, +such that the state presented matches that found immediately after +returning from resume(). + +Fixes: 8854700115ec ("[MIPS] kgdb: add arch support for the kernel's kgdb core") +Signed-off-by: James Hogan <james.hogan@imgtec.com> +Cc: Jason Wessel <jason.wessel@windriver.com> +Cc: linux-mips@linux-mips.org +Cc: stable@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/15829/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> + +diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c +index 1f4bd222ba76..eb6c0d582626 100644 +--- a/arch/mips/kernel/kgdb.c ++++ b/arch/mips/kernel/kgdb.c +@@ -244,9 +244,6 @@ static int compute_signal(int tt) + void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) + { + int reg; +- struct thread_info *ti = task_thread_info(p); +- unsigned long ksp = (unsigned long)ti + THREAD_SIZE - 32; +- struct pt_regs *regs = (struct pt_regs *)ksp - 1; + #if (KGDB_GDB_REG_SIZE == 32) + u32 *ptr = (u32 *)gdb_regs; + #else +@@ -254,25 +251,46 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) + #endif + + for (reg = 0; reg < 16; reg++) +- *(ptr++) = regs->regs[reg]; ++ *(ptr++) = 0; + + /* S0 - S7 */ +- for (reg = 16; reg < 24; reg++) +- *(ptr++) = regs->regs[reg]; ++ *(ptr++) = p->thread.reg16; ++ *(ptr++) = p->thread.reg17; ++ *(ptr++) = p->thread.reg18; ++ *(ptr++) = p->thread.reg19; ++ *(ptr++) = p->thread.reg20; ++ *(ptr++) = p->thread.reg21; ++ *(ptr++) = p->thread.reg22; ++ *(ptr++) = p->thread.reg23; + + for (reg = 24; reg < 28; reg++) + *(ptr++) = 0; + + /* GP, SP, FP, RA */ +- for (reg = 28; reg < 32; reg++) +- *(ptr++) = regs->regs[reg]; +- +- *(ptr++) = regs->cp0_status; +- *(ptr++) = regs->lo; +- *(ptr++) = regs->hi; +- *(ptr++) = regs->cp0_badvaddr; +- *(ptr++) = regs->cp0_cause; +- *(ptr++) = regs->cp0_epc; ++ *(ptr++) = (long)p; ++ *(ptr++) = p->thread.reg29; ++ *(ptr++) = p->thread.reg30; ++ *(ptr++) = p->thread.reg31; ++ ++ *(ptr++) = p->thread.cp0_status; ++ ++ /* lo, hi */ ++ *(ptr++) = 0; ++ *(ptr++) = 0; ++ ++ /* ++ * BadVAddr, Cause ++ * Ideally these would come from the last exception frame up the stack ++ * but that requires unwinding, otherwise we can't know much for sure. ++ */ ++ *(ptr++) = 0; ++ *(ptr++) = 0; ++ ++ /* ++ * PC ++ * use return address (RA), i.e. the moment after return from resume() ++ */ ++ *(ptr++) = p->thread.reg31; + } + + void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) +-- +2.12.0 + diff --git a/queue/MIPS-R2-on-R6-MULTU-MADDU-MSUBU-emulation-bugfix.patch b/queue/MIPS-R2-on-R6-MULTU-MADDU-MSUBU-emulation-bugfix.patch new file mode 100644 index 0000000..b072075 --- /dev/null +++ b/queue/MIPS-R2-on-R6-MULTU-MADDU-MSUBU-emulation-bugfix.patch @@ -0,0 +1,66 @@ +From d65e5677ad5b3a49c43f60ec07644dc1f87bbd2e Mon Sep 17 00:00:00 2001 +From: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com> +Date: Thu, 25 Aug 2016 10:37:38 -0700 +Subject: [PATCH] MIPS: R2-on-R6 MULTU/MADDU/MSUBU emulation bugfix + +commit d65e5677ad5b3a49c43f60ec07644dc1f87bbd2e upstream. + +MIPS instructions MULTU, MADDU and MSUBU emulation requires registers HI/LO +to be converted to signed 32bits before 64bit sign extension on MIPS64. + +Bug was found on running MIPS32 R2 test application on MIPS64 R6 kernel. + +Fixes: b0a668fb2038 ("MIPS: kernel: mips-r2-to-r6-emul: Add R2 emulator for MIPS R6") +Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com> +Reported-by: Nikola.Veljkovic@imgtec.com +Cc: paul.burton@imgtec.com +Cc: yamada.masahiro@socionext.com +Cc: akpm@linux-foundation.org +Cc: andrea.gelmini@gelma.net +Cc: macro@imgtec.com +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/14043/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> + +diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c +index ef2ca28a028b..d8f1cf1ec370 100644 +--- a/arch/mips/kernel/mips-r2-to-r6-emul.c ++++ b/arch/mips/kernel/mips-r2-to-r6-emul.c +@@ -433,8 +433,8 @@ static int multu_func(struct pt_regs *regs, u32 ir) + rs = regs->regs[MIPSInst_RS(ir)]; + res = (u64)rt * (u64)rs; + rt = res; +- regs->lo = (s64)rt; +- regs->hi = (s64)(res >> 32); ++ regs->lo = (s64)(s32)rt; ++ regs->hi = (s64)(s32)(res >> 32); + + MIPS_R2_STATS(muls); + +@@ -670,9 +670,9 @@ static int maddu_func(struct pt_regs *regs, u32 ir) + res += ((((s64)rt) << 32) | (u32)rs); + + rt = res; +- regs->lo = (s64)rt; ++ regs->lo = (s64)(s32)rt; + rs = res >> 32; +- regs->hi = (s64)rs; ++ regs->hi = (s64)(s32)rs; + + MIPS_R2_STATS(dsps); + +@@ -728,9 +728,9 @@ static int msubu_func(struct pt_regs *regs, u32 ir) + res = ((((s64)rt) << 32) | (u32)rs) - res; + + rt = res; +- regs->lo = (s64)rt; ++ regs->lo = (s64)(s32)rt; + rs = res >> 32; +- regs->hi = (s64)rs; ++ regs->hi = (s64)(s32)rs; + + MIPS_R2_STATS(dsps); + +-- +2.12.0 + diff --git a/queue/MIPS-cevt-r4k-Fix-out-of-bounds-array-access.patch b/queue/MIPS-cevt-r4k-Fix-out-of-bounds-array-access.patch new file mode 100644 index 0000000..9b20381 --- /dev/null +++ b/queue/MIPS-cevt-r4k-Fix-out-of-bounds-array-access.patch @@ -0,0 +1,87 @@ +From 9d7f29cdb4ca53506115cf1d7a02ce6013894df0 Mon Sep 17 00:00:00 2001 +From: James Hogan <james.hogan@imgtec.com> +Date: Wed, 5 Apr 2017 16:32:45 +0100 +Subject: [PATCH] MIPS: cevt-r4k: Fix out-of-bounds array access + +commit 9d7f29cdb4ca53506115cf1d7a02ce6013894df0 upstream. + +calculate_min_delta() may incorrectly access a 4th element of buf2[] +which only has 3 elements. This may trigger undefined behaviour and has +been reported to cause strange crashes in start_kernel() sometime after +timer initialization when built with GCC 5.3, possibly due to +register/stack corruption: + +sched_clock: 32 bits at 200MHz, resolution 5ns, wraps every 10737418237ns +CPU 0 Unable to handle kernel paging request at virtual address ffffb0aa, epc == 8067daa8, ra == 8067da84 +Oops[#1]: +CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.9.18 #51 +task: 8065e3e0 task.stack: 80644000 +$ 0 : 00000000 00000001 00000000 00000000 +$ 4 : 8065b4d0 00000000 805d0000 00000010 +$ 8 : 00000010 80321400 fffff000 812de408 +$12 : 00000000 00000000 00000000 ffffffff +$16 : 00000002 ffffffff 80660000 806a666c +$20 : 806c0000 00000000 00000000 00000000 +$24 : 00000000 00000010 +$28 : 80644000 80645ed0 00000000 8067da84 +Hi : 00000000 +Lo : 00000000 +epc : 8067daa8 start_kernel+0x33c/0x500 +ra : 8067da84 start_kernel+0x318/0x500 +Status: 11000402 KERNEL EXL +Cause : 4080040c (ExcCode 03) +BadVA : ffffb0aa +PrId : 0501992c (MIPS 1004Kc) +Modules linked in: +Process swapper/0 (pid: 0, threadinfo=80644000, task=8065e3e0, tls=00000000) +Call Trace: +[<8067daa8>] start_kernel+0x33c/0x500 +Code: 24050240 0c0131f9 24849c64 <a200b0a8> 41606020 000000c0 0c1a45e6 00000000 0c1a5f44 + +UBSAN also detects the same issue: + +================================================================ +UBSAN: Undefined behaviour in arch/mips/kernel/cevt-r4k.c:85:41 +load of address 80647e4c with insufficient space +for an object of type 'unsigned int' +CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.9.18 #47 +Call Trace: +[<80028f70>] show_stack+0x88/0xa4 +[<80312654>] dump_stack+0x84/0xc0 +[<8034163c>] ubsan_epilogue+0x14/0x50 +[<803417d8>] __ubsan_handle_type_mismatch+0x160/0x168 +[<8002dab0>] r4k_clockevent_init+0x544/0x764 +[<80684d34>] time_init+0x18/0x90 +[<8067fa5c>] start_kernel+0x2f0/0x500 +================================================================= + +buf2[] is intentionally only 3 elements so that the last element is the +median once 5 samples have been inserted, so explicitly prevent the +possibility of comparing against the 4th element rather than extending +the array. + +Fixes: 1fa405552e33f2 ("MIPS: cevt-r4k: Dynamically calculate min_delta_ns") +Reported-by: Rabin Vincent <rabinv@axis.com> +Signed-off-by: James Hogan <james.hogan@imgtec.com> +Tested-by: Rabin Vincent <rabinv@axis.com> +Cc: linux-mips@linux-mips.org +Cc: <stable@vger.kernel.org> # 4.7.x- +Patchwork: https://patchwork.linux-mips.org/patch/15892/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> + +diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c +index 804d2a2a19fe..dd6a18bc10ab 100644 +--- a/arch/mips/kernel/cevt-r4k.c ++++ b/arch/mips/kernel/cevt-r4k.c +@@ -80,7 +80,7 @@ static unsigned int calculate_min_delta(void) + } + + /* Sorted insert of 75th percentile into buf2 */ +- for (k = 0; k < i; ++k) { ++ for (k = 0; k < i && k < ARRAY_SIZE(buf2); ++k) { + if (buf1[ARRAY_SIZE(buf1) - 1] < buf2[k]) { + l = min_t(unsigned int, + i, ARRAY_SIZE(buf2) - 1); +-- +2.12.0 + diff --git a/queue/Revert-KVM-nested-VMX-disable-perf-cpuid-reporting.patch b/queue/Revert-KVM-nested-VMX-disable-perf-cpuid-reporting.patch new file mode 100644 index 0000000..93654d4 --- /dev/null +++ b/queue/Revert-KVM-nested-VMX-disable-perf-cpuid-reporting.patch @@ -0,0 +1,54 @@ +From 0b4c208d443ba2af82b4c70f99ca8df31e9a0020 Mon Sep 17 00:00:00 2001 +From: Jim Mattson <jmattson@google.com> +Date: Tue, 20 Dec 2016 16:34:50 -0800 +Subject: [PATCH] Revert "KVM: nested VMX: disable perf cpuid reporting" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 0b4c208d443ba2af82b4c70f99ca8df31e9a0020 upstream. + +This reverts commit bc6134942dbbf31c25e9bd7c876be5da81c9e1ce. + +A CPUID instruction executed in VMX non-root mode always causes a +VM-exit, regardless of the leaf being queried. + +Fixes: bc6134942dbb ("KVM: nested VMX: disable perf cpuid reporting") +Signed-off-by: Jim Mattson <jmattson@google.com> +[The issue solved by bc6134942dbb has been resolved with ff651cb613b4 + ("KVM: nVMX: Add nested msr load/restore algorithm").] +Signed-off-by: Radim Krčmář <rkrcmar@redhat.com> + +diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c +index 09c2ac741567..c0e2036217ad 100644 +--- a/arch/x86/kvm/cpuid.c ++++ b/arch/x86/kvm/cpuid.c +@@ -861,12 +861,6 @@ void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) + if (!best) + best = check_cpuid_limit(vcpu, function, index); + +- /* +- * Perfmon not yet supported for L2 guest. +- */ +- if (is_guest_mode(vcpu) && function == 0xa) +- best = NULL; +- + if (best) { + *eax = best->eax; + *ebx = best->ebx; +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index 4e691035a32d..c7bafa1457e2 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -8203,8 +8203,6 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) + case EXIT_REASON_TASK_SWITCH: + return true; + case EXIT_REASON_CPUID: +- if (kvm_register_read(vcpu, VCPU_REGS_RAX) == 0xa) +- return false; + return true; + case EXIT_REASON_HLT: + return nested_cpu_has(vmcs12, CPU_BASED_HLT_EXITING); +-- +2.12.0 + diff --git a/queue/SMB3-Work-around-mount-failure-when-using-SMB3-diale.patch b/queue/SMB3-Work-around-mount-failure-when-using-SMB3-diale.patch new file mode 100644 index 0000000..196ea86 --- /dev/null +++ b/queue/SMB3-Work-around-mount-failure-when-using-SMB3-diale.patch @@ -0,0 +1,55 @@ +From 7db0a6efdc3e990cdfd4b24820d010e9eb7890ad Mon Sep 17 00:00:00 2001 +From: Steve French <smfrench@gmail.com> +Date: Wed, 3 May 2017 21:12:20 -0500 +Subject: [PATCH] SMB3: Work around mount failure when using SMB3 dialect to + Macs + +commit 7db0a6efdc3e990cdfd4b24820d010e9eb7890ad upstream. + +Macs send the maximum buffer size in response on ioctl to validate +negotiate security information, which causes us to fail the mount +as the response buffer is larger than the expected response. + +Changed ioctl response processing to allow for padding of validate +negotiate ioctl response and limit the maximum response size to +maximum buffer size. + +Signed-off-by: Steve French <steve.french@primarydata.com> +CC: Stable <stable@vger.kernel.org> + +diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c +index 02da648041fc..0fd63f0bc440 100644 +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -632,8 +632,12 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) + } + + if (rsplen != sizeof(struct validate_negotiate_info_rsp)) { +- cifs_dbg(VFS, "invalid size of protocol negotiate response\n"); +- return -EIO; ++ cifs_dbg(VFS, "invalid protocol negotiate response size: %d\n", ++ rsplen); ++ ++ /* relax check since Mac returns max bufsize allowed on ioctl */ ++ if (rsplen > CIFSMaxBufSize) ++ return -EIO; + } + + /* check validate negotiate info response matches what we got earlier */ +@@ -1853,8 +1857,12 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, + * than one credit. Windows typically sets this smaller, but for some + * ioctls it may be useful to allow server to send more. No point + * limiting what the server can send as long as fits in one credit ++ * Unfortunately - we can not handle more than CIFS_MAX_MSG_SIZE ++ * (by default, note that it can be overridden to make max larger) ++ * in responses (except for read responses which can be bigger. ++ * We may want to bump this limit up + */ +- req->MaxOutputResponse = cpu_to_le32(0xFF00); /* < 64K uses 1 credit */ ++ req->MaxOutputResponse = cpu_to_le32(CIFSMaxBufSize); + + if (is_fsctl) + req->Flags = cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL); +-- +2.12.0 + diff --git a/queue/Set-unicode-flag-on-cifs-echo-request-to-avoid-Mac-e.patch b/queue/Set-unicode-flag-on-cifs-echo-request-to-avoid-Mac-e.patch new file mode 100644 index 0000000..53fdc3f --- /dev/null +++ b/queue/Set-unicode-flag-on-cifs-echo-request-to-avoid-Mac-e.patch @@ -0,0 +1,33 @@ +From 26c9cb668c7fbf9830516b75d8bee70b699ed449 Mon Sep 17 00:00:00 2001 +From: Steve French <smfrench@gmail.com> +Date: Tue, 2 May 2017 13:35:20 -0500 +Subject: [PATCH] Set unicode flag on cifs echo request to avoid Mac error + +commit 26c9cb668c7fbf9830516b75d8bee70b699ed449 upstream. + +Mac requires the unicode flag to be set for cifs, even for the smb +echo request (which doesn't have strings). + +Without this Mac rejects the periodic echo requests (when mounting +with cifs) that we use to check if server is down + +Signed-off-by: Steve French <smfrench@gmail.com> +CC: Stable <stable@vger.kernel.org> + +diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c +index 5d21f00ae341..205fd94f52fd 100644 +--- a/fs/cifs/cifssmb.c ++++ b/fs/cifs/cifssmb.c +@@ -718,6 +718,9 @@ CIFSSMBEcho(struct TCP_Server_Info *server) + if (rc) + return rc; + ++ if (server->capabilities & CAP_UNICODE) ++ smb->hdr.Flags2 |= SMBFLG2_UNICODE; ++ + /* set up echo request */ + smb->hdr.Tid = 0xffff; + smb->hdr.WordCount = 1; +-- +2.12.0 + diff --git a/queue/USB-Proper-handling-of-Race-Condition-when-two-USB-c.patch b/queue/USB-Proper-handling-of-Race-Condition-when-two-USB-c.patch new file mode 100644 index 0000000..64cc4e5 --- /dev/null +++ b/queue/USB-Proper-handling-of-Race-Condition-when-two-USB-c.patch @@ -0,0 +1,61 @@ +From 2f86a96be0ccb1302b7eee7855dbee5ce4dc5dfb Mon Sep 17 00:00:00 2001 +From: Ajay Kaher <ajay.kaher@samsung.com> +Date: Tue, 28 Mar 2017 08:09:32 -0400 +Subject: [PATCH] USB: Proper handling of Race Condition when two USB class + drivers try to call init_usb_class simultaneously + +commit 2f86a96be0ccb1302b7eee7855dbee5ce4dc5dfb upstream. + +There is race condition when two USB class drivers try to call +init_usb_class at the same time and leads to crash. +code path: probe->usb_register_dev->init_usb_class + +To solve this, mutex locking has been added in init_usb_class() and +destroy_usb_class(). + +As pointed by Alan, removed "if (usb_class)" test from destroy_usb_class() +because usb_class can never be NULL there. + +Signed-off-by: Ajay Kaher <ajay.kaher@samsung.com> +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Cc: stable <stable@vger.kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c +index e26bd5e773ad..87ad6b6bfee8 100644 +--- a/drivers/usb/core/file.c ++++ b/drivers/usb/core/file.c +@@ -29,6 +29,7 @@ + #define MAX_USB_MINORS 256 + static const struct file_operations *usb_minors[MAX_USB_MINORS]; + static DECLARE_RWSEM(minor_rwsem); ++static DEFINE_MUTEX(init_usb_class_mutex); + + static int usb_open(struct inode *inode, struct file *file) + { +@@ -111,8 +112,9 @@ static void release_usb_class(struct kref *kref) + + static void destroy_usb_class(void) + { +- if (usb_class) +- kref_put(&usb_class->kref, release_usb_class); ++ mutex_lock(&init_usb_class_mutex); ++ kref_put(&usb_class->kref, release_usb_class); ++ mutex_unlock(&init_usb_class_mutex); + } + + int usb_major_init(void) +@@ -173,7 +175,10 @@ int usb_register_dev(struct usb_interface *intf, + if (intf->minor >= 0) + return -EADDRINUSE; + ++ mutex_lock(&init_usb_class_mutex); + retval = init_usb_class(); ++ mutex_unlock(&init_usb_class_mutex); ++ + if (retval) + return retval; + +-- +2.12.0 + diff --git a/queue/USB-Revert-cdc-wdm-fix-out-of-sync-due-to-missing-no.patch b/queue/USB-Revert-cdc-wdm-fix-out-of-sync-due-to-missing-no.patch new file mode 100644 index 0000000..cd06ee8 --- /dev/null +++ b/queue/USB-Revert-cdc-wdm-fix-out-of-sync-due-to-missing-no.patch @@ -0,0 +1,204 @@ +From 19445816996d1a89682c37685fe95959631d9f32 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no> +Date: Fri, 21 Apr 2017 10:01:29 +0200 +Subject: [PATCH] USB: Revert "cdc-wdm: fix "out-of-sync" due to missing + notifications" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 19445816996d1a89682c37685fe95959631d9f32 upstream. + +This reverts commit 833415a3e781 ("cdc-wdm: fix "out-of-sync" due to +missing notifications") + +There have been several reports of wdm_read returning unexpected EIO +errors with QMI devices using the qmi_wwan driver. The reporters +confirm that reverting prevents these errors. I have been unable to +reproduce the bug myself, and have no explanation to offer either. But +reverting is the safe choice here, given that the commit was an +attempt to work around a firmware problem. Living with a firmware +problem is still better than adding driver bugs. + +Reported-by: Kasper Holtze <kasper@holtze.dk> +Reported-by: Aleksander Morgado <aleksander@aleksander.es> +Reported-by: Daniele Palmas <dnlplm@gmail.com> +Cc: <stable@vger.kernel.org> # v4.9+ +Fixes: 833415a3e781 ("cdc-wdm: fix "out-of-sync" due to missing notifications") +Signed-off-by: Bjørn Mork <bjorn@mork.no> +Acked-by: Oliver Neukum <oneukum@suse.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c +index 8fda45a45bd3..08669fee6d7f 100644 +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -58,7 +58,6 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); + #define WDM_SUSPENDING 8 + #define WDM_RESETTING 9 + #define WDM_OVERFLOW 10 +-#define WDM_DRAIN_ON_OPEN 11 + + #define WDM_MAX 16 + +@@ -182,7 +181,7 @@ static void wdm_in_callback(struct urb *urb) + "nonzero urb status received: -ESHUTDOWN\n"); + goto skip_error; + case -EPIPE: +- dev_dbg(&desc->intf->dev, ++ dev_err(&desc->intf->dev, + "nonzero urb status received: -EPIPE\n"); + break; + default: +@@ -210,25 +209,6 @@ static void wdm_in_callback(struct urb *urb) + desc->reslength = length; + } + } +- +- /* +- * Handling devices with the WDM_DRAIN_ON_OPEN flag set: +- * If desc->resp_count is unset, then the urb was submitted +- * without a prior notification. If the device returned any +- * data, then this implies that it had messages queued without +- * notifying us. Continue reading until that queue is flushed. +- */ +- if (!desc->resp_count) { +- if (!length) { +- /* do not propagate the expected -EPIPE */ +- desc->rerr = 0; +- goto unlock; +- } +- dev_dbg(&desc->intf->dev, "got %d bytes without notification\n", length); +- set_bit(WDM_RESPONDING, &desc->flags); +- usb_submit_urb(desc->response, GFP_ATOMIC); +- } +- + skip_error: + set_bit(WDM_READ, &desc->flags); + wake_up(&desc->wait); +@@ -243,7 +223,6 @@ skip_error: + service_outstanding_interrupt(desc); + } + +-unlock: + spin_unlock(&desc->iuspin); + } + +@@ -686,17 +665,6 @@ static int wdm_open(struct inode *inode, struct file *file) + dev_err(&desc->intf->dev, + "Error submitting int urb - %d\n", rv); + rv = usb_translate_errors(rv); +- } else if (test_bit(WDM_DRAIN_ON_OPEN, &desc->flags)) { +- /* +- * Some devices keep pending messages queued +- * without resending notifications. We must +- * flush the message queue before we can +- * assume a one-to-one relationship between +- * notifications and messages in the queue +- */ +- dev_dbg(&desc->intf->dev, "draining queued data\n"); +- set_bit(WDM_RESPONDING, &desc->flags); +- rv = usb_submit_urb(desc->response, GFP_KERNEL); + } + } else { + rv = 0; +@@ -803,8 +771,7 @@ static void wdm_rxwork(struct work_struct *work) + /* --- hotplug --- */ + + static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor *ep, +- u16 bufsize, int (*manage_power)(struct usb_interface *, int), +- bool drain_on_open) ++ u16 bufsize, int (*manage_power)(struct usb_interface *, int)) + { + int rv = -ENOMEM; + struct wdm_device *desc; +@@ -891,68 +858,6 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor + + desc->manage_power = manage_power; + +- /* +- * "drain_on_open" enables a hack to work around a firmware +- * issue observed on network functions, in particular MBIM +- * functions. +- * +- * Quoting section 7 of the CDC-WMC r1.1 specification: +- * +- * "The firmware shall interpret GetEncapsulatedResponse as a +- * request to read response bytes. The firmware shall send +- * the next wLength bytes from the response. The firmware +- * shall allow the host to retrieve data using any number of +- * GetEncapsulatedResponse requests. The firmware shall +- * return a zero- length reply if there are no data bytes +- * available. +- * +- * The firmware shall send ResponseAvailable notifications +- * periodically, using any appropriate algorithm, to inform +- * the host that there is data available in the reply +- * buffer. The firmware is allowed to send ResponseAvailable +- * notifications even if there is no data available, but +- * this will obviously reduce overall performance." +- * +- * These requirements, although they make equally sense, are +- * often not implemented by network functions. Some firmwares +- * will queue data indefinitely, without ever resending a +- * notification. The result is that the driver and firmware +- * loses "syncronization" if the driver ever fails to respond +- * to a single notification, something which easily can happen +- * on release(). When this happens, the driver will appear to +- * never receive notifications for the most current data. Each +- * notification will only cause a single read, which returns +- * the oldest data in the firmware's queue. +- * +- * The "drain_on_open" hack resolves the situation by draining +- * data from the firmware until none is returned, without a +- * prior notification. +- * +- * This will inevitably race with the firmware, risking that +- * we read data from the device before handling the associated +- * notification. To make things worse, some of the devices +- * needing the hack do not implement the "return zero if no +- * data is available" requirement either. Instead they return +- * an error on the subsequent read in this case. This means +- * that "winning" the race can cause an unexpected EIO to +- * userspace. +- * +- * "winning" the race is more likely on resume() than on +- * open(), and the unexpected error is more harmful in the +- * middle of an open session. The hack is therefore only +- * applied on open(), and not on resume() where it logically +- * would be equally necessary. So we define open() as the only +- * driver <-> device "syncronization point". Should we happen +- * to lose a notification after open(), then syncronization +- * will be lost until release() +- * +- * The hack should not be enabled for CDC WDM devices +- * conforming to the CDC-WMC r1.1 specification. This is +- * ensured by setting drain_on_open to false in wdm_probe(). +- */ +- if (drain_on_open) +- set_bit(WDM_DRAIN_ON_OPEN, &desc->flags); +- + spin_lock(&wdm_device_list_lock); + list_add(&desc->device_list, &wdm_device_list); + spin_unlock(&wdm_device_list_lock); +@@ -1006,7 +911,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) + goto err; + ep = &iface->endpoint[0].desc; + +- rv = wdm_create(intf, ep, maxcom, &wdm_manage_power, false); ++ rv = wdm_create(intf, ep, maxcom, &wdm_manage_power); + + err: + return rv; +@@ -1038,7 +943,7 @@ struct usb_driver *usb_cdc_wdm_register(struct usb_interface *intf, + { + int rv = -EINVAL; + +- rv = wdm_create(intf, ep, bufsize, manage_power, true); ++ rv = wdm_create(intf, ep, bufsize, manage_power); + if (rv < 0) + goto err; + +-- +2.12.0 + diff --git a/queue/USB-serial-ark3116-fix-open-error-handling.patch b/queue/USB-serial-ark3116-fix-open-error-handling.patch new file mode 100644 index 0000000..e5ffe8b --- /dev/null +++ b/queue/USB-serial-ark3116-fix-open-error-handling.patch @@ -0,0 +1,79 @@ +From b631433b175f1002a31020e09bbfc2e5caecf290 Mon Sep 17 00:00:00 2001 +From: Johan Hovold <johan@kernel.org> +Date: Thu, 12 Jan 2017 14:56:10 +0100 +Subject: [PATCH] USB: serial: ark3116: fix open error handling + +commit b631433b175f1002a31020e09bbfc2e5caecf290 upstream. + +Fix open error handling which failed to detect errors when reading the +MSR and LSR registers, something which could lead to the shadow +registers being initialised from errnos. + +Note that calling the generic close implementation is sufficient in the +error paths as the interrupt urb has not yet been submitted and the +register updates have not been made. + +Fixes: f4c1e8d597d1 ("USB: ark3116: Make existing functions 16450-aware +and add close and release functions.") +Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Johan Hovold <johan@kernel.org> + +diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c +index 7812052dc700..754fc3e41005 100644 +--- a/drivers/usb/serial/ark3116.c ++++ b/drivers/usb/serial/ark3116.c +@@ -373,23 +373,29 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) + dev_dbg(&port->dev, + "%s - usb_serial_generic_open failed: %d\n", + __func__, result); +- goto err_out; ++ goto err_free; + } + + /* remove any data still left: also clears error state */ + ark3116_read_reg(serial, UART_RX, buf); + + /* read modem status */ +- priv->msr = ark3116_read_reg(serial, UART_MSR, buf); ++ result = ark3116_read_reg(serial, UART_MSR, buf); ++ if (result < 0) ++ goto err_close; ++ priv->msr = *buf; ++ + /* read line status */ +- priv->lsr = ark3116_read_reg(serial, UART_LSR, buf); ++ result = ark3116_read_reg(serial, UART_LSR, buf); ++ if (result < 0) ++ goto err_close; ++ priv->lsr = *buf; + + result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); + if (result) { + dev_err(&port->dev, "submit irq_in urb failed %d\n", + result); +- ark3116_close(port); +- goto err_out; ++ goto err_close; + } + + /* activate interrupts */ +@@ -402,8 +408,15 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) + if (tty) + ark3116_set_termios(tty, port, NULL); + +-err_out: + kfree(buf); ++ ++ return 0; ++ ++err_close: ++ usb_serial_generic_close(port); ++err_free: ++ kfree(buf); ++ + return result; + } + +-- +2.12.0 + diff --git a/queue/USB-serial-digi_acceleport-fix-incomplete-rx-sanity-.patch b/queue/USB-serial-digi_acceleport-fix-incomplete-rx-sanity-.patch new file mode 100644 index 0000000..e373275 --- /dev/null +++ b/queue/USB-serial-digi_acceleport-fix-incomplete-rx-sanity-.patch @@ -0,0 +1,79 @@ +From 1b0aed2b1600f6e5c7b9acfbd610a4e351ef5232 Mon Sep 17 00:00:00 2001 +From: Johan Hovold <johan@kernel.org> +Date: Tue, 31 Jan 2017 17:17:28 +0100 +Subject: [PATCH] USB: serial: digi_acceleport: fix incomplete rx sanity check + +commit 1b0aed2b1600f6e5c7b9acfbd610a4e351ef5232 upstream. + +Make sure the received data has the required headers before parsing it. + +Also drop the redundant urb-status check, which has already been handled +by the caller. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Johan Hovold <johan@kernel.org> + +diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c +index 3b610f1e3f7c..eb433922598c 100644 +--- a/drivers/usb/serial/digi_acceleport.c ++++ b/drivers/usb/serial/digi_acceleport.c +@@ -1398,25 +1398,30 @@ static int digi_read_inb_callback(struct urb *urb) + { + struct usb_serial_port *port = urb->context; + struct digi_port *priv = usb_get_serial_port_data(port); +- int opcode = ((unsigned char *)urb->transfer_buffer)[0]; +- int len = ((unsigned char *)urb->transfer_buffer)[1]; +- int port_status = ((unsigned char *)urb->transfer_buffer)[2]; +- unsigned char *data = ((unsigned char *)urb->transfer_buffer) + 3; ++ unsigned char *buf = urb->transfer_buffer; ++ int opcode; ++ int len; ++ int port_status; ++ unsigned char *data; + int flag, throttled; +- int status = urb->status; +- +- /* do not process callbacks on closed ports */ +- /* but do continue the read chain */ +- if (urb->status == -ENOENT) +- return 0; + + /* short/multiple packet check */ ++ if (urb->actual_length < 2) { ++ dev_warn(&port->dev, "short packet received\n"); ++ return -1; ++ } ++ ++ opcode = buf[0]; ++ len = buf[1]; ++ + if (urb->actual_length != len + 2) { +- dev_err(&port->dev, "%s: INCOMPLETE OR MULTIPLE PACKET, " +- "status=%d, port=%d, opcode=%d, len=%d, " +- "actual_length=%d, status=%d\n", __func__, status, +- priv->dp_port_num, opcode, len, urb->actual_length, +- port_status); ++ dev_err(&port->dev, "malformed packet received: port=%d, opcode=%d, len=%d, actual_length=%u\n", ++ priv->dp_port_num, opcode, len, urb->actual_length); ++ return -1; ++ } ++ ++ if (opcode == DIGI_CMD_RECEIVE_DATA && len < 1) { ++ dev_err(&port->dev, "malformed data packet received\n"); + return -1; + } + +@@ -1430,6 +1435,9 @@ static int digi_read_inb_callback(struct urb *urb) + + /* receive data */ + if (opcode == DIGI_CMD_RECEIVE_DATA) { ++ port_status = buf[2]; ++ data = &buf[3]; ++ + /* get flag from port_status */ + flag = 0; + +-- +2.12.0 + diff --git a/queue/USB-serial-ftdi_sio-add-device-ID-for-Microsemi-Arro.patch b/queue/USB-serial-ftdi_sio-add-device-ID-for-Microsemi-Arro.patch new file mode 100644 index 0000000..576508c --- /dev/null +++ b/queue/USB-serial-ftdi_sio-add-device-ID-for-Microsemi-Arro.patch @@ -0,0 +1,52 @@ +From 31c5d1922b90ddc1da6a6ddecef7cd31f17aa32b Mon Sep 17 00:00:00 2001 +From: Marek Vasut <marex@denx.de> +Date: Tue, 18 Apr 2017 20:07:56 +0200 +Subject: [PATCH] USB: serial: ftdi_sio: add device ID for Microsemi/Arrow + SF2PLUS Dev Kit + +commit 31c5d1922b90ddc1da6a6ddecef7cd31f17aa32b upstream. + +This development kit has an FT4232 on it with a custom USB VID/PID. +The FT4232 provides four UARTs, but only two are used. The UART 0 +is used by the FlashPro5 programmer and UART 2 is connected to the +SmartFusion2 CortexM3 SoC UART port. + +Note that the USB VID is registered to Actel according to Linux USB +VID database, but that was acquired by Microsemi. + +Signed-off-by: Marek Vasut <marex@denx.de> +Cc: stable <stable@vger.kernel.org> +Signed-off-by: Johan Hovold <johan@kernel.org> + +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index 546171289869..d38780fa8788 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -873,6 +873,7 @@ static const struct usb_device_id id_table_combined[] = { + { USB_DEVICE_AND_INTERFACE_INFO(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID, + USB_CLASS_VENDOR_SPEC, + USB_SUBCLASS_VENDOR_SPEC, 0x00) }, ++ { USB_DEVICE_INTERFACE_NUMBER(ACTEL_VID, MICROSEMI_ARROW_SF2PLUS_BOARD_PID, 2) }, + { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, + { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, +diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h +index 48ee04c94a75..71fb9e59db71 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -873,6 +873,12 @@ + #define FIC_VID 0x1457 + #define FIC_NEO1973_DEBUG_PID 0x5118 + ++/* ++ * Actel / Microsemi ++ */ ++#define ACTEL_VID 0x1514 ++#define MICROSEMI_ARROW_SF2PLUS_BOARD_PID 0x2008 ++ + /* Olimex */ + #define OLIMEX_VID 0x15BA + #define OLIMEX_ARM_USB_OCD_PID 0x0003 +-- +2.12.0 + diff --git a/queue/USB-serial-ftdi_sio-fix-latency-timer-error-handling.patch b/queue/USB-serial-ftdi_sio-fix-latency-timer-error-handling.patch new file mode 100644 index 0000000..6224070 --- /dev/null +++ b/queue/USB-serial-ftdi_sio-fix-latency-timer-error-handling.patch @@ -0,0 +1,40 @@ +From e3e574ad85a208cb179f33720bb5f12b453de33c Mon Sep 17 00:00:00 2001 +From: Johan Hovold <johan@kernel.org> +Date: Thu, 12 Jan 2017 14:56:12 +0100 +Subject: [PATCH] USB: serial: ftdi_sio: fix latency-timer error handling + +commit e3e574ad85a208cb179f33720bb5f12b453de33c upstream. + +Make sure to detect short responses when reading the latency timer to +avoid using stale buffer data. + +Note that no heap data would currently leak through sysfs as +ASYNC_LOW_LATENCY is set by default. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Johan Hovold <johan@kernel.org> + +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index 6dee20fc7e45..b064fad8e3ee 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -1439,10 +1439,13 @@ static int read_latency_timer(struct usb_serial_port *port) + FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, + 0, priv->interface, + buf, 1, WDR_TIMEOUT); +- if (rv < 0) ++ if (rv < 1) { + dev_err(&port->dev, "Unable to read latency timer: %i\n", rv); +- else ++ if (rv >= 0) ++ rv = -EIO; ++ } else { + priv->latency = buf[0]; ++ } + + kfree(buf); + +-- +2.12.0 + diff --git a/queue/USB-serial-io_edgeport-fix-descriptor-error-handling.patch b/queue/USB-serial-io_edgeport-fix-descriptor-error-handling.patch new file mode 100644 index 0000000..00fd816 --- /dev/null +++ b/queue/USB-serial-io_edgeport-fix-descriptor-error-handling.patch @@ -0,0 +1,81 @@ +From 3c0e25d883d06a1fbd1ad35257e8abaa57befb37 Mon Sep 17 00:00:00 2001 +From: Johan Hovold <johan@kernel.org> +Date: Thu, 12 Jan 2017 14:56:14 +0100 +Subject: [PATCH] USB: serial: io_edgeport: fix descriptor error handling + +commit 3c0e25d883d06a1fbd1ad35257e8abaa57befb37 upstream. + +Make sure to detect short control-message transfers and log an error +when reading incomplete manufacturer and boot descriptors. + +Note that the default all-zero descriptors will now be used after a +short transfer is detected instead of partially initialised ones. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Johan Hovold <johan@kernel.org> + +diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c +index 993a36a3e557..8ab5f5b49ef3 100644 +--- a/drivers/usb/serial/io_edgeport.c ++++ b/drivers/usb/serial/io_edgeport.c +@@ -2102,8 +2102,7 @@ static int rom_write(struct usb_serial *serial, __u16 extAddr, __u16 addr, + * rom_read + * reads a number of bytes from the Edgeport device starting at the given + * address. +- * If successful returns the number of bytes read, otherwise it returns +- * a negative error number of the problem. ++ * Returns zero on success or a negative error number. + ****************************************************************************/ + static int rom_read(struct usb_serial *serial, __u16 extAddr, + __u16 addr, __u16 length, __u8 *data) +@@ -2128,12 +2127,17 @@ static int rom_read(struct usb_serial *serial, __u16 extAddr, + USB_REQUEST_ION_READ_ROM, + 0xC0, addr, extAddr, transfer_buffer, + current_length, 300); +- if (result < 0) ++ if (result < current_length) { ++ if (result >= 0) ++ result = -EIO; + break; ++ } + memcpy(data, transfer_buffer, current_length); + length -= current_length; + addr += current_length; + data += current_length; ++ ++ result = 0; + } + + kfree(transfer_buffer); +@@ -2587,9 +2591,10 @@ static void get_manufacturing_desc(struct edgeport_serial *edge_serial) + EDGE_MANUF_DESC_LEN, + (__u8 *)(&edge_serial->manuf_descriptor)); + +- if (response < 1) +- dev_err(dev, "error in getting manufacturer descriptor\n"); +- else { ++ if (response < 0) { ++ dev_err(dev, "error in getting manufacturer descriptor: %d\n", ++ response); ++ } else { + char string[30]; + dev_dbg(dev, "**Manufacturer Descriptor\n"); + dev_dbg(dev, " RomSize: %dK\n", +@@ -2646,9 +2651,10 @@ static void get_boot_desc(struct edgeport_serial *edge_serial) + EDGE_BOOT_DESC_LEN, + (__u8 *)(&edge_serial->boot_descriptor)); + +- if (response < 1) +- dev_err(dev, "error in getting boot descriptor\n"); +- else { ++ if (response < 0) { ++ dev_err(dev, "error in getting boot descriptor: %d\n", ++ response); ++ } else { + dev_dbg(dev, "**Boot Descriptor:\n"); + dev_dbg(dev, " BootCodeLength: %d\n", + le16_to_cpu(edge_serial->boot_descriptor.BootCodeLength)); +-- +2.12.0 + diff --git a/queue/USB-serial-io_edgeport-fix-epic-descriptor-handling.patch b/queue/USB-serial-io_edgeport-fix-epic-descriptor-handling.patch new file mode 100644 index 0000000..157d210 --- /dev/null +++ b/queue/USB-serial-io_edgeport-fix-epic-descriptor-handling.patch @@ -0,0 +1,77 @@ +From e4457d9798adb96272468e93da663de9bd0a4198 Mon Sep 17 00:00:00 2001 +From: Johan Hovold <johan@kernel.org> +Date: Thu, 12 Jan 2017 14:56:13 +0100 +Subject: [PATCH] USB: serial: io_edgeport: fix epic-descriptor handling + +commit e4457d9798adb96272468e93da663de9bd0a4198 upstream. + +Use a dedicated buffer for the DMA transfer and make sure to detect +short transfers to avoid parsing a corrupt descriptor. + +Fixes: 6e8cf7751f9f ("USB: add EPIC support to the io_edgeport driver") +Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Johan Hovold <johan@kernel.org> + +diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c +index d50e5773483f..993a36a3e557 100644 +--- a/drivers/usb/serial/io_edgeport.c ++++ b/drivers/usb/serial/io_edgeport.c +@@ -492,20 +492,24 @@ static int get_epic_descriptor(struct edgeport_serial *ep) + int result; + struct usb_serial *serial = ep->serial; + struct edgeport_product_info *product_info = &ep->product_info; +- struct edge_compatibility_descriptor *epic = &ep->epic_descriptor; ++ struct edge_compatibility_descriptor *epic; + struct edge_compatibility_bits *bits; + struct device *dev = &serial->dev->dev; + + ep->is_epic = 0; ++ ++ epic = kmalloc(sizeof(*epic), GFP_KERNEL); ++ if (!epic) ++ return -ENOMEM; ++ + result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), + USB_REQUEST_ION_GET_EPIC_DESC, + 0xC0, 0x00, 0x00, +- &ep->epic_descriptor, +- sizeof(struct edge_compatibility_descriptor), ++ epic, sizeof(*epic), + 300); +- +- if (result > 0) { ++ if (result == sizeof(*epic)) { + ep->is_epic = 1; ++ memcpy(&ep->epic_descriptor, epic, sizeof(*epic)); + memset(product_info, 0, sizeof(struct edgeport_product_info)); + + product_info->NumPorts = epic->NumPorts; +@@ -534,8 +538,16 @@ static int get_epic_descriptor(struct edgeport_serial *ep) + dev_dbg(dev, " IOSPWriteLCR : %s\n", bits->IOSPWriteLCR ? "TRUE": "FALSE"); + dev_dbg(dev, " IOSPSetBaudRate : %s\n", bits->IOSPSetBaudRate ? "TRUE": "FALSE"); + dev_dbg(dev, " TrueEdgeport : %s\n", bits->TrueEdgeport ? "TRUE": "FALSE"); ++ ++ result = 0; ++ } else if (result >= 0) { ++ dev_warn(&serial->interface->dev, "short epic descriptor received: %d\n", ++ result); ++ result = -EIO; + } + ++ kfree(epic); ++ + return result; + } + +@@ -2779,7 +2791,7 @@ static int edge_startup(struct usb_serial *serial) + dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name); + + /* Read the epic descriptor */ +- if (get_epic_descriptor(edge_serial) <= 0) { ++ if (get_epic_descriptor(edge_serial) < 0) { + /* memcpy descriptor to Supports structures */ + memcpy(&edge_serial->epic_descriptor.Supports, descriptor, + sizeof(struct edge_compatibility_bits)); +-- +2.12.0 + diff --git a/queue/USB-serial-keyspan_pda-fix-receive-sanity-checks.patch b/queue/USB-serial-keyspan_pda-fix-receive-sanity-checks.patch new file mode 100644 index 0000000..8645fb3 --- /dev/null +++ b/queue/USB-serial-keyspan_pda-fix-receive-sanity-checks.patch @@ -0,0 +1,61 @@ +From c528fcb116e61afc379a2e0a0f70906b937f1e2c Mon Sep 17 00:00:00 2001 +From: Johan Hovold <johan@kernel.org> +Date: Tue, 31 Jan 2017 17:17:29 +0100 +Subject: [PATCH] USB: serial: keyspan_pda: fix receive sanity checks + +commit c528fcb116e61afc379a2e0a0f70906b937f1e2c upstream. + +Make sure to check for short transfers before parsing the receive buffer +to avoid acting on stale data. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Johan Hovold <johan@kernel.org> + +diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c +index 83523fcf6fb9..d2dab2a341b8 100644 +--- a/drivers/usb/serial/keyspan_pda.c ++++ b/drivers/usb/serial/keyspan_pda.c +@@ -139,6 +139,7 @@ static void keyspan_pda_rx_interrupt(struct urb *urb) + { + struct usb_serial_port *port = urb->context; + unsigned char *data = urb->transfer_buffer; ++ unsigned int len = urb->actual_length; + int retval; + int status = urb->status; + struct keyspan_pda_private *priv; +@@ -159,18 +160,26 @@ static void keyspan_pda_rx_interrupt(struct urb *urb) + goto exit; + } + ++ if (len < 1) { ++ dev_warn(&port->dev, "short message received\n"); ++ goto exit; ++ } ++ + /* see if the message is data or a status interrupt */ + switch (data[0]) { + case 0: + /* rest of message is rx data */ +- if (urb->actual_length) { +- tty_insert_flip_string(&port->port, data + 1, +- urb->actual_length - 1); +- tty_flip_buffer_push(&port->port); +- } ++ if (len < 2) ++ break; ++ tty_insert_flip_string(&port->port, data + 1, len - 1); ++ tty_flip_buffer_push(&port->port); + break; + case 1: + /* status interrupt */ ++ if (len < 3) { ++ dev_warn(&port->dev, "short interrupt message received\n"); ++ break; ++ } + dev_dbg(&port->dev, "rx int, d1=%d, d2=%d\n", data[1], data[2]); + switch (data[1]) { + case 1: /* modemline change */ +-- +2.12.0 + diff --git a/queue/USB-serial-mct_u232-fix-modem-status-error-handling.patch b/queue/USB-serial-mct_u232-fix-modem-status-error-handling.patch new file mode 100644 index 0000000..0d6a8df --- /dev/null +++ b/queue/USB-serial-mct_u232-fix-modem-status-error-handling.patch @@ -0,0 +1,39 @@ +From 36356a669eddb32917fc4b5c2b9b8bf80ede69de Mon Sep 17 00:00:00 2001 +From: Johan Hovold <johan@kernel.org> +Date: Thu, 12 Jan 2017 14:56:16 +0100 +Subject: [PATCH] USB: serial: mct_u232: fix modem-status error handling + +commit 36356a669eddb32917fc4b5c2b9b8bf80ede69de upstream. + +Make sure to detect short control-message transfers so that errors are +logged when reading the modem status at open. + +Note that while this also avoids initialising the modem status using +uninitialised heap data, these bits could not leak to user space as they +are currently not used. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Johan Hovold <johan@kernel.org> + +diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c +index 885655315de1..edbc81f205c2 100644 +--- a/drivers/usb/serial/mct_u232.c ++++ b/drivers/usb/serial/mct_u232.c +@@ -322,8 +322,12 @@ static int mct_u232_get_modem_stat(struct usb_serial_port *port, + MCT_U232_GET_REQUEST_TYPE, + 0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE, + WDR_TIMEOUT); +- if (rc < 0) { ++ if (rc < MCT_U232_GET_MODEM_STAT_SIZE) { + dev_err(&port->dev, "Get MODEM STATus failed (error = %d)\n", rc); ++ ++ if (rc >= 0) ++ rc = -EIO; ++ + *msr = 0; + } else { + *msr = buf[0]; +-- +2.12.0 + diff --git a/queue/USB-serial-quatech2-fix-control-message-error-handli.patch b/queue/USB-serial-quatech2-fix-control-message-error-handli.patch new file mode 100644 index 0000000..72e0032 --- /dev/null +++ b/queue/USB-serial-quatech2-fix-control-message-error-handli.patch @@ -0,0 +1,73 @@ +From 8c34cb8ddfe808d557b51da983ff10c02793beb2 Mon Sep 17 00:00:00 2001 +From: Johan Hovold <johan@kernel.org> +Date: Thu, 12 Jan 2017 14:56:20 +0100 +Subject: [PATCH] USB: serial: quatech2: fix control-message error handling + +commit 8c34cb8ddfe808d557b51da983ff10c02793beb2 upstream. + +Make sure to detect short control-message transfers when fetching +modem and line state in open and when retrieving registers. + +This specifically makes sure that an errno is returned to user space on +errors in TIOCMGET instead of a zero bitmask. + +Also drop the unused getdevice function which also lacked appropriate +error handling. + +Fixes: f7a33e608d9a ("USB: serial: add quatech2 usb to serial driver") +Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Johan Hovold <johan@kernel.org> + +diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c +index 5709cc93b083..cf29128327d3 100644 +--- a/drivers/usb/serial/quatech2.c ++++ b/drivers/usb/serial/quatech2.c +@@ -188,22 +188,22 @@ static inline int qt2_setdevice(struct usb_device *dev, u8 *data) + } + + +-static inline int qt2_getdevice(struct usb_device *dev, u8 *data) +-{ +- return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), +- QT_SET_GET_DEVICE, 0xc0, 0, 0, +- data, 3, QT2_USB_TIMEOUT); +-} +- + static inline int qt2_getregister(struct usb_device *dev, + u8 uart, + u8 reg, + u8 *data) + { +- return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), +- QT_SET_GET_REGISTER, 0xc0, reg, +- uart, data, sizeof(*data), QT2_USB_TIMEOUT); ++ int ret; ++ ++ ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ++ QT_SET_GET_REGISTER, 0xc0, reg, ++ uart, data, sizeof(*data), QT2_USB_TIMEOUT); ++ if (ret < sizeof(*data)) { ++ if (ret >= 0) ++ ret = -EIO; ++ } + ++ return ret; + } + + static inline int qt2_setregister(struct usb_device *dev, +@@ -372,9 +372,11 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) + 0xc0, 0, + device_port, data, 2, QT2_USB_TIMEOUT); + +- if (status < 0) { ++ if (status < 2) { + dev_err(&port->dev, "%s - open port failed %i\n", __func__, + status); ++ if (status >= 0) ++ status = -EIO; + kfree(data); + return status; + } +-- +2.12.0 + diff --git a/queue/USB-serial-ssu100-fix-control-message-error-handling.patch b/queue/USB-serial-ssu100-fix-control-message-error-handling.patch new file mode 100644 index 0000000..4f588e1 --- /dev/null +++ b/queue/USB-serial-ssu100-fix-control-message-error-handling.patch @@ -0,0 +1,76 @@ +From 1eac5c244f705182d1552a53e2f74e2775ed95d6 Mon Sep 17 00:00:00 2001 +From: Johan Hovold <johan@kernel.org> +Date: Thu, 12 Jan 2017 14:56:22 +0100 +Subject: [PATCH] USB: serial: ssu100: fix control-message error handling + +commit 1eac5c244f705182d1552a53e2f74e2775ed95d6 upstream. + +Make sure to detect short control-message transfers rather than continue +with zero-initialised data when retrieving modem status and during +device initialisation. + +Fixes: 52af95459939 ("USB: add USB serial ssu100 driver") +Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Johan Hovold <johan@kernel.org> + +diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c +index 2a156144c76c..55814538ff1f 100644 +--- a/drivers/usb/serial/ssu100.c ++++ b/drivers/usb/serial/ssu100.c +@@ -80,9 +80,17 @@ static inline int ssu100_setdevice(struct usb_device *dev, u8 *data) + + static inline int ssu100_getdevice(struct usb_device *dev, u8 *data) + { +- return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), +- QT_SET_GET_DEVICE, 0xc0, 0, 0, +- data, 3, 300); ++ int ret; ++ ++ ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ++ QT_SET_GET_DEVICE, 0xc0, 0, 0, ++ data, 3, 300); ++ if (ret < 3) { ++ if (ret >= 0) ++ ret = -EIO; ++ } ++ ++ return ret; + } + + static inline int ssu100_getregister(struct usb_device *dev, +@@ -90,10 +98,17 @@ static inline int ssu100_getregister(struct usb_device *dev, + unsigned short reg, + u8 *data) + { +- return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), +- QT_SET_GET_REGISTER, 0xc0, reg, +- uart, data, sizeof(*data), 300); ++ int ret; ++ ++ ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ++ QT_SET_GET_REGISTER, 0xc0, reg, ++ uart, data, sizeof(*data), 300); ++ if (ret < sizeof(*data)) { ++ if (ret >= 0) ++ ret = -EIO; ++ } + ++ return ret; + } + + +@@ -289,8 +304,10 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port) + QT_OPEN_CLOSE_CHANNEL, + QT_TRANSFER_IN, 0x01, + 0, data, 2, 300); +- if (result < 0) { ++ if (result < 2) { + dev_dbg(&port->dev, "%s - open failed %i\n", __func__, result); ++ if (result >= 0) ++ result = -EIO; + kfree(data); + return result; + } +-- +2.12.0 + diff --git a/queue/USB-serial-ti_usb_3410_5052-fix-control-message-erro.patch b/queue/USB-serial-ti_usb_3410_5052-fix-control-message-erro.patch new file mode 100644 index 0000000..8aab6cd --- /dev/null +++ b/queue/USB-serial-ti_usb_3410_5052-fix-control-message-erro.patch @@ -0,0 +1,54 @@ +From 39712e8bfa8d3aa6ce1e60fc9d62c9b076c17a30 Mon Sep 17 00:00:00 2001 +From: Johan Hovold <johan@kernel.org> +Date: Thu, 12 Jan 2017 14:56:23 +0100 +Subject: [PATCH] USB: serial: ti_usb_3410_5052: fix control-message error + handling + +commit 39712e8bfa8d3aa6ce1e60fc9d62c9b076c17a30 upstream. + +Make sure to detect and return an error on zero-length control-message +transfers when reading from the device. + +This addresses a potential failure to detect an empty transmit buffer +during close. + +Also remove a redundant check for short transfer when sending a command. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Johan Hovold <johan@kernel.org> + +diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c +index 64b85b8dedf3..3107bf5d1c96 100644 +--- a/drivers/usb/serial/ti_usb_3410_5052.c ++++ b/drivers/usb/serial/ti_usb_3410_5052.c +@@ -1553,13 +1553,10 @@ static int ti_command_out_sync(struct ti_device *tdev, __u8 command, + (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT), + value, moduleid, data, size, 1000); + +- if (status == size) +- status = 0; +- +- if (status > 0) +- status = -ECOMM; ++ if (status < 0) ++ return status; + +- return status; ++ return 0; + } + + +@@ -1575,8 +1572,7 @@ static int ti_command_in_sync(struct ti_device *tdev, __u8 command, + + if (status == size) + status = 0; +- +- if (status > 0) ++ else if (status >= 0) + status = -ECOMM; + + return status; +-- +2.12.0 + diff --git a/queue/arm-dts-qcom-Fix-ipq-board-clock-rates.patch b/queue/arm-dts-qcom-Fix-ipq-board-clock-rates.patch new file mode 100644 index 0000000..634aa93 --- /dev/null +++ b/queue/arm-dts-qcom-Fix-ipq-board-clock-rates.patch @@ -0,0 +1,38 @@ +From 06dbf468a2c42bf6c327a8eaf11ecb3ea96196f9 Mon Sep 17 00:00:00 2001 +From: Stephen Boyd <sboyd@codeaurora.org> +Date: Wed, 9 Nov 2016 17:13:57 -0800 +Subject: [PATCH] arm: dts: qcom: Fix ipq board clock rates + +commit 06dbf468a2c42bf6c327a8eaf11ecb3ea96196f9 upstream. + +The ipq board has these rates as 25MHz, and not 19.2 and 27. I +copy/pasted from other boards that have those rates but forgot +to fix the rates here. + +Fixes: 30fc4212d541 ("arm: dts: qcom: Add more board clocks") +Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> +Signed-off-by: Andy Gross <andy.gross@linaro.org> + +diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi +index 2e375576ffd0..76f4e8921d58 100644 +--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi +@@ -65,13 +65,13 @@ + cxo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; +- clock-frequency = <19200000>; ++ clock-frequency = <25000000>; + }; + + pxo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; +- clock-frequency = <27000000>; ++ clock-frequency = <25000000>; + }; + + sleep_clk: sleep_clk { +-- +2.12.0 + diff --git a/queue/arm64-Improve-detection-of-user-non-user-mappings-in.patch b/queue/arm64-Improve-detection-of-user-non-user-mappings-in.patch new file mode 100644 index 0000000..85c02a8 --- /dev/null +++ b/queue/arm64-Improve-detection-of-user-non-user-mappings-in.patch @@ -0,0 +1,77 @@ +From ec663d967b2276448a416406ca59ff247c0c80c5 Mon Sep 17 00:00:00 2001 +From: Catalin Marinas <catalin.marinas@arm.com> +Date: Fri, 27 Jan 2017 10:54:12 +0000 +Subject: [PATCH] arm64: Improve detection of user/non-user mappings in + set_pte(_at) + +commit ec663d967b2276448a416406ca59ff247c0c80c5 upstream. + +Commit cab15ce604e5 ("arm64: Introduce execute-only page access +permissions") allowed a valid user PTE to have the PTE_USER bit clear. +As a consequence, the pte_valid_not_user() macro in set_pte() was +replaced with pte_valid_global() under the assumption that only user +pages have the nG bit set. EFI mappings, however, also have the nG bit +set and set_pte() wrongly ignores issuing the DSB+ISB. + +This patch reinstates the pte_valid_not_user() macro and adds the +PTE_UXN bit check since all kernel mappings have this bit set. For +clarity, pte_exec() is renamed to pte_user_exec() as it only checks for +the absence of PTE_UXN. Consequently, the user executable check in +set_pte_at() drops the pte_ng() test since pte_user_exec() is +sufficient. + +Fixes: cab15ce604e5 ("arm64: Introduce execute-only page access permissions") +Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> +Signed-off-by: Will Deacon <will.deacon@arm.com> + +diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h +index 090134c346db..0eef6064bf3b 100644 +--- a/arch/arm64/include/asm/pgtable.h ++++ b/arch/arm64/include/asm/pgtable.h +@@ -71,9 +71,8 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; + #define pte_young(pte) (!!(pte_val(pte) & PTE_AF)) + #define pte_special(pte) (!!(pte_val(pte) & PTE_SPECIAL)) + #define pte_write(pte) (!!(pte_val(pte) & PTE_WRITE)) +-#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) ++#define pte_user_exec(pte) (!(pte_val(pte) & PTE_UXN)) + #define pte_cont(pte) (!!(pte_val(pte) & PTE_CONT)) +-#define pte_ng(pte) (!!(pte_val(pte) & PTE_NG)) + + #ifdef CONFIG_ARM64_HW_AFDBM + #define pte_hw_dirty(pte) (pte_write(pte) && !(pte_val(pte) & PTE_RDONLY)) +@@ -84,8 +83,12 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; + #define pte_dirty(pte) (pte_sw_dirty(pte) || pte_hw_dirty(pte)) + + #define pte_valid(pte) (!!(pte_val(pte) & PTE_VALID)) +-#define pte_valid_global(pte) \ +- ((pte_val(pte) & (PTE_VALID | PTE_NG)) == PTE_VALID) ++/* ++ * Execute-only user mappings do not have the PTE_USER bit set. All valid ++ * kernel mappings have the PTE_UXN bit set. ++ */ ++#define pte_valid_not_user(pte) \ ++ ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == (PTE_VALID | PTE_UXN)) + #define pte_valid_young(pte) \ + ((pte_val(pte) & (PTE_VALID | PTE_AF)) == (PTE_VALID | PTE_AF)) + +@@ -178,7 +181,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte) + * Only if the new pte is valid and kernel, otherwise TLB maintenance + * or update_mmu_cache() have the necessary barriers. + */ +- if (pte_valid_global(pte)) { ++ if (pte_valid_not_user(pte)) { + dsb(ishst); + isb(); + } +@@ -212,7 +215,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_val(pte) &= ~PTE_RDONLY; + else + pte_val(pte) |= PTE_RDONLY; +- if (pte_ng(pte) && pte_exec(pte) && !pte_special(pte)) ++ if (pte_user_exec(pte) && !pte_special(pte)) + __sync_icache_dcache(pte, addr); + } + +-- +2.12.0 + diff --git a/queue/arm64-KVM-Fix-decoding-of-Rt-Rt2-when-trapping-AArch.patch b/queue/arm64-KVM-Fix-decoding-of-Rt-Rt2-when-trapping-AArch.patch new file mode 100644 index 0000000..fd539b5 --- /dev/null +++ b/queue/arm64-KVM-Fix-decoding-of-Rt-Rt2-when-trapping-AArch.patch @@ -0,0 +1,72 @@ +From c667186f1c01ca8970c785888868b7ffd74e51ee Mon Sep 17 00:00:00 2001 +From: Marc Zyngier <marc.zyngier@arm.com> +Date: Thu, 27 Apr 2017 19:06:48 +0100 +Subject: [PATCH] arm64: KVM: Fix decoding of Rt/Rt2 when trapping AArch32 CP + accesses + +commit c667186f1c01ca8970c785888868b7ffd74e51ee upstream. + +Our 32bit CP14/15 handling inherited some of the ARMv7 code for handling +the trapped system registers, completely missing the fact that the +fields for Rt and Rt2 are now 5 bit wide, and not 4... + +Let's fix it, and provide an accessor for the most common Rt case. + +Cc: stable@vger.kernel.org +Reviewed-by: Christoffer Dall <cdall@linaro.org> +Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> +Signed-off-by: Christoffer Dall <cdall@linaro.org> + +diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h +index f5ea0ba70f07..fe39e6841326 100644 +--- a/arch/arm64/include/asm/kvm_emulate.h ++++ b/arch/arm64/include/asm/kvm_emulate.h +@@ -240,6 +240,12 @@ static inline u8 kvm_vcpu_trap_get_fault_type(const struct kvm_vcpu *vcpu) + return kvm_vcpu_get_hsr(vcpu) & ESR_ELx_FSC_TYPE; + } + ++static inline int kvm_vcpu_sys_get_rt(struct kvm_vcpu *vcpu) ++{ ++ u32 esr = kvm_vcpu_get_hsr(vcpu); ++ return (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT; ++} ++ + static inline unsigned long kvm_vcpu_get_mpidr_aff(struct kvm_vcpu *vcpu) + { + return vcpu_sys_reg(vcpu, MPIDR_EL1) & MPIDR_HWID_BITMASK; +diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c +index 8ddcee6e4702..ea9fbb5c17d0 100644 +--- a/arch/arm64/kvm/sys_regs.c ++++ b/arch/arm64/kvm/sys_regs.c +@@ -1529,8 +1529,8 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu, + { + struct sys_reg_params params; + u32 hsr = kvm_vcpu_get_hsr(vcpu); +- int Rt = (hsr >> 5) & 0xf; +- int Rt2 = (hsr >> 10) & 0xf; ++ int Rt = kvm_vcpu_sys_get_rt(vcpu); ++ int Rt2 = (hsr >> 10) & 0x1f; + + params.is_aarch32 = true; + params.is_32bit = false; +@@ -1586,7 +1586,7 @@ static int kvm_handle_cp_32(struct kvm_vcpu *vcpu, + { + struct sys_reg_params params; + u32 hsr = kvm_vcpu_get_hsr(vcpu); +- int Rt = (hsr >> 5) & 0xf; ++ int Rt = kvm_vcpu_sys_get_rt(vcpu); + + params.is_aarch32 = true; + params.is_32bit = true; +@@ -1688,7 +1688,7 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run) + { + struct sys_reg_params params; + unsigned long esr = kvm_vcpu_get_hsr(vcpu); +- int Rt = (esr >> 5) & 0x1f; ++ int Rt = kvm_vcpu_sys_get_rt(vcpu); + int ret; + + trace_kvm_handle_sys_reg(esr); +-- +2.12.0 + diff --git a/queue/arm64-dts-r8a7795-Mark-EthernetAVB-device-node-disab.patch b/queue/arm64-dts-r8a7795-Mark-EthernetAVB-device-node-disab.patch new file mode 100644 index 0000000..c1ae4de --- /dev/null +++ b/queue/arm64-dts-r8a7795-Mark-EthernetAVB-device-node-disab.patch @@ -0,0 +1,29 @@ +From 0d1390ff283f6c38595288e7f74da6829896b8b7 Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven <geert+renesas@glider.be> +Date: Wed, 25 Jan 2017 14:19:30 +0100 +Subject: [PATCH] arm64: dts: r8a7795: Mark EthernetAVB device node disabled + +commit 0d1390ff283f6c38595288e7f74da6829896b8b7 upstream. + +Device nodes representing I/O devices should be marked disabled in the +SoC-specific DTS, and overridden by board-specific DTSes where needed. + +Fixes: a92843c8a6f8c039 ("arm64: dts: r8a7795: add EthernetAVB device node") +Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi +index 74a4e1ad057d..eac4f29aa5cd 100644 +--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi +@@ -566,6 +566,7 @@ + phy-mode = "rgmii-id"; + #address-cells = <1>; + #size-cells = <0>; ++ status = "disabled"; + }; + + can0: can@e6c30000 { +-- +2.12.0 + diff --git a/queue/block-fix-blk_integrity_register-to-use-template-s-i.patch b/queue/block-fix-blk_integrity_register-to-use-template-s-i.patch new file mode 100644 index 0000000..3ac6af0 --- /dev/null +++ b/queue/block-fix-blk_integrity_register-to-use-template-s-i.patch @@ -0,0 +1,39 @@ +From 2859323e35ab5fc42f351fbda23ab544eaa85945 Mon Sep 17 00:00:00 2001 +From: Mike Snitzer <snitzer@redhat.com> +Date: Sat, 22 Apr 2017 17:22:09 -0400 +Subject: [PATCH] block: fix blk_integrity_register to use template's + interval_exp if not 0 + +commit 2859323e35ab5fc42f351fbda23ab544eaa85945 upstream. + +When registering an integrity profile: if the template's interval_exp is +not 0 use it, otherwise use the ilog2() of logical block size of the +provided gendisk. + +This fixes a long-standing DM linear target bug where it cannot pass +integrity data to the underlying device if its logical block size +conflicts with the underlying device's logical block size. + +Cc: stable@vger.kernel.org +Reported-by: Mikulas Patocka <mpatocka@redhat.com> +Signed-off-by: Mike Snitzer <snitzer@redhat.com> +Acked-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Jens Axboe <axboe@fb.com> + +diff --git a/block/blk-integrity.c b/block/blk-integrity.c +index ce43a8214d3e..0f891a9aff4d 100644 +--- a/block/blk-integrity.c ++++ b/block/blk-integrity.c +@@ -412,7 +412,8 @@ void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template + + bi->flags = BLK_INTEGRITY_VERIFY | BLK_INTEGRITY_GENERATE | + template->flags; +- bi->interval_exp = ilog2(queue_logical_block_size(disk->queue)); ++ bi->interval_exp = template->interval_exp ? : ++ ilog2(queue_logical_block_size(disk->queue)); + bi->profile = template->profile ? template->profile : &nop_profile; + bi->tuple_size = template->tuple_size; + bi->tag_size = template->tag_size; +-- +2.12.0 + diff --git a/queue/block-get-rid-of-blk_integrity_revalidate.patch b/queue/block-get-rid-of-blk_integrity_revalidate.patch new file mode 100644 index 0000000..e8a54df --- /dev/null +++ b/queue/block-get-rid-of-blk_integrity_revalidate.patch @@ -0,0 +1,126 @@ +From 19b7ccf8651df09d274671b53039c672a52ad84d Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov <idryomov@gmail.com> +Date: Tue, 18 Apr 2017 18:43:20 +0200 +Subject: [PATCH] block: get rid of blk_integrity_revalidate() + +commit 19b7ccf8651df09d274671b53039c672a52ad84d upstream. + +Commit 25520d55cdb6 ("block: Inline blk_integrity in struct gendisk") +introduced blk_integrity_revalidate(), which seems to assume ownership +of the stable pages flag and unilaterally clears it if no blk_integrity +profile is registered: + + if (bi->profile) + disk->queue->backing_dev_info->capabilities |= + BDI_CAP_STABLE_WRITES; + else + disk->queue->backing_dev_info->capabilities &= + ~BDI_CAP_STABLE_WRITES; + +It's called from revalidate_disk() and rescan_partitions(), making it +impossible to enable stable pages for drivers that support partitions +and don't use blk_integrity: while the call in revalidate_disk() can be +trivially worked around (see zram, which doesn't support partitions and +hence gets away with zram_revalidate_disk()), rescan_partitions() can +be triggered from userspace at any time. This breaks rbd, where the +ceph messenger is responsible for generating/verifying CRCs. + +Since blk_integrity_{un,}register() "must" be used for (un)registering +the integrity profile with the block layer, move BDI_CAP_STABLE_WRITES +setting there. This way drivers that call blk_integrity_register() and +use integrity infrastructure won't interfere with drivers that don't +but still want stable pages. + +Fixes: 25520d55cdb6 ("block: Inline blk_integrity in struct gendisk") +Cc: "Martin K. Petersen" <martin.petersen@oracle.com> +Cc: Christoph Hellwig <hch@lst.de> +Cc: Mike Snitzer <snitzer@redhat.com> +Cc: stable@vger.kernel.org # 4.4+, needs backporting +Tested-by: Dan Williams <dan.j.williams@intel.com> +Signed-off-by: Ilya Dryomov <idryomov@gmail.com> +Signed-off-by: Jens Axboe <axboe@fb.com> + +diff --git a/block/blk-integrity.c b/block/blk-integrity.c +index b3622cb00fc2..ce43a8214d3e 100644 +--- a/block/blk-integrity.c ++++ b/block/blk-integrity.c +@@ -417,7 +417,7 @@ void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template + bi->tuple_size = template->tuple_size; + bi->tag_size = template->tag_size; + +- blk_integrity_revalidate(disk); ++ disk->queue->backing_dev_info->capabilities |= BDI_CAP_STABLE_WRITES; + } + EXPORT_SYMBOL(blk_integrity_register); + +@@ -430,26 +430,11 @@ EXPORT_SYMBOL(blk_integrity_register); + */ + void blk_integrity_unregister(struct gendisk *disk) + { +- blk_integrity_revalidate(disk); ++ disk->queue->backing_dev_info->capabilities &= ~BDI_CAP_STABLE_WRITES; + memset(&disk->queue->integrity, 0, sizeof(struct blk_integrity)); + } + EXPORT_SYMBOL(blk_integrity_unregister); + +-void blk_integrity_revalidate(struct gendisk *disk) +-{ +- struct blk_integrity *bi = &disk->queue->integrity; +- +- if (!(disk->flags & GENHD_FL_UP)) +- return; +- +- if (bi->profile) +- disk->queue->backing_dev_info->capabilities |= +- BDI_CAP_STABLE_WRITES; +- else +- disk->queue->backing_dev_info->capabilities &= +- ~BDI_CAP_STABLE_WRITES; +-} +- + void blk_integrity_add(struct gendisk *disk) + { + if (kobject_init_and_add(&disk->integrity_kobj, &integrity_ktype, +diff --git a/block/partition-generic.c b/block/partition-generic.c +index 7afb9907821f..0171a2faad68 100644 +--- a/block/partition-generic.c ++++ b/block/partition-generic.c +@@ -497,7 +497,6 @@ rescan: + + if (disk->fops->revalidate_disk) + disk->fops->revalidate_disk(disk); +- blk_integrity_revalidate(disk); + check_disk_size_change(disk, bdev); + bdev->bd_invalidated = 0; + if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) +diff --git a/fs/block_dev.c b/fs/block_dev.c +index e405d8e58e31..9ccabe3bb7de 100644 +--- a/fs/block_dev.c ++++ b/fs/block_dev.c +@@ -1453,7 +1453,6 @@ int revalidate_disk(struct gendisk *disk) + + if (disk->fops->revalidate_disk) + ret = disk->fops->revalidate_disk(disk); +- blk_integrity_revalidate(disk); + bdev = bdget_disk(disk, 0); + if (!bdev) + return ret; +diff --git a/include/linux/genhd.h b/include/linux/genhd.h +index 9e11082c7f9b..acff9437e5c3 100644 +--- a/include/linux/genhd.h ++++ b/include/linux/genhd.h +@@ -722,11 +722,9 @@ static inline void part_nr_sects_write(struct hd_struct *part, sector_t size) + #if defined(CONFIG_BLK_DEV_INTEGRITY) + extern void blk_integrity_add(struct gendisk *); + extern void blk_integrity_del(struct gendisk *); +-extern void blk_integrity_revalidate(struct gendisk *); + #else /* CONFIG_BLK_DEV_INTEGRITY */ + static inline void blk_integrity_add(struct gendisk *disk) { } + static inline void blk_integrity_del(struct gendisk *disk) { } +-static inline void blk_integrity_revalidate(struct gendisk *disk) { } + #endif /* CONFIG_BLK_DEV_INTEGRITY */ + + #else /* CONFIG_BLOCK */ +-- +2.12.0 + diff --git a/queue/bnxt_en-allocate-enough-space-for-ntp_fltr_bmap.patch b/queue/bnxt_en-allocate-enough-space-for-ntp_fltr_bmap.patch new file mode 100644 index 0000000..55e140f --- /dev/null +++ b/queue/bnxt_en-allocate-enough-space-for-ntp_fltr_bmap.patch @@ -0,0 +1,32 @@ +From ac45bd93a5035c2f39c9862b8b6ed692db0fdc87 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Sat, 6 May 2017 03:49:01 +0300 +Subject: [PATCH] bnxt_en: allocate enough space for ->ntp_fltr_bmap + +commit ac45bd93a5035c2f39c9862b8b6ed692db0fdc87 upstream. + +We have the number of longs, but we need to calculate the number of +bytes required. + +Fixes: c0c050c58d84 ("bnxt_en: New Broadcom ethernet driver.") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Acked-by: Michael Chan <michael.chan@broadcom.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index b3ba66032980..b56c54d68d5e 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -3000,7 +3000,8 @@ static int bnxt_alloc_ntp_fltrs(struct bnxt *bp) + INIT_HLIST_HEAD(&bp->ntp_fltr_hash_tbl[i]); + + bp->ntp_fltr_count = 0; +- bp->ntp_fltr_bmap = kzalloc(BITS_TO_LONGS(BNXT_NTP_FLTR_MAX_FLTR), ++ bp->ntp_fltr_bmap = kcalloc(BITS_TO_LONGS(BNXT_NTP_FLTR_MAX_FLTR), ++ sizeof(long), + GFP_KERNEL); + + if (!bp->ntp_fltr_bmap) +-- +2.12.0 + diff --git a/queue/bpf-arm64-fix-jit-branch-offset-related-to-ldimm64.patch b/queue/bpf-arm64-fix-jit-branch-offset-related-to-ldimm64.patch new file mode 100644 index 0000000..e4eb518 --- /dev/null +++ b/queue/bpf-arm64-fix-jit-branch-offset-related-to-ldimm64.patch @@ -0,0 +1,143 @@ +From ddc665a4bb4b728b4e6ecec8db1b64efa9184b9c Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann <daniel@iogearbox.net> +Date: Tue, 2 May 2017 20:34:54 +0200 +Subject: [PATCH] bpf, arm64: fix jit branch offset related to ldimm64 + +commit ddc665a4bb4b728b4e6ecec8db1b64efa9184b9c upstream. + +When the instruction right before the branch destination is +a 64 bit load immediate, we currently calculate the wrong +jump offset in the ctx->offset[] array as we only account +one instruction slot for the 64 bit load immediate although +it uses two BPF instructions. Fix it up by setting the offset +into the right slot after we incremented the index. + +Before (ldimm64 test 1): + + [...] + 00000020: 52800007 mov w7, #0x0 // #0 + 00000024: d2800060 mov x0, #0x3 // #3 + 00000028: d2800041 mov x1, #0x2 // #2 + 0000002c: eb01001f cmp x0, x1 + 00000030: 54ffff82 b.cs 0x00000020 + 00000034: d29fffe7 mov x7, #0xffff // #65535 + 00000038: f2bfffe7 movk x7, #0xffff, lsl #16 + 0000003c: f2dfffe7 movk x7, #0xffff, lsl #32 + 00000040: f2ffffe7 movk x7, #0xffff, lsl #48 + 00000044: d29dddc7 mov x7, #0xeeee // #61166 + 00000048: f2bdddc7 movk x7, #0xeeee, lsl #16 + 0000004c: f2ddddc7 movk x7, #0xeeee, lsl #32 + 00000050: f2fdddc7 movk x7, #0xeeee, lsl #48 + [...] + +After (ldimm64 test 1): + + [...] + 00000020: 52800007 mov w7, #0x0 // #0 + 00000024: d2800060 mov x0, #0x3 // #3 + 00000028: d2800041 mov x1, #0x2 // #2 + 0000002c: eb01001f cmp x0, x1 + 00000030: 540000a2 b.cs 0x00000044 + 00000034: d29fffe7 mov x7, #0xffff // #65535 + 00000038: f2bfffe7 movk x7, #0xffff, lsl #16 + 0000003c: f2dfffe7 movk x7, #0xffff, lsl #32 + 00000040: f2ffffe7 movk x7, #0xffff, lsl #48 + 00000044: d29dddc7 mov x7, #0xeeee // #61166 + 00000048: f2bdddc7 movk x7, #0xeeee, lsl #16 + 0000004c: f2ddddc7 movk x7, #0xeeee, lsl #32 + 00000050: f2fdddc7 movk x7, #0xeeee, lsl #48 + [...] + +Also, add a couple of test cases to make sure JITs pass +this test. Tested on Cavium ThunderX ARMv8. The added +test cases all pass after the fix. + +Fixes: 8eee539ddea0 ("arm64: bpf: fix out-of-bounds read in bpf2a64_offset()") +Reported-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> +Acked-by: Alexei Starovoitov <ast@kernel.org> +Cc: Xi Wang <xi.wang@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c +index 4f2b35130f3c..d68abde52740 100644 +--- a/arch/arm64/net/bpf_jit_comp.c ++++ b/arch/arm64/net/bpf_jit_comp.c +@@ -776,14 +776,14 @@ static int build_body(struct jit_ctx *ctx) + int ret; + + ret = build_insn(insn, ctx); +- +- if (ctx->image == NULL) +- ctx->offset[i] = ctx->idx; +- + if (ret > 0) { + i++; ++ if (ctx->image == NULL) ++ ctx->offset[i] = ctx->idx; + continue; + } ++ if (ctx->image == NULL) ++ ctx->offset[i] = ctx->idx; + if (ret) + return ret; + } +diff --git a/lib/test_bpf.c b/lib/test_bpf.c +index 3a7730ca81be..a0f66280ea50 100644 +--- a/lib/test_bpf.c ++++ b/lib/test_bpf.c +@@ -4761,6 +4761,51 @@ static struct bpf_test tests[] = { + { }, + { { 0, 1 } }, + }, ++ { ++ /* Mainly testing JIT + imm64 here. */ ++ "JMP_JGE_X: ldimm64 test 1", ++ .u.insns_int = { ++ BPF_ALU32_IMM(BPF_MOV, R0, 0), ++ BPF_LD_IMM64(R1, 3), ++ BPF_LD_IMM64(R2, 2), ++ BPF_JMP_REG(BPF_JGE, R1, R2, 2), ++ BPF_LD_IMM64(R0, 0xffffffffffffffffUL), ++ BPF_LD_IMM64(R0, 0xeeeeeeeeeeeeeeeeUL), ++ BPF_EXIT_INSN(), ++ }, ++ INTERNAL, ++ { }, ++ { { 0, 0xeeeeeeeeU } }, ++ }, ++ { ++ "JMP_JGE_X: ldimm64 test 2", ++ .u.insns_int = { ++ BPF_ALU32_IMM(BPF_MOV, R0, 0), ++ BPF_LD_IMM64(R1, 3), ++ BPF_LD_IMM64(R2, 2), ++ BPF_JMP_REG(BPF_JGE, R1, R2, 0), ++ BPF_LD_IMM64(R0, 0xffffffffffffffffUL), ++ BPF_EXIT_INSN(), ++ }, ++ INTERNAL, ++ { }, ++ { { 0, 0xffffffffU } }, ++ }, ++ { ++ "JMP_JGE_X: ldimm64 test 3", ++ .u.insns_int = { ++ BPF_ALU32_IMM(BPF_MOV, R0, 1), ++ BPF_LD_IMM64(R1, 3), ++ BPF_LD_IMM64(R2, 2), ++ BPF_JMP_REG(BPF_JGE, R1, R2, 4), ++ BPF_LD_IMM64(R0, 0xffffffffffffffffUL), ++ BPF_LD_IMM64(R0, 0xeeeeeeeeeeeeeeeeUL), ++ BPF_EXIT_INSN(), ++ }, ++ INTERNAL, ++ { }, ++ { { 0, 1 } }, ++ }, + /* BPF_JMP | BPF_JNE | BPF_X */ + { + "JMP_JNE_X: if (3 != 2) return 1", +-- +2.12.0 + diff --git a/queue/bpf-don-t-let-ldimm64-leak-map-addresses-on-unprivil.patch b/queue/bpf-don-t-let-ldimm64-leak-map-addresses-on-unprivil.patch new file mode 100644 index 0000000..0e1f8dd --- /dev/null +++ b/queue/bpf-don-t-let-ldimm64-leak-map-addresses-on-unprivil.patch @@ -0,0 +1,77 @@ +From 0d0e57697f162da4aa218b5feafe614fb666db07 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann <daniel@iogearbox.net> +Date: Mon, 8 May 2017 00:04:09 +0200 +Subject: [PATCH] bpf: don't let ldimm64 leak map addresses on unprivileged + +commit 0d0e57697f162da4aa218b5feafe614fb666db07 upstream. + +The patch fixes two things at once: + +1) It checks the env->allow_ptr_leaks and only prints the map address to + the log if we have the privileges to do so, otherwise it just dumps 0 + as we would when kptr_restrict is enabled on %pK. Given the latter is + off by default and not every distro sets it, I don't want to rely on + this, hence the 0 by default for unprivileged. + +2) Printing of ldimm64 in the verifier log is currently broken in that + we don't print the full immediate, but only the 32 bit part of the + first insn part for ldimm64. Thus, fix this up as well; it's okay to + access, since we verified all ldimm64 earlier already (including just + constants) through replace_map_fd_with_map_ptr(). + +Fixes: 1be7f75d1668 ("bpf: enable non-root eBPF programs") +Fixes: cbd357008604 ("bpf: verifier (add ability to receive verification log)") +Reported-by: Jann Horn <jannh@google.com> +Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> +Acked-by: Alexei Starovoitov <ast@kernel.org> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index c2ff608c1984..c5b56c92f8e2 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -298,7 +298,8 @@ static const char *const bpf_jmp_string[16] = { + [BPF_EXIT >> 4] = "exit", + }; + +-static void print_bpf_insn(struct bpf_insn *insn) ++static void print_bpf_insn(const struct bpf_verifier_env *env, ++ const struct bpf_insn *insn) + { + u8 class = BPF_CLASS(insn->code); + +@@ -362,9 +363,19 @@ static void print_bpf_insn(struct bpf_insn *insn) + insn->code, + bpf_ldst_string[BPF_SIZE(insn->code) >> 3], + insn->src_reg, insn->imm); +- } else if (BPF_MODE(insn->code) == BPF_IMM) { +- verbose("(%02x) r%d = 0x%x\n", +- insn->code, insn->dst_reg, insn->imm); ++ } else if (BPF_MODE(insn->code) == BPF_IMM && ++ BPF_SIZE(insn->code) == BPF_DW) { ++ /* At this point, we already made sure that the second ++ * part of the ldimm64 insn is accessible. ++ */ ++ u64 imm = ((u64)(insn + 1)->imm << 32) | (u32)insn->imm; ++ bool map_ptr = insn->src_reg == BPF_PSEUDO_MAP_FD; ++ ++ if (map_ptr && !env->allow_ptr_leaks) ++ imm = 0; ++ ++ verbose("(%02x) r%d = 0x%llx\n", insn->code, ++ insn->dst_reg, (unsigned long long)imm); + } else { + verbose("BUG_ld_%02x\n", insn->code); + return; +@@ -2853,7 +2864,7 @@ static int do_check(struct bpf_verifier_env *env) + + if (log_level) { + verbose("%d: ", insn_idx); +- print_bpf_insn(insn); ++ print_bpf_insn(env, insn); + } + + err = ext_analyzer_insn_hook(env, insn_idx, prev_insn_idx); +-- +2.12.0 + diff --git a/queue/bpf-enhance-verifier-to-understand-stack-pointer-ari.patch b/queue/bpf-enhance-verifier-to-understand-stack-pointer-ari.patch new file mode 100644 index 0000000..da9858e --- /dev/null +++ b/queue/bpf-enhance-verifier-to-understand-stack-pointer-ari.patch @@ -0,0 +1,90 @@ +From 332270fdc8b6fba07d059a9ad44df9e1a2ad4529 Mon Sep 17 00:00:00 2001 +From: Yonghong Song <yhs@fb.com> +Date: Sat, 29 Apr 2017 22:52:42 -0700 +Subject: [PATCH] bpf: enhance verifier to understand stack pointer arithmetic + +commit 332270fdc8b6fba07d059a9ad44df9e1a2ad4529 upstream. + +llvm 4.0 and above generates the code like below: +.... +440: (b7) r1 = 15 +441: (05) goto pc+73 +515: (79) r6 = *(u64 *)(r10 -152) +516: (bf) r7 = r10 +517: (07) r7 += -112 +518: (bf) r2 = r7 +519: (0f) r2 += r1 +520: (71) r1 = *(u8 *)(r8 +0) +521: (73) *(u8 *)(r2 +45) = r1 +.... +and the verifier complains "R2 invalid mem access 'inv'" for insn #521. +This is because verifier marks register r2 as unknown value after #519 +where r2 is a stack pointer and r1 holds a constant value. + +Teach verifier to recognize "stack_ptr + imm" and +"stack_ptr + reg with const val" as valid stack_ptr with new offset. + +Signed-off-by: Yonghong Song <yhs@fb.com> +Acked-by: Martin KaFai Lau <kafai@fb.com> +Acked-by: Daniel Borkmann <daniel@iogearbox.net> +Signed-off-by: Alexei Starovoitov <ast@kernel.org> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 6f8b6ed690be..c2ff608c1984 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -1924,6 +1924,17 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) + return 0; + } else if (opcode == BPF_ADD && + BPF_CLASS(insn->code) == BPF_ALU64 && ++ dst_reg->type == PTR_TO_STACK && ++ ((BPF_SRC(insn->code) == BPF_X && ++ regs[insn->src_reg].type == CONST_IMM) || ++ BPF_SRC(insn->code) == BPF_K)) { ++ if (BPF_SRC(insn->code) == BPF_X) ++ dst_reg->imm += regs[insn->src_reg].imm; ++ else ++ dst_reg->imm += insn->imm; ++ return 0; ++ } else if (opcode == BPF_ADD && ++ BPF_CLASS(insn->code) == BPF_ALU64 && + (dst_reg->type == PTR_TO_PACKET || + (BPF_SRC(insn->code) == BPF_X && + regs[insn->src_reg].type == PTR_TO_PACKET))) { +diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c +index d3395c192a24..3773562056da 100644 +--- a/tools/testing/selftests/bpf/test_verifier.c ++++ b/tools/testing/selftests/bpf/test_verifier.c +@@ -1932,16 +1932,22 @@ static struct bpf_test tests[] = { + .result = ACCEPT, + }, + { +- "unpriv: obfuscate stack pointer", ++ "stack pointer arithmetic", + .insns = { +- BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), +- BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), +- BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), ++ BPF_MOV64_IMM(BPF_REG_1, 4), ++ BPF_JMP_IMM(BPF_JA, 0, 0, 0), ++ BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), ++ BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10), ++ BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10), ++ BPF_MOV64_REG(BPF_REG_2, BPF_REG_7), ++ BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1), ++ BPF_ST_MEM(0, BPF_REG_2, 4, 0), ++ BPF_MOV64_REG(BPF_REG_2, BPF_REG_7), ++ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8), ++ BPF_ST_MEM(0, BPF_REG_2, 4, 0), + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, +- .errstr_unpriv = "R2 pointer arithmetic", +- .result_unpriv = REJECT, + .result = ACCEPT, + }, + { +-- +2.12.0 + diff --git a/queue/bpf-improve-verifier-packet-range-checks.patch b/queue/bpf-improve-verifier-packet-range-checks.patch new file mode 100644 index 0000000..bbcdc2a --- /dev/null +++ b/queue/bpf-improve-verifier-packet-range-checks.patch @@ -0,0 +1,82 @@ +From b1977682a3858b5584ffea7cfb7bd863f68db18d Mon Sep 17 00:00:00 2001 +From: Alexei Starovoitov <ast@fb.com> +Date: Fri, 24 Mar 2017 15:57:33 -0700 +Subject: [PATCH] bpf: improve verifier packet range checks + +commit b1977682a3858b5584ffea7cfb7bd863f68db18d upstream. + +llvm can optimize the 'if (ptr > data_end)' checks to be in the order +slightly different than the original C code which will confuse verifier. +Like: +if (ptr + 16 > data_end) + return TC_ACT_SHOT; +// may be followed by +if (ptr + 14 > data_end) + return TC_ACT_SHOT; +while llvm can see that 'ptr' is valid for all 16 bytes, +the verifier could not. +Fix verifier logic to account for such case and add a test. + +Reported-by: Huapeng Zhou <hzhou@fb.com> +Fixes: 969bf05eb3ce ("bpf: direct packet access") +Signed-off-by: Alexei Starovoitov <ast@kernel.org> +Acked-by: Daniel Borkmann <daniel@iogearbox.net> +Acked-by: Martin KaFai Lau <kafai@fb.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 796b68d00119..5e6202e62265 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -1973,14 +1973,15 @@ static void find_good_pkt_pointers(struct bpf_verifier_state *state, + + for (i = 0; i < MAX_BPF_REG; i++) + if (regs[i].type == PTR_TO_PACKET && regs[i].id == dst_reg->id) +- regs[i].range = dst_reg->off; ++ /* keep the maximum range already checked */ ++ regs[i].range = max(regs[i].range, dst_reg->off); + + for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) { + if (state->stack_slot_type[i] != STACK_SPILL) + continue; + reg = &state->spilled_regs[i / BPF_REG_SIZE]; + if (reg->type == PTR_TO_PACKET && reg->id == dst_reg->id) +- reg->range = dst_reg->off; ++ reg->range = max(reg->range, dst_reg->off); + } + } + +diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c +index d1555e4240c0..7d761d4cc759 100644 +--- a/tools/testing/selftests/bpf/test_verifier.c ++++ b/tools/testing/selftests/bpf/test_verifier.c +@@ -3418,6 +3418,26 @@ static struct bpf_test tests[] = { + .prog_type = BPF_PROG_TYPE_LWT_XMIT, + }, + { ++ "overlapping checks for direct packet access", ++ .insns = { ++ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, ++ offsetof(struct __sk_buff, data)), ++ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, ++ offsetof(struct __sk_buff, data_end)), ++ BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), ++ BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), ++ BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4), ++ BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), ++ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6), ++ BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1), ++ BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6), ++ BPF_MOV64_IMM(BPF_REG_0, 0), ++ BPF_EXIT_INSN(), ++ }, ++ .result = ACCEPT, ++ .prog_type = BPF_PROG_TYPE_LWT_XMIT, ++ }, ++ { + "invalid access of tc_classid for LWT_IN", + .insns = { + BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, +-- +2.12.0 + diff --git a/queue/brcmfmac-Ensure-pointer-correctly-set-if-skb-data-lo.patch b/queue/brcmfmac-Ensure-pointer-correctly-set-if-skb-data-lo.patch new file mode 100644 index 0000000..1651907 --- /dev/null +++ b/queue/brcmfmac-Ensure-pointer-correctly-set-if-skb-data-lo.patch @@ -0,0 +1,43 @@ +From 455a1eb4654c24560eb9dfc634f29cba3d87601e Mon Sep 17 00:00:00 2001 +From: James Hughes <james.hughes@raspberrypi.org> +Date: Mon, 24 Apr 2017 12:40:50 +0100 +Subject: [PATCH] brcmfmac: Ensure pointer correctly set if skb data location + changes + +commit 455a1eb4654c24560eb9dfc634f29cba3d87601e upstream. + +The incoming skb header may be resized if header space is +insufficient, which might change the data adddress in the skb. +Ensure that a cached pointer to that data is correctly set by +moving assignment to after any possible changes. + +Signed-off-by: James Hughes <james.hughes@raspberrypi.org> + +Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +index 24118ce72b4f..753db686649f 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -197,7 +197,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, + int ret; + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_pub *drvr = ifp->drvr; +- struct ethhdr *eh = (struct ethhdr *)(skb->data); ++ struct ethhdr *eh; + + brcmf_dbg(DATA, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx); + +@@ -235,6 +235,8 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, + goto done; + } + ++ eh = (struct ethhdr *)(skb->data); ++ + if (eh->h_proto == htons(ETH_P_PAE)) + atomic_inc(&ifp->pend_8021x_cnt); + +-- +2.12.0 + diff --git a/queue/brcmfmac-Make-skb-header-writable-before-use.patch b/queue/brcmfmac-Make-skb-header-writable-before-use.patch new file mode 100644 index 0000000..18453b9 --- /dev/null +++ b/queue/brcmfmac-Make-skb-header-writable-before-use.patch @@ -0,0 +1,52 @@ +From 9cc4b7cb86cbcc6330a3faa8cd65268cd2d3c227 Mon Sep 17 00:00:00 2001 +From: James Hughes <james.hughes@raspberrypi.org> +Date: Tue, 25 Apr 2017 10:15:06 +0100 +Subject: [PATCH] brcmfmac: Make skb header writable before use + +commit 9cc4b7cb86cbcc6330a3faa8cd65268cd2d3c227 upstream. + +The driver was making changes to the skb_header without +ensuring it was writable (i.e. uncloned). +This patch also removes some boiler plate header size +checking/adjustment code as that is also handled by the +skb_cow_header function used to make header writable. + +Signed-off-by: James Hughes <james.hughes@raspberrypi.org> +Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +index 753db686649f..a3d82368f1a9 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -210,22 +210,13 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, + goto done; + } + +- /* Make sure there's enough room for any header */ +- if (skb_headroom(skb) < drvr->hdrlen) { +- struct sk_buff *skb2; +- +- brcmf_dbg(INFO, "%s: insufficient headroom\n", ++ /* Make sure there's enough writable headroom*/ ++ ret = skb_cow_head(skb, drvr->hdrlen); ++ if (ret < 0) { ++ brcmf_err("%s: skb_cow_head failed\n", + brcmf_ifname(ifp)); +- drvr->bus_if->tx_realloc++; +- skb2 = skb_realloc_headroom(skb, drvr->hdrlen); + dev_kfree_skb(skb); +- skb = skb2; +- if (skb == NULL) { +- brcmf_err("%s: skb_realloc_headroom failed\n", +- brcmf_ifname(ifp)); +- ret = -ENOMEM; +- goto done; +- } ++ goto done; + } + + /* validate length for ether packet */ +-- +2.12.0 + diff --git a/queue/ceph-fix-memory-leak-in-__ceph_setxattr.patch b/queue/ceph-fix-memory-leak-in-__ceph_setxattr.patch new file mode 100644 index 0000000..ce0b575 --- /dev/null +++ b/queue/ceph-fix-memory-leak-in-__ceph_setxattr.patch @@ -0,0 +1,70 @@ +From eeca958dce0a9231d1969f86196653eb50fcc9b3 Mon Sep 17 00:00:00 2001 +From: Luis Henriques <lhenriques@suse.com> +Date: Fri, 28 Apr 2017 11:14:04 +0100 +Subject: [PATCH] ceph: fix memory leak in __ceph_setxattr() + +commit eeca958dce0a9231d1969f86196653eb50fcc9b3 upstream. + +The ceph_inode_xattr needs to be released when removing an xattr. Easily +reproducible running the 'generic/020' test from xfstests or simply by +doing: + + attr -s attr0 -V 0 /mnt/test && attr -r attr0 /mnt/test + +While there, also fix the error path. + +Here's the kmemleak splat: + +unreferenced object 0xffff88001f86fbc0 (size 64): + comm "attr", pid 244, jiffies 4294904246 (age 98.464s) + hex dump (first 32 bytes): + 40 fa 86 1f 00 88 ff ff 80 32 38 1f 00 88 ff ff @........28..... + 00 01 00 00 00 00 ad de 00 02 00 00 00 00 ad de ................ + backtrace: + [<ffffffff81560199>] kmemleak_alloc+0x49/0xa0 + [<ffffffff810f3e5b>] kmem_cache_alloc+0x9b/0xf0 + [<ffffffff812b157e>] __ceph_setxattr+0x17e/0x820 + [<ffffffff812b1c57>] ceph_set_xattr_handler+0x37/0x40 + [<ffffffff8111fb4b>] __vfs_removexattr+0x4b/0x60 + [<ffffffff8111fd37>] vfs_removexattr+0x77/0xd0 + [<ffffffff8111fdd1>] removexattr+0x41/0x60 + [<ffffffff8111fe65>] path_removexattr+0x75/0xa0 + [<ffffffff81120aeb>] SyS_lremovexattr+0xb/0x10 + [<ffffffff81564b20>] entry_SYSCALL_64_fastpath+0x13/0x94 + [<ffffffffffffffff>] 0xffffffffffffffff + +Cc: stable@vger.kernel.org +Signed-off-by: Luis Henriques <lhenriques@suse.com> +Reviewed-by: "Yan, Zheng" <zyan@redhat.com> +Signed-off-by: Ilya Dryomov <idryomov@gmail.com> + +diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c +index febc28f9e2c2..75267cdd5dfd 100644 +--- a/fs/ceph/xattr.c ++++ b/fs/ceph/xattr.c +@@ -392,6 +392,7 @@ static int __set_xattr(struct ceph_inode_info *ci, + + if (update_xattr) { + int err = 0; ++ + if (xattr && (flags & XATTR_CREATE)) + err = -EEXIST; + else if (!xattr && (flags & XATTR_REPLACE)) +@@ -399,12 +400,14 @@ static int __set_xattr(struct ceph_inode_info *ci, + if (err) { + kfree(name); + kfree(val); ++ kfree(*newxattr); + return err; + } + if (update_xattr < 0) { + if (xattr) + __remove_xattr(ci, xattr); + kfree(name); ++ kfree(*newxattr); + return 0; + } + } +-- +2.12.0 + diff --git a/queue/ceph-fix-recursion-between-ceph_set_acl-and-__ceph_s.patch b/queue/ceph-fix-recursion-between-ceph_set_acl-and-__ceph_s.patch new file mode 100644 index 0000000..e5e3235 --- /dev/null +++ b/queue/ceph-fix-recursion-between-ceph_set_acl-and-__ceph_s.patch @@ -0,0 +1,78 @@ +From 8179a101eb5f4ef0ac9a915fcea9a9d3109efa90 Mon Sep 17 00:00:00 2001 +From: "Yan, Zheng" <zyan@redhat.com> +Date: Wed, 19 Apr 2017 10:01:48 +0800 +Subject: [PATCH] ceph: fix recursion between ceph_set_acl() and + __ceph_setattr() + +commit 8179a101eb5f4ef0ac9a915fcea9a9d3109efa90 upstream. + +ceph_set_acl() calls __ceph_setattr() if the setacl operation needs +to modify inode's i_mode. __ceph_setattr() updates inode's i_mode, +then calls posix_acl_chmod(). + +The problem is that __ceph_setattr() calls posix_acl_chmod() before +sending the setattr request. The get_acl() call in posix_acl_chmod() +can trigger a getxattr request. The reply of the getxattr request +can restore inode's i_mode to its old value. The set_acl() call in +posix_acl_chmod() sees old value of inode's i_mode, so it calls +__ceph_setattr() again. + +Cc: stable@vger.kernel.org # needs backporting for < 4.9 +Link: http://tracker.ceph.com/issues/19688 +Reported-by: Jerry Lee <leisurelysw24@gmail.com> +Signed-off-by: "Yan, Zheng" <zyan@redhat.com> +Reviewed-by: Jeff Layton <jlayton@redhat.com> +Tested-by: Luis Henriques <lhenriques@suse.com> +Signed-off-by: Ilya Dryomov <idryomov@gmail.com> + +diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c +index d449e1c03cbd..d3119fe3ab45 100644 +--- a/fs/ceph/inode.c ++++ b/fs/ceph/inode.c +@@ -2071,11 +2071,6 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr) + if (inode_dirty_flags) + __mark_inode_dirty(inode, inode_dirty_flags); + +- if (ia_valid & ATTR_MODE) { +- err = posix_acl_chmod(inode, attr->ia_mode); +- if (err) +- goto out_put; +- } + + if (mask) { + req->r_inode = inode; +@@ -2089,13 +2084,11 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr) + ceph_cap_string(dirtied), mask); + + ceph_mdsc_put_request(req); +- if (mask & CEPH_SETATTR_SIZE) +- __ceph_do_pending_vmtruncate(inode); +- ceph_free_cap_flush(prealloc_cf); +- return err; +-out_put: +- ceph_mdsc_put_request(req); + ceph_free_cap_flush(prealloc_cf); ++ ++ if (err >= 0 && (mask & CEPH_SETATTR_SIZE)) ++ __ceph_do_pending_vmtruncate(inode); ++ + return err; + } + +@@ -2114,7 +2107,12 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) + if (err != 0) + return err; + +- return __ceph_setattr(inode, attr); ++ err = __ceph_setattr(inode, attr); ++ ++ if (err >= 0 && (attr->ia_valid & ATTR_MODE)) ++ err = posix_acl_chmod(inode, attr->ia_mode); ++ ++ return err; + } + + /* +-- +2.12.0 + diff --git a/queue/ceph-try-getting-buffer-capability-for-readahead-fad.patch b/queue/ceph-try-getting-buffer-capability-for-readahead-fad.patch new file mode 100644 index 0000000..1198ee4 --- /dev/null +++ b/queue/ceph-try-getting-buffer-capability-for-readahead-fad.patch @@ -0,0 +1,187 @@ +From 2b1ac852eb67a6e95595e576371d23519105559f Mon Sep 17 00:00:00 2001 +From: "Yan, Zheng" <zyan@redhat.com> +Date: Tue, 25 Oct 2016 10:51:55 +0800 +Subject: [PATCH] ceph: try getting buffer capability for readahead/fadvise + +commit 2b1ac852eb67a6e95595e576371d23519105559f upstream. + +For readahead/fadvise cases, caller of ceph_readpages does not +hold buffer capability. Pages can be added to page cache while +there is no buffer capability. This can cause data integrity +issue. + +Signed-off-by: Yan, Zheng <zyan@redhat.com> + +diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c +index ef3ebd780aff..dbb5f7d69216 100644 +--- a/fs/ceph/addr.c ++++ b/fs/ceph/addr.c +@@ -315,7 +315,32 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max) + struct page **pages; + pgoff_t next_index; + int nr_pages = 0; +- int ret; ++ int got = 0; ++ int ret = 0; ++ ++ if (!current->journal_info) { ++ /* caller of readpages does not hold buffer and read caps ++ * (fadvise, madvise and readahead cases) */ ++ int want = CEPH_CAP_FILE_CACHE; ++ ret = ceph_try_get_caps(ci, CEPH_CAP_FILE_RD, want, &got); ++ if (ret < 0) { ++ dout("start_read %p, error getting cap\n", inode); ++ } else if (!(got & want)) { ++ dout("start_read %p, no cache cap\n", inode); ++ ret = 0; ++ } ++ if (ret <= 0) { ++ if (got) ++ ceph_put_cap_refs(ci, got); ++ while (!list_empty(page_list)) { ++ page = list_entry(page_list->prev, ++ struct page, lru); ++ list_del(&page->lru); ++ put_page(page); ++ } ++ return ret; ++ } ++ } + + off = (u64) page_offset(page); + +@@ -338,15 +363,18 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max) + CEPH_OSD_FLAG_READ, NULL, + ci->i_truncate_seq, ci->i_truncate_size, + false); +- if (IS_ERR(req)) +- return PTR_ERR(req); ++ if (IS_ERR(req)) { ++ ret = PTR_ERR(req); ++ goto out; ++ } + + /* build page vector */ + nr_pages = calc_pages_for(0, len); + pages = kmalloc(sizeof(*pages) * nr_pages, GFP_KERNEL); +- ret = -ENOMEM; +- if (!pages) +- goto out; ++ if (!pages) { ++ ret = -ENOMEM; ++ goto out_put; ++ } + for (i = 0; i < nr_pages; ++i) { + page = list_entry(page_list->prev, struct page, lru); + BUG_ON(PageLocked(page)); +@@ -378,6 +406,12 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max) + if (ret < 0) + goto out_pages; + ceph_osdc_put_request(req); ++ ++ /* After adding locked pages to page cache, the inode holds cache cap. ++ * So we can drop our cap refs. */ ++ if (got) ++ ceph_put_cap_refs(ci, got); ++ + return nr_pages; + + out_pages: +@@ -386,8 +420,11 @@ out_pages: + unlock_page(pages[i]); + } + ceph_put_page_vector(pages, nr_pages, false); +-out: ++out_put: + ceph_osdc_put_request(req); ++out: ++ if (got) ++ ceph_put_cap_refs(ci, got); + return ret; + } + +@@ -424,7 +461,6 @@ static int ceph_readpages(struct file *file, struct address_space *mapping, + rc = start_read(inode, page_list, max); + if (rc < 0) + goto out; +- BUG_ON(rc == 0); + } + out: + ceph_fscache_readpages_cancel(inode, page_list); +@@ -1371,9 +1407,11 @@ static int ceph_filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + inode, off, (size_t)PAGE_SIZE, ceph_cap_string(got)); + + if ((got & (CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO)) || +- ci->i_inline_version == CEPH_INLINE_NONE) ++ ci->i_inline_version == CEPH_INLINE_NONE) { ++ current->journal_info = vma->vm_file; + ret = filemap_fault(vma, vmf); +- else ++ current->journal_info = NULL; ++ } else + ret = -EAGAIN; + + dout("filemap_fault %p %llu~%zd dropping cap refs on %s ret %d\n", +diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c +index 4037b389a7e9..edb407f38b40 100644 +--- a/fs/ceph/caps.c ++++ b/fs/ceph/caps.c +@@ -2479,6 +2479,27 @@ static void check_max_size(struct inode *inode, loff_t endoff) + ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); + } + ++int ceph_try_get_caps(struct ceph_inode_info *ci, int need, int want, int *got) ++{ ++ int ret, err = 0; ++ ++ BUG_ON(need & ~CEPH_CAP_FILE_RD); ++ BUG_ON(want & ~(CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)); ++ ret = ceph_pool_perm_check(ci, need); ++ if (ret < 0) ++ return ret; ++ ++ ret = try_get_cap_refs(ci, need, want, 0, true, got, &err); ++ if (ret) { ++ if (err == -EAGAIN) { ++ ret = 0; ++ } else if (err < 0) { ++ ret = err; ++ } ++ } ++ return ret; ++} ++ + /* + * Wait for caps, and take cap references. If we can't get a WR cap + * due to a small max_size, make sure we check_max_size (and possibly +diff --git a/fs/ceph/file.c b/fs/ceph/file.c +index 10cd6acad44c..ae3cec5724d6 100644 +--- a/fs/ceph/file.c ++++ b/fs/ceph/file.c +@@ -1249,8 +1249,9 @@ again: + dout("aio_read %p %llx.%llx %llu~%u got cap refs on %s\n", + inode, ceph_vinop(inode), iocb->ki_pos, (unsigned)len, + ceph_cap_string(got)); +- ++ current->journal_info = filp; + ret = generic_file_read_iter(iocb, to); ++ current->journal_info = NULL; + } + dout("aio_read %p %llx.%llx dropping cap refs on %s = %d\n", + inode, ceph_vinop(inode), ceph_cap_string(got), (int)ret); +diff --git a/fs/ceph/super.h b/fs/ceph/super.h +index 3e3fa9163059..622d5dd9f616 100644 +--- a/fs/ceph/super.h ++++ b/fs/ceph/super.h +@@ -905,6 +905,8 @@ extern int ceph_encode_dentry_release(void **p, struct dentry *dn, + + extern int ceph_get_caps(struct ceph_inode_info *ci, int need, int want, + loff_t endoff, int *got, struct page **pinned_page); ++extern int ceph_try_get_caps(struct ceph_inode_info *ci, ++ int need, int want, int *got); + + /* for counting open files by mode */ + extern void __ceph_get_fmode(struct ceph_inode_info *ci, int mode); +-- +2.12.0 + diff --git a/queue/cifs-Do-not-send-echoes-before-Negotiate-is-complete.patch b/queue/cifs-Do-not-send-echoes-before-Negotiate-is-complete.patch new file mode 100644 index 0000000..a7b74f8 --- /dev/null +++ b/queue/cifs-Do-not-send-echoes-before-Negotiate-is-complete.patch @@ -0,0 +1,64 @@ +From 62a6cfddcc0a5313e7da3e8311ba16226fe0ac10 Mon Sep 17 00:00:00 2001 +From: Sachin Prabhu <sprabhu@redhat.com> +Date: Sun, 16 Apr 2017 20:37:24 +0100 +Subject: [PATCH] cifs: Do not send echoes before Negotiate is complete + +commit 62a6cfddcc0a5313e7da3e8311ba16226fe0ac10 upstream. + +commit 4fcd1813e640 ("Fix reconnect to not defer smb3 session reconnect +long after socket reconnect") added support for Negotiate requests to +be initiated by echo calls. + +To avoid delays in calling echo after a reconnect, I added the patch +introduced by the commit b8c600120fc8 ("Call echo service immediately +after socket reconnect"). + +This has however caused a regression with cifs shares which do not have +support for echo calls to trigger Negotiate requests. On connections +which need to call Negotiation, the echo calls trigger an error which +triggers a reconnect which in turn triggers another echo call. This +results in a loop which is only broken when an operation is performed on +the cifs share. For an idle share, it can DOS a server. + +The patch uses the smb_operation can_echo() for cifs so that it is +called only if connection has been already been setup. + +kernel bz: 194531 + +Signed-off-by: Sachin Prabhu <sprabhu@redhat.com> +Tested-by: Jonathan Liu <net147@gmail.com> +Acked-by: Pavel Shilovsky <pshilov@microsoft.com> +CC: Stable <stable@vger.kernel.org> +Signed-off-by: Steve French <smfrench@gmail.com> + +diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c +index cc93ba4da9b5..27bc360c7ffd 100644 +--- a/fs/cifs/smb1ops.c ++++ b/fs/cifs/smb1ops.c +@@ -1015,6 +1015,15 @@ cifs_dir_needs_close(struct cifsFileInfo *cfile) + return !cfile->srch_inf.endOfSearch && !cfile->invalidHandle; + } + ++static bool ++cifs_can_echo(struct TCP_Server_Info *server) ++{ ++ if (server->tcpStatus == CifsGood) ++ return true; ++ ++ return false; ++} ++ + struct smb_version_operations smb1_operations = { + .send_cancel = send_nt_cancel, + .compare_fids = cifs_compare_fids, +@@ -1049,6 +1058,7 @@ struct smb_version_operations smb1_operations = { + .get_dfs_refer = CIFSGetDFSRefer, + .qfs_tcon = cifs_qfs_tcon, + .is_path_accessible = cifs_is_path_accessible, ++ .can_echo = cifs_can_echo, + .query_path_info = cifs_query_path_info, + .query_file_info = cifs_query_file_info, + .get_srv_inum = cifs_get_srv_inum, +-- +2.12.0 + diff --git a/queue/cifs-fix-CIFS_ENUMERATE_SNAPSHOTS-oops.patch b/queue/cifs-fix-CIFS_ENUMERATE_SNAPSHOTS-oops.patch new file mode 100644 index 0000000..d92aa3e --- /dev/null +++ b/queue/cifs-fix-CIFS_ENUMERATE_SNAPSHOTS-oops.patch @@ -0,0 +1,32 @@ +From 6026685de33b0db5b2b6b0e9b41b3a1a3261033c Mon Sep 17 00:00:00 2001 +From: David Disseldorp <ddiss@suse.de> +Date: Wed, 3 May 2017 17:39:08 +0200 +Subject: [PATCH] cifs: fix CIFS_ENUMERATE_SNAPSHOTS oops + +commit 6026685de33b0db5b2b6b0e9b41b3a1a3261033c upstream. + +As with 618763958b22, an open directory may have a NULL private_data +pointer prior to readdir. CIFS_ENUMERATE_SNAPSHOTS must check for this +before dereference. + +Fixes: 834170c85978 ("Enable previous version support") +Signed-off-by: David Disseldorp <ddiss@suse.de> +CC: Stable <stable@vger.kernel.org> +Signed-off-by: Steve French <smfrench@gmail.com> + +diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c +index 7f4bba574930..4d598a71cf84 100644 +--- a/fs/cifs/ioctl.c ++++ b/fs/cifs/ioctl.c +@@ -213,6 +213,8 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) + rc = smb_mnt_get_fsinfo(xid, tcon, (void __user *)arg); + break; + case CIFS_ENUMERATE_SNAPSHOTS: ++ if (pSMBFile == NULL) ++ break; + if (arg == 0) { + rc = -EINVAL; + goto cifs_ioc_exit; +-- +2.12.0 + diff --git a/queue/cifs-fix-CIFS_IOC_GET_MNT_INFO-oops.patch b/queue/cifs-fix-CIFS_IOC_GET_MNT_INFO-oops.patch new file mode 100644 index 0000000..18c5a0d --- /dev/null +++ b/queue/cifs-fix-CIFS_IOC_GET_MNT_INFO-oops.patch @@ -0,0 +1,30 @@ +From d8a6e505d6bba2250852fbc1c1c86fe68aaf9af3 Mon Sep 17 00:00:00 2001 +From: David Disseldorp <ddiss@suse.de> +Date: Thu, 4 May 2017 00:41:13 +0200 +Subject: [PATCH] cifs: fix CIFS_IOC_GET_MNT_INFO oops + +commit d8a6e505d6bba2250852fbc1c1c86fe68aaf9af3 upstream. + +An open directory may have a NULL private_data pointer prior to readdir. + +Fixes: 0de1f4c6f6c0 ("Add way to query server fs info for smb3") +Cc: stable@vger.kernel.org +Signed-off-by: David Disseldorp <ddiss@suse.de> +Signed-off-by: Steve French <smfrench@gmail.com> + +diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c +index 4d598a71cf84..76fb0917dc8c 100644 +--- a/fs/cifs/ioctl.c ++++ b/fs/cifs/ioctl.c +@@ -209,6 +209,8 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) + rc = -EOPNOTSUPP; + break; + case CIFS_IOC_GET_MNT_INFO: ++ if (pSMBFile == NULL) ++ break; + tcon = tlink_tcon(pSMBFile->tlink); + rc = smb_mnt_get_fsinfo(xid, tcon, (void __user *)arg); + break; +-- +2.12.0 + diff --git a/queue/cifs-fix-leak-in-FSCTL_ENUM_SNAPS-response-handling.patch b/queue/cifs-fix-leak-in-FSCTL_ENUM_SNAPS-response-handling.patch new file mode 100644 index 0000000..a61af1f --- /dev/null +++ b/queue/cifs-fix-leak-in-FSCTL_ENUM_SNAPS-response-handling.patch @@ -0,0 +1,31 @@ +From 0e5c795592930d51fd30d53a2e7b73cba022a29b Mon Sep 17 00:00:00 2001 +From: David Disseldorp <ddiss@suse.de> +Date: Wed, 3 May 2017 17:39:09 +0200 +Subject: [PATCH] cifs: fix leak in FSCTL_ENUM_SNAPS response handling + +commit 0e5c795592930d51fd30d53a2e7b73cba022a29b upstream. + +The server may respond with success, and an output buffer less than +sizeof(struct smb_snapshot_array) in length. Do not leak the output +buffer in this case. + +Fixes: 834170c85978 ("Enable previous version support") +Signed-off-by: David Disseldorp <ddiss@suse.de> +CC: Stable <stable@vger.kernel.org> +Signed-off-by: Steve French <smfrench@gmail.com> + +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index 152e37f2ad92..c58691834eb2 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -942,6 +942,7 @@ smb3_enum_snapshots(const unsigned int xid, struct cifs_tcon *tcon, + } + if (snapshot_in.snapshot_array_size < sizeof(struct smb_snapshot_array)) { + rc = -ERANGE; ++ kfree(retbuf); + return rc; + } + +-- +2.12.0 + diff --git a/queue/clk-Make-x86-conditional-on-CONFIG_COMMON_CLK.patch b/queue/clk-Make-x86-conditional-on-CONFIG_COMMON_CLK.patch new file mode 100644 index 0000000..59bcf59 --- /dev/null +++ b/queue/clk-Make-x86-conditional-on-CONFIG_COMMON_CLK.patch @@ -0,0 +1,31 @@ +From f35b6542c3ac3f28056d298348a81f7d56d3a041 Mon Sep 17 00:00:00 2001 +From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> +Date: Mon, 23 Jan 2017 12:07:41 -0600 +Subject: [PATCH] clk: Make x86/ conditional on CONFIG_COMMON_CLK + +commit f35b6542c3ac3f28056d298348a81f7d56d3a041 upstream. + +Fix Makefile for x86 support, dependency on CONFIG_COMMON_CLK +was not explicit + +Fixes: 701190fd7419 ('clk: x86: add support for Lynxpoint LPSS clocks') +Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> +Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> + +diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile +index e0754d9fc2df..92c12b86c2e8 100644 +--- a/drivers/clk/Makefile ++++ b/drivers/clk/Makefile +@@ -88,6 +88,8 @@ obj-y += ti/ + obj-$(CONFIG_CLK_UNIPHIER) += uniphier/ + obj-$(CONFIG_ARCH_U8500) += ux500/ + obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ ++ifeq ($(CONFIG_COMMON_CLK), y) + obj-$(CONFIG_X86) += x86/ ++endif + obj-$(CONFIG_ARCH_ZX) += zte/ + obj-$(CONFIG_ARCH_ZYNQ) += zynq/ +-- +2.12.0 + diff --git a/queue/clk-rockchip-add-to-mux_pll_src_apll_dpll_gpll_usb48.patch b/queue/clk-rockchip-add-to-mux_pll_src_apll_dpll_gpll_usb48.patch new file mode 100644 index 0000000..3207a3d --- /dev/null +++ b/queue/clk-rockchip-add-to-mux_pll_src_apll_dpll_gpll_usb48.patch @@ -0,0 +1,32 @@ +From 9b1b23f03abdd25ffde8bbfe5824b89bc0448c28 Mon Sep 17 00:00:00 2001 +From: Heiko Stuebner <heiko@sntech.de> +Date: Wed, 1 Mar 2017 22:00:41 +0100 +Subject: [PATCH] clk: rockchip: add "," to + mux_pll_src_apll_dpll_gpll_usb480m_p on rk3036 + +commit 9b1b23f03abdd25ffde8bbfe5824b89bc0448c28 upstream. + +The mux_pll_src_apll_dpll_gpll_usb480m_p parent list was missing a "," +between the 3rd and 4th parent names, making them fall together and thus +lookups fail. Fix that. + +Fixes: 5190c08b2989 ("clk: rockchip: add clock controller for rk3036") +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> + +diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c +index 924f560dcf80..dcde70f4c105 100644 +--- a/drivers/clk/rockchip/clk-rk3036.c ++++ b/drivers/clk/rockchip/clk-rk3036.c +@@ -127,7 +127,7 @@ PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr" }; + PNAME(mux_pll_src_3plls_p) = { "apll", "dpll", "gpll" }; + PNAME(mux_timer_p) = { "xin24m", "pclk_peri_src" }; + +-PNAME(mux_pll_src_apll_dpll_gpll_usb480m_p) = { "apll", "dpll", "gpll" "usb480m" }; ++PNAME(mux_pll_src_apll_dpll_gpll_usb480m_p) = { "apll", "dpll", "gpll", "usb480m" }; + + PNAME(mux_mmc_src_p) = { "apll", "dpll", "gpll", "xin24m" }; + PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" }; +-- +2.12.0 + diff --git a/queue/cpu-hotplug-Serialize-callback-invocations-proper.patch b/queue/cpu-hotplug-Serialize-callback-invocations-proper.patch new file mode 100644 index 0000000..cb8e2a6 --- /dev/null +++ b/queue/cpu-hotplug-Serialize-callback-invocations-proper.patch @@ -0,0 +1,155 @@ +From dc434e056fe1dada20df7ba07f32739d3a701adf Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Tue, 14 Mar 2017 16:06:45 +0100 +Subject: [PATCH] cpu/hotplug: Serialize callback invocations proper + +commit dc434e056fe1dada20df7ba07f32739d3a701adf upstream. + +The setup/remove_state/instance() functions in the hotplug core code are +serialized against concurrent CPU hotplug, but unfortunately not serialized +against themself. + +As a consequence a concurrent invocation of these function results in +corruption of the callback machinery because two instances try to invoke +callbacks on remote cpus at the same time. This results in missing callback +invocations and initiator threads waiting forever on the completion. + +The obvious solution to replace get_cpu_online() with cpu_hotplug_begin() +is not possible because at least one callsite calls into these functions +from a get_online_cpu() locked region. + +Extend the protection scope of the cpuhp_state_mutex from solely protecting +the state arrays to cover the callback invocation machinery as well. + +Fixes: 5b7aa87e0482 ("cpu/hotplug: Implement setup/removal interface") +Reported-and-tested-by: Bart Van Assche <Bart.VanAssche@sandisk.com> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Cc: hpa@zytor.com +Cc: mingo@kernel.org +Cc: akpm@linux-foundation.org +Cc: torvalds@linux-foundation.org +Link: http://lkml.kernel.org/r/20170314150645.g4tdyoszlcbajmna@linutronix.de +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + +diff --git a/kernel/cpu.c b/kernel/cpu.c +index f7c063239fa5..37b223e4fc05 100644 +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -1335,26 +1335,21 @@ static int cpuhp_store_callbacks(enum cpuhp_state state, const char *name, + struct cpuhp_step *sp; + int ret = 0; + +- mutex_lock(&cpuhp_state_mutex); +- + if (state == CPUHP_AP_ONLINE_DYN || state == CPUHP_BP_PREPARE_DYN) { + ret = cpuhp_reserve_state(state); + if (ret < 0) +- goto out; ++ return ret; + state = ret; + } + sp = cpuhp_get_step(state); +- if (name && sp->name) { +- ret = -EBUSY; +- goto out; +- } ++ if (name && sp->name) ++ return -EBUSY; ++ + sp->startup.single = startup; + sp->teardown.single = teardown; + sp->name = name; + sp->multi_instance = multi_instance; + INIT_HLIST_HEAD(&sp->list); +-out: +- mutex_unlock(&cpuhp_state_mutex); + return ret; + } + +@@ -1428,6 +1423,7 @@ int __cpuhp_state_add_instance(enum cpuhp_state state, struct hlist_node *node, + return -EINVAL; + + get_online_cpus(); ++ mutex_lock(&cpuhp_state_mutex); + + if (!invoke || !sp->startup.multi) + goto add_node; +@@ -1447,16 +1443,14 @@ int __cpuhp_state_add_instance(enum cpuhp_state state, struct hlist_node *node, + if (ret) { + if (sp->teardown.multi) + cpuhp_rollback_install(cpu, state, node); +- goto err; ++ goto unlock; + } + } + add_node: + ret = 0; +- mutex_lock(&cpuhp_state_mutex); + hlist_add_head(node, &sp->list); ++unlock: + mutex_unlock(&cpuhp_state_mutex); +- +-err: + put_online_cpus(); + return ret; + } +@@ -1491,6 +1485,7 @@ int __cpuhp_setup_state(enum cpuhp_state state, + return -EINVAL; + + get_online_cpus(); ++ mutex_lock(&cpuhp_state_mutex); + + ret = cpuhp_store_callbacks(state, name, startup, teardown, + multi_instance); +@@ -1524,6 +1519,7 @@ int __cpuhp_setup_state(enum cpuhp_state state, + } + } + out: ++ mutex_unlock(&cpuhp_state_mutex); + put_online_cpus(); + /* + * If the requested state is CPUHP_AP_ONLINE_DYN, return the +@@ -1547,6 +1543,8 @@ int __cpuhp_state_remove_instance(enum cpuhp_state state, + return -EINVAL; + + get_online_cpus(); ++ mutex_lock(&cpuhp_state_mutex); ++ + if (!invoke || !cpuhp_get_teardown_cb(state)) + goto remove; + /* +@@ -1563,7 +1561,6 @@ int __cpuhp_state_remove_instance(enum cpuhp_state state, + } + + remove: +- mutex_lock(&cpuhp_state_mutex); + hlist_del(node); + mutex_unlock(&cpuhp_state_mutex); + put_online_cpus(); +@@ -1571,6 +1568,7 @@ remove: + return 0; + } + EXPORT_SYMBOL_GPL(__cpuhp_state_remove_instance); ++ + /** + * __cpuhp_remove_state - Remove the callbacks for an hotplug machine state + * @state: The state to remove +@@ -1589,6 +1587,7 @@ void __cpuhp_remove_state(enum cpuhp_state state, bool invoke) + + get_online_cpus(); + ++ mutex_lock(&cpuhp_state_mutex); + if (sp->multi_instance) { + WARN(!hlist_empty(&sp->list), + "Error: Removing state %d which has instances left.\n", +@@ -1613,6 +1612,7 @@ void __cpuhp_remove_state(enum cpuhp_state state, bool invoke) + } + remove: + cpuhp_store_callbacks(state, NULL, NULL, NULL, false); ++ mutex_unlock(&cpuhp_state_mutex); + put_online_cpus(); + } + EXPORT_SYMBOL(__cpuhp_remove_state); +-- +2.12.0 + diff --git a/queue/cpupower-Fix-turbo-frequency-reporting-for-pre-Sandy.patch b/queue/cpupower-Fix-turbo-frequency-reporting-for-pre-Sandy.patch new file mode 100644 index 0000000..fb449ca --- /dev/null +++ b/queue/cpupower-Fix-turbo-frequency-reporting-for-pre-Sandy.patch @@ -0,0 +1,34 @@ +From 4cca0457686e4ee1677d69469e4ddfd94d389a80 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings <ben@decadent.org.uk> +Date: Tue, 11 Apr 2017 00:29:44 +0100 +Subject: [PATCH] cpupower: Fix turbo frequency reporting for pre-Sandy Bridge + cores + +commit 4cca0457686e4ee1677d69469e4ddfd94d389a80 upstream. + +The switch that conditionally sets CPUPOWER_CAP_HAS_TURBO_RATIO and +CPUPOWER_CAP_IS_SNB flags is missing a break, so all cores get both +flags set and an assumed base clock of 100 MHz for turbo values. + +Reported-by: GSR <gsr.bugs@infernal-iceberg.com> +Tested-by: GSR <gsr.bugs@infernal-iceberg.com> +References: https://bugs.debian.org/859978 +Fixes: 8fb2e440b223 (cpupower: Show Intel turbo ratio support via ...) +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> + +diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c +index 93b0aa74ca03..39c2c7d067bb 100644 +--- a/tools/power/cpupower/utils/helpers/cpuid.c ++++ b/tools/power/cpupower/utils/helpers/cpuid.c +@@ -156,6 +156,7 @@ out: + */ + case 0x2C: /* Westmere EP - Gulftown */ + cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO; ++ break; + case 0x2A: /* SNB */ + case 0x2D: /* SNB Xeon */ + case 0x3A: /* IVB */ +-- +2.12.0 + diff --git a/queue/crypto-algif_aead-Require-setkey-before-accept-2.patch b/queue/crypto-algif_aead-Require-setkey-before-accept-2.patch new file mode 100644 index 0000000..1d88a65 --- /dev/null +++ b/queue/crypto-algif_aead-Require-setkey-before-accept-2.patch @@ -0,0 +1,240 @@ +From 2a2a251f110576b1d89efbd0662677d7e7db21a8 Mon Sep 17 00:00:00 2001 +From: Stephan Mueller <smueller@chronox.de> +Date: Mon, 24 Apr 2017 11:15:23 +0200 +Subject: [PATCH] crypto: algif_aead - Require setkey before accept(2) + +commit 2a2a251f110576b1d89efbd0662677d7e7db21a8 upstream. + +Some cipher implementations will crash if you try to use them +without calling setkey first. This patch adds a check so that +the accept(2) call will fail with -ENOKEY if setkey hasn't been +done on the socket yet. + +Fixes: 400c40cf78da ("crypto: algif - add AEAD support") +Cc: <stable@vger.kernel.org> +Signed-off-by: Stephan Mueller <smueller@chronox.de> +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> + +diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c +index 5a8053758657..e0d55ea2f0eb 100644 +--- a/crypto/algif_aead.c ++++ b/crypto/algif_aead.c +@@ -44,6 +44,11 @@ struct aead_async_req { + char iv[]; + }; + ++struct aead_tfm { ++ struct crypto_aead *aead; ++ bool has_key; ++}; ++ + struct aead_ctx { + struct aead_sg_list tsgl; + struct aead_async_rsgl first_rsgl; +@@ -723,24 +728,146 @@ static struct proto_ops algif_aead_ops = { + .poll = aead_poll, + }; + ++static int aead_check_key(struct socket *sock) ++{ ++ int err = 0; ++ struct sock *psk; ++ struct alg_sock *pask; ++ struct aead_tfm *tfm; ++ struct sock *sk = sock->sk; ++ struct alg_sock *ask = alg_sk(sk); ++ ++ lock_sock(sk); ++ if (ask->refcnt) ++ goto unlock_child; ++ ++ psk = ask->parent; ++ pask = alg_sk(ask->parent); ++ tfm = pask->private; ++ ++ err = -ENOKEY; ++ lock_sock_nested(psk, SINGLE_DEPTH_NESTING); ++ if (!tfm->has_key) ++ goto unlock; ++ ++ if (!pask->refcnt++) ++ sock_hold(psk); ++ ++ ask->refcnt = 1; ++ sock_put(psk); ++ ++ err = 0; ++ ++unlock: ++ release_sock(psk); ++unlock_child: ++ release_sock(sk); ++ ++ return err; ++} ++ ++static int aead_sendmsg_nokey(struct socket *sock, struct msghdr *msg, ++ size_t size) ++{ ++ int err; ++ ++ err = aead_check_key(sock); ++ if (err) ++ return err; ++ ++ return aead_sendmsg(sock, msg, size); ++} ++ ++static ssize_t aead_sendpage_nokey(struct socket *sock, struct page *page, ++ int offset, size_t size, int flags) ++{ ++ int err; ++ ++ err = aead_check_key(sock); ++ if (err) ++ return err; ++ ++ return aead_sendpage(sock, page, offset, size, flags); ++} ++ ++static int aead_recvmsg_nokey(struct socket *sock, struct msghdr *msg, ++ size_t ignored, int flags) ++{ ++ int err; ++ ++ err = aead_check_key(sock); ++ if (err) ++ return err; ++ ++ return aead_recvmsg(sock, msg, ignored, flags); ++} ++ ++static struct proto_ops algif_aead_ops_nokey = { ++ .family = PF_ALG, ++ ++ .connect = sock_no_connect, ++ .socketpair = sock_no_socketpair, ++ .getname = sock_no_getname, ++ .ioctl = sock_no_ioctl, ++ .listen = sock_no_listen, ++ .shutdown = sock_no_shutdown, ++ .getsockopt = sock_no_getsockopt, ++ .mmap = sock_no_mmap, ++ .bind = sock_no_bind, ++ .accept = sock_no_accept, ++ .setsockopt = sock_no_setsockopt, ++ ++ .release = af_alg_release, ++ .sendmsg = aead_sendmsg_nokey, ++ .sendpage = aead_sendpage_nokey, ++ .recvmsg = aead_recvmsg_nokey, ++ .poll = aead_poll, ++}; ++ + static void *aead_bind(const char *name, u32 type, u32 mask) + { +- return crypto_alloc_aead(name, type, mask); ++ struct aead_tfm *tfm; ++ struct crypto_aead *aead; ++ ++ tfm = kzalloc(sizeof(*tfm), GFP_KERNEL); ++ if (!tfm) ++ return ERR_PTR(-ENOMEM); ++ ++ aead = crypto_alloc_aead(name, type, mask); ++ if (IS_ERR(aead)) { ++ kfree(tfm); ++ return ERR_CAST(aead); ++ } ++ ++ tfm->aead = aead; ++ ++ return tfm; + } + + static void aead_release(void *private) + { +- crypto_free_aead(private); ++ struct aead_tfm *tfm = private; ++ ++ crypto_free_aead(tfm->aead); ++ kfree(tfm); + } + + static int aead_setauthsize(void *private, unsigned int authsize) + { +- return crypto_aead_setauthsize(private, authsize); ++ struct aead_tfm *tfm = private; ++ ++ return crypto_aead_setauthsize(tfm->aead, authsize); + } + + static int aead_setkey(void *private, const u8 *key, unsigned int keylen) + { +- return crypto_aead_setkey(private, key, keylen); ++ struct aead_tfm *tfm = private; ++ int err; ++ ++ err = crypto_aead_setkey(tfm->aead, key, keylen); ++ tfm->has_key = !err; ++ ++ return err; + } + + static void aead_sock_destruct(struct sock *sk) +@@ -757,12 +884,14 @@ static void aead_sock_destruct(struct sock *sk) + af_alg_release_parent(sk); + } + +-static int aead_accept_parent(void *private, struct sock *sk) ++static int aead_accept_parent_nokey(void *private, struct sock *sk) + { + struct aead_ctx *ctx; + struct alg_sock *ask = alg_sk(sk); +- unsigned int len = sizeof(*ctx) + crypto_aead_reqsize(private); +- unsigned int ivlen = crypto_aead_ivsize(private); ++ struct aead_tfm *tfm = private; ++ struct crypto_aead *aead = tfm->aead; ++ unsigned int len = sizeof(*ctx) + crypto_aead_reqsize(aead); ++ unsigned int ivlen = crypto_aead_ivsize(aead); + + ctx = sock_kmalloc(sk, len, GFP_KERNEL); + if (!ctx) +@@ -789,7 +918,7 @@ static int aead_accept_parent(void *private, struct sock *sk) + + ask->private = ctx; + +- aead_request_set_tfm(&ctx->aead_req, private); ++ aead_request_set_tfm(&ctx->aead_req, aead); + aead_request_set_callback(&ctx->aead_req, CRYPTO_TFM_REQ_MAY_BACKLOG, + af_alg_complete, &ctx->completion); + +@@ -798,13 +927,25 @@ static int aead_accept_parent(void *private, struct sock *sk) + return 0; + } + ++static int aead_accept_parent(void *private, struct sock *sk) ++{ ++ struct aead_tfm *tfm = private; ++ ++ if (!tfm->has_key) ++ return -ENOKEY; ++ ++ return aead_accept_parent_nokey(private, sk); ++} ++ + static const struct af_alg_type algif_type_aead = { + .bind = aead_bind, + .release = aead_release, + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .accept = aead_accept_parent, ++ .accept_nokey = aead_accept_parent_nokey, + .ops = &algif_aead_ops, ++ .ops_nokey = &algif_aead_ops_nokey, + .name = "aead", + .owner = THIS_MODULE + }; +-- +2.12.0 + diff --git a/queue/crypto-caam-fix-error-path-for-ctx_dma-mapping-failu.patch b/queue/crypto-caam-fix-error-path-for-ctx_dma-mapping-failu.patch new file mode 100644 index 0000000..efcdb6c --- /dev/null +++ b/queue/crypto-caam-fix-error-path-for-ctx_dma-mapping-failu.patch @@ -0,0 +1,71 @@ +From 87ec02e7409d787348c244039aa3536a812dfa8b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Horia=20Geant=C4=83?= <horia.geanta@nxp.com> +Date: Fri, 10 Feb 2017 14:07:23 +0200 +Subject: [PATCH] crypto: caam - fix error path for ctx_dma mapping failure +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 87ec02e7409d787348c244039aa3536a812dfa8b upstream. + +In case ctx_dma dma mapping fails, ahash_unmap_ctx() tries to +dma unmap an invalid address: +map_seq_out_ptr_ctx() / ctx_map_to_sec4_sg() -> goto unmap_ctx -> +-> ahash_unmap_ctx() -> dma unmap ctx_dma + +There is also possible to reach ahash_unmap_ctx() with ctx_dma +uninitialzed or to try to unmap the same address twice. + +Fix these by setting ctx_dma = 0 where needed: +-initialize ctx_dma in ahash_init() +-clear ctx_dma in case of mapping error (instead of holding +the error code returned by the dma map function) +-clear ctx_dma after each unmapping + +Fixes: 32686d34f8fb6 ("crypto: caam - ensure that we clean up after an error") +Signed-off-by: Horia Geantă <horia.geanta@nxp.com> +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> + +diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c +index 2ad83a8dc0fe..6c6c005f417b 100644 +--- a/drivers/crypto/caam/caamhash.c ++++ b/drivers/crypto/caam/caamhash.c +@@ -148,6 +148,7 @@ static inline int map_seq_out_ptr_ctx(u32 *desc, struct device *jrdev, + ctx_len, DMA_FROM_DEVICE); + if (dma_mapping_error(jrdev, state->ctx_dma)) { + dev_err(jrdev, "unable to map ctx\n"); ++ state->ctx_dma = 0; + return -ENOMEM; + } + +@@ -208,6 +209,7 @@ static inline int ctx_map_to_sec4_sg(u32 *desc, struct device *jrdev, + state->ctx_dma = dma_map_single(jrdev, state->caam_ctx, ctx_len, flag); + if (dma_mapping_error(jrdev, state->ctx_dma)) { + dev_err(jrdev, "unable to map ctx\n"); ++ state->ctx_dma = 0; + return -ENOMEM; + } + +@@ -482,8 +484,10 @@ static inline void ahash_unmap_ctx(struct device *dev, + struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct caam_hash_state *state = ahash_request_ctx(req); + +- if (state->ctx_dma) ++ if (state->ctx_dma) { + dma_unmap_single(dev, state->ctx_dma, ctx->ctx_len, flag); ++ state->ctx_dma = 0; ++ } + ahash_unmap(dev, edesc, req, dst_len); + } + +@@ -1463,6 +1467,7 @@ static int ahash_init(struct ahash_request *req) + state->finup = ahash_finup_first; + state->final = ahash_final_no_ctx; + ++ state->ctx_dma = 0; + state->current_buf = 0; + state->buf_dma = 0; + state->buflen_0 = 0; +-- +2.12.0 + diff --git a/queue/crypto-ccp-Change-ISR-handler-method-for-a-v3-CCP.patch b/queue/crypto-ccp-Change-ISR-handler-method-for-a-v3-CCP.patch new file mode 100644 index 0000000..437fcc9 --- /dev/null +++ b/queue/crypto-ccp-Change-ISR-handler-method-for-a-v3-CCP.patch @@ -0,0 +1,267 @@ +From 7b537b24e76a1e8e6d7ea91483a45d5b1426809b Mon Sep 17 00:00:00 2001 +From: Gary R Hook <gary.hook@amd.com> +Date: Fri, 21 Apr 2017 10:50:05 -0500 +Subject: [PATCH] crypto: ccp - Change ISR handler method for a v3 CCP + +commit 7b537b24e76a1e8e6d7ea91483a45d5b1426809b upstream. + +The CCP has the ability to perform several operations simultaneously, +but only one interrupt. When implemented as a PCI device and using +MSI-X/MSI interrupts, use a tasklet model to service interrupts. By +disabling and enabling interrupts from the CCP, coupled with the +queuing that tasklets provide, we can ensure that all events +(occurring on the device) are recognized and serviced. + +This change fixes a problem wherein 2 or more busy queues can cause +notification bits to change state while a (CCP) interrupt is being +serviced, but after the queue state has been evaluated. This results +in the event being 'lost' and the queue hanging, waiting to be +serviced. Since the status bits are never fully de-asserted, the +CCP never generates another interrupt (all bits zero -> one or more +bits one), and no further CCP operations will be executed. + +Cc: <stable@vger.kernel.org> # 4.9.x+ + +Signed-off-by: Gary R Hook <gary.hook@amd.com> +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> + +diff --git a/drivers/crypto/ccp/ccp-dev-v3.c b/drivers/crypto/ccp/ccp-dev-v3.c +index a3689a66cb1d..367c2e30656f 100644 +--- a/drivers/crypto/ccp/ccp-dev-v3.c ++++ b/drivers/crypto/ccp/ccp-dev-v3.c +@@ -315,17 +315,73 @@ static int ccp_perform_ecc(struct ccp_op *op) + return ccp_do_cmd(op, cr, ARRAY_SIZE(cr)); + } + ++static void ccp_disable_queue_interrupts(struct ccp_device *ccp) ++{ ++ iowrite32(0x00, ccp->io_regs + IRQ_MASK_REG); ++} ++ ++static void ccp_enable_queue_interrupts(struct ccp_device *ccp) ++{ ++ iowrite32(ccp->qim, ccp->io_regs + IRQ_MASK_REG); ++} ++ ++static void ccp_irq_bh(unsigned long data) ++{ ++ struct ccp_device *ccp = (struct ccp_device *)data; ++ struct ccp_cmd_queue *cmd_q; ++ u32 q_int, status; ++ unsigned int i; ++ ++ status = ioread32(ccp->io_regs + IRQ_STATUS_REG); ++ ++ for (i = 0; i < ccp->cmd_q_count; i++) { ++ cmd_q = &ccp->cmd_q[i]; ++ ++ q_int = status & (cmd_q->int_ok | cmd_q->int_err); ++ if (q_int) { ++ cmd_q->int_status = status; ++ cmd_q->q_status = ioread32(cmd_q->reg_status); ++ cmd_q->q_int_status = ioread32(cmd_q->reg_int_status); ++ ++ /* On error, only save the first error value */ ++ if ((q_int & cmd_q->int_err) && !cmd_q->cmd_error) ++ cmd_q->cmd_error = CMD_Q_ERROR(cmd_q->q_status); ++ ++ cmd_q->int_rcvd = 1; ++ ++ /* Acknowledge the interrupt and wake the kthread */ ++ iowrite32(q_int, ccp->io_regs + IRQ_STATUS_REG); ++ wake_up_interruptible(&cmd_q->int_queue); ++ } ++ } ++ ccp_enable_queue_interrupts(ccp); ++} ++ ++static irqreturn_t ccp_irq_handler(int irq, void *data) ++{ ++ struct device *dev = data; ++ struct ccp_device *ccp = dev_get_drvdata(dev); ++ ++ ccp_disable_queue_interrupts(ccp); ++ if (ccp->use_tasklet) ++ tasklet_schedule(&ccp->irq_tasklet); ++ else ++ ccp_irq_bh((unsigned long)ccp); ++ ++ return IRQ_HANDLED; ++} ++ + static int ccp_init(struct ccp_device *ccp) + { + struct device *dev = ccp->dev; + struct ccp_cmd_queue *cmd_q; + struct dma_pool *dma_pool; + char dma_pool_name[MAX_DMAPOOL_NAME_LEN]; +- unsigned int qmr, qim, i; ++ unsigned int qmr, i; + int ret; + + /* Find available queues */ +- qim = 0; ++ ccp->qim = 0; + qmr = ioread32(ccp->io_regs + Q_MASK_REG); + for (i = 0; i < MAX_HW_QUEUES; i++) { + if (!(qmr & (1 << i))) +@@ -370,7 +426,7 @@ static int ccp_init(struct ccp_device *ccp) + init_waitqueue_head(&cmd_q->int_queue); + + /* Build queue interrupt mask (two interrupts per queue) */ +- qim |= cmd_q->int_ok | cmd_q->int_err; ++ ccp->qim |= cmd_q->int_ok | cmd_q->int_err; + + #ifdef CONFIG_ARM64 + /* For arm64 set the recommended queue cache settings */ +@@ -388,14 +444,14 @@ static int ccp_init(struct ccp_device *ccp) + dev_notice(dev, "%u command queues available\n", ccp->cmd_q_count); + + /* Disable and clear interrupts until ready */ +- iowrite32(0x00, ccp->io_regs + IRQ_MASK_REG); ++ ccp_disable_queue_interrupts(ccp); + for (i = 0; i < ccp->cmd_q_count; i++) { + cmd_q = &ccp->cmd_q[i]; + + ioread32(cmd_q->reg_int_status); + ioread32(cmd_q->reg_status); + } +- iowrite32(qim, ccp->io_regs + IRQ_STATUS_REG); ++ iowrite32(ccp->qim, ccp->io_regs + IRQ_STATUS_REG); + + /* Request an irq */ + ret = ccp->get_irq(ccp); +@@ -404,6 +460,11 @@ static int ccp_init(struct ccp_device *ccp) + goto e_pool; + } + ++ /* Initialize the ISR tasklet? */ ++ if (ccp->use_tasklet) ++ tasklet_init(&ccp->irq_tasklet, ccp_irq_bh, ++ (unsigned long)ccp); ++ + dev_dbg(dev, "Starting threads...\n"); + /* Create a kthread for each queue */ + for (i = 0; i < ccp->cmd_q_count; i++) { +@@ -426,7 +487,7 @@ static int ccp_init(struct ccp_device *ccp) + + dev_dbg(dev, "Enabling interrupts...\n"); + /* Enable interrupts */ +- iowrite32(qim, ccp->io_regs + IRQ_MASK_REG); ++ ccp_enable_queue_interrupts(ccp); + + dev_dbg(dev, "Registering device...\n"); + ccp_add_device(ccp); +@@ -463,7 +524,7 @@ static void ccp_destroy(struct ccp_device *ccp) + { + struct ccp_cmd_queue *cmd_q; + struct ccp_cmd *cmd; +- unsigned int qim, i; ++ unsigned int i; + + /* Unregister the DMA engine */ + ccp_dmaengine_unregister(ccp); +@@ -474,22 +535,15 @@ static void ccp_destroy(struct ccp_device *ccp) + /* Remove this device from the list of available units */ + ccp_del_device(ccp); + +- /* Build queue interrupt mask (two interrupt masks per queue) */ +- qim = 0; +- for (i = 0; i < ccp->cmd_q_count; i++) { +- cmd_q = &ccp->cmd_q[i]; +- qim |= cmd_q->int_ok | cmd_q->int_err; +- } +- + /* Disable and clear interrupts */ +- iowrite32(0x00, ccp->io_regs + IRQ_MASK_REG); ++ ccp_disable_queue_interrupts(ccp); + for (i = 0; i < ccp->cmd_q_count; i++) { + cmd_q = &ccp->cmd_q[i]; + + ioread32(cmd_q->reg_int_status); + ioread32(cmd_q->reg_status); + } +- iowrite32(qim, ccp->io_regs + IRQ_STATUS_REG); ++ iowrite32(ccp->qim, ccp->io_regs + IRQ_STATUS_REG); + + /* Stop the queue kthreads */ + for (i = 0; i < ccp->cmd_q_count; i++) +@@ -516,40 +570,6 @@ static void ccp_destroy(struct ccp_device *ccp) + } + } + +-static irqreturn_t ccp_irq_handler(int irq, void *data) +-{ +- struct device *dev = data; +- struct ccp_device *ccp = dev_get_drvdata(dev); +- struct ccp_cmd_queue *cmd_q; +- u32 q_int, status; +- unsigned int i; +- +- status = ioread32(ccp->io_regs + IRQ_STATUS_REG); +- +- for (i = 0; i < ccp->cmd_q_count; i++) { +- cmd_q = &ccp->cmd_q[i]; +- +- q_int = status & (cmd_q->int_ok | cmd_q->int_err); +- if (q_int) { +- cmd_q->int_status = status; +- cmd_q->q_status = ioread32(cmd_q->reg_status); +- cmd_q->q_int_status = ioread32(cmd_q->reg_int_status); +- +- /* On error, only save the first error value */ +- if ((q_int & cmd_q->int_err) && !cmd_q->cmd_error) +- cmd_q->cmd_error = CMD_Q_ERROR(cmd_q->q_status); +- +- cmd_q->int_rcvd = 1; +- +- /* Acknowledge the interrupt and wake the kthread */ +- iowrite32(q_int, ccp->io_regs + IRQ_STATUS_REG); +- wake_up_interruptible(&cmd_q->int_queue); +- } +- } +- +- return IRQ_HANDLED; +-} +- + static const struct ccp_actions ccp3_actions = { + .aes = ccp_perform_aes, + .xts_aes = ccp_perform_xts_aes, +diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h +index 2dfec019a832..0cb09d0feeaf 100644 +--- a/drivers/crypto/ccp/ccp-dev.h ++++ b/drivers/crypto/ccp/ccp-dev.h +@@ -339,7 +339,10 @@ struct ccp_device { + void *dev_specific; + int (*get_irq)(struct ccp_device *ccp); + void (*free_irq)(struct ccp_device *ccp); ++ unsigned int qim; + unsigned int irq; ++ bool use_tasklet; ++ struct tasklet_struct irq_tasklet; + + /* I/O area used for device communication. The register mapping + * starts at an offset into the mapped bar. +diff --git a/drivers/crypto/ccp/ccp-pci.c b/drivers/crypto/ccp/ccp-pci.c +index 28a9996c1085..e880d4cf4ada 100644 +--- a/drivers/crypto/ccp/ccp-pci.c ++++ b/drivers/crypto/ccp/ccp-pci.c +@@ -69,6 +69,7 @@ static int ccp_get_msix_irqs(struct ccp_device *ccp) + goto e_irq; + } + } ++ ccp->use_tasklet = true; + + return 0; + +@@ -100,6 +101,7 @@ static int ccp_get_msi_irq(struct ccp_device *ccp) + dev_notice(dev, "unable to allocate MSI IRQ (%d)\n", ret); + goto e_msi; + } ++ ccp->use_tasklet = true; + + return 0; + +-- +2.12.0 + diff --git a/queue/crypto-ccp-Change-ISR-handler-method-for-a-v5-CCP.patch b/queue/crypto-ccp-Change-ISR-handler-method-for-a-v5-CCP.patch new file mode 100644 index 0000000..b50fd9a --- /dev/null +++ b/queue/crypto-ccp-Change-ISR-handler-method-for-a-v5-CCP.patch @@ -0,0 +1,202 @@ +From 6263b51eb3190d30351360fd168959af7e3a49a9 Mon Sep 17 00:00:00 2001 +From: Gary R Hook <gary.hook@amd.com> +Date: Fri, 21 Apr 2017 10:50:14 -0500 +Subject: [PATCH] crypto: ccp - Change ISR handler method for a v5 CCP + +commit 6263b51eb3190d30351360fd168959af7e3a49a9 upstream. + +The CCP has the ability to perform several operations simultaneously, +but only one interrupt. When implemented as a PCI device and using +MSI-X/MSI interrupts, use a tasklet model to service interrupts. By +disabling and enabling interrupts from the CCP, coupled with the +queuing that tasklets provide, we can ensure that all events +(occurring on the device) are recognized and serviced. + +This change fixes a problem wherein 2 or more busy queues can cause +notification bits to change state while a (CCP) interrupt is being +serviced, but after the queue state has been evaluated. This results +in the event being 'lost' and the queue hanging, waiting to be +serviced. Since the status bits are never fully de-asserted, the +CCP never generates another interrupt (all bits zero -> one or more +bits one), and no further CCP operations will be executed. + +Cc: <stable@vger.kernel.org> # 4.9.x+ + +Signed-off-by: Gary R Hook <gary.hook@amd.com> +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> + +diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c +index 13b81a1c1184..ccbe32d5dd1c 100644 +--- a/drivers/crypto/ccp/ccp-dev-v5.c ++++ b/drivers/crypto/ccp/ccp-dev-v5.c +@@ -705,6 +705,65 @@ static int ccp_assign_lsbs(struct ccp_device *ccp) + return rc; + } + ++static void ccp5_disable_queue_interrupts(struct ccp_device *ccp) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ccp->cmd_q_count; i++) ++ iowrite32(0x0, ccp->cmd_q[i].reg_int_enable); ++} ++ ++static void ccp5_enable_queue_interrupts(struct ccp_device *ccp) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ccp->cmd_q_count; i++) ++ iowrite32(SUPPORTED_INTERRUPTS, ccp->cmd_q[i].reg_int_enable); ++} ++ ++static void ccp5_irq_bh(unsigned long data) ++{ ++ struct ccp_device *ccp = (struct ccp_device *)data; ++ u32 status; ++ unsigned int i; ++ ++ for (i = 0; i < ccp->cmd_q_count; i++) { ++ struct ccp_cmd_queue *cmd_q = &ccp->cmd_q[i]; ++ ++ status = ioread32(cmd_q->reg_interrupt_status); ++ ++ if (status) { ++ cmd_q->int_status = status; ++ cmd_q->q_status = ioread32(cmd_q->reg_status); ++ cmd_q->q_int_status = ioread32(cmd_q->reg_int_status); ++ ++ /* On error, only save the first error value */ ++ if ((status & INT_ERROR) && !cmd_q->cmd_error) ++ cmd_q->cmd_error = CMD_Q_ERROR(cmd_q->q_status); ++ ++ cmd_q->int_rcvd = 1; ++ ++ /* Acknowledge the interrupt and wake the kthread */ ++ iowrite32(status, cmd_q->reg_interrupt_status); ++ wake_up_interruptible(&cmd_q->int_queue); ++ } ++ } ++ ccp5_enable_queue_interrupts(ccp); ++} ++ ++static irqreturn_t ccp5_irq_handler(int irq, void *data) ++{ ++ struct device *dev = data; ++ struct ccp_device *ccp = dev_get_drvdata(dev); ++ ++ ccp5_disable_queue_interrupts(ccp); ++ if (ccp->use_tasklet) ++ tasklet_schedule(&ccp->irq_tasklet); ++ else ++ ccp5_irq_bh((unsigned long)ccp); ++ return IRQ_HANDLED; ++} ++ + static int ccp5_init(struct ccp_device *ccp) + { + struct device *dev = ccp->dev; +@@ -789,18 +848,17 @@ static int ccp5_init(struct ccp_device *ccp) + } + + /* Turn off the queues and disable interrupts until ready */ ++ ccp5_disable_queue_interrupts(ccp); + for (i = 0; i < ccp->cmd_q_count; i++) { + cmd_q = &ccp->cmd_q[i]; + + cmd_q->qcontrol = 0; /* Start with nothing */ + iowrite32(cmd_q->qcontrol, cmd_q->reg_control); + +- /* Disable the interrupts */ +- iowrite32(0x00, cmd_q->reg_int_enable); + ioread32(cmd_q->reg_int_status); + ioread32(cmd_q->reg_status); + +- /* Clear the interrupts */ ++ /* Clear the interrupt status */ + iowrite32(SUPPORTED_INTERRUPTS, cmd_q->reg_interrupt_status); + } + +@@ -811,6 +869,10 @@ static int ccp5_init(struct ccp_device *ccp) + dev_err(dev, "unable to allocate an IRQ\n"); + goto e_pool; + } ++ /* Initialize the ISR tasklet */ ++ if (ccp->use_tasklet) ++ tasklet_init(&ccp->irq_tasklet, ccp5_irq_bh, ++ (unsigned long)ccp); + + dev_dbg(dev, "Loading LSB map...\n"); + /* Copy the private LSB mask to the public registers */ +@@ -879,11 +941,7 @@ static int ccp5_init(struct ccp_device *ccp) + } + + dev_dbg(dev, "Enabling interrupts...\n"); +- /* Enable interrupts */ +- for (i = 0; i < ccp->cmd_q_count; i++) { +- cmd_q = &ccp->cmd_q[i]; +- iowrite32(SUPPORTED_INTERRUPTS, cmd_q->reg_int_enable); +- } ++ ccp5_enable_queue_interrupts(ccp); + + dev_dbg(dev, "Registering device...\n"); + /* Put this on the unit list to make it available */ +@@ -935,15 +993,13 @@ static void ccp5_destroy(struct ccp_device *ccp) + ccp_del_device(ccp); + + /* Disable and clear interrupts */ ++ ccp5_disable_queue_interrupts(ccp); + for (i = 0; i < ccp->cmd_q_count; i++) { + cmd_q = &ccp->cmd_q[i]; + + /* Turn off the run bit */ + iowrite32(cmd_q->qcontrol & ~CMD5_Q_RUN, cmd_q->reg_control); + +- /* Disable the interrupts */ +- iowrite32(0x00, cmd_q->reg_int_enable); +- + /* Clear the interrupt status */ + iowrite32(SUPPORTED_INTERRUPTS, cmd_q->reg_interrupt_status); + ioread32(cmd_q->reg_int_status); +@@ -978,39 +1034,6 @@ static void ccp5_destroy(struct ccp_device *ccp) + } + } + +-static irqreturn_t ccp5_irq_handler(int irq, void *data) +-{ +- struct device *dev = data; +- struct ccp_device *ccp = dev_get_drvdata(dev); +- u32 status; +- unsigned int i; +- +- for (i = 0; i < ccp->cmd_q_count; i++) { +- struct ccp_cmd_queue *cmd_q = &ccp->cmd_q[i]; +- +- status = ioread32(cmd_q->reg_interrupt_status); +- +- if (status) { +- cmd_q->int_status = status; +- cmd_q->q_status = ioread32(cmd_q->reg_status); +- cmd_q->q_int_status = ioread32(cmd_q->reg_int_status); +- +- /* On error, only save the first error value */ +- if ((status & INT_ERROR) && !cmd_q->cmd_error) +- cmd_q->cmd_error = CMD_Q_ERROR(cmd_q->q_status); +- +- cmd_q->int_rcvd = 1; +- +- /* Acknowledge the interrupt and wake the kthread */ +- iowrite32(SUPPORTED_INTERRUPTS, +- cmd_q->reg_interrupt_status); +- wake_up_interruptible(&cmd_q->int_queue); +- } +- } +- +- return IRQ_HANDLED; +-} +- + static void ccp5_config(struct ccp_device *ccp) + { + /* Public side */ +-- +2.12.0 + diff --git a/queue/crypto-ccp-Disable-interrupts-early-on-unload.patch b/queue/crypto-ccp-Disable-interrupts-early-on-unload.patch new file mode 100644 index 0000000..78d121f --- /dev/null +++ b/queue/crypto-ccp-Disable-interrupts-early-on-unload.patch @@ -0,0 +1,35 @@ +From 116591fe3eef11c6f06b662c9176385f13891183 Mon Sep 17 00:00:00 2001 +From: Gary R Hook <ghook@amd.com> +Date: Thu, 20 Apr 2017 15:24:22 -0500 +Subject: [PATCH] crypto: ccp - Disable interrupts early on unload + +commit 116591fe3eef11c6f06b662c9176385f13891183 upstream. + +Ensure that we disable interrupts first when shutting down +the driver. + +Cc: <stable@vger.kernel.org> # 4.9.x+ + +Signed-off-by: Gary R Hook <ghook@amd.com> +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> + +diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c +index c7972e733e43..13b81a1c1184 100644 +--- a/drivers/crypto/ccp/ccp-dev-v5.c ++++ b/drivers/crypto/ccp/ccp-dev-v5.c +@@ -942,10 +942,10 @@ static void ccp5_destroy(struct ccp_device *ccp) + iowrite32(cmd_q->qcontrol & ~CMD5_Q_RUN, cmd_q->reg_control); + + /* Disable the interrupts */ +- iowrite32(SUPPORTED_INTERRUPTS, cmd_q->reg_interrupt_status); ++ iowrite32(0x00, cmd_q->reg_int_enable); + + /* Clear the interrupt status */ +- iowrite32(0x00, cmd_q->reg_int_enable); ++ iowrite32(SUPPORTED_INTERRUPTS, cmd_q->reg_interrupt_status); + ioread32(cmd_q->reg_int_status); + ioread32(cmd_q->reg_status); + } +-- +2.12.0 + diff --git a/queue/crypto-ccp-Use-only-the-relevant-interrupt-bits.patch b/queue/crypto-ccp-Use-only-the-relevant-interrupt-bits.patch new file mode 100644 index 0000000..cbaca9f --- /dev/null +++ b/queue/crypto-ccp-Use-only-the-relevant-interrupt-bits.patch @@ -0,0 +1,76 @@ +From 56467cb11cf8ae4db9003f54b3d3425b5f07a10a Mon Sep 17 00:00:00 2001 +From: Gary R Hook <gary.hook@amd.com> +Date: Thu, 20 Apr 2017 15:24:09 -0500 +Subject: [PATCH] crypto: ccp - Use only the relevant interrupt bits + +commit 56467cb11cf8ae4db9003f54b3d3425b5f07a10a upstream. + +Each CCP queue can product interrupts for 4 conditions: +operation complete, queue empty, error, and queue stopped. +This driver only works with completion and error events. + +Cc: <stable@vger.kernel.org> # 4.9.x+ + +Signed-off-by: Gary R Hook <gary.hook@amd.com> +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> + +diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c +index e03d06a54d4e..c7972e733e43 100644 +--- a/drivers/crypto/ccp/ccp-dev-v5.c ++++ b/drivers/crypto/ccp/ccp-dev-v5.c +@@ -801,7 +801,7 @@ static int ccp5_init(struct ccp_device *ccp) + ioread32(cmd_q->reg_status); + + /* Clear the interrupts */ +- iowrite32(ALL_INTERRUPTS, cmd_q->reg_interrupt_status); ++ iowrite32(SUPPORTED_INTERRUPTS, cmd_q->reg_interrupt_status); + } + + dev_dbg(dev, "Requesting an IRQ...\n"); +@@ -882,7 +882,7 @@ static int ccp5_init(struct ccp_device *ccp) + /* Enable interrupts */ + for (i = 0; i < ccp->cmd_q_count; i++) { + cmd_q = &ccp->cmd_q[i]; +- iowrite32(ALL_INTERRUPTS, cmd_q->reg_int_enable); ++ iowrite32(SUPPORTED_INTERRUPTS, cmd_q->reg_int_enable); + } + + dev_dbg(dev, "Registering device...\n"); +@@ -942,7 +942,7 @@ static void ccp5_destroy(struct ccp_device *ccp) + iowrite32(cmd_q->qcontrol & ~CMD5_Q_RUN, cmd_q->reg_control); + + /* Disable the interrupts */ +- iowrite32(ALL_INTERRUPTS, cmd_q->reg_interrupt_status); ++ iowrite32(SUPPORTED_INTERRUPTS, cmd_q->reg_interrupt_status); + + /* Clear the interrupt status */ + iowrite32(0x00, cmd_q->reg_int_enable); +@@ -1002,7 +1002,8 @@ static irqreturn_t ccp5_irq_handler(int irq, void *data) + cmd_q->int_rcvd = 1; + + /* Acknowledge the interrupt and wake the kthread */ +- iowrite32(ALL_INTERRUPTS, cmd_q->reg_interrupt_status); ++ iowrite32(SUPPORTED_INTERRUPTS, ++ cmd_q->reg_interrupt_status); + wake_up_interruptible(&cmd_q->int_queue); + } + } +diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h +index 191274d41036..2dfec019a832 100644 +--- a/drivers/crypto/ccp/ccp-dev.h ++++ b/drivers/crypto/ccp/ccp-dev.h +@@ -109,9 +109,8 @@ + #define INT_COMPLETION 0x1 + #define INT_ERROR 0x2 + #define INT_QUEUE_STOPPED 0x4 +-#define ALL_INTERRUPTS (INT_COMPLETION| \ +- INT_ERROR| \ +- INT_QUEUE_STOPPED) ++#define INT_EMPTY_QUEUE 0x8 ++#define SUPPORTED_INTERRUPTS (INT_COMPLETION | INT_ERROR) + + #define LSB_REGION_WIDTH 5 + #define MAX_LSB_CNT 8 +-- +2.12.0 + diff --git a/queue/device-dax-fix-cdev-leak.patch b/queue/device-dax-fix-cdev-leak.patch new file mode 100644 index 0000000..2f9367f --- /dev/null +++ b/queue/device-dax-fix-cdev-leak.patch @@ -0,0 +1,69 @@ +From ed01e50acdd3e4a640cf9ebd28a7e810c3ceca97 Mon Sep 17 00:00:00 2001 +From: Dan Williams <dan.j.williams@intel.com> +Date: Fri, 17 Mar 2017 12:48:09 -0600 +Subject: [PATCH] device-dax: fix cdev leak + +commit ed01e50acdd3e4a640cf9ebd28a7e810c3ceca97 upstream. + +If device_add() fails, cleanup the cdev. Otherwise, we leak a kobj_map() +with a stale device number. + +As Jason points out, there is a small possibility that userspace has +opened and mapped the device in the time between cdev_add() and the +device_add() failure. We need a new kill_dax_dev() helper to invalidate +any established mappings. + +Fixes: ba09c01d2fa8 ("dax: convert to the cdev api") +Cc: <stable@vger.kernel.org> +Reported-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> +Signed-off-by: Dan Williams <dan.j.williams@intel.com> +Signed-off-by: Logan Gunthorpe <logang@deltatee.com> +Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/dax/dax.c b/drivers/dax/dax.c +index 8d9829ff2a78..a5ed59a5a968 100644 +--- a/drivers/dax/dax.c ++++ b/drivers/dax/dax.c +@@ -675,13 +675,10 @@ static void dax_dev_release(struct device *dev) + kfree(dax_dev); + } + +-static void unregister_dax_dev(void *dev) ++static void kill_dax_dev(struct dax_dev *dax_dev) + { +- struct dax_dev *dax_dev = to_dax_dev(dev); + struct cdev *cdev = &dax_dev->cdev; + +- dev_dbg(dev, "%s\n", __func__); +- + /* + * Note, rcu is not protecting the liveness of dax_dev, rcu is + * ensuring that any fault handlers that might have seen +@@ -693,6 +690,15 @@ static void unregister_dax_dev(void *dev) + synchronize_rcu(); + unmap_mapping_range(dax_dev->inode->i_mapping, 0, 0, 1); + cdev_del(cdev); ++} ++ ++static void unregister_dax_dev(void *dev) ++{ ++ struct dax_dev *dax_dev = to_dax_dev(dev); ++ ++ dev_dbg(dev, "%s\n", __func__); ++ ++ kill_dax_dev(dax_dev); + device_unregister(dev); + } + +@@ -769,6 +775,7 @@ struct dax_dev *devm_create_dax_dev(struct dax_region *dax_region, + dev_set_name(dev, "dax%d.%d", dax_region->id, dax_dev->id); + rc = device_add(dev); + if (rc) { ++ kill_dax_dev(dax_dev); + put_device(dev); + return ERR_PTR(rc); + } +-- +2.12.0 + diff --git a/queue/device-dax-switch-to-srcu-fix-rcu_read_lock-vs-pte-a.patch b/queue/device-dax-switch-to-srcu-fix-rcu_read_lock-vs-pte-a.patch new file mode 100644 index 0000000..4dd7516 --- /dev/null +++ b/queue/device-dax-switch-to-srcu-fix-rcu_read_lock-vs-pte-a.patch @@ -0,0 +1,134 @@ +From 956a4cd2c957acf638ff29951aabaa9d8e92bbc2 Mon Sep 17 00:00:00 2001 +From: Dan Williams <dan.j.williams@intel.com> +Date: Fri, 7 Apr 2017 16:42:08 -0700 +Subject: [PATCH] device-dax: switch to srcu, fix rcu_read_lock() vs pte + allocation + +commit 956a4cd2c957acf638ff29951aabaa9d8e92bbc2 upstream. + +The following warning triggers with a new unit test that stresses the +device-dax interface. + + =============================== + [ ERR: suspicious RCU usage. ] + 4.11.0-rc4+ #1049 Tainted: G O + ------------------------------- + ./include/linux/rcupdate.h:521 Illegal context switch in RCU read-side critical section! + + other info that might help us debug this: + + rcu_scheduler_active = 2, debug_locks = 0 + 2 locks held by fio/9070: + #0: (&mm->mmap_sem){++++++}, at: [<ffffffff8d0739d7>] __do_page_fault+0x167/0x4f0 + #1: (rcu_read_lock){......}, at: [<ffffffffc03fbd02>] dax_dev_huge_fault+0x32/0x620 [dax] + + Call Trace: + dump_stack+0x86/0xc3 + lockdep_rcu_suspicious+0xd7/0x110 + ___might_sleep+0xac/0x250 + __might_sleep+0x4a/0x80 + __alloc_pages_nodemask+0x23a/0x360 + alloc_pages_current+0xa1/0x1f0 + pte_alloc_one+0x17/0x80 + __pte_alloc+0x1e/0x120 + __get_locked_pte+0x1bf/0x1d0 + insert_pfn.isra.70+0x3a/0x100 + ? lookup_memtype+0xa6/0xd0 + vm_insert_mixed+0x64/0x90 + dax_dev_huge_fault+0x520/0x620 [dax] + ? dax_dev_huge_fault+0x32/0x620 [dax] + dax_dev_fault+0x10/0x20 [dax] + __do_fault+0x1e/0x140 + __handle_mm_fault+0x9af/0x10d0 + handle_mm_fault+0x16d/0x370 + ? handle_mm_fault+0x47/0x370 + __do_page_fault+0x28c/0x4f0 + trace_do_page_fault+0x58/0x2a0 + do_async_page_fault+0x1a/0xa0 + async_page_fault+0x28/0x30 + +Inserting a page table entry may trigger an allocation while we are +holding a read lock to keep the device instance alive for the duration +of the fault. Use srcu for this keep-alive protection. + +Fixes: dee410792419 ("/dev/dax, core: file operations and dax-mmap") +Cc: <stable@vger.kernel.org> +Signed-off-by: Dan Williams <dan.j.williams@intel.com> + +diff --git a/drivers/dax/Kconfig b/drivers/dax/Kconfig +index 3e2ab3b14eea..9e95bf94eb13 100644 +--- a/drivers/dax/Kconfig ++++ b/drivers/dax/Kconfig +@@ -2,6 +2,7 @@ menuconfig DEV_DAX + tristate "DAX: direct access to differentiated memory" + default m if NVDIMM_DAX + depends on TRANSPARENT_HUGEPAGE ++ select SRCU + help + Support raw access to differentiated (persistence, bandwidth, + latency...) memory via an mmap(2) capable character +diff --git a/drivers/dax/dax.c b/drivers/dax/dax.c +index 80c6db279ae1..806f180c80d8 100644 +--- a/drivers/dax/dax.c ++++ b/drivers/dax/dax.c +@@ -25,6 +25,7 @@ + #include "dax.h" + + static dev_t dax_devt; ++DEFINE_STATIC_SRCU(dax_srcu); + static struct class *dax_class; + static DEFINE_IDA(dax_minor_ida); + static int nr_dax = CONFIG_NR_DEV_DAX; +@@ -60,7 +61,7 @@ struct dax_region { + * @region - parent region + * @dev - device backing the character device + * @cdev - core chardev data +- * @alive - !alive + rcu grace period == no new mappings can be established ++ * @alive - !alive + srcu grace period == no new mappings can be established + * @id - child id in the region + * @num_resources - number of physical address extents in this device + * @res - array of physical address ranges +@@ -569,7 +570,7 @@ static int __dax_dev_pud_fault(struct dax_dev *dax_dev, struct vm_fault *vmf) + static int dax_dev_huge_fault(struct vm_fault *vmf, + enum page_entry_size pe_size) + { +- int rc; ++ int rc, id; + struct file *filp = vmf->vma->vm_file; + struct dax_dev *dax_dev = filp->private_data; + +@@ -578,7 +579,7 @@ static int dax_dev_huge_fault(struct vm_fault *vmf, + ? "write" : "read", + vmf->vma->vm_start, vmf->vma->vm_end); + +- rcu_read_lock(); ++ id = srcu_read_lock(&dax_srcu); + switch (pe_size) { + case PE_SIZE_PTE: + rc = __dax_dev_pte_fault(dax_dev, vmf); +@@ -592,7 +593,7 @@ static int dax_dev_huge_fault(struct vm_fault *vmf, + default: + return VM_FAULT_FALLBACK; + } +- rcu_read_unlock(); ++ srcu_read_unlock(&dax_srcu, id); + + return rc; + } +@@ -713,11 +714,11 @@ static void unregister_dax_dev(void *dev) + * Note, rcu is not protecting the liveness of dax_dev, rcu is + * ensuring that any fault handlers that might have seen + * dax_dev->alive == true, have completed. Any fault handlers +- * that start after synchronize_rcu() has started will abort ++ * that start after synchronize_srcu() has started will abort + * upon seeing dax_dev->alive == false. + */ + dax_dev->alive = false; +- synchronize_rcu(); ++ synchronize_srcu(&dax_srcu); + unmap_mapping_range(dax_dev->inode->i_mapping, 0, 0, 1); + cdev_del(cdev); + device_unregister(dev); +-- +2.12.0 + diff --git a/queue/dm-era-save-spacemap-metadata-root-after-the-pre-com.patch b/queue/dm-era-save-spacemap-metadata-root-after-the-pre-com.patch new file mode 100644 index 0000000..00d174d --- /dev/null +++ b/queue/dm-era-save-spacemap-metadata-root-after-the-pre-com.patch @@ -0,0 +1,44 @@ +From 117aceb030307dcd431fdcff87ce988d3016c34a Mon Sep 17 00:00:00 2001 +From: Somasundaram Krishnasamy <somasundaram.krishnasamy@oracle.com> +Date: Fri, 7 Apr 2017 12:14:55 -0700 +Subject: [PATCH] dm era: save spacemap metadata root after the pre-commit + +commit 117aceb030307dcd431fdcff87ce988d3016c34a upstream. + +When committing era metadata to disk, it doesn't always save the latest +spacemap metadata root in superblock. Due to this, metadata is getting +corrupted sometimes when reopening the device. The correct order of update +should be, pre-commit (shadows spacemap root), save the spacemap root +(newly shadowed block) to in-core superblock and then the final commit. + +Cc: stable@vger.kernel.org +Signed-off-by: Somasundaram Krishnasamy <somasundaram.krishnasamy@oracle.com> +Signed-off-by: Mike Snitzer <snitzer@redhat.com> + +diff --git a/drivers/md/dm-era-target.c b/drivers/md/dm-era-target.c +index 9fab33b113c4..68d4084377ad 100644 +--- a/drivers/md/dm-era-target.c ++++ b/drivers/md/dm-era-target.c +@@ -961,15 +961,15 @@ static int metadata_commit(struct era_metadata *md) + } + } + +- r = save_sm_root(md); ++ r = dm_tm_pre_commit(md->tm); + if (r) { +- DMERR("%s: save_sm_root failed", __func__); ++ DMERR("%s: pre commit failed", __func__); + return r; + } + +- r = dm_tm_pre_commit(md->tm); ++ r = save_sm_root(md); + if (r) { +- DMERR("%s: pre commit failed", __func__); ++ DMERR("%s: save_sm_root failed", __func__); + return r; + } + +-- +2.12.0 + diff --git a/queue/dm-ioctl-prevent-stack-leak-in-dm-ioctl-call.patch b/queue/dm-ioctl-prevent-stack-leak-in-dm-ioctl-call.patch new file mode 100644 index 0000000..3654c2e --- /dev/null +++ b/queue/dm-ioctl-prevent-stack-leak-in-dm-ioctl-call.patch @@ -0,0 +1,35 @@ +From 4617f564c06117c7d1b611be49521a4430042287 Mon Sep 17 00:00:00 2001 +From: Adrian Salido <salidoa@google.com> +Date: Thu, 27 Apr 2017 10:32:55 -0700 +Subject: [PATCH] dm ioctl: prevent stack leak in dm ioctl call + +commit 4617f564c06117c7d1b611be49521a4430042287 upstream. + +When calling a dm ioctl that doesn't process any data +(IOCTL_FLAGS_NO_PARAMS), the contents of the data field in struct +dm_ioctl are left initialized. Current code is incorrectly extending +the size of data copied back to user, causing the contents of kernel +stack to be leaked to user. Fix by only copying contents before data +and allow the functions processing the ioctl to override. + +Cc: stable@vger.kernel.org +Signed-off-by: Adrian Salido <salidoa@google.com> +Reviewed-by: Alasdair G Kergon <agk@redhat.com> +Signed-off-by: Mike Snitzer <snitzer@redhat.com> + +diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c +index 0956b8659360..ddda8107aa7e 100644 +--- a/drivers/md/dm-ioctl.c ++++ b/drivers/md/dm-ioctl.c +@@ -1840,7 +1840,7 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user) + if (r) + goto out; + +- param->data_size = sizeof(*param); ++ param->data_size = offsetof(struct dm_ioctl, data); + r = fn(param, input_param_size); + + if (unlikely(param->flags & DM_BUFFER_FULL_FLAG) && +-- +2.12.0 + diff --git a/queue/dm-rq-check-blk_mq_register_dev-return-value-in-dm_m.patch b/queue/dm-rq-check-blk_mq_register_dev-return-value-in-dm_m.patch new file mode 100644 index 0000000..45ba709 --- /dev/null +++ b/queue/dm-rq-check-blk_mq_register_dev-return-value-in-dm_m.patch @@ -0,0 +1,40 @@ +From 23a601248958fa4142d49294352fe8d1fdf3e509 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche <bart.vanassche@sandisk.com> +Date: Thu, 27 Apr 2017 10:11:19 -0700 +Subject: [PATCH] dm rq: check blk_mq_register_dev() return value in + dm_mq_init_request_queue() + +commit 23a601248958fa4142d49294352fe8d1fdf3e509 upstream. + +Otherwise the request-based DM blk-mq request_queue will be put into +service without being properly exported via sysfs. + +Cc: stable@vger.kernel.org +Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> +Reviewed-by: Hannes Reinecke <hare@suse.com> +Cc: Christoph Hellwig <hch@lst.de> +Signed-off-by: Mike Snitzer <snitzer@redhat.com> + +diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c +index 90756a56c4d3..a6e8da9da7a4 100644 +--- a/drivers/md/dm-rq.c ++++ b/drivers/md/dm-rq.c +@@ -809,10 +809,14 @@ int dm_mq_init_request_queue(struct mapped_device *md, struct dm_table *t) + dm_init_md_queue(md); + + /* backfill 'mq' sysfs registration normally done in blk_register_queue */ +- blk_mq_register_dev(disk_to_dev(md->disk), q); ++ err = blk_mq_register_dev(disk_to_dev(md->disk), q); ++ if (err) ++ goto out_cleanup_queue; + + return 0; + ++out_cleanup_queue: ++ blk_cleanup_queue(q); + out_tag_set: + blk_mq_free_tag_set(md->tag_set); + out_kfree_tag_set: +-- +2.12.0 + diff --git a/queue/dm-thin-fix-a-memory-leak-when-passing-discard-bio-d.patch b/queue/dm-thin-fix-a-memory-leak-when-passing-discard-bio-d.patch new file mode 100644 index 0000000..7f8280b --- /dev/null +++ b/queue/dm-thin-fix-a-memory-leak-when-passing-discard-bio-d.patch @@ -0,0 +1,54 @@ +From 948f581a53b704b984aa20df009f0a2b4cf7f907 Mon Sep 17 00:00:00 2001 +From: Dennis Yang <dennisyang@qnap.com> +Date: Tue, 18 Apr 2017 15:27:06 +0800 +Subject: [PATCH] dm thin: fix a memory leak when passing discard bio down + +commit 948f581a53b704b984aa20df009f0a2b4cf7f907 upstream. + +dm-thin does not free the discard_parent bio after all chained sub +bios finished. The following kmemleak report could be observed after +pool with discard_passdown option processes discard bios in +linux v4.11-rc7. To fix this, we drop the discard_parent bio reference +when its endio (passdown_endio) called. + +unreferenced object 0xffff8803d6b29700 (size 256): + comm "kworker/u8:0", pid 30349, jiffies 4379504020 (age 143002.776s) + hex dump (first 32 bytes): + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 01 00 00 00 00 00 00 f0 00 00 00 00 00 00 00 00 ................ + backtrace: + [<ffffffff81a5efd9>] kmemleak_alloc+0x49/0xa0 + [<ffffffff8114ec34>] kmem_cache_alloc+0xb4/0x100 + [<ffffffff8110eec0>] mempool_alloc_slab+0x10/0x20 + [<ffffffff8110efa5>] mempool_alloc+0x55/0x150 + [<ffffffff81374939>] bio_alloc_bioset+0xb9/0x260 + [<ffffffffa018fd20>] process_prepared_discard_passdown_pt1+0x40/0x1c0 [dm_thin_pool] + [<ffffffffa018b409>] break_up_discard_bio+0x1a9/0x200 [dm_thin_pool] + [<ffffffffa018b484>] process_discard_cell_passdown+0x24/0x40 [dm_thin_pool] + [<ffffffffa018b24d>] process_discard_bio+0xdd/0xf0 [dm_thin_pool] + [<ffffffffa018ecf6>] do_worker+0xa76/0xd50 [dm_thin_pool] + [<ffffffff81086239>] process_one_work+0x139/0x370 + [<ffffffff810867b1>] worker_thread+0x61/0x450 + [<ffffffff8108b316>] kthread+0xd6/0xf0 + [<ffffffff81a6cd1f>] ret_from_fork+0x3f/0x70 + [<ffffffffffffffff>] 0xffffffffffffffff + +Cc: stable@vger.kernel.org +Signed-off-by: Dennis Yang <dennisyang@qnap.com> +Signed-off-by: Mike Snitzer <snitzer@redhat.com> + +diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c +index 9b3e2fcbfb1b..f90bcbf24ebc 100644 +--- a/drivers/md/dm-thin.c ++++ b/drivers/md/dm-thin.c +@@ -1069,6 +1069,7 @@ static void passdown_endio(struct bio *bio) + * to unmap (we ignore err). + */ + queue_passdown_pt2(bio->bi_private); ++ bio_put(bio); + } + + static void process_prepared_discard_passdown_pt1(struct dm_thin_new_mapping *m) +-- +2.12.0 + diff --git a/queue/dp83640-don-t-recieve-time-stamps-twice.patch b/queue/dp83640-don-t-recieve-time-stamps-twice.patch new file mode 100644 index 0000000..599ca66 --- /dev/null +++ b/queue/dp83640-don-t-recieve-time-stamps-twice.patch @@ -0,0 +1,42 @@ +From 9d386cd9a755c8293e8916264d4d053878a7c9c7 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Tue, 18 Apr 2017 22:14:26 +0300 +Subject: [PATCH] dp83640: don't recieve time stamps twice +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 9d386cd9a755c8293e8916264d4d053878a7c9c7 upstream. + +This patch is prompted by a static checker warning about a potential +use after free. The concern is that netif_rx_ni() can free "skb" and we +call it twice. + +When I look at the commit that added this, it looks like some stray +lines were added accidentally. It doesn't make sense to me that we +would recieve the same data two times. I asked the author but never +recieved a response. + +I can't test this code, but I'm pretty sure my patch is correct. + +Fixes: 4b063258ab93 ("dp83640: Delay scheduled work.") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Acked-by: Stefan Sørensen <stefan.sorensen@spectralink.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c +index e2460a57e4b1..ed0d10f54f26 100644 +--- a/drivers/net/phy/dp83640.c ++++ b/drivers/net/phy/dp83640.c +@@ -1438,8 +1438,6 @@ static bool dp83640_rxtstamp(struct phy_device *phydev, + skb_info->tmo = jiffies + SKB_TIMESTAMP_TIMEOUT; + skb_queue_tail(&dp83640->rx_queue, skb); + schedule_delayed_work(&dp83640->ts_work, SKB_TIMESTAMP_TIMEOUT); +- } else { +- netif_rx_ni(skb); + } + + return true; +-- +2.12.0 + diff --git a/queue/drm-sti-fix-GDP-size-to-support-up-to-UHD-resolution.patch b/queue/drm-sti-fix-GDP-size-to-support-up-to-UHD-resolution.patch new file mode 100644 index 0000000..4edd42c --- /dev/null +++ b/queue/drm-sti-fix-GDP-size-to-support-up-to-UHD-resolution.patch @@ -0,0 +1,55 @@ +From 2f410f88c0a1c7e19762918d2614f506a7b63a82 Mon Sep 17 00:00:00 2001 +From: Vincent Abriou <vincent.abriou@st.com> +Date: Thu, 23 Mar 2017 15:44:52 +0100 +Subject: [PATCH] drm/sti: fix GDP size to support up to UHD resolution + +commit 2f410f88c0a1c7e19762918d2614f506a7b63a82 upstream. + +On stih407-410 chip family the GDP layers are able to support up to UHD +resolution (3840 x 2160). + +Signed-off-by: Vincent Abriou <vincent.abriou@st.com> +Acked-by: Lee Jones <lee.jones@linaro.org> +Tested-by: Lee Jones <lee.jones@linaro.org> +Link: http://patchwork.freedesktop.org/patch/msgid/1490280292-30466-1-git-send-email-vincent.abriou@st.com + +diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c +index 86279f5022c2..88f16cdf6a4b 100644 +--- a/drivers/gpu/drm/sti/sti_gdp.c ++++ b/drivers/gpu/drm/sti/sti_gdp.c +@@ -66,7 +66,9 @@ static struct gdp_format_to_str { + #define GAM_GDP_ALPHARANGE_255 BIT(5) + #define GAM_GDP_AGC_FULL_RANGE 0x00808080 + #define GAM_GDP_PPT_IGNORE (BIT(1) | BIT(0)) +-#define GAM_GDP_SIZE_MAX 0x7FF ++ ++#define GAM_GDP_SIZE_MAX_WIDTH 3840 ++#define GAM_GDP_SIZE_MAX_HEIGHT 2160 + + #define GDP_NODE_NB_BANK 2 + #define GDP_NODE_PER_FIELD 2 +@@ -632,8 +634,8 @@ static int sti_gdp_atomic_check(struct drm_plane *drm_plane, + /* src_x are in 16.16 format */ + src_x = state->src_x >> 16; + src_y = state->src_y >> 16; +- src_w = clamp_val(state->src_w >> 16, 0, GAM_GDP_SIZE_MAX); +- src_h = clamp_val(state->src_h >> 16, 0, GAM_GDP_SIZE_MAX); ++ src_w = clamp_val(state->src_w >> 16, 0, GAM_GDP_SIZE_MAX_WIDTH); ++ src_h = clamp_val(state->src_h >> 16, 0, GAM_GDP_SIZE_MAX_HEIGHT); + + format = sti_gdp_fourcc2format(fb->format->format); + if (format == -1) { +@@ -741,8 +743,8 @@ static void sti_gdp_atomic_update(struct drm_plane *drm_plane, + /* src_x are in 16.16 format */ + src_x = state->src_x >> 16; + src_y = state->src_y >> 16; +- src_w = clamp_val(state->src_w >> 16, 0, GAM_GDP_SIZE_MAX); +- src_h = clamp_val(state->src_h >> 16, 0, GAM_GDP_SIZE_MAX); ++ src_w = clamp_val(state->src_w >> 16, 0, GAM_GDP_SIZE_MAX_WIDTH); ++ src_h = clamp_val(state->src_h >> 16, 0, GAM_GDP_SIZE_MAX_HEIGHT); + + list = sti_gdp_get_free_nodes(gdp); + top_field = list->top_field; +-- +2.12.0 + diff --git a/queue/drm-ttm-fix-use-after-free-races-in-vm-fault-handlin.patch b/queue/drm-ttm-fix-use-after-free-races-in-vm-fault-handlin.patch new file mode 100644 index 0000000..ba58b90 --- /dev/null +++ b/queue/drm-ttm-fix-use-after-free-races-in-vm-fault-handlin.patch @@ -0,0 +1,67 @@ +From 3089c1df10e2931b1d72d2ffa7d86431084c86b3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nicolai=20H=C3=A4hnle?= <nicolai.haehnle@amd.com> +Date: Sat, 18 Feb 2017 22:59:56 +0100 +Subject: [PATCH] drm/ttm: fix use-after-free races in vm fault handling +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 3089c1df10e2931b1d72d2ffa7d86431084c86b3 upstream. + +The vm fault handler relies on the fact that the VMA owns a reference +to the BO. However, once mmap_sem is released, other tasks are free to +destroy the VMA, which can lead to the BO being freed. Fix two code +paths where that can happen, both related to vm fault retries. + +Found via a lock debugging warning which flagged &bo->wu_mutex as +locked while being destroyed. + +Fixes: cbe12e74ee4e ("drm/ttm: Allow vm fault retries") +Signed-off-by: Nicolai Hähnle <nicolai.haehnle@amd.com> +Reviewed-by: Christian König <christian.koenig@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> + +diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c +index 68ef993ab431..88169141bef5 100644 +--- a/drivers/gpu/drm/ttm/ttm_bo_vm.c ++++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c +@@ -66,8 +66,11 @@ static int ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo, + if (vmf->flags & FAULT_FLAG_RETRY_NOWAIT) + goto out_unlock; + ++ ttm_bo_reference(bo); + up_read(&vma->vm_mm->mmap_sem); + (void) dma_fence_wait(bo->moving, true); ++ ttm_bo_unreserve(bo); ++ ttm_bo_unref(&bo); + goto out_unlock; + } + +@@ -120,8 +123,10 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + + if (vmf->flags & FAULT_FLAG_ALLOW_RETRY) { + if (!(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) { ++ ttm_bo_reference(bo); + up_read(&vma->vm_mm->mmap_sem); + (void) ttm_bo_wait_unreserved(bo); ++ ttm_bo_unref(&bo); + } + + return VM_FAULT_RETRY; +@@ -166,6 +171,13 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + ret = ttm_bo_vm_fault_idle(bo, vma, vmf); + if (unlikely(ret != 0)) { + retval = ret; ++ ++ if (retval == VM_FAULT_RETRY && ++ !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) { ++ /* The BO has already been unreserved. */ ++ return retval; ++ } ++ + goto out_unlock; + } + +-- +2.12.0 + diff --git a/queue/ext4-evict-inline-data-when-writing-to-memory-map.patch b/queue/ext4-evict-inline-data-when-writing-to-memory-map.patch new file mode 100644 index 0000000..f5e6991 --- /dev/null +++ b/queue/ext4-evict-inline-data-when-writing-to-memory-map.patch @@ -0,0 +1,85 @@ +From 7b4cc9787fe35b3ee2dfb1c35e22eafc32e00c33 Mon Sep 17 00:00:00 2001 +From: Eric Biggers <ebiggers@google.com> +Date: Sun, 30 Apr 2017 00:10:50 -0400 +Subject: [PATCH] ext4: evict inline data when writing to memory map + +commit 7b4cc9787fe35b3ee2dfb1c35e22eafc32e00c33 upstream. + +Currently the case of writing via mmap to a file with inline data is not +handled. This is maybe a rare case since it requires a writable memory +map of a very small file, but it is trivial to trigger with on +inline_data filesystem, and it causes the +'BUG_ON(ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA));' in +ext4_writepages() to be hit: + + mkfs.ext4 -O inline_data /dev/vdb + mount /dev/vdb /mnt + xfs_io -f /mnt/file \ + -c 'pwrite 0 1' \ + -c 'mmap -w 0 1m' \ + -c 'mwrite 0 1' \ + -c 'fsync' + + kernel BUG at fs/ext4/inode.c:2723! + invalid opcode: 0000 [#1] SMP + CPU: 1 PID: 2532 Comm: xfs_io Not tainted 4.11.0-rc1-xfstests-00301-g071d9acf3d1f #633 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-20170228_101828-anatol 04/01/2014 + task: ffff88003d3a8040 task.stack: ffffc90000300000 + RIP: 0010:ext4_writepages+0xc89/0xf8a + RSP: 0018:ffffc90000303ca0 EFLAGS: 00010283 + RAX: 0000028410000000 RBX: ffff8800383fa3b0 RCX: ffffffff812afcdc + RDX: 00000a9d00000246 RSI: ffffffff81e660e0 RDI: 0000000000000246 + RBP: ffffc90000303dc0 R08: 0000000000000002 R09: 869618e8f99b4fa5 + R10: 00000000852287a2 R11: 00000000a03b49f4 R12: ffff88003808e698 + R13: 0000000000000000 R14: 7fffffffffffffff R15: 7fffffffffffffff + FS: 00007fd3e53094c0(0000) GS:ffff88003e400000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 00007fd3e4c51000 CR3: 000000003d554000 CR4: 00000000003406e0 + Call Trace: + ? _raw_spin_unlock+0x27/0x2a + ? kvm_clock_read+0x1e/0x20 + do_writepages+0x23/0x2c + ? do_writepages+0x23/0x2c + __filemap_fdatawrite_range+0x80/0x87 + filemap_write_and_wait_range+0x67/0x8c + ext4_sync_file+0x20e/0x472 + vfs_fsync_range+0x8e/0x9f + ? syscall_trace_enter+0x25b/0x2d0 + vfs_fsync+0x1c/0x1e + do_fsync+0x31/0x4a + SyS_fsync+0x10/0x14 + do_syscall_64+0x69/0x131 + entry_SYSCALL64_slow_path+0x25/0x25 + +We could try to be smart and keep the inline data in this case, or at +least support delayed allocation when allocating the block, but these +solutions would be more complicated and don't seem worthwhile given how +rare this case seems to be. So just fix the bug by calling +ext4_convert_inline_data() when we're asked to make a page writable, so +that any inline data gets evicted, with the block allocated immediately. + +Reported-by: Nick Alcock <nick.alcock@oracle.com> +Cc: stable@vger.kernel.org +Reviewed-by: Andreas Dilger <adilger@dilger.ca> +Signed-off-by: Eric Biggers <ebiggers@google.com> +Signed-off-by: Theodore Ts'o <tytso@mit.edu> + +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index b9ffa9f4191f..88203ae5b154 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -5874,6 +5874,11 @@ int ext4_page_mkwrite(struct vm_fault *vmf) + file_update_time(vma->vm_file); + + down_read(&EXT4_I(inode)->i_mmap_sem); ++ ++ ret = ext4_convert_inline_data(inode); ++ if (ret) ++ goto out_ret; ++ + /* Delalloc case is easy... */ + if (test_opt(inode->i_sb, DELALLOC) && + !ext4_should_journal_data(inode) && +-- +2.12.0 + diff --git a/queue/f2fs-sanity-check-segment-count.patch b/queue/f2fs-sanity-check-segment-count.patch new file mode 100644 index 0000000..a4e1a2d --- /dev/null +++ b/queue/f2fs-sanity-check-segment-count.patch @@ -0,0 +1,51 @@ +From b9dd46188edc2f0d1f37328637860bb65a771124 Mon Sep 17 00:00:00 2001 +From: Jin Qian <jinqian@google.com> +Date: Tue, 25 Apr 2017 16:28:48 -0700 +Subject: [PATCH] f2fs: sanity check segment count + +commit b9dd46188edc2f0d1f37328637860bb65a771124 upstream. + +F2FS uses 4 bytes to represent block address. As a result, supported +size of disk is 16 TB and it equals to 16 * 1024 * 1024 / 2 segments. + +Signed-off-by: Jin Qian <jinqian@google.com> +Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> + +diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c +index 97c07a5153e9..4cd3bee6775f 100644 +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -1494,6 +1494,13 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, + return 1; + } + ++ if (le32_to_cpu(raw_super->segment_count) > F2FS_MAX_SEGMENT) { ++ f2fs_msg(sb, KERN_INFO, ++ "Invalid segment count (%u)", ++ le32_to_cpu(raw_super->segment_count)); ++ return 1; ++ } ++ + /* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */ + if (sanity_check_area_boundary(sbi, bh)) + return 1; +diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h +index 639cbdf65e2b..093549e10ee2 100644 +--- a/include/linux/f2fs_fs.h ++++ b/include/linux/f2fs_fs.h +@@ -302,6 +302,12 @@ struct f2fs_nat_block { + #define SIT_ENTRY_PER_BLOCK (PAGE_SIZE / sizeof(struct f2fs_sit_entry)) + + /* ++ * F2FS uses 4 bytes to represent block address. As a result, supported size of ++ * disk is 16 TB and it equals to 16 * 1024 * 1024 / 2 segments. ++ */ ++#define F2FS_MAX_SEGMENT ((16 * 1024 * 1024) / 2) ++ ++/* + * Note that f2fs_sit_entry->vblocks has the following bit-field information. + * [15:10] : allocation type such as CURSEG_XXXX_TYPE + * [9:0] : valid block count +-- +2.12.0 + diff --git a/queue/fs-block_dev-always-invalidate-cleancache-in-invalid.patch b/queue/fs-block_dev-always-invalidate-cleancache-in-invalid.patch new file mode 100644 index 0000000..515158c --- /dev/null +++ b/queue/fs-block_dev-always-invalidate-cleancache-in-invalid.patch @@ -0,0 +1,55 @@ +From a5f6a6a9c72eac38a7fadd1a038532bc8516337c Mon Sep 17 00:00:00 2001 +From: Andrey Ryabinin <aryabinin@virtuozzo.com> +Date: Wed, 3 May 2017 14:56:02 -0700 +Subject: [PATCH] fs/block_dev: always invalidate cleancache in + invalidate_bdev() + +commit a5f6a6a9c72eac38a7fadd1a038532bc8516337c upstream. + +invalidate_bdev() calls cleancache_invalidate_inode() iff ->nrpages != 0 +which doen't make any sense. + +Make sure that invalidate_bdev() always calls cleancache_invalidate_inode() +regardless of mapping->nrpages value. + +Fixes: c515e1fd361c ("mm/fs: add hooks to support cleancache") +Link: http://lkml.kernel.org/r/20170424164135.22350-3-aryabinin@virtuozzo.com +Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com> +Reviewed-by: Jan Kara <jack@suse.cz> +Acked-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Cc: Alexander Viro <viro@zeniv.linux.org.uk> +Cc: Ross Zwisler <ross.zwisler@linux.intel.com> +Cc: Jens Axboe <axboe@kernel.dk> +Cc: Johannes Weiner <hannes@cmpxchg.org> +Cc: Alexey Kuznetsov <kuznet@virtuozzo.com> +Cc: Christoph Hellwig <hch@lst.de> +Cc: Nikolay Borisov <n.borisov.lkml@gmail.com> +Cc: <stable@vger.kernel.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> + +diff --git a/fs/block_dev.c b/fs/block_dev.c +index 9ccabe3bb7de..0d435c794d76 100644 +--- a/fs/block_dev.c ++++ b/fs/block_dev.c +@@ -103,12 +103,11 @@ void invalidate_bdev(struct block_device *bdev) + { + struct address_space *mapping = bdev->bd_inode->i_mapping; + +- if (mapping->nrpages == 0) +- return; +- +- invalidate_bh_lrus(); +- lru_add_drain_all(); /* make sure all lru add caches are flushed */ +- invalidate_mapping_pages(mapping, 0, -1); ++ if (mapping->nrpages) { ++ invalidate_bh_lrus(); ++ lru_add_drain_all(); /* make sure all lru add caches are flushed */ ++ invalidate_mapping_pages(mapping, 0, -1); ++ } + /* 99% of the time, we don't need to flush the cleancache on the bdev. + * But, for the strange corners, lets be cautious + */ +-- +2.12.0 + diff --git a/queue/fs-xattr.c-zero-out-memory-copied-to-userspace-in-ge.patch b/queue/fs-xattr.c-zero-out-memory-copied-to-userspace-in-ge.patch new file mode 100644 index 0000000..e63d49b --- /dev/null +++ b/queue/fs-xattr.c-zero-out-memory-copied-to-userspace-in-ge.patch @@ -0,0 +1,39 @@ +From 81be3dee96346fbe08c31be5ef74f03f6b63cf68 Mon Sep 17 00:00:00 2001 +From: Michal Hocko <mhocko@suse.com> +Date: Mon, 8 May 2017 15:57:24 -0700 +Subject: [PATCH] fs/xattr.c: zero out memory copied to userspace in getxattr + +commit 81be3dee96346fbe08c31be5ef74f03f6b63cf68 upstream. + +getxattr uses vmalloc to allocate memory if kzalloc fails. This is +filled by vfs_getxattr and then copied to the userspace. vmalloc, +however, doesn't zero out the memory so if the specific implementation +of the xattr handler is sloppy we can theoretically expose a kernel +memory. There is no real sign this is really the case but let's make +sure this will not happen and use vzalloc instead. + +Fixes: 779302e67835 ("fs/xattr.c:getxattr(): improve handling of allocation failures") +Link: http://lkml.kernel.org/r/20170306103327.2766-1-mhocko@kernel.org +Acked-by: Kees Cook <keescook@chromium.org> +Reported-by: Vlastimil Babka <vbabka@suse.cz> +Signed-off-by: Michal Hocko <mhocko@suse.com> +Cc: <stable@vger.kernel.org> [3.6+] +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> + +diff --git a/fs/xattr.c b/fs/xattr.c +index 7e3317cf4045..94f49a082dd2 100644 +--- a/fs/xattr.c ++++ b/fs/xattr.c +@@ -530,7 +530,7 @@ getxattr(struct dentry *d, const char __user *name, void __user *value, + size = XATTR_SIZE_MAX; + kvalue = kzalloc(size, GFP_KERNEL | __GFP_NOWARN); + if (!kvalue) { +- kvalue = vmalloc(size); ++ kvalue = vzalloc(size); + if (!kvalue) + return -ENOMEM; + } +-- +2.12.0 + diff --git a/queue/fscrypt-fix-context-consistency-check-when-key-s-una.patch b/queue/fscrypt-fix-context-consistency-check-when-key-s-una.patch new file mode 100644 index 0000000..4a569dc --- /dev/null +++ b/queue/fscrypt-fix-context-consistency-check-when-key-s-una.patch @@ -0,0 +1,166 @@ +From 272f98f6846277378e1758a49a49d7bf39343c02 Mon Sep 17 00:00:00 2001 +From: Eric Biggers <ebiggers@google.com> +Date: Fri, 7 Apr 2017 10:58:37 -0700 +Subject: [PATCH] fscrypt: fix context consistency check when key(s) + unavailable + +commit 272f98f6846277378e1758a49a49d7bf39343c02 upstream. + +To mitigate some types of offline attacks, filesystem encryption is +designed to enforce that all files in an encrypted directory tree use +the same encryption policy (i.e. the same encryption context excluding +the nonce). However, the fscrypt_has_permitted_context() function which +enforces this relies on comparing struct fscrypt_info's, which are only +available when we have the encryption keys. This can cause two +incorrect behaviors: + +1. If we have the parent directory's key but not the child's key, or + vice versa, then fscrypt_has_permitted_context() returned false, + causing applications to see EPERM or ENOKEY. This is incorrect if + the encryption contexts are in fact consistent. Although we'd + normally have either both keys or neither key in that case since the + master_key_descriptors would be the same, this is not guaranteed + because keys can be added or removed from keyrings at any time. + +2. If we have neither the parent's key nor the child's key, then + fscrypt_has_permitted_context() returned true, causing applications + to see no error (or else an error for some other reason). This is + incorrect if the encryption contexts are in fact inconsistent, since + in that case we should deny access. + +To fix this, retrieve and compare the fscrypt_contexts if we are unable +to set up both fscrypt_infos. + +While this slightly hurts performance when accessing an encrypted +directory tree without the key, this isn't a case we really need to be +optimizing for; access *with* the key is much more important. +Furthermore, the performance hit is barely noticeable given that we are +already retrieving the fscrypt_context and doing two keyring searches in +fscrypt_get_encryption_info(). If we ever actually wanted to optimize +this case we might start by caching the fscrypt_contexts. + +Cc: stable@vger.kernel.org # 4.0+ +Signed-off-by: Eric Biggers <ebiggers@google.com> +Signed-off-by: Theodore Ts'o <tytso@mit.edu> + +diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c +index d71ec3780d0c..210976e7a269 100644 +--- a/fs/crypto/policy.c ++++ b/fs/crypto/policy.c +@@ -137,27 +137,61 @@ int fscrypt_ioctl_get_policy(struct file *filp, void __user *arg) + } + EXPORT_SYMBOL(fscrypt_ioctl_get_policy); + ++/** ++ * fscrypt_has_permitted_context() - is a file's encryption policy permitted ++ * within its directory? ++ * ++ * @parent: inode for parent directory ++ * @child: inode for file being looked up, opened, or linked into @parent ++ * ++ * Filesystems must call this before permitting access to an inode in a ++ * situation where the parent directory is encrypted (either before allowing ++ * ->lookup() to succeed, or for a regular file before allowing it to be opened) ++ * and before any operation that involves linking an inode into an encrypted ++ * directory, including link, rename, and cross rename. It enforces the ++ * constraint that within a given encrypted directory tree, all files use the ++ * same encryption policy. The pre-access check is needed to detect potentially ++ * malicious offline violations of this constraint, while the link and rename ++ * checks are needed to prevent online violations of this constraint. ++ * ++ * Return: 1 if permitted, 0 if forbidden. If forbidden, the caller must fail ++ * the filesystem operation with EPERM. ++ */ + int fscrypt_has_permitted_context(struct inode *parent, struct inode *child) + { +- struct fscrypt_info *parent_ci, *child_ci; ++ const struct fscrypt_operations *cops = parent->i_sb->s_cop; ++ const struct fscrypt_info *parent_ci, *child_ci; ++ struct fscrypt_context parent_ctx, child_ctx; + int res; + +- if ((parent == NULL) || (child == NULL)) { +- printk(KERN_ERR "parent %p child %p\n", parent, child); +- BUG_ON(1); +- } +- + /* No restrictions on file types which are never encrypted */ + if (!S_ISREG(child->i_mode) && !S_ISDIR(child->i_mode) && + !S_ISLNK(child->i_mode)) + return 1; + +- /* no restrictions if the parent directory is not encrypted */ +- if (!parent->i_sb->s_cop->is_encrypted(parent)) ++ /* No restrictions if the parent directory is unencrypted */ ++ if (!cops->is_encrypted(parent)) + return 1; +- /* if the child directory is not encrypted, this is always a problem */ +- if (!parent->i_sb->s_cop->is_encrypted(child)) ++ ++ /* Encrypted directories must not contain unencrypted files */ ++ if (!cops->is_encrypted(child)) + return 0; ++ ++ /* ++ * Both parent and child are encrypted, so verify they use the same ++ * encryption policy. Compare the fscrypt_info structs if the keys are ++ * available, otherwise retrieve and compare the fscrypt_contexts. ++ * ++ * Note that the fscrypt_context retrieval will be required frequently ++ * when accessing an encrypted directory tree without the key. ++ * Performance-wise this is not a big deal because we already don't ++ * really optimize for file access without the key (to the extent that ++ * such access is even possible), given that any attempted access ++ * already causes a fscrypt_context retrieval and keyring search. ++ * ++ * In any case, if an unexpected error occurs, fall back to "forbidden". ++ */ ++ + res = fscrypt_get_encryption_info(parent); + if (res) + return 0; +@@ -166,17 +200,32 @@ int fscrypt_has_permitted_context(struct inode *parent, struct inode *child) + return 0; + parent_ci = parent->i_crypt_info; + child_ci = child->i_crypt_info; +- if (!parent_ci && !child_ci) +- return 1; +- if (!parent_ci || !child_ci) ++ ++ if (parent_ci && child_ci) { ++ return memcmp(parent_ci->ci_master_key, child_ci->ci_master_key, ++ FS_KEY_DESCRIPTOR_SIZE) == 0 && ++ (parent_ci->ci_data_mode == child_ci->ci_data_mode) && ++ (parent_ci->ci_filename_mode == ++ child_ci->ci_filename_mode) && ++ (parent_ci->ci_flags == child_ci->ci_flags); ++ } ++ ++ res = cops->get_context(parent, &parent_ctx, sizeof(parent_ctx)); ++ if (res != sizeof(parent_ctx)) ++ return 0; ++ ++ res = cops->get_context(child, &child_ctx, sizeof(child_ctx)); ++ if (res != sizeof(child_ctx)) + return 0; + +- return (memcmp(parent_ci->ci_master_key, +- child_ci->ci_master_key, +- FS_KEY_DESCRIPTOR_SIZE) == 0 && +- (parent_ci->ci_data_mode == child_ci->ci_data_mode) && +- (parent_ci->ci_filename_mode == child_ci->ci_filename_mode) && +- (parent_ci->ci_flags == child_ci->ci_flags)); ++ return memcmp(parent_ctx.master_key_descriptor, ++ child_ctx.master_key_descriptor, ++ FS_KEY_DESCRIPTOR_SIZE) == 0 && ++ (parent_ctx.contents_encryption_mode == ++ child_ctx.contents_encryption_mode) && ++ (parent_ctx.filenames_encryption_mode == ++ child_ctx.filenames_encryption_mode) && ++ (parent_ctx.flags == child_ctx.flags); + } + EXPORT_SYMBOL(fscrypt_has_permitted_context); + +-- +2.12.0 + diff --git a/queue/ftrace-x86-Fix-triple-fault-with-graph-tracing-and-s.patch b/queue/ftrace-x86-Fix-triple-fault-with-graph-tracing-and-s.patch new file mode 100644 index 0000000..dd102e9 --- /dev/null +++ b/queue/ftrace-x86-Fix-triple-fault-with-graph-tracing-and-s.patch @@ -0,0 +1,82 @@ +From 34a477e5297cbaa6ecc6e17c042a866e1cbe80d6 Mon Sep 17 00:00:00 2001 +From: Josh Poimboeuf <jpoimboe@redhat.com> +Date: Thu, 13 Apr 2017 17:53:55 -0500 +Subject: [PATCH] ftrace/x86: Fix triple fault with graph tracing and + suspend-to-ram + +commit 34a477e5297cbaa6ecc6e17c042a866e1cbe80d6 upstream. + +On x86-32, with CONFIG_FIRMWARE and multiple CPUs, if you enable function +graph tracing and then suspend to RAM, it will triple fault and reboot when +it resumes. + +The first fault happens when booting a secondary CPU: + +startup_32_smp() + load_ucode_ap() + prepare_ftrace_return() + ftrace_graph_is_dead() + (accesses 'kill_ftrace_graph') + +The early head_32.S code calls into load_ucode_ap(), which has an an +ftrace hook, so it calls prepare_ftrace_return(), which calls +ftrace_graph_is_dead(), which tries to access the global +'kill_ftrace_graph' variable with a virtual address, causing a fault +because the CPU is still in real mode. + +The fix is to add a check in prepare_ftrace_return() to make sure it's +running in protected mode before continuing. The check makes sure the +stack pointer is a virtual kernel address. It's a bit of a hack, but +it's not very intrusive and it works well enough. + +For reference, here are a few other (more difficult) ways this could +have potentially been fixed: + +- Move startup_32_smp()'s call to load_ucode_ap() down to *after* paging + is enabled. (No idea what that would break.) + +- Track down load_ucode_ap()'s entire callee tree and mark all the + functions 'notrace'. (Probably not realistic.) + +- Pause graph tracing in ftrace_suspend_notifier_call() or bringup_cpu() + or __cpu_up(), and ensure that the pause facility can be queried from + real mode. + +Reported-by: Paul Menzel <pmenzel@molgen.mpg.de> +Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> +Tested-by: Paul Menzel <pmenzel@molgen.mpg.de> +Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org> +Cc: "Rafael J . Wysocki" <rjw@rjwysocki.net> +Cc: linux-acpi@vger.kernel.org +Cc: Borislav Petkov <bp@alien8.de> +Cc: stable@kernel.org +Cc: Len Brown <lenb@kernel.org> +Link: http://lkml.kernel.org/r/5c1272269a580660703ed2eccf44308e790c7a98.1492123841.git.jpoimboe@redhat.com +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + +diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c +index cbd73eb42170..0e5ceac3597d 100644 +--- a/arch/x86/kernel/ftrace.c ++++ b/arch/x86/kernel/ftrace.c +@@ -989,6 +989,18 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent, + unsigned long return_hooker = (unsigned long) + &return_to_handler; + ++ /* ++ * When resuming from suspend-to-ram, this function can be indirectly ++ * called from early CPU startup code while the CPU is in real mode, ++ * which would fail miserably. Make sure the stack pointer is a ++ * virtual address. ++ * ++ * This check isn't as accurate as virt_addr_valid(), but it should be ++ * good enough for this purpose, and it's fast. ++ */ ++ if (unlikely((long)__builtin_frame_address(0) >= 0)) ++ return; ++ + if (unlikely(ftrace_graph_is_dead())) + return; + +-- +2.12.0 + diff --git a/queue/gso-Validate-assumption-of-frag_list-segementation.patch b/queue/gso-Validate-assumption-of-frag_list-segementation.patch new file mode 100644 index 0000000..cf41635 --- /dev/null +++ b/queue/gso-Validate-assumption-of-frag_list-segementation.patch @@ -0,0 +1,73 @@ +From 43170c4e0ba709c79130c3fe5a41e66279950cd0 Mon Sep 17 00:00:00 2001 +From: Ilan Tayari <ilant@mellanox.com> +Date: Wed, 19 Apr 2017 21:26:07 +0300 +Subject: [PATCH] gso: Validate assumption of frag_list segementation + +commit 43170c4e0ba709c79130c3fe5a41e66279950cd0 upstream. + +Commit 07b26c9454a2 ("gso: Support partial splitting at the frag_list +pointer") assumes that all SKBs in a frag_list (except maybe the last +one) contain the same amount of GSO payload. + +This assumption is not always correct, resulting in the following +warning message in the log: + skb_segment: too many frags + +For example, mlx5 driver in Striding RQ mode creates some RX SKBs with +one frag, and some with 2 frags. +After GRO, the frag_list SKBs end up having different amounts of payload. +If this frag_list SKB is then forwarded, the aforementioned assumption +is violated. + +Validate the assumption, and fall back to software GSO if it not true. + +Change-Id: Ia03983f4a47b6534dd987d7a2aad96d54d46d212 +Fixes: 07b26c9454a2 ("gso: Support partial splitting at the frag_list pointer") +Signed-off-by: Ilan Tayari <ilant@mellanox.com> +Signed-off-by: Ilya Lesokhin <ilyal@mellanox.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 35c1e2460206..f86bf69cfb8d 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -3082,22 +3082,32 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, + if (sg && csum && (mss != GSO_BY_FRAGS)) { + if (!(features & NETIF_F_GSO_PARTIAL)) { + struct sk_buff *iter; ++ unsigned int frag_len; + + if (!list_skb || + !net_gso_ok(features, skb_shinfo(head_skb)->gso_type)) + goto normal; + +- /* Split the buffer at the frag_list pointer. +- * This is based on the assumption that all +- * buffers in the chain excluding the last +- * containing the same amount of data. ++ /* If we get here then all the required ++ * GSO features except frag_list are supported. ++ * Try to split the SKB to multiple GSO SKBs ++ * with no frag_list. ++ * Currently we can do that only when the buffers don't ++ * have a linear part and all the buffers except ++ * the last are of the same length. + */ ++ frag_len = list_skb->len; + skb_walk_frags(head_skb, iter) { ++ if (frag_len != iter->len && iter->next) ++ goto normal; + if (skb_headlen(iter)) + goto normal; + + len -= iter->len; + } ++ ++ if (len != frag_len) ++ goto normal; + } + + /* GSO partial only requires that we trim off any excess that +-- +2.12.0 + diff --git a/queue/hwmon-it87-Avoid-registering-the-same-chip-on-both-S.patch b/queue/hwmon-it87-Avoid-registering-the-same-chip-on-both-S.patch new file mode 100644 index 0000000..e106a33 --- /dev/null +++ b/queue/hwmon-it87-Avoid-registering-the-same-chip-on-both-S.patch @@ -0,0 +1,65 @@ +From 8358378b22518d92424597503d3c1cd302a490b6 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck <linux@roeck-us.net> +Date: Sun, 12 Mar 2017 06:18:58 -0700 +Subject: [PATCH] hwmon: (it87) Avoid registering the same chip on both SIO + addresses + +commit 8358378b22518d92424597503d3c1cd302a490b6 upstream. + +IT8705F is known to respond on both SIO addresses. Registering it twice +may result in system lockups. + +Reported-by: Russell King <linux@armlinux.org.uk> +Fixes: e84bd9535e2b ("hwmon: (it87) Add support for second Super-IO chip") +Signed-off-by: Guenter Roeck <linux@roeck-us.net> + +diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c +index efb01c247e2d..4dfc7238313e 100644 +--- a/drivers/hwmon/it87.c ++++ b/drivers/hwmon/it87.c +@@ -3198,7 +3198,7 @@ static int __init sm_it87_init(void) + { + int sioaddr[2] = { REG_2E, REG_4E }; + struct it87_sio_data sio_data; +- unsigned short isa_address; ++ unsigned short isa_address[2]; + bool found = false; + int i, err; + +@@ -3208,15 +3208,29 @@ static int __init sm_it87_init(void) + + for (i = 0; i < ARRAY_SIZE(sioaddr); i++) { + memset(&sio_data, 0, sizeof(struct it87_sio_data)); +- isa_address = 0; +- err = it87_find(sioaddr[i], &isa_address, &sio_data); +- if (err || isa_address == 0) ++ isa_address[i] = 0; ++ err = it87_find(sioaddr[i], &isa_address[i], &sio_data); ++ if (err || isa_address[i] == 0) + continue; ++ /* ++ * Don't register second chip if its ISA address matches ++ * the first chip's ISA address. ++ */ ++ if (i && isa_address[i] == isa_address[0]) ++ break; + +- err = it87_device_add(i, isa_address, &sio_data); ++ err = it87_device_add(i, isa_address[i], &sio_data); + if (err) + goto exit_dev_unregister; ++ + found = true; ++ ++ /* ++ * IT8705F may respond on both SIO addresses. ++ * Stop probing after finding one. ++ */ ++ if (sio_data.type == it87) ++ break; + } + + if (!found) { +-- +2.12.0 + diff --git a/queue/hwmon-it87-Fix-pwm4-detection-for-IT8620-and-IT8628.patch b/queue/hwmon-it87-Fix-pwm4-detection-for-IT8620-and-IT8628.patch new file mode 100644 index 0000000..f284570 --- /dev/null +++ b/queue/hwmon-it87-Fix-pwm4-detection-for-IT8620-and-IT8628.patch @@ -0,0 +1,30 @@ +From d66777caa57ffade6061782f3a4d4056f0b0c1ac Mon Sep 17 00:00:00 2001 +From: Guenter Roeck <linux@roeck-us.net> +Date: Wed, 8 Feb 2017 14:05:56 -0800 +Subject: [PATCH] hwmon: (it87) Fix pwm4 detection for IT8620 and IT8628 + +commit d66777caa57ffade6061782f3a4d4056f0b0c1ac upstream. + +pwm4 is enabled if bit 2 of GPIO control register 4 is disabled, +not when it is enabled. Since the check is for the skip condition, +it is reversed. This applies to both IT8620 and IT8628. + +Fixes: 36c4d98a7883d ("hwmon: (it87) Add support for all pwm channels ...") +Signed-off-by: Guenter Roeck <linux@roeck-us.net> + +diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c +index 85918d8a747a..4f3fabcd470d 100644 +--- a/drivers/hwmon/it87.c ++++ b/drivers/hwmon/it87.c +@@ -2614,7 +2614,7 @@ static int __init it87_find(int sioaddr, unsigned short *address, + + /* Check for pwm4 */ + reg = superio_inb(sioaddr, IT87_SIO_GPIO4_REG); +- if (!(reg & BIT(2))) ++ if (reg & BIT(2)) + sio_data->skip_pwm |= BIT(3); + + /* Check for pwm2, fan2 */ +-- +2.12.0 + diff --git a/queue/iov_iter-don-t-revert-iov-buffer-if-csum-error.patch b/queue/iov_iter-don-t-revert-iov-buffer-if-csum-error.patch new file mode 100644 index 0000000..d329833 --- /dev/null +++ b/queue/iov_iter-don-t-revert-iov-buffer-if-csum-error.patch @@ -0,0 +1,60 @@ +From a6a5993243550b09f620941dea741b7421fdf79c Mon Sep 17 00:00:00 2001 +From: Ding Tianhong <dingtianhong@huawei.com> +Date: Sat, 29 Apr 2017 10:38:48 +0800 +Subject: [PATCH] iov_iter: don't revert iov buffer if csum error + +commit a6a5993243550b09f620941dea741b7421fdf79c upstream. + +The patch 327868212381 (make skb_copy_datagram_msg() et.al. preserve +->msg_iter on error) will revert the iov buffer if copy to iter +failed, but it didn't copy any datagram if the skb_checksum_complete +error, so no need to revert any data at this place. + +v2: Sabrina notice that return -EFAULT when checksum error is not correct + here, it would confuse the caller about the return value, so fix it. + +Fixes: 327868212381 ("make skb_copy_datagram_msg() et.al. preserve->msg_iter on error") +Cc: stable@vger.kernel.org # v4.11 +Signed-off-by: Ding Tianhong <dingtianhong@huawei.com> +Acked-by: Al Viro <viro@zeniv.linux.org.uk> +Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com> +Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> + +diff --git a/net/core/datagram.c b/net/core/datagram.c +index f4947e737f34..d797baa69e43 100644 +--- a/net/core/datagram.c ++++ b/net/core/datagram.c +@@ -760,7 +760,7 @@ int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, + + if (msg_data_left(msg) < chunk) { + if (__skb_checksum_complete(skb)) +- goto csum_error; ++ return -EINVAL; + if (skb_copy_datagram_msg(skb, hlen, msg, chunk)) + goto fault; + } else { +@@ -768,15 +768,16 @@ int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, + if (skb_copy_and_csum_datagram(skb, hlen, &msg->msg_iter, + chunk, &csum)) + goto fault; +- if (csum_fold(csum)) +- goto csum_error; ++ ++ if (csum_fold(csum)) { ++ iov_iter_revert(&msg->msg_iter, chunk); ++ return -EINVAL; ++ } ++ + if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE)) + netdev_rx_csum_fault(skb->dev); + } + return 0; +-csum_error: +- iov_iter_revert(&msg->msg_iter, chunk); +- return -EINVAL; + fault: + return -EFAULT; + } +-- +2.12.0 + diff --git a/queue/ip6mr-fix-notification-device-destruction.patch b/queue/ip6mr-fix-notification-device-destruction.patch new file mode 100644 index 0000000..d874ed0 --- /dev/null +++ b/queue/ip6mr-fix-notification-device-destruction.patch @@ -0,0 +1,129 @@ +From 723b929ca0f79c0796f160c2eeda4597ee98d2b8 Mon Sep 17 00:00:00 2001 +From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> +Date: Fri, 21 Apr 2017 20:42:16 +0300 +Subject: [PATCH] ip6mr: fix notification device destruction + +commit 723b929ca0f79c0796f160c2eeda4597ee98d2b8 upstream. + +Andrey Konovalov reported a BUG caused by the ip6mr code which is caused +because we call unregister_netdevice_many for a device that is already +being destroyed. In IPv4's ipmr that has been resolved by two commits +long time ago by introducing the "notify" parameter to the delete +function and avoiding the unregister when called from a notifier, so +let's do the same for ip6mr. + +The trace from Andrey: +------------[ cut here ]------------ +kernel BUG at net/core/dev.c:6813! +invalid opcode: 0000 [#1] SMP KASAN +Modules linked in: +CPU: 1 PID: 1165 Comm: kworker/u4:3 Not tainted 4.11.0-rc7+ #251 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs +01/01/2011 +Workqueue: netns cleanup_net +task: ffff880069208000 task.stack: ffff8800692d8000 +RIP: 0010:rollback_registered_many+0x348/0xeb0 net/core/dev.c:6813 +RSP: 0018:ffff8800692de7f0 EFLAGS: 00010297 +RAX: ffff880069208000 RBX: 0000000000000002 RCX: 0000000000000001 +RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff88006af90569 +RBP: ffff8800692de9f0 R08: ffff8800692dec60 R09: 0000000000000000 +R10: 0000000000000006 R11: 0000000000000000 R12: ffff88006af90070 +R13: ffff8800692debf0 R14: dffffc0000000000 R15: ffff88006af90000 +FS: 0000000000000000(0000) GS:ffff88006cb00000(0000) +knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007fe7e897d870 CR3: 00000000657e7000 CR4: 00000000000006e0 +Call Trace: + unregister_netdevice_many.part.105+0x87/0x440 net/core/dev.c:7881 + unregister_netdevice_many+0xc8/0x120 net/core/dev.c:7880 + ip6mr_device_event+0x362/0x3f0 net/ipv6/ip6mr.c:1346 + notifier_call_chain+0x145/0x2f0 kernel/notifier.c:93 + __raw_notifier_call_chain kernel/notifier.c:394 + raw_notifier_call_chain+0x2d/0x40 kernel/notifier.c:401 + call_netdevice_notifiers_info+0x51/0x90 net/core/dev.c:1647 + call_netdevice_notifiers net/core/dev.c:1663 + rollback_registered_many+0x919/0xeb0 net/core/dev.c:6841 + unregister_netdevice_many.part.105+0x87/0x440 net/core/dev.c:7881 + unregister_netdevice_many net/core/dev.c:7880 + default_device_exit_batch+0x4fa/0x640 net/core/dev.c:8333 + ops_exit_list.isra.4+0x100/0x150 net/core/net_namespace.c:144 + cleanup_net+0x5a8/0xb40 net/core/net_namespace.c:463 + process_one_work+0xc04/0x1c10 kernel/workqueue.c:2097 + worker_thread+0x223/0x19c0 kernel/workqueue.c:2231 + kthread+0x35e/0x430 kernel/kthread.c:231 + ret_from_fork+0x31/0x40 arch/x86/entry/entry_64.S:430 +Code: 3c 32 00 0f 85 70 0b 00 00 48 b8 00 02 00 00 00 00 ad de 49 89 +47 78 e9 93 fe ff ff 49 8d 57 70 49 8d 5f 78 eb 9e e8 88 7a 14 fe <0f> +0b 48 8b 9d 28 fe ff ff e8 7a 7a 14 fe 48 b8 00 00 00 00 00 +RIP: rollback_registered_many+0x348/0xeb0 RSP: ffff8800692de7f0 +---[ end trace e0b29c57e9b3292c ]--- + +Reported-by: Andrey Konovalov <andreyknvl@google.com> +Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> +Tested-by: Andrey Konovalov <andreyknvl@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c +index 6ba6c900ebcf..bf34d0950752 100644 +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -774,7 +774,8 @@ failure: + * Delete a VIF entry + */ + +-static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head) ++static int mif6_delete(struct mr6_table *mrt, int vifi, int notify, ++ struct list_head *head) + { + struct mif_device *v; + struct net_device *dev; +@@ -820,7 +821,7 @@ static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head) + dev->ifindex, &in6_dev->cnf); + } + +- if (v->flags & MIFF_REGISTER) ++ if ((v->flags & MIFF_REGISTER) && !notify) + unregister_netdevice_queue(dev, head); + + dev_put(dev); +@@ -1331,7 +1332,6 @@ static int ip6mr_device_event(struct notifier_block *this, + struct mr6_table *mrt; + struct mif_device *v; + int ct; +- LIST_HEAD(list); + + if (event != NETDEV_UNREGISTER) + return NOTIFY_DONE; +@@ -1340,10 +1340,9 @@ static int ip6mr_device_event(struct notifier_block *this, + v = &mrt->vif6_table[0]; + for (ct = 0; ct < mrt->maxvif; ct++, v++) { + if (v->dev == dev) +- mif6_delete(mrt, ct, &list); ++ mif6_delete(mrt, ct, 1, NULL); + } + } +- unregister_netdevice_many(&list); + + return NOTIFY_DONE; + } +@@ -1552,7 +1551,7 @@ static void mroute_clean_tables(struct mr6_table *mrt, bool all) + for (i = 0; i < mrt->maxvif; i++) { + if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC)) + continue; +- mif6_delete(mrt, i, &list); ++ mif6_delete(mrt, i, 0, &list); + } + unregister_netdevice_many(&list); + +@@ -1707,7 +1706,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns + if (copy_from_user(&mifi, optval, sizeof(mifi_t))) + return -EFAULT; + rtnl_lock(); +- ret = mif6_delete(mrt, mifi, NULL); ++ ret = mif6_delete(mrt, mifi, 0, NULL); + rtnl_unlock(); + return ret; + +-- +2.12.0 + diff --git a/queue/ipmi-Fix-kernel-panic-at-ipmi_ssif_thread.patch b/queue/ipmi-Fix-kernel-panic-at-ipmi_ssif_thread.patch new file mode 100644 index 0000000..204733f --- /dev/null +++ b/queue/ipmi-Fix-kernel-panic-at-ipmi_ssif_thread.patch @@ -0,0 +1,50 @@ +From 6de65fcfdb51835789b245203d1bfc8d14cb1e06 Mon Sep 17 00:00:00 2001 +From: Joeseph Chang <joechang@codeaurora.org> +Date: Mon, 27 Mar 2017 20:22:09 -0600 +Subject: [PATCH] ipmi: Fix kernel panic at ipmi_ssif_thread() + +commit 6de65fcfdb51835789b245203d1bfc8d14cb1e06 upstream. + +msg_written_handler() may set ssif_info->multi_data to NULL +when using ipmitool to write fru. + +Before setting ssif_info->multi_data to NULL, add new local +pointer "data_to_send" and store correct i2c data pointer to +it to fix NULL pointer kernel panic and incorrect ssif_info->multi_pos. + +Signed-off-by: Joeseph Chang <joechang@codeaurora.org> +Signed-off-by: Corey Minyard <cminyard@mvista.com> +Cc: stable@vger.kernel.org # 3.19- + +diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c +index cca6e5bc1cea..51ba67de862e 100644 +--- a/drivers/char/ipmi/ipmi_ssif.c ++++ b/drivers/char/ipmi/ipmi_ssif.c +@@ -891,6 +891,7 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result, + * for details on the intricacies of this. + */ + int left; ++ unsigned char *data_to_send; + + ssif_inc_stat(ssif_info, sent_messages_parts); + +@@ -899,6 +900,7 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result, + left = 32; + /* Length byte. */ + ssif_info->multi_data[ssif_info->multi_pos] = left; ++ data_to_send = ssif_info->multi_data + ssif_info->multi_pos; + ssif_info->multi_pos += left; + if (left < 32) + /* +@@ -912,7 +914,7 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result, + rv = ssif_i2c_send(ssif_info, msg_written_handler, + I2C_SMBUS_WRITE, + SSIF_IPMI_MULTI_PART_REQUEST_MIDDLE, +- ssif_info->multi_data + ssif_info->multi_pos, ++ data_to_send, + I2C_SMBUS_BLOCK_DATA); + if (rv < 0) { + /* request failed, just return the error. */ +-- +2.12.0 + diff --git a/queue/ipv4-ipv6-ensure-raw-socket-message-is-big-enough-to.patch b/queue/ipv4-ipv6-ensure-raw-socket-message-is-big-enough-to.patch new file mode 100644 index 0000000..b572b6d --- /dev/null +++ b/queue/ipv4-ipv6-ensure-raw-socket-message-is-big-enough-to.patch @@ -0,0 +1,112 @@ +From 86f4c90a1c5c1493f07f2d12c1079f5bf01936f2 Mon Sep 17 00:00:00 2001 +From: Alexander Potapenko <glider@google.com> +Date: Wed, 3 May 2017 17:06:58 +0200 +Subject: [PATCH] ipv4, ipv6: ensure raw socket message is big enough to hold + an IP header + +commit 86f4c90a1c5c1493f07f2d12c1079f5bf01936f2 upstream. + +raw_send_hdrinc() and rawv6_send_hdrinc() expect that the buffer copied +from the userspace contains the IPv4/IPv6 header, so if too few bytes are +copied, parts of the header may remain uninitialized. + +This bug has been detected with KMSAN. + +For the record, the KMSAN report: + +================================================================== +BUG: KMSAN: use of unitialized memory in nf_ct_frag6_gather+0xf5a/0x44a0 +inter: 0 +CPU: 0 PID: 1036 Comm: probe Not tainted 4.11.0-rc5+ #2455 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:16 + dump_stack+0x143/0x1b0 lib/dump_stack.c:52 + kmsan_report+0x16b/0x1e0 mm/kmsan/kmsan.c:1078 + __kmsan_warning_32+0x5c/0xa0 mm/kmsan/kmsan_instr.c:510 + nf_ct_frag6_gather+0xf5a/0x44a0 net/ipv6/netfilter/nf_conntrack_reasm.c:577 + ipv6_defrag+0x1d9/0x280 net/ipv6/netfilter/nf_defrag_ipv6_hooks.c:68 + nf_hook_entry_hookfn ./include/linux/netfilter.h:102 + nf_hook_slow+0x13f/0x3c0 net/netfilter/core.c:310 + nf_hook ./include/linux/netfilter.h:212 + NF_HOOK ./include/linux/netfilter.h:255 + rawv6_send_hdrinc net/ipv6/raw.c:673 + rawv6_sendmsg+0x2fcb/0x41a0 net/ipv6/raw.c:919 + inet_sendmsg+0x3f8/0x6d0 net/ipv4/af_inet.c:762 + sock_sendmsg_nosec net/socket.c:633 + sock_sendmsg net/socket.c:643 + SYSC_sendto+0x6a5/0x7c0 net/socket.c:1696 + SyS_sendto+0xbc/0xe0 net/socket.c:1664 + do_syscall_64+0x72/0xa0 arch/x86/entry/common.c:285 + entry_SYSCALL64_slow_path+0x25/0x25 arch/x86/entry/entry_64.S:246 +RIP: 0033:0x436e03 +RSP: 002b:00007ffce48baf38 EFLAGS: 00000246 ORIG_RAX: 000000000000002c +RAX: ffffffffffffffda RBX: 00000000004002b0 RCX: 0000000000436e03 +RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000003 +RBP: 00007ffce48baf90 R08: 00007ffce48baf50 R09: 000000000000001c +R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 +R13: 0000000000401790 R14: 0000000000401820 R15: 0000000000000000 +origin: 00000000d9400053 + save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59 + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:362 + kmsan_internal_poison_shadow+0xb1/0x1a0 mm/kmsan/kmsan.c:257 + kmsan_poison_shadow+0x6d/0xc0 mm/kmsan/kmsan.c:270 + slab_alloc_node mm/slub.c:2735 + __kmalloc_node_track_caller+0x1f4/0x390 mm/slub.c:4341 + __kmalloc_reserve net/core/skbuff.c:138 + __alloc_skb+0x2cd/0x740 net/core/skbuff.c:231 + alloc_skb ./include/linux/skbuff.h:933 + alloc_skb_with_frags+0x209/0xbc0 net/core/skbuff.c:4678 + sock_alloc_send_pskb+0x9ff/0xe00 net/core/sock.c:1903 + sock_alloc_send_skb+0xe4/0x100 net/core/sock.c:1920 + rawv6_send_hdrinc net/ipv6/raw.c:638 + rawv6_sendmsg+0x2918/0x41a0 net/ipv6/raw.c:919 + inet_sendmsg+0x3f8/0x6d0 net/ipv4/af_inet.c:762 + sock_sendmsg_nosec net/socket.c:633 + sock_sendmsg net/socket.c:643 + SYSC_sendto+0x6a5/0x7c0 net/socket.c:1696 + SyS_sendto+0xbc/0xe0 net/socket.c:1664 + do_syscall_64+0x72/0xa0 arch/x86/entry/common.c:285 + return_from_SYSCALL_64+0x0/0x6a arch/x86/entry/entry_64.S:246 +================================================================== + +, triggered by the following syscalls: + socket(PF_INET6, SOCK_RAW, IPPROTO_RAW) = 3 + sendto(3, NULL, 0, 0, {sa_family=AF_INET6, sin6_port=htons(0), inet_pton(AF_INET6, "ff00::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EPERM + +A similar report is triggered in net/ipv4/raw.c if we use a PF_INET socket +instead of a PF_INET6 one. + +Signed-off-by: Alexander Potapenko <glider@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c +index 9d943974de2b..bdffad875691 100644 +--- a/net/ipv4/raw.c ++++ b/net/ipv4/raw.c +@@ -358,6 +358,9 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, + rt->dst.dev->mtu); + return -EMSGSIZE; + } ++ if (length < sizeof(struct iphdr)) ++ return -EINVAL; ++ + if (flags&MSG_PROBE) + goto out; + +diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c +index 0da6a12b5472..1f992d9e261d 100644 +--- a/net/ipv6/raw.c ++++ b/net/ipv6/raw.c +@@ -632,6 +632,8 @@ static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length, + ipv6_local_error(sk, EMSGSIZE, fl6, rt->dst.dev->mtu); + return -EMSGSIZE; + } ++ if (length < sizeof(struct ipv6hdr)) ++ return -EINVAL; + if (flags&MSG_PROBE) + goto out; + +-- +2.12.0 + diff --git a/queue/ipv6-Fix-idev-addr_list-corruption.patch b/queue/ipv6-Fix-idev-addr_list-corruption.patch new file mode 100644 index 0000000..51676b4 --- /dev/null +++ b/queue/ipv6-Fix-idev-addr_list-corruption.patch @@ -0,0 +1,68 @@ +From a2d6cbb0670d54806f18192cb0db266b4a6d285a Mon Sep 17 00:00:00 2001 +From: Rabin Vincent <rabinv@axis.com> +Date: Mon, 10 Apr 2017 08:36:39 +0200 +Subject: [PATCH] ipv6: Fix idev->addr_list corruption + +commit a2d6cbb0670d54806f18192cb0db266b4a6d285a upstream. + +addrconf_ifdown() removes elements from the idev->addr_list without +holding the idev->lock. + +If this happens while the loop in __ipv6_dev_get_saddr() is handling the +same element, that function ends up in an infinite loop: + + NMI watchdog: BUG: soft lockup - CPU#1 stuck for 23s! [test:1719] + Call Trace: + ipv6_get_saddr_eval+0x13c/0x3a0 + __ipv6_dev_get_saddr+0xe4/0x1f0 + ipv6_dev_get_saddr+0x1b4/0x204 + ip6_dst_lookup_tail+0xcc/0x27c + ip6_dst_lookup_flow+0x38/0x80 + udpv6_sendmsg+0x708/0xba8 + sock_sendmsg+0x18/0x30 + SyS_sendto+0xb8/0xf8 + syscall_common+0x34/0x58 + +Fixes: 6a923934c33 (Revert "ipv6: Revert optional address flusing on ifdown.") +Signed-off-by: Rabin Vincent <rabinv@axis.com> +Acked-by: David Ahern <dsa@cumulusnetworks.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index 363172527e43..80ce478c4851 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -3626,14 +3626,19 @@ restart: + INIT_LIST_HEAD(&del_list); + list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) { + struct rt6_info *rt = NULL; ++ bool keep; + + addrconf_del_dad_work(ifa); + ++ keep = keep_addr && (ifa->flags & IFA_F_PERMANENT) && ++ !addr_is_local(&ifa->addr); ++ if (!keep) ++ list_move(&ifa->if_list, &del_list); ++ + write_unlock_bh(&idev->lock); + spin_lock_bh(&ifa->lock); + +- if (keep_addr && (ifa->flags & IFA_F_PERMANENT) && +- !addr_is_local(&ifa->addr)) { ++ if (keep) { + /* set state to skip the notifier below */ + state = INET6_IFADDR_STATE_DEAD; + ifa->state = 0; +@@ -3645,8 +3650,6 @@ restart: + } else { + state = ifa->state; + ifa->state = INET6_IFADDR_STATE_DEAD; +- +- list_move(&ifa->if_list, &del_list); + } + + spin_unlock_bh(&ifa->lock); +-- +2.12.0 + diff --git a/queue/ipv6-check-raw-payload-size-correctly-in-ioctl.patch b/queue/ipv6-check-raw-payload-size-correctly-in-ioctl.patch new file mode 100644 index 0000000..dfbe3ef --- /dev/null +++ b/queue/ipv6-check-raw-payload-size-correctly-in-ioctl.patch @@ -0,0 +1,37 @@ +From 105f5528b9bbaa08b526d3405a5bcd2ff0c953c8 Mon Sep 17 00:00:00 2001 +From: Jamie Bainbridge <jbainbri@redhat.com> +Date: Wed, 26 Apr 2017 10:43:27 +1000 +Subject: [PATCH] ipv6: check raw payload size correctly in ioctl + +commit 105f5528b9bbaa08b526d3405a5bcd2ff0c953c8 upstream. + +In situations where an skb is paged, the transport header pointer and +tail pointer can be the same because the skb contents are in frags. + +This results in ioctl(SIOCINQ/FIONREAD) incorrectly returning a +length of 0 when the length to receive is actually greater than zero. + +skb->len is already correctly set in ip6_input_finish() with +pskb_pull(), so use skb->len as it always returns the correct result +for both linear and paged data. + +Signed-off-by: Jamie Bainbridge <jbainbri@redhat.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c +index f174e76e6505..0da6a12b5472 100644 +--- a/net/ipv6/raw.c ++++ b/net/ipv6/raw.c +@@ -1178,8 +1178,7 @@ static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg) + spin_lock_bh(&sk->sk_receive_queue.lock); + skb = skb_peek(&sk->sk_receive_queue); + if (skb) +- amount = skb_tail_pointer(skb) - +- skb_transport_header(skb); ++ amount = skb->len; + spin_unlock_bh(&sk->sk_receive_queue.lock); + return put_user(amount, (int __user *)arg); + } +-- +2.12.0 + diff --git a/queue/ipv6-check-skb-protocol-before-lookup-for-nexthop.patch b/queue/ipv6-check-skb-protocol-before-lookup-for-nexthop.patch new file mode 100644 index 0000000..4b6f3d0 --- /dev/null +++ b/queue/ipv6-check-skb-protocol-before-lookup-for-nexthop.patch @@ -0,0 +1,101 @@ +From 199ab00f3cdb6f154ea93fa76fd80192861a821d Mon Sep 17 00:00:00 2001 +From: WANG Cong <xiyou.wangcong@gmail.com> +Date: Tue, 25 Apr 2017 14:37:15 -0700 +Subject: [PATCH] ipv6: check skb->protocol before lookup for nexthop + +commit 199ab00f3cdb6f154ea93fa76fd80192861a821d upstream. + +Andrey reported a out-of-bound access in ip6_tnl_xmit(), this +is because we use an ipv4 dst in ip6_tnl_xmit() and cast an IPv4 +neigh key as an IPv6 address: + + neigh = dst_neigh_lookup(skb_dst(skb), + &ipv6_hdr(skb)->daddr); + if (!neigh) + goto tx_err_link_failure; + + addr6 = (struct in6_addr *)&neigh->primary_key; // <=== HERE + addr_type = ipv6_addr_type(addr6); + + if (addr_type == IPV6_ADDR_ANY) + addr6 = &ipv6_hdr(skb)->daddr; + + memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr)); + +Also the network header of the skb at this point should be still IPv4 +for 4in6 tunnels, we shold not just use it as IPv6 header. + +This patch fixes it by checking if skb->protocol is ETH_P_IPV6: if it +is, we are safe to do the nexthop lookup using skb_dst() and +ipv6_hdr(skb)->daddr; if not (aka IPv4), we have no clue about which +dest address we can pick here, we have to rely on callers to fill it +from tunnel config, so just fall to ip6_route_output() to make the +decision. + +Fixes: ea3dc9601bda ("ip6_tunnel: Add support for wildcard tunnel endpoints.") +Reported-by: Andrey Konovalov <andreyknvl@google.com> +Tested-by: Andrey Konovalov <andreyknvl@google.com> +Cc: Steffen Klassert <steffen.klassert@secunet.com> +Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c +index 75fac933c209..a9692ec0cd6d 100644 +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -1037,7 +1037,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, + struct ip6_tnl *t = netdev_priv(dev); + struct net *net = t->net; + struct net_device_stats *stats = &t->dev->stats; +- struct ipv6hdr *ipv6h = ipv6_hdr(skb); ++ struct ipv6hdr *ipv6h; + struct ipv6_tel_txoption opt; + struct dst_entry *dst = NULL, *ndst = NULL; + struct net_device *tdev; +@@ -1057,26 +1057,28 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, + + /* NBMA tunnel */ + if (ipv6_addr_any(&t->parms.raddr)) { +- struct in6_addr *addr6; +- struct neighbour *neigh; +- int addr_type; ++ if (skb->protocol == htons(ETH_P_IPV6)) { ++ struct in6_addr *addr6; ++ struct neighbour *neigh; ++ int addr_type; + +- if (!skb_dst(skb)) +- goto tx_err_link_failure; ++ if (!skb_dst(skb)) ++ goto tx_err_link_failure; + +- neigh = dst_neigh_lookup(skb_dst(skb), +- &ipv6_hdr(skb)->daddr); +- if (!neigh) +- goto tx_err_link_failure; ++ neigh = dst_neigh_lookup(skb_dst(skb), ++ &ipv6_hdr(skb)->daddr); ++ if (!neigh) ++ goto tx_err_link_failure; + +- addr6 = (struct in6_addr *)&neigh->primary_key; +- addr_type = ipv6_addr_type(addr6); ++ addr6 = (struct in6_addr *)&neigh->primary_key; ++ addr_type = ipv6_addr_type(addr6); + +- if (addr_type == IPV6_ADDR_ANY) +- addr6 = &ipv6_hdr(skb)->daddr; ++ if (addr_type == IPV6_ADDR_ANY) ++ addr6 = &ipv6_hdr(skb)->daddr; + +- memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr)); +- neigh_release(neigh); ++ memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr)); ++ neigh_release(neigh); ++ } + } else if (!(t->parms.flags & + (IP6_TNL_F_USE_ORIG_TCLASS | IP6_TNL_F_USE_ORIG_FWMARK))) { + /* enable the cache only only if the routing decision does +-- +2.12.0 + diff --git a/queue/ipv6-initialize-route-null-entry-in-addrconf_init.patch b/queue/ipv6-initialize-route-null-entry-in-addrconf_init.patch new file mode 100644 index 0000000..f7774d9 --- /dev/null +++ b/queue/ipv6-initialize-route-null-entry-in-addrconf_init.patch @@ -0,0 +1,97 @@ +From 2f460933f58eee3393aba64f0f6d14acb08d1724 Mon Sep 17 00:00:00 2001 +From: WANG Cong <xiyou.wangcong@gmail.com> +Date: Wed, 3 May 2017 22:07:31 -0700 +Subject: [PATCH] ipv6: initialize route null entry in addrconf_init() + +commit 2f460933f58eee3393aba64f0f6d14acb08d1724 upstream. + +Andrey reported a crash on init_net.ipv6.ip6_null_entry->rt6i_idev +since it is always NULL. + +This is clearly wrong, we have code to initialize it to loopback_dev, +unfortunately the order is still not correct. + +loopback_dev is registered very early during boot, we lose a chance +to re-initialize it in notifier. addrconf_init() is called after +ip6_route_init(), which means we have no chance to correct it. + +Fix it by moving this initialization explicitly after +ipv6_add_dev(init_net.loopback_dev) in addrconf_init(). + +Reported-by: Andrey Konovalov <andreyknvl@google.com> +Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> +Tested-by: Andrey Konovalov <andreyknvl@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h +index 9dc2c182a263..f5e625f53367 100644 +--- a/include/net/ip6_route.h ++++ b/include/net/ip6_route.h +@@ -84,6 +84,7 @@ struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6, + struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, + int ifindex, struct flowi6 *fl6, int flags); + ++void ip6_route_init_special_entries(void); + int ip6_route_init(void); + void ip6_route_cleanup(void); + +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index a2a370b71249..77a4bd526d6e 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -6573,6 +6573,8 @@ int __init addrconf_init(void) + goto errlo; + } + ++ ip6_route_init_special_entries(); ++ + for (i = 0; i < IN6_ADDR_HSIZE; i++) + INIT_HLIST_HEAD(&inet6_addr_lst[i]); + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index a1bf426c959b..2f1136627dcb 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -4027,6 +4027,21 @@ static struct notifier_block ip6_route_dev_notifier = { + .priority = 0, + }; + ++void __init ip6_route_init_special_entries(void) ++{ ++ /* Registering of the loopback is done before this portion of code, ++ * the loopback reference in rt6_info will not be taken, do it ++ * manually for init_net */ ++ init_net.ipv6.ip6_null_entry->dst.dev = init_net.loopback_dev; ++ init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); ++ #ifdef CONFIG_IPV6_MULTIPLE_TABLES ++ init_net.ipv6.ip6_prohibit_entry->dst.dev = init_net.loopback_dev; ++ init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); ++ init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev; ++ init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); ++ #endif ++} ++ + int __init ip6_route_init(void) + { + int ret; +@@ -4053,17 +4068,6 @@ int __init ip6_route_init(void) + + ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep; + +- /* Registering of the loopback is done before this portion of code, +- * the loopback reference in rt6_info will not be taken, do it +- * manually for init_net */ +- init_net.ipv6.ip6_null_entry->dst.dev = init_net.loopback_dev; +- init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); +- #ifdef CONFIG_IPV6_MULTIPLE_TABLES +- init_net.ipv6.ip6_prohibit_entry->dst.dev = init_net.loopback_dev; +- init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); +- init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev; +- init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); +- #endif + ret = fib6_init(); + if (ret) + goto out_register_subsys; +-- +2.12.0 + diff --git a/queue/ipv6-reorder-ip6_route_dev_notifier-after-ipv6_dev_n.patch b/queue/ipv6-reorder-ip6_route_dev_notifier-after-ipv6_dev_n.patch new file mode 100644 index 0000000..e2db7e3 --- /dev/null +++ b/queue/ipv6-reorder-ip6_route_dev_notifier-after-ipv6_dev_n.patch @@ -0,0 +1,101 @@ +From 242d3a49a2a1a71d8eb9f953db1bcaa9d698ce00 Mon Sep 17 00:00:00 2001 +From: WANG Cong <xiyou.wangcong@gmail.com> +Date: Mon, 8 May 2017 10:12:13 -0700 +Subject: [PATCH] ipv6: reorder ip6_route_dev_notifier after ipv6_dev_notf + +commit 242d3a49a2a1a71d8eb9f953db1bcaa9d698ce00 upstream. + +For each netns (except init_net), we initialize its null entry +in 3 places: + +1) The template itself, as we use kmemdup() +2) Code around dst_init_metrics() in ip6_route_net_init() +3) ip6_route_dev_notify(), which is supposed to initialize it after + loopback registers + +Unfortunately the last one still happens in a wrong order because +we expect to initialize net->ipv6.ip6_null_entry->rt6i_idev to +net->loopback_dev's idev, thus we have to do that after we add +idev to loopback. However, this notifier has priority == 0 same as +ipv6_dev_notf, and ipv6_dev_notf is registered after +ip6_route_dev_notifier so it is called actually after +ip6_route_dev_notifier. This is similar to commit 2f460933f58e +("ipv6: initialize route null entry in addrconf_init()") which +fixes init_net. + +Fix it by picking a smaller priority for ip6_route_dev_notifier. +Also, we have to release the refcnt accordingly when unregistering +loopback_dev because device exit functions are called before subsys +exit functions. + +Acked-by: David Ahern <dsahern@gmail.com> +Tested-by: David Ahern <dsahern@gmail.com> +Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/include/net/addrconf.h b/include/net/addrconf.h +index 2452e6449532..b43a4eec3cec 100644 +--- a/include/net/addrconf.h ++++ b/include/net/addrconf.h +@@ -20,6 +20,8 @@ + #define ADDRCONF_TIMER_FUZZ (HZ / 4) + #define ADDRCONF_TIMER_FUZZ_MAX (HZ) + ++#define ADDRCONF_NOTIFY_PRIORITY 0 ++ + #include <linux/in.h> + #include <linux/in6.h> + +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index 77a4bd526d6e..8d297a79b568 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -3548,6 +3548,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, + */ + static struct notifier_block ipv6_dev_notf = { + .notifier_call = addrconf_notify, ++ .priority = ADDRCONF_NOTIFY_PRIORITY, + }; + + static void addrconf_type_change(struct net_device *dev, unsigned long event) +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 2f1136627dcb..dc61b0b5e64e 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -3709,7 +3709,10 @@ static int ip6_route_dev_notify(struct notifier_block *this, + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + struct net *net = dev_net(dev); + +- if (event == NETDEV_REGISTER && (dev->flags & IFF_LOOPBACK)) { ++ if (!(dev->flags & IFF_LOOPBACK)) ++ return NOTIFY_OK; ++ ++ if (event == NETDEV_REGISTER) { + net->ipv6.ip6_null_entry->dst.dev = dev; + net->ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(dev); + #ifdef CONFIG_IPV6_MULTIPLE_TABLES +@@ -3718,6 +3721,12 @@ static int ip6_route_dev_notify(struct notifier_block *this, + net->ipv6.ip6_blk_hole_entry->dst.dev = dev; + net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev); + #endif ++ } else if (event == NETDEV_UNREGISTER) { ++ in6_dev_put(net->ipv6.ip6_null_entry->rt6i_idev); ++#ifdef CONFIG_IPV6_MULTIPLE_TABLES ++ in6_dev_put(net->ipv6.ip6_prohibit_entry->rt6i_idev); ++ in6_dev_put(net->ipv6.ip6_blk_hole_entry->rt6i_idev); ++#endif + } + + return NOTIFY_OK; +@@ -4024,7 +4033,7 @@ static struct pernet_operations ip6_route_net_late_ops = { + + static struct notifier_block ip6_route_dev_notifier = { + .notifier_call = ip6_route_dev_notify, +- .priority = 0, ++ .priority = ADDRCONF_NOTIFY_PRIORITY - 10, + }; + + void __init ip6_route_init_special_entries(void) +-- +2.12.0 + diff --git a/queue/iscsi-target-Set-session_fall_back_to_erl0-when-forc.patch b/queue/iscsi-target-Set-session_fall_back_to_erl0-when-forc.patch new file mode 100644 index 0000000..a334526 --- /dev/null +++ b/queue/iscsi-target-Set-session_fall_back_to_erl0-when-forc.patch @@ -0,0 +1,77 @@ +From 197b806ae5db60c6f609d74da04ddb62ea5e1b00 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger <nab@linux-iscsi.org> +Date: Tue, 25 Apr 2017 10:55:12 -0700 +Subject: [PATCH] iscsi-target: Set session_fall_back_to_erl0 when forcing + reinstatement + +commit 197b806ae5db60c6f609d74da04ddb62ea5e1b00 upstream. + +While testing modification of per se_node_acl queue_depth forcing +session reinstatement via lio_target_nacl_cmdsn_depth_store() -> +core_tpg_set_initiator_node_queue_depth(), a hung task bug triggered +when changing cmdsn_depth invoked session reinstatement while an iscsi +login was already waiting for session reinstatement to complete. + +This can happen when an outstanding se_cmd descriptor is taking a +long time to complete, and session reinstatement from iscsi login +or cmdsn_depth change occurs concurrently. + +To address this bug, explicitly set session_fall_back_to_erl0 = 1 +when forcing session reinstatement, so session reinstatement is +not attempted if an active session is already being shutdown. + +This patch has been tested with two scenarios. The first when +iscsi login is blocked waiting for iscsi session reinstatement +to complete followed by queue_depth change via configfs, and +second when queue_depth change via configfs us blocked followed +by a iscsi login driven session reinstatement. + +Note this patch depends on commit d36ad77f702 to handle multiple +sessions per se_node_acl when changing cmdsn_depth, and for +pre v4.5 kernels will need to be included for stable as well. + +Reported-by: Gary Guo <ghg@datera.io> +Tested-by: Gary Guo <ghg@datera.io> +Cc: Gary Guo <ghg@datera.io> +Cc: <stable@vger.kernel.org> # v4.1+ +Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> + +diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c +index 0f7ade04b583..26a9bcd5ee6a 100644 +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -4663,6 +4663,7 @@ int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *tpg, int force) + continue; + } + atomic_set(&sess->session_reinstatement, 1); ++ atomic_set(&sess->session_fall_back_to_erl0, 1); + spin_unlock(&sess->conn_lock); + + list_move_tail(&se_sess->sess_list, &free_list); +diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c +index 344e8448869c..96d9c73af1ae 100644 +--- a/drivers/target/iscsi/iscsi_target_configfs.c ++++ b/drivers/target/iscsi/iscsi_target_configfs.c +@@ -1528,6 +1528,7 @@ static void lio_tpg_close_session(struct se_session *se_sess) + return; + } + atomic_set(&sess->session_reinstatement, 1); ++ atomic_set(&sess->session_fall_back_to_erl0, 1); + spin_unlock(&sess->conn_lock); + + iscsit_stop_time2retain_timer(sess); +diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c +index ad8f3011bdc2..66238477137b 100644 +--- a/drivers/target/iscsi/iscsi_target_login.c ++++ b/drivers/target/iscsi/iscsi_target_login.c +@@ -208,6 +208,7 @@ int iscsi_check_for_session_reinstatement(struct iscsi_conn *conn) + initiatorname_param->value) && + (sess_p->sess_ops->SessionType == sessiontype))) { + atomic_set(&sess_p->session_reinstatement, 1); ++ atomic_set(&sess_p->session_fall_back_to_erl0, 1); + spin_unlock(&sess_p->conn_lock); + iscsit_inc_session_usage_count(sess_p); + iscsit_stop_time2retain_timer(sess_p); +-- +2.12.0 + diff --git a/queue/iwlwifi-fix-MODULE_FIRMWARE-for-6030.patch b/queue/iwlwifi-fix-MODULE_FIRMWARE-for-6030.patch new file mode 100644 index 0000000..52f0a9b --- /dev/null +++ b/queue/iwlwifi-fix-MODULE_FIRMWARE-for-6030.patch @@ -0,0 +1,31 @@ +From d8320d75b59ecdc1b8e60ac793d3a54d84333a18 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=BCrg=20Billeter?= <j@bitron.ch> +Date: Mon, 10 Oct 2016 18:30:00 +0200 +Subject: [PATCH] iwlwifi: fix MODULE_FIRMWARE for 6030 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit d8320d75b59ecdc1b8e60ac793d3a54d84333a18 upstream. + +IWL6000G2B_UCODE_API_MAX is not defined. ucode_api_max of +IWL_DEVICE_6030 uses IWL6000G2_UCODE_API_MAX. Use this also for +MODULE_FIRMWARE. + +Fixes: 9d9b21d1b616 ("iwlwifi: remove IWL_*_UCODE_API_OK") +Signed-off-by: Jürg Billeter <j@bitron.ch> +Signed-off-by: Luca Coelho <luciano.coelho@intel.com> + +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-6000.c b/drivers/net/wireless/intel/iwlwifi/iwl-6000.c +index 0b9f6a7bc834..39335b7b0c16 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-6000.c ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-6000.c +@@ -371,4 +371,4 @@ const struct iwl_cfg iwl6000_3agn_cfg = { + MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); + MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); + MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); +-MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2B_UCODE_API_MAX)); ++MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); +-- +2.12.0 + diff --git a/queue/iwlwifi-mvm-Use-aux-queue-for-offchannel-frames-in-d.patch b/queue/iwlwifi-mvm-Use-aux-queue-for-offchannel-frames-in-d.patch new file mode 100644 index 0000000..d788868 --- /dev/null +++ b/queue/iwlwifi-mvm-Use-aux-queue-for-offchannel-frames-in-d.patch @@ -0,0 +1,47 @@ +From 6574dc943fc32a2fce69fab14891abca7eecb67c Mon Sep 17 00:00:00 2001 +From: Beni Lev <beni.lev@intel.com> +Date: Thu, 17 Nov 2016 14:03:17 +0200 +Subject: [PATCH] iwlwifi: mvm: Use aux queue for offchannel frames in dqa + +commit 6574dc943fc32a2fce69fab14891abca7eecb67c upstream. + +Since offchannel activity doesn't always require a BSS, e.g. ANQP +sessions, offchannel frames should not use the BSS queue, because it +might not be initialized. +Use the auxilary queue instead + +Fixes: e3118ad74d7e ("iwlwifi: mvm: support tdls in dqa mode") +Signed-off-by: Beni Lev <beni.lev@intel.com> +Signed-off-by: Luca Coelho <luciano.coelho@intel.com> + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +index 2b2db38eee3e..ea5d5b0d85b3 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -570,9 +570,10 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) + * (this is not possible for unicast packets as a TLDS discovery + * response are sent without a station entry); otherwise use the + * AUX station. +- * In DQA mode, if vif is of type STATION and frames are not multicast, +- * they should be sent from the BSS queue. For example, TDLS setup +- * frames should be sent on this queue, as they go through the AP. ++ * In DQA mode, if vif is of type STATION and frames are not multicast ++ * or offchannel, they should be sent from the BSS queue. ++ * For example, TDLS setup frames should be sent on this queue, ++ * as they go through the AP. + */ + sta_id = mvm->aux_sta.sta_id; + if (info.control.vif) { +@@ -594,7 +595,8 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) + if (ap_sta_id != IWL_MVM_STATION_COUNT) + sta_id = ap_sta_id; + } else if (iwl_mvm_is_dqa_supported(mvm) && +- info.control.vif->type == NL80211_IFTYPE_STATION) { ++ info.control.vif->type == NL80211_IFTYPE_STATION && ++ queue != mvm->aux_queue) { + queue = IWL_MVM_DQA_BSS_CLIENT_QUEUE; + } + } +-- +2.12.0 + diff --git a/queue/iwlwifi-mvm-don-t-restart-HW-if-suspend-fails-with-u.patch b/queue/iwlwifi-mvm-don-t-restart-HW-if-suspend-fails-with-u.patch new file mode 100644 index 0000000..4bc8404 --- /dev/null +++ b/queue/iwlwifi-mvm-don-t-restart-HW-if-suspend-fails-with-u.patch @@ -0,0 +1,43 @@ +From bac453ab3745eaa64137ea6e77e009b45954f0ae Mon Sep 17 00:00:00 2001 +From: Luca Coelho <luciano.coelho@intel.com> +Date: Fri, 7 Oct 2016 15:16:26 +0300 +Subject: [PATCH] iwlwifi: mvm: don't restart HW if suspend fails with unified + image + +commit bac453ab3745eaa64137ea6e77e009b45954f0ae upstream. + +For unified images, we shouldn't restart the HW if suspend fails. The +only reason for restarting the HW with non-unified images is to go +back to the D0 image. + +Fixes: 23ae61282b88 ("iwlwifi: mvm: Do not switch to D3 image on suspend") +Signed-off-by: Luca Coelho <luciano.coelho@intel.com> + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +index b88e2048ae0b..207d8ae1e116 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +@@ -1262,12 +1262,15 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, + iwl_trans_d3_suspend(mvm->trans, test, !unified_image); + out: + if (ret < 0) { +- iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); +- if (mvm->restart_fw > 0) { +- mvm->restart_fw--; +- ieee80211_restart_hw(mvm->hw); +- } + iwl_mvm_free_nd(mvm); ++ ++ if (!unified_image) { ++ iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); ++ if (mvm->restart_fw > 0) { ++ mvm->restart_fw--; ++ ieee80211_restart_hw(mvm->hw); ++ } ++ } + } + out_noreset: + mutex_unlock(&mvm->mutex); +-- +2.12.0 + diff --git a/queue/iwlwifi-mvm-fix-pending-frame-counter-calculation.patch b/queue/iwlwifi-mvm-fix-pending-frame-counter-calculation.patch new file mode 100644 index 0000000..9c908b0 --- /dev/null +++ b/queue/iwlwifi-mvm-fix-pending-frame-counter-calculation.patch @@ -0,0 +1,148 @@ +From 94c3e614df2117626fccfac8f821c66e30556384 Mon Sep 17 00:00:00 2001 +From: Sara Sharon <sara.sharon@intel.com> +Date: Wed, 7 Dec 2016 15:04:37 +0200 +Subject: [PATCH] iwlwifi: mvm: fix pending frame counter calculation + +commit 94c3e614df2117626fccfac8f821c66e30556384 upstream. + +In DQA mode the check whether to decrement the pending frames +counter relies on the tid status and not on the txq id. +This may result in an inconsistent state of the pending frames +counter in case frame is queued on a non aggregation queue but +with this TID, and will be followed by a failure to remove the +station and later on SYSASSERT 0x3421 when trying to remove the +MAC. +Such frames are for example bar and qos NDPs. +Fix it by aligning the condition of incrementing the counter +with the condition of decrementing it - rely on TID state for +DQA mode. +Also, avoid internal error like this affecting station removal +for DQA mode - since we can know for sure it is an internal +error. + +Fixes: cf961e16620f ("iwlwifi: mvm: support dqa-mode agg on non-shared queue") +Signed-off-by: Sara Sharon <sara.sharon@intel.com> +Signed-off-by: Luca Coelho <luciano.coelho@intel.com> + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +index 40fb64ead469..1bad933b3ad4 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +@@ -1501,6 +1501,7 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, + { + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta); ++ u8 sta_id = mvm_sta->sta_id; + int ret; + + lockdep_assert_held(&mvm->mutex); +@@ -1509,7 +1510,7 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, + kfree(mvm_sta->dup_data); + + if ((vif->type == NL80211_IFTYPE_STATION && +- mvmvif->ap_sta_id == mvm_sta->sta_id) || ++ mvmvif->ap_sta_id == sta_id) || + iwl_mvm_is_dqa_supported(mvm)){ + ret = iwl_mvm_drain_sta(mvm, mvm_sta, true); + if (ret) +@@ -1525,8 +1526,17 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, + ret = iwl_mvm_drain_sta(mvm, mvm_sta, false); + + /* If DQA is supported - the queues can be disabled now */ +- if (iwl_mvm_is_dqa_supported(mvm)) ++ if (iwl_mvm_is_dqa_supported(mvm)) { + iwl_mvm_disable_sta_queues(mvm, vif, mvm_sta); ++ /* ++ * If pending_frames is set at this point - it must be ++ * driver internal logic error, since queues are empty ++ * and removed successuly. ++ * warn on it but set it to 0 anyway to avoid station ++ * not being removed later in the function ++ */ ++ WARN_ON(atomic_xchg(&mvm->pending_frames[sta_id], 0)); ++ } + + /* If there is a TXQ still marked as reserved - free it */ + if (iwl_mvm_is_dqa_supported(mvm) && +@@ -1544,7 +1554,7 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, + if (WARN((*status != IWL_MVM_QUEUE_RESERVED) && + (*status != IWL_MVM_QUEUE_FREE), + "sta_id %d reserved txq %d status %d", +- mvm_sta->sta_id, reserved_txq, *status)) { ++ sta_id, reserved_txq, *status)) { + spin_unlock_bh(&mvm->queue_info_lock); + return -EINVAL; + } +@@ -1554,7 +1564,7 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, + } + + if (vif->type == NL80211_IFTYPE_STATION && +- mvmvif->ap_sta_id == mvm_sta->sta_id) { ++ mvmvif->ap_sta_id == sta_id) { + /* if associated - we can't remove the AP STA now */ + if (vif->bss_conf.assoc) + return ret; +@@ -1563,7 +1573,7 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, + mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT; + + /* clear d0i3_ap_sta_id if no longer relevant */ +- if (mvm->d0i3_ap_sta_id == mvm_sta->sta_id) ++ if (mvm->d0i3_ap_sta_id == sta_id) + mvm->d0i3_ap_sta_id = IWL_MVM_STATION_COUNT; + } + } +@@ -1572,7 +1582,7 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, + * This shouldn't happen - the TDLS channel switch should be canceled + * before the STA is removed. + */ +- if (WARN_ON_ONCE(mvm->tdls_cs.peer.sta_id == mvm_sta->sta_id)) { ++ if (WARN_ON_ONCE(mvm->tdls_cs.peer.sta_id == sta_id)) { + mvm->tdls_cs.peer.sta_id = IWL_MVM_STATION_COUNT; + cancel_delayed_work(&mvm->tdls_cs.dwork); + } +@@ -1582,21 +1592,20 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, + * calls the drain worker. + */ + spin_lock_bh(&mvm_sta->lock); ++ + /* + * There are frames pending on the AC queues for this station. + * We need to wait until all the frames are drained... + */ +- if (atomic_read(&mvm->pending_frames[mvm_sta->sta_id])) { +- rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], ++ if (atomic_read(&mvm->pending_frames[sta_id])) { ++ rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], + ERR_PTR(-EBUSY)); + spin_unlock_bh(&mvm_sta->lock); + + /* disable TDLS sta queues on drain complete */ + if (sta->tdls) { +- mvm->tfd_drained[mvm_sta->sta_id] = +- mvm_sta->tfd_queue_msk; +- IWL_DEBUG_TDLS(mvm, "Draining TDLS sta %d\n", +- mvm_sta->sta_id); ++ mvm->tfd_drained[sta_id] = mvm_sta->tfd_queue_msk; ++ IWL_DEBUG_TDLS(mvm, "Draining TDLS sta %d\n", sta_id); + } + + ret = iwl_mvm_drain_sta(mvm, mvm_sta, true); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +index 8daf4fbe4534..f82b765650d6 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -1015,7 +1015,10 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, + spin_unlock(&mvmsta->lock); + + /* Increase pending frames count if this isn't AMPDU */ +- if (!is_ampdu) ++ if ((iwl_mvm_is_dqa_supported(mvm) && ++ mvmsta->tid_data[tx_cmd->tid_tspec].state != IWL_AGG_ON && ++ mvmsta->tid_data[tx_cmd->tid_tspec].state != IWL_AGG_STARTING) || ++ (!iwl_mvm_is_dqa_supported(mvm) && !is_ampdu)) + atomic_inc(&mvm->pending_frames[mvmsta->sta_id]); + + return 0; +-- +2.12.0 + diff --git a/queue/iwlwifi-mvm-fix-references-to-first_agg_queue-in-DQA.patch b/queue/iwlwifi-mvm-fix-references-to-first_agg_queue-in-DQA.patch new file mode 100644 index 0000000..ae9b6cd --- /dev/null +++ b/queue/iwlwifi-mvm-fix-references-to-first_agg_queue-in-DQA.patch @@ -0,0 +1,73 @@ +From c56108b58ab870892277940a1def0d6b153f3e26 Mon Sep 17 00:00:00 2001 +From: Sara Sharon <sara.sharon@intel.com> +Date: Sun, 1 Jan 2017 18:42:23 +0200 +Subject: [PATCH] iwlwifi: mvm: fix references to first_agg_queue in DQA mode + +commit c56108b58ab870892277940a1def0d6b153f3e26 upstream. + +In DQA mode, first_agg_queue is initialized to +IWL_MVM_DQA_MIN_DATA_QUEUE. This causes two bugs in the tx response +flow: + +1. When TX fails, we set IEEE80211_TX_STAT_AMPDU_NO_BACK regardless + if we actually have aggregation open on the queue. This causes + mac80211 to send a BAR frame even though there is no aggregation + open. + Fix that by simply checking the AMPDU flag that is set on by + mac80211 for AMPDU packets. + +2. When reclaiming frames in aggregation mode, we reclaim based on + scheduler ssn and not the SN. + The reason is that scheduler ssn may be ahead of SN due to a hole + in the BA window that was filled. + However, if we have aggregations open on IWL_MVM_DQA_BSS_CLIENT_QUEUE + the reclaim flow will still go to the code of non-aggregation + instead of the aggregation code since IWL_MVM_DQA_BSS_CLIENT_QUEUE + is smaller than IWL_MVM_DQA_MIN_DATA_QUEUE, although it is a valid + aggregation queue. + Fix that by always using the aggregation reclaim code by default in + DQA mode (currently it is implicitly used by default for all queues + except the reserved BSS queue). + +Fixes: cf961e16620f ("iwlwifi: mvm: support dqa-mode agg on non-shared queue") +Signed-off-by: Sara Sharon <sara.sharon@intel.com> +Signed-off-by: Luca Coelho <luciano.coelho@intel.com> + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +index 4ba639eda7a3..1d147599cca9 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -1274,8 +1274,6 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, + + memset(&info->status, 0, sizeof(info->status)); + +- info->flags &= ~IEEE80211_TX_CTL_AMPDU; +- + /* inform mac80211 about what happened with the frame */ + switch (status & TX_STATUS_MSK) { + case TX_STATUS_SUCCESS: +@@ -1298,10 +1296,11 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, + (void *)(uintptr_t)le32_to_cpu(tx_resp->initial_rate); + + /* Single frame failure in an AMPDU queue => send BAR */ +- if (txq_id >= mvm->first_agg_queue && ++ if (info->flags & IEEE80211_TX_CTL_AMPDU && + !(info->flags & IEEE80211_TX_STAT_ACK) && + !(info->flags & IEEE80211_TX_STAT_TX_FILTERED)) + info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; ++ info->flags &= ~IEEE80211_TX_CTL_AMPDU; + + /* W/A FW bug: seq_ctl is wrong when the status isn't success */ + if (status != TX_STATUS_SUCCESS) { +@@ -1336,7 +1335,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, + ieee80211_tx_status(mvm->hw, skb); + } + +- if (txq_id >= mvm->first_agg_queue) { ++ if (iwl_mvm_is_dqa_supported(mvm) || txq_id >= mvm->first_agg_queue) { + /* If this is an aggregation queue, we use the ssn since: + * ssn = wifi seq_num % 256. + * The seq_ctl is the sequence control of the packet to which +-- +2.12.0 + diff --git a/queue/iwlwifi-mvm-fix-reorder-timer-re-arming.patch b/queue/iwlwifi-mvm-fix-reorder-timer-re-arming.patch new file mode 100644 index 0000000..e787124 --- /dev/null +++ b/queue/iwlwifi-mvm-fix-reorder-timer-re-arming.patch @@ -0,0 +1,40 @@ +From 5351f9ab254c30d41659924265f1ecd7b4758d9e Mon Sep 17 00:00:00 2001 +From: Sara Sharon <sara.sharon@intel.com> +Date: Tue, 3 Jan 2017 21:03:35 +0200 +Subject: [PATCH] iwlwifi: mvm: fix reorder timer re-arming + +commit 5351f9ab254c30d41659924265f1ecd7b4758d9e upstream. + +When NSSN is behind the reorder buffer due to timeout +the reorder timer isn't getting re-armed until NSSN +catches up. Fix it. + +Fixes: 0690405fef29 ("iwlwifi: mvm: add reorder timeout per frame") + +Signed-off-by: Sara Sharon <sara.sharon@intel.com> +Signed-off-by: Luca Coelho <luciano.coelho@intel.com> + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +index c154ab42c80d..d79e9c2a2654 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +@@ -418,7 +418,7 @@ static void iwl_mvm_release_frames(struct iwl_mvm *mvm, + + /* ignore nssn smaller than head sn - this can happen due to timeout */ + if (iwl_mvm_is_sn_less(nssn, ssn, reorder_buf->buf_size)) +- return; ++ goto set_timer; + + while (iwl_mvm_is_sn_less(ssn, nssn, reorder_buf->buf_size)) { + int index = ssn % reorder_buf->buf_size; +@@ -441,6 +441,7 @@ static void iwl_mvm_release_frames(struct iwl_mvm *mvm, + } + reorder_buf->head_sn = nssn; + ++set_timer: + if (reorder_buf->num_stored && !reorder_buf->removed) { + u16 index = reorder_buf->head_sn % reorder_buf->buf_size; + +-- +2.12.0 + diff --git a/queue/iwlwifi-mvm-overwrite-skb-info-later.patch b/queue/iwlwifi-mvm-overwrite-skb-info-later.patch new file mode 100644 index 0000000..3c1ee23 --- /dev/null +++ b/queue/iwlwifi-mvm-overwrite-skb-info-later.patch @@ -0,0 +1,86 @@ +From bd05a5bd6b11d7fd26a668de83c5cb996de05f8f Mon Sep 17 00:00:00 2001 +From: Johannes Berg <johannes.berg@intel.com> +Date: Fri, 2 Dec 2016 09:57:40 +0100 +Subject: [PATCH] iwlwifi: mvm: overwrite skb info later + +commit bd05a5bd6b11d7fd26a668de83c5cb996de05f8f upstream. + +We don't really need clear the skb's status area nor store the +dev_cmd into it until we really commit to the frame by handing +it to the transport - defer those operations until just before +we do that. + +This doesn't entirely fix the bug with frames not getting sent +out after having been deferred due to DQA, because it doesn't +restore the info->driver_data[0] place that was already set to +zero (or another value) by the A-MSDU logic. + +Fixes: 24afba7690e4 ("iwlwifi: mvm: support bss dynamic alloc/dealloc of queues") +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +Signed-off-by: Luca Coelho <luciano.coelho@intel.com> + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +index e2f82c10b019..0dcf0ebab45d 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -466,7 +466,6 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, + struct ieee80211_sta *sta, u8 sta_id) + { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; +- struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb); + struct iwl_device_cmd *dev_cmd; + struct iwl_tx_cmd *tx_cmd; + +@@ -486,12 +485,18 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, + + iwl_mvm_set_tx_cmd_rate(mvm, tx_cmd, info, sta, hdr->frame_control); + ++ return dev_cmd; ++} ++ ++static void iwl_mvm_skb_prepare_status(struct sk_buff *skb, ++ struct iwl_device_cmd *cmd) ++{ ++ struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb); ++ + memset(&skb_info->status, 0, sizeof(skb_info->status)); + memset(skb_info->driver_data, 0, sizeof(skb_info->driver_data)); + +- skb_info->driver_data[1] = dev_cmd; +- +- return dev_cmd; ++ skb_info->driver_data[1] = cmd; + } + + static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm, +@@ -607,6 +612,9 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) + if (!dev_cmd) + return -1; + ++ /* From now on, we cannot access info->control */ ++ iwl_mvm_skb_prepare_status(skb, dev_cmd); ++ + tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload; + + /* Copy MAC header from skb into command buffer */ +@@ -917,7 +925,6 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, + goto drop; + + tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload; +- /* From now on, we cannot access info->control */ + + /* + * we handle that entirely ourselves -- for uAPSD the firmware +@@ -1024,6 +1031,9 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, + IWL_DEBUG_TX(mvm, "TX to [%d|%d] Q:%d - seq: 0x%x\n", mvmsta->sta_id, + tid, txq_id, IEEE80211_SEQ_TO_SN(seq_number)); + ++ /* From now on, we cannot access info->control */ ++ iwl_mvm_skb_prepare_status(skb, dev_cmd); ++ + if (iwl_trans_tx(mvm->trans, skb, dev_cmd, txq_id)) + goto drop_unlock_sta; + +-- +2.12.0 + diff --git a/queue/iwlwifi-mvm-pcie-adjust-A-MSDU-tx_cmd-length-in-PCIe.patch b/queue/iwlwifi-mvm-pcie-adjust-A-MSDU-tx_cmd-length-in-PCIe.patch new file mode 100644 index 0000000..7c9d426 --- /dev/null +++ b/queue/iwlwifi-mvm-pcie-adjust-A-MSDU-tx_cmd-length-in-PCIe.patch @@ -0,0 +1,198 @@ +From 05e5a7e58d3f8f597ebe6f78aaa13a2656b78239 Mon Sep 17 00:00:00 2001 +From: Johannes Berg <johannes.berg@intel.com> +Date: Fri, 2 Dec 2016 10:04:49 +0100 +Subject: [PATCH] iwlwifi: mvm/pcie: adjust A-MSDU tx_cmd length in PCIe + +commit 05e5a7e58d3f8f597ebe6f78aaa13a2656b78239 upstream. + +Instead of setting the tx_cmd length in the mvm code, which is +complicated by the fact that DQA may want to temporarily store +the SKB on the side, adjust the length in the PCIe code which +also knows about this since it's responsible for duplicating +all those headers that are account for in this code. + +As the PCIe code already relies on the tx_cmd->len field, this +doesn't really introduce any new dependencies. + +To make this possible we need to move the memcpy() of the TX +command until after it was updated. + +This does even simplify the code though, since the PCIe code +already does a lot of manipulations to build A-MSDUs correctly +and changing the length becomes a simple operation to see how +much was added/removed, rather than predicting it. + +Fixes: 24afba7690e4 ("iwlwifi: mvm: support bss dynamic alloc/dealloc of queues") +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +Signed-off-by: Luca Coelho <luciano.coelho@intel.com> + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +index 0dcf0ebab45d..8daf4fbe4534 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -202,7 +202,6 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, + struct iwl_tx_cmd *tx_cmd, + struct ieee80211_tx_info *info, u8 sta_id) + { +- struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (void *)skb->data; + __le16 fc = hdr->frame_control; + u32 tx_flags = le32_to_cpu(tx_cmd->tx_flags); +@@ -284,9 +283,8 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, + tx_flags |= TX_CMD_FLG_WRITE_TX_POWER; + + tx_cmd->tx_flags = cpu_to_le32(tx_flags); +- /* Total # bytes to be transmitted */ +- tx_cmd->len = cpu_to_le16((u16)skb->len + +- (uintptr_t)skb_info->driver_data[0]); ++ /* Total # bytes to be transmitted - PCIe code will adjust for A-MSDU */ ++ tx_cmd->len = cpu_to_le16((u16)skb->len); + tx_cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); + tx_cmd->sta_id = sta_id; + +@@ -562,9 +560,6 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) + info.hw_queue != info.control.vif->cab_queue))) + return -1; + +- /* This holds the amsdu headers length */ +- skb_info->driver_data[0] = (void *)(uintptr_t)0; +- + queue = info.hw_queue; + + /* +@@ -651,7 +646,7 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, + unsigned int num_subframes, tcp_payload_len, subf_len, max_amsdu_len; + bool ipv4 = (skb->protocol == htons(ETH_P_IP)); + u16 ip_base_id = ipv4 ? ntohs(ip_hdr(skb)->id) : 0; +- u16 amsdu_add, snap_ip_tcp, pad, i = 0; ++ u16 snap_ip_tcp, pad, i = 0; + unsigned int dbg_max_amsdu_len; + netdev_features_t netdev_features = NETIF_F_CSUM_MASK | NETIF_F_SG; + u8 *qc, tid, txf; +@@ -753,21 +748,6 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, + + /* This skb fits in one single A-MSDU */ + if (num_subframes * mss >= tcp_payload_len) { +- struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb); +- +- /* +- * Compute the length of all the data added for the A-MSDU. +- * This will be used to compute the length to write in the TX +- * command. We have: SNAP + IP + TCP for n -1 subframes and +- * ETH header for n subframes. Note that the original skb +- * already had one set of SNAP / IP / TCP headers. +- */ +- num_subframes = DIV_ROUND_UP(tcp_payload_len, mss); +- amsdu_add = num_subframes * sizeof(struct ethhdr) + +- (num_subframes - 1) * (snap_ip_tcp + pad); +- /* This holds the amsdu headers length */ +- skb_info->driver_data[0] = (void *)(uintptr_t)amsdu_add; +- + __skb_queue_tail(mpdus_skb, skb); + return 0; + } +@@ -806,14 +786,6 @@ segment: + ip_hdr(tmp)->id = htons(ip_base_id + i * num_subframes); + + if (tcp_payload_len > mss) { +- struct ieee80211_tx_info *skb_info = +- IEEE80211_SKB_CB(tmp); +- +- num_subframes = DIV_ROUND_UP(tcp_payload_len, mss); +- amsdu_add = num_subframes * sizeof(struct ethhdr) + +- (num_subframes - 1) * (snap_ip_tcp + pad); +- skb_info->driver_data[0] = +- (void *)(uintptr_t)amsdu_add; + skb_shinfo(tmp)->gso_size = mss; + } else { + qc = ieee80211_get_qos_ctl((void *)tmp->data); +@@ -1059,7 +1031,6 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, + struct ieee80211_sta *sta) + { + struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); +- struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb); + struct ieee80211_tx_info info; + struct sk_buff_head mpdus_skbs; + unsigned int payload_len; +@@ -1073,9 +1044,6 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, + + memcpy(&info, skb->cb, sizeof(info)); + +- /* This holds the amsdu headers length */ +- skb_info->driver_data[0] = (void *)(uintptr_t)0; +- + if (!skb_is_gso(skb)) + return iwl_mvm_tx_mpdu(mvm, skb, &info, sta); + +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +index e44e5adc2b95..911cf9868107 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +@@ -2096,6 +2096,7 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, + struct iwl_cmd_meta *out_meta, + struct iwl_device_cmd *dev_cmd, u16 tb1_len) + { ++ struct iwl_tx_cmd *tx_cmd = (void *)dev_cmd->payload; + struct iwl_trans_pcie *trans_pcie = txq->trans_pcie; + struct ieee80211_hdr *hdr = (void *)skb->data; + unsigned int snap_ip_tcp_hdrlen, ip_hdrlen, total_len, hdr_room; +@@ -2145,6 +2146,13 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, + */ + skb_pull(skb, hdr_len + iv_len); + ++ /* ++ * Remove the length of all the headers that we don't actually ++ * have in the MPDU by themselves, but that we duplicate into ++ * all the different MSDUs inside the A-MSDU. ++ */ ++ le16_add_cpu(&tx_cmd->len, -snap_ip_tcp_hdrlen); ++ + tso_start(skb, &tso); + + while (total_len) { +@@ -2155,7 +2163,7 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, + unsigned int hdr_tb_len; + dma_addr_t hdr_tb_phys; + struct tcphdr *tcph; +- u8 *iph; ++ u8 *iph, *subf_hdrs_start = hdr_page->pos; + + total_len -= data_left; + +@@ -2216,6 +2224,8 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, + hdr_tb_len, false); + trace_iwlwifi_dev_tx_tso_chunk(trans->dev, start_hdr, + hdr_tb_len); ++ /* add this subframe's headers' length to the tx_cmd */ ++ le16_add_cpu(&tx_cmd->len, hdr_page->pos - subf_hdrs_start); + + /* prepare the start_hdr for the next subframe */ + start_hdr = hdr_page->pos; +@@ -2408,9 +2418,10 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, + tb1_len = len; + } + +- /* The first TB points to bi-directional DMA data */ +- memcpy(&txq->first_tb_bufs[txq->write_ptr], &dev_cmd->hdr, +- IWL_FIRST_TB_SIZE); ++ /* ++ * The first TB points to bi-directional DMA data, we'll ++ * memcpy the data into it later. ++ */ + iwl_pcie_txq_build_tfd(trans, txq, tb0_phys, + IWL_FIRST_TB_SIZE, true); + +@@ -2434,6 +2445,10 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, + goto out_err; + } + ++ /* building the A-MSDU might have changed this data, so memcpy it now */ ++ memcpy(&txq->first_tb_bufs[txq->write_ptr], &dev_cmd->hdr, ++ IWL_FIRST_TB_SIZE); ++ + tfd = iwl_pcie_get_tfd(trans_pcie, txq, txq->write_ptr); + /* Set up entry for this TFD in Tx byte-count array */ + iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len), +-- +2.12.0 + diff --git a/queue/iwlwifi-mvm-synchronize-firmware-DMA-paging-memory.patch b/queue/iwlwifi-mvm-synchronize-firmware-DMA-paging-memory.patch new file mode 100644 index 0000000..76b5f55 --- /dev/null +++ b/queue/iwlwifi-mvm-synchronize-firmware-DMA-paging-memory.patch @@ -0,0 +1,95 @@ +From 4b70f07686d75d1eb5d956812cc810944e0b29b2 Mon Sep 17 00:00:00 2001 +From: Sara Sharon <sara.sharon@intel.com> +Date: Wed, 30 Nov 2016 16:49:11 +0200 +Subject: [PATCH] iwlwifi: mvm: synchronize firmware DMA paging memory + +commit 4b70f07686d75d1eb5d956812cc810944e0b29b2 upstream. + +When driver needs to access the contents of a streaming DMA buffer +without unmapping it it should call dma_sync_single_for_cpu(). +Once the call has been made, the CPU "owns" the DMA buffer and can +work with it as needed. +Before the device accesses the buffer, however, ownership should be +transferred back to it with dma_sync_single_for_device(). +Both calls weren't performed by the driver, resulting with odd paging +errors on some platforms. Fix it. + +Fixes: a6c4fb4441f4 ("iwlwifi: mvm: Add FW paging mechanism for the UMAC on PCI") +Signed-off-by: Sara Sharon <sara.sharon@intel.com> +Signed-off-by: Luca Coelho <luciano.coelho@intel.com> + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c +index e7b3b712d778..a027b11bbdb3 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c +@@ -811,12 +811,16 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) + struct iwl_fw_error_dump_paging *paging; + struct page *pages = + mvm->fw_paging_db[i].fw_paging_block; ++ dma_addr_t addr = mvm->fw_paging_db[i].fw_paging_phys; + + dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PAGING); + dump_data->len = cpu_to_le32(sizeof(*paging) + + PAGING_BLOCK_SIZE); + paging = (void *)dump_data->data; + paging->index = cpu_to_le32(i); ++ dma_sync_single_for_cpu(mvm->trans->dev, addr, ++ PAGING_BLOCK_SIZE, ++ DMA_BIDIRECTIONAL); + memcpy(paging->data, page_address(pages), + PAGING_BLOCK_SIZE); + dump_data = iwl_fw_error_next_data(dump_data); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +index 8fd3c2b12ea2..c42ef8681b75 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +@@ -214,6 +214,10 @@ static int iwl_fill_paging_mem(struct iwl_mvm *mvm, const struct fw_img *image) + memcpy(page_address(mvm->fw_paging_db[0].fw_paging_block), + image->sec[sec_idx].data, + mvm->fw_paging_db[0].fw_paging_size); ++ dma_sync_single_for_device(mvm->trans->dev, ++ mvm->fw_paging_db[0].fw_paging_phys, ++ mvm->fw_paging_db[0].fw_paging_size, ++ DMA_BIDIRECTIONAL); + + IWL_DEBUG_FW(mvm, + "Paging: copied %d CSS bytes to first block\n", +@@ -228,9 +232,16 @@ static int iwl_fill_paging_mem(struct iwl_mvm *mvm, const struct fw_img *image) + * loop stop at num_of_paging_blk since that last block is not full. + */ + for (idx = 1; idx < mvm->num_of_paging_blk; idx++) { +- memcpy(page_address(mvm->fw_paging_db[idx].fw_paging_block), ++ struct iwl_fw_paging *block = &mvm->fw_paging_db[idx]; ++ ++ memcpy(page_address(block->fw_paging_block), + image->sec[sec_idx].data + offset, +- mvm->fw_paging_db[idx].fw_paging_size); ++ block->fw_paging_size); ++ dma_sync_single_for_device(mvm->trans->dev, ++ block->fw_paging_phys, ++ block->fw_paging_size, ++ DMA_BIDIRECTIONAL); ++ + + IWL_DEBUG_FW(mvm, + "Paging: copied %d paging bytes to block %d\n", +@@ -242,9 +253,15 @@ static int iwl_fill_paging_mem(struct iwl_mvm *mvm, const struct fw_img *image) + + /* copy the last paging block */ + if (mvm->num_of_pages_in_last_blk > 0) { +- memcpy(page_address(mvm->fw_paging_db[idx].fw_paging_block), ++ struct iwl_fw_paging *block = &mvm->fw_paging_db[idx]; ++ ++ memcpy(page_address(block->fw_paging_block), + image->sec[sec_idx].data + offset, + FW_PAGING_SIZE * mvm->num_of_pages_in_last_blk); ++ dma_sync_single_for_device(mvm->trans->dev, ++ block->fw_paging_phys, ++ block->fw_paging_size, ++ DMA_BIDIRECTIONAL); + + IWL_DEBUG_FW(mvm, + "Paging: copied %d pages in the last block %d\n", +-- +2.12.0 + diff --git a/queue/iwlwifi-mvm-writing-zero-bytes-to-debugfs-causes-a-c.patch b/queue/iwlwifi-mvm-writing-zero-bytes-to-debugfs-causes-a-c.patch new file mode 100644 index 0000000..72122e5 --- /dev/null +++ b/queue/iwlwifi-mvm-writing-zero-bytes-to-debugfs-causes-a-c.patch @@ -0,0 +1,35 @@ +From 251fe09f13bfb54c1ede66ee8bf8ddd0061c4f7c Mon Sep 17 00:00:00 2001 +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Thu, 23 Mar 2017 13:40:00 +0300 +Subject: [PATCH] iwlwifi: mvm: writing zero bytes to debugfs causes a crash + +commit 251fe09f13bfb54c1ede66ee8bf8ddd0061c4f7c upstream. + +This is a static analysis fix. The warning is: + + drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c:912 iwl_mvm_fw_dbg_collect() + warn: integer overflows 'sizeof(*desc) + len' + +I guess this code is supposed to take a NUL character, but if we write +zero bytes then it tries to write -1 characters and crashes. + +Fixes: c91b865cb14d ("iwlwifi: mvm: support description for user triggered fw dbg collection") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Luca Coelho <luciano.coelho@intel.com> + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +index a260cd503200..077bfd8f4c0c 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +@@ -1056,6 +1056,8 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm, + + if (ret) + return ret; ++ if (count == 0) ++ return 0; + + iwl_mvm_fw_dbg_collect(mvm, FW_DBG_TRIGGER_USER, buf, + (count - 1), NULL); +-- +2.12.0 + diff --git a/queue/iwlwifi-pcie-don-t-increment-decrement-a-bool.patch b/queue/iwlwifi-pcie-don-t-increment-decrement-a-bool.patch new file mode 100644 index 0000000..8e109bf --- /dev/null +++ b/queue/iwlwifi-pcie-don-t-increment-decrement-a-bool.patch @@ -0,0 +1,33 @@ +From 04fa3e680b4dd2fdd11d0152fb9b6067e7aac140 Mon Sep 17 00:00:00 2001 +From: Emmanuel Grumbach <emmanuel.grumbach@intel.com> +Date: Sat, 7 Jan 2017 20:11:47 +0200 +Subject: [PATCH] iwlwifi: pcie: don't increment / decrement a bool + +commit 04fa3e680b4dd2fdd11d0152fb9b6067e7aac140 upstream. + +David reported that the code I added uses the decrement +and increment operator on a boolean variable. + +Fix that. + +Fixes: 0cd58eaab148 ("iwlwifi: pcie: allow the op_mode to block the tx queues") +Reported-by: David Binderman <dcb314@hotmail.com> +Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> +Signed-off-by: Luca Coelho <luciano.coelho@intel.com> + +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +index cf5bda06042c..10937309641a 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +@@ -279,7 +279,7 @@ struct iwl_txq { + bool frozen; + u8 active; + bool ampdu; +- bool block; ++ int block; + unsigned long wd_timeout; + struct sk_buff_head overflow_q; + +-- +2.12.0 + diff --git a/queue/iwlwifi-pcie-fix-the-set-of-DMA-memory-mask.patch b/queue/iwlwifi-pcie-fix-the-set-of-DMA-memory-mask.patch new file mode 100644 index 0000000..e3ad1c1 --- /dev/null +++ b/queue/iwlwifi-pcie-fix-the-set-of-DMA-memory-mask.patch @@ -0,0 +1,43 @@ +From 2c6262b754f3c3338cb40b23880a3ac1f4693b25 Mon Sep 17 00:00:00 2001 +From: Sara Sharon <sara.sharon@intel.com> +Date: Wed, 7 Dec 2016 12:22:11 +0200 +Subject: [PATCH] iwlwifi: pcie: fix the set of DMA memory mask + +commit 2c6262b754f3c3338cb40b23880a3ac1f4693b25 upstream. + +Our 9000 device supports 64 bit DMA address for RX only, and +not for TX. +Setting DMA mask to 64 for the whole device is erroneous - we +can do it only for a000 devices where device is capable of +both RX & TX DMA with 64 bit address space. + +Fixes: 96a6497bc3ed ("iwlwifi: pcie: add 9000 series multi queue rx DMA support") +Signed-off-by: Sara Sharon <sara.sharon@intel.com> +Signed-off-by: Luca Coelho <luciano.coelho@intel.com> + +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +index c1d99d15796d..b28d99f61a35 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +@@ -2953,16 +2953,12 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, + PCIE_LINK_STATE_CLKPM); + } + +- if (cfg->mq_rx_supported) +- addr_size = 64; +- else +- addr_size = 36; +- + if (cfg->use_tfh) { ++ addr_size = 64; + trans_pcie->max_tbs = IWL_TFH_NUM_TBS; + trans_pcie->tfd_size = sizeof(struct iwl_tfh_tfd); +- + } else { ++ addr_size = 36; + trans_pcie->max_tbs = IWL_NUM_OF_TBS; + trans_pcie->tfd_size = sizeof(struct iwl_tfd); + } +-- +2.12.0 + diff --git a/queue/iwlwifi-pcie-trans-Remove-unused-shift_param.patch b/queue/iwlwifi-pcie-trans-Remove-unused-shift_param.patch new file mode 100644 index 0000000..b508ca3 --- /dev/null +++ b/queue/iwlwifi-pcie-trans-Remove-unused-shift_param.patch @@ -0,0 +1,59 @@ +From 3ce4a03852d6dd3fd28c2fb2ee9f89bb9ccf9a9b Mon Sep 17 00:00:00 2001 +From: Kirtika Ruchandani <kirtika.ruchandani@gmail.com> +Date: Tue, 8 Nov 2016 21:50:48 -0800 +Subject: [PATCH] iwlwifi: pcie: trans: Remove unused 'shift_param' +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 3ce4a03852d6dd3fd28c2fb2ee9f89bb9ccf9a9b upstream. + +shift_param is defined and set in iwl_pcie_load_cpu_sections but not +used. Fix this to avoid -Wunused-but-set-variable warning. + +The code using it turned into dead code with commit dcab8ecd5617 +("iwlwifi: mvm: support ucode load for family_8000 B0 only") which +added a separate function iwl_pcie_load_given_ucode_8000 (then 8000b) +for IWL_DEVICE_FAMILY_8000. Commit 76f8c0e17edc ("iwlwifi: pcie: +remove dead code") removed the dead code but left shift_param as is. + +iwlwifi/pcie/trans.c: In function ‘iwl_pcie_load_cpu_sections’: +iwlwifi/pcie/trans.c:871:6: warning: variable ‘shift_param’ set but not used [-Wunused-but-set-variable] + +Fixes: dcab8ecd5617 ("iwlwifi: mvm: support ucode load for family_8000 B0 only") +Fixes: 76f8c0e17edc ("iwlwifi: pcie: remove dead code") +Signed-off-by: Kirtika Ruchandani <kirtika@google.com> +Cc: Sara Sharon <sara.sharon@intel.com> +Cc: Luca Coelho <luciano.coelho@intel.com> +Cc: Liad Kaufman <liad.kaufman@intel.com> +Cc: Emmanuel Grumbach <emmanuel.grumbach@intel.com> +[removed some unnecessary braces] +Signed-off-by: Luca Coelho <luciano.coelho@intel.com> + +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +index bf0ecdcf7402..16790db650c1 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +@@ -868,17 +868,13 @@ static int iwl_pcie_load_cpu_sections(struct iwl_trans *trans, + int cpu, + int *first_ucode_section) + { +- int shift_param; + int i, ret = 0; + u32 last_read_idx = 0; + +- if (cpu == 1) { +- shift_param = 0; ++ if (cpu == 1) + *first_ucode_section = 0; +- } else { +- shift_param = 16; ++ else + (*first_ucode_section)++; +- } + + for (i = *first_ucode_section; i < image->num_sec; i++) { + last_read_idx = i; +-- +2.12.0 + diff --git a/queue/kcm-return-immediately-after-copy_from_user-failure.patch b/queue/kcm-return-immediately-after-copy_from_user-failure.patch new file mode 100644 index 0000000..a9a5897 --- /dev/null +++ b/queue/kcm-return-immediately-after-copy_from_user-failure.patch @@ -0,0 +1,49 @@ +From a80db69e47d764bbcaf2fec54b1f308925e7c490 Mon Sep 17 00:00:00 2001 +From: WANG Cong <xiyou.wangcong@gmail.com> +Date: Thu, 23 Mar 2017 11:03:31 -0700 +Subject: [PATCH] kcm: return immediately after copy_from_user() failure + +commit a80db69e47d764bbcaf2fec54b1f308925e7c490 upstream. + +There is no reason to continue after a copy_from_user() +failure. + +Fixes: ab7ac4eb9832 ("kcm: Kernel Connection Multiplexor module") +Cc: Tom Herbert <tom@herbertland.com> +Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c +index 309062f3debe..31762f76cdb5 100644 +--- a/net/kcm/kcmsock.c ++++ b/net/kcm/kcmsock.c +@@ -1687,7 +1687,7 @@ static int kcm_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) + struct kcm_attach info; + + if (copy_from_user(&info, (void __user *)arg, sizeof(info))) +- err = -EFAULT; ++ return -EFAULT; + + err = kcm_attach_ioctl(sock, &info); + +@@ -1697,7 +1697,7 @@ static int kcm_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) + struct kcm_unattach info; + + if (copy_from_user(&info, (void __user *)arg, sizeof(info))) +- err = -EFAULT; ++ return -EFAULT; + + err = kcm_unattach_ioctl(sock, &info); + +@@ -1708,7 +1708,7 @@ static int kcm_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) + struct socket *newsock = NULL; + + if (copy_from_user(&info, (void __user *)arg, sizeof(info))) +- err = -EFAULT; ++ return -EFAULT; + + err = kcm_clone(sock, &info, &newsock); + +-- +2.12.0 + diff --git a/queue/kprobes-x86-Fix-kernel-panic-when-certain-exception-.patch b/queue/kprobes-x86-Fix-kernel-panic-when-certain-exception-.patch new file mode 100644 index 0000000..8a74c1b --- /dev/null +++ b/queue/kprobes-x86-Fix-kernel-panic-when-certain-exception-.patch @@ -0,0 +1,88 @@ +From 75013fb16f8484898eaa8d0b08fed942d790f029 Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu <mhiramat@kernel.org> +Date: Wed, 1 Mar 2017 01:23:24 +0900 +Subject: [PATCH] kprobes/x86: Fix kernel panic when certain exception-handling + addresses are probed + +commit 75013fb16f8484898eaa8d0b08fed942d790f029 upstream. + +Fix to the exception table entry check by using probed address +instead of the address of copied instruction. + +This bug may cause unexpected kernel panic if user probe an address +where an exception can happen which should be fixup by __ex_table +(e.g. copy_from_user.) + +Unless user puts a kprobe on such address, this doesn't +cause any problem. + +This bug has been introduced years ago, by commit: + + 464846888d9a ("x86/kprobes: Fix a bug which can modify kernel code permanently"). + +Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> +Cc: Borislav Petkov <bp@alien8.de> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Fixes: 464846888d9a ("x86/kprobes: Fix a bug which can modify kernel code permanently") +Link: http://lkml.kernel.org/r/148829899399.28855.12581062400757221722.stgit@devbox +Signed-off-by: Ingo Molnar <mingo@kernel.org> + +diff --git a/arch/x86/kernel/kprobes/common.h b/arch/x86/kernel/kprobes/common.h +index c6ee63f927ab..d688826e5736 100644 +--- a/arch/x86/kernel/kprobes/common.h ++++ b/arch/x86/kernel/kprobes/common.h +@@ -67,7 +67,7 @@ + #endif + + /* Ensure if the instruction can be boostable */ +-extern int can_boost(kprobe_opcode_t *instruction); ++extern int can_boost(kprobe_opcode_t *instruction, void *addr); + /* Recover instruction if given address is probed */ + extern unsigned long recover_probed_instruction(kprobe_opcode_t *buf, + unsigned long addr); +diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c +index 520b8dfe1640..88b3c942473d 100644 +--- a/arch/x86/kernel/kprobes/core.c ++++ b/arch/x86/kernel/kprobes/core.c +@@ -166,12 +166,12 @@ NOKPROBE_SYMBOL(skip_prefixes); + * Returns non-zero if opcode is boostable. + * RIP relative instructions are adjusted at copying time in 64 bits mode + */ +-int can_boost(kprobe_opcode_t *opcodes) ++int can_boost(kprobe_opcode_t *opcodes, void *addr) + { + kprobe_opcode_t opcode; + kprobe_opcode_t *orig_opcodes = opcodes; + +- if (search_exception_tables((unsigned long)opcodes)) ++ if (search_exception_tables((unsigned long)addr)) + return 0; /* Page fault may occur on this address. */ + + retry: +@@ -416,7 +416,7 @@ static int arch_copy_kprobe(struct kprobe *p) + * __copy_instruction can modify the displacement of the instruction, + * but it doesn't affect boostable check. + */ +- if (can_boost(p->ainsn.insn)) ++ if (can_boost(p->ainsn.insn, p->addr)) + p->ainsn.boostable = 0; + else + p->ainsn.boostable = -1; +diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c +index 3d1bee9d6a72..3e7c6e5a08ff 100644 +--- a/arch/x86/kernel/kprobes/opt.c ++++ b/arch/x86/kernel/kprobes/opt.c +@@ -178,7 +178,7 @@ static int copy_optimized_instructions(u8 *dest, u8 *src) + + while (len < RELATIVEJUMP_SIZE) { + ret = __copy_instruction(dest + len, src + len); +- if (!ret || !can_boost(dest + len)) ++ if (!ret || !can_boost(dest + len, src + len)) + return -EINVAL; + len += ret; + } +-- +2.12.0 + diff --git a/queue/l2tp-fix-PPP-pseudo-wire-auto-loading.patch b/queue/l2tp-fix-PPP-pseudo-wire-auto-loading.patch new file mode 100644 index 0000000..ef2424d --- /dev/null +++ b/queue/l2tp-fix-PPP-pseudo-wire-auto-loading.patch @@ -0,0 +1,26 @@ +From 249ee819e24c180909f43c1173c8ef6724d21faf Mon Sep 17 00:00:00 2001 +From: Guillaume Nault <g.nault@alphalink.fr> +Date: Mon, 3 Apr 2017 13:23:15 +0200 +Subject: [PATCH] l2tp: fix PPP pseudo-wire auto-loading + +commit 249ee819e24c180909f43c1173c8ef6724d21faf upstream. + +PPP pseudo-wire type is 7 (11 is L2TP_PWTYPE_IP). + +Fixes: f1f39f911027 ("l2tp: auto load type modules") +Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c +index 7bf73091baa2..861b255a2d51 100644 +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -1853,4 +1853,4 @@ MODULE_DESCRIPTION("PPP over L2TP over UDP"); + MODULE_LICENSE("GPL"); + MODULE_VERSION(PPPOL2TP_DRV_VERSION); + MODULE_ALIAS_NET_PF_PROTO(PF_PPPOX, PX_PROTO_OL2TP); +-MODULE_ALIAS_L2TP_PWTYPE(11); ++MODULE_ALIAS_L2TP_PWTYPE(7); +-- +2.12.0 + diff --git a/queue/l2tp-hold-tunnel-socket-when-handling-control-frames.patch b/queue/l2tp-hold-tunnel-socket-when-handling-control-frames.patch new file mode 100644 index 0000000..a30816b --- /dev/null +++ b/queue/l2tp-hold-tunnel-socket-when-handling-control-frames.patch @@ -0,0 +1,55 @@ +From 94d7ee0baa8b764cf64ad91ed69464c1a6a0066b Mon Sep 17 00:00:00 2001 +From: Guillaume Nault <g.nault@alphalink.fr> +Date: Wed, 29 Mar 2017 08:44:59 +0200 +Subject: [PATCH] l2tp: hold tunnel socket when handling control frames in + l2tp_ip and l2tp_ip6 + +commit 94d7ee0baa8b764cf64ad91ed69464c1a6a0066b upstream. + +The code following l2tp_tunnel_find() expects that a new reference is +held on sk. Either sk_receive_skb() or the discard_put error path will +drop a reference from the tunnel's socket. + +This issue exists in both l2tp_ip and l2tp_ip6. + +Fixes: a3c18422a4b4 ("l2tp: hold socket before dropping lock in l2tp_ip{, 6}_recv()") +Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c +index d25038cfd64e..7208fbe5856b 100644 +--- a/net/l2tp/l2tp_ip.c ++++ b/net/l2tp/l2tp_ip.c +@@ -178,9 +178,10 @@ pass_up: + + tunnel_id = ntohl(*(__be32 *) &skb->data[4]); + tunnel = l2tp_tunnel_find(net, tunnel_id); +- if (tunnel != NULL) ++ if (tunnel) { + sk = tunnel->sock; +- else { ++ sock_hold(sk); ++ } else { + struct iphdr *iph = (struct iphdr *) skb_network_header(skb); + + read_lock_bh(&l2tp_ip_lock); +diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c +index a4abcbc4c09a..516d7ce24ba7 100644 +--- a/net/l2tp/l2tp_ip6.c ++++ b/net/l2tp/l2tp_ip6.c +@@ -191,9 +191,10 @@ pass_up: + + tunnel_id = ntohl(*(__be32 *) &skb->data[4]); + tunnel = l2tp_tunnel_find(net, tunnel_id); +- if (tunnel != NULL) ++ if (tunnel) { + sk = tunnel->sock; +- else { ++ sock_hold(sk); ++ } else { + struct ipv6hdr *iph = ipv6_hdr(skb); + + read_lock_bh(&l2tp_ip6_lock); +-- +2.12.0 + diff --git a/queue/l2tp-purge-socket-queues-in-the-.destruct-callback.patch b/queue/l2tp-purge-socket-queues-in-the-.destruct-callback.patch new file mode 100644 index 0000000..839701e --- /dev/null +++ b/queue/l2tp-purge-socket-queues-in-the-.destruct-callback.patch @@ -0,0 +1,47 @@ +From e91793bb615cf6cdd59c0b6749fe173687bb0947 Mon Sep 17 00:00:00 2001 +From: Guillaume Nault <g.nault@alphalink.fr> +Date: Wed, 29 Mar 2017 08:45:29 +0200 +Subject: [PATCH] l2tp: purge socket queues in the .destruct() callback + +commit e91793bb615cf6cdd59c0b6749fe173687bb0947 upstream. + +The Rx path may grab the socket right before pppol2tp_release(), but +nothing guarantees that it will enqueue packets before +skb_queue_purge(). Therefore, the socket can be destroyed without its +queues fully purged. + +Fix this by purging queues in pppol2tp_session_destruct() where we're +guaranteed nothing is still referencing the socket. + +Fixes: 9e9cb6221aa7 ("l2tp: fix userspace reception on plain L2TP sockets") +Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c +index 36cc56fd0418..123b6a2411a0 100644 +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -450,6 +450,10 @@ static void pppol2tp_session_close(struct l2tp_session *session) + static void pppol2tp_session_destruct(struct sock *sk) + { + struct l2tp_session *session = sk->sk_user_data; ++ ++ skb_queue_purge(&sk->sk_receive_queue); ++ skb_queue_purge(&sk->sk_write_queue); ++ + if (session) { + sk->sk_user_data = NULL; + BUG_ON(session->magic != L2TP_SESSION_MAGIC); +@@ -488,9 +492,6 @@ static int pppol2tp_release(struct socket *sock) + l2tp_session_queue_purge(session); + sock_put(sk); + } +- skb_queue_purge(&sk->sk_receive_queue); +- skb_queue_purge(&sk->sk_write_queue); +- + release_sock(sk); + + /* This will delete the session context via +-- +2.12.0 + diff --git a/queue/l2tp-take-reference-on-sessions-being-dumped.patch b/queue/l2tp-take-reference-on-sessions-being-dumped.patch new file mode 100644 index 0000000..c95cfa7 --- /dev/null +++ b/queue/l2tp-take-reference-on-sessions-being-dumped.patch @@ -0,0 +1,161 @@ +From e08293a4ccbcc993ded0fdc46f1e57926b833d63 Mon Sep 17 00:00:00 2001 +From: Guillaume Nault <g.nault@alphalink.fr> +Date: Mon, 3 Apr 2017 12:03:13 +0200 +Subject: [PATCH] l2tp: take reference on sessions being dumped + +commit e08293a4ccbcc993ded0fdc46f1e57926b833d63 upstream. + +Take a reference on the sessions returned by l2tp_session_find_nth() +(and rename it l2tp_session_get_nth() to reflect this change), so that +caller is assured that the session isn't going to disappear while +processing it. + +For procfs and debugfs handlers, the session is held in the .start() +callback and dropped in .show(). Given that pppol2tp_seq_session_show() +dereferences the associated PPPoL2TP socket and that +l2tp_dfs_seq_session_show() might call pppol2tp_show(), we also need to +call the session's .ref() callback to prevent the socket from going +away from under us. + +Fixes: fd558d186df2 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts") +Fixes: 0ad6614048cf ("l2tp: Add debugfs files for dumping l2tp debug info") +Fixes: 309795f4bec2 ("l2tp: Add netlink control API for L2TP") +Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c +index e927422d8c58..e37d9554da7b 100644 +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -327,7 +327,8 @@ struct l2tp_session *l2tp_session_get(struct net *net, + } + EXPORT_SYMBOL_GPL(l2tp_session_get); + +-struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth) ++struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth, ++ bool do_ref) + { + int hash; + struct l2tp_session *session; +@@ -337,6 +338,9 @@ struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth) + for (hash = 0; hash < L2TP_HASH_SIZE; hash++) { + hlist_for_each_entry(session, &tunnel->session_hlist[hash], hlist) { + if (++count > nth) { ++ l2tp_session_inc_refcount(session); ++ if (do_ref && session->ref) ++ session->ref(session); + read_unlock_bh(&tunnel->hlist_lock); + return session; + } +@@ -347,7 +351,7 @@ struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth) + + return NULL; + } +-EXPORT_SYMBOL_GPL(l2tp_session_find_nth); ++EXPORT_SYMBOL_GPL(l2tp_session_get_nth); + + /* Lookup a session by interface name. + * This is very inefficient but is only used by management interfaces. +diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h +index 3b9b704a84e4..8ce7818c7a9d 100644 +--- a/net/l2tp/l2tp_core.h ++++ b/net/l2tp/l2tp_core.h +@@ -236,7 +236,8 @@ struct l2tp_session *l2tp_session_get(struct net *net, + struct l2tp_session *l2tp_session_find(struct net *net, + struct l2tp_tunnel *tunnel, + u32 session_id); +-struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth); ++struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth, ++ bool do_ref); + struct l2tp_session *l2tp_session_get_by_ifname(struct net *net, char *ifname, + bool do_ref); + struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id); +diff --git a/net/l2tp/l2tp_debugfs.c b/net/l2tp/l2tp_debugfs.c +index 2d6760a2ae34..d100aed3d06f 100644 +--- a/net/l2tp/l2tp_debugfs.c ++++ b/net/l2tp/l2tp_debugfs.c +@@ -53,7 +53,7 @@ static void l2tp_dfs_next_tunnel(struct l2tp_dfs_seq_data *pd) + + static void l2tp_dfs_next_session(struct l2tp_dfs_seq_data *pd) + { +- pd->session = l2tp_session_find_nth(pd->tunnel, pd->session_idx); ++ pd->session = l2tp_session_get_nth(pd->tunnel, pd->session_idx, true); + pd->session_idx++; + + if (pd->session == NULL) { +@@ -238,10 +238,14 @@ static int l2tp_dfs_seq_show(struct seq_file *m, void *v) + } + + /* Show the tunnel or session context */ +- if (pd->session == NULL) ++ if (!pd->session) { + l2tp_dfs_seq_tunnel_show(m, pd->tunnel); +- else ++ } else { + l2tp_dfs_seq_session_show(m, pd->session); ++ if (pd->session->deref) ++ pd->session->deref(pd->session); ++ l2tp_session_dec_refcount(pd->session); ++ } + + out: + return 0; +diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c +index 93e317377c66..7e3e669baac4 100644 +--- a/net/l2tp/l2tp_netlink.c ++++ b/net/l2tp/l2tp_netlink.c +@@ -867,7 +867,7 @@ static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callback + goto out; + } + +- session = l2tp_session_find_nth(tunnel, si); ++ session = l2tp_session_get_nth(tunnel, si, false); + if (session == NULL) { + ti++; + tunnel = NULL; +@@ -877,8 +877,11 @@ static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callback + + if (l2tp_nl_session_send(skb, NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, NLM_F_MULTI, +- session, L2TP_CMD_SESSION_GET) < 0) ++ session, L2TP_CMD_SESSION_GET) < 0) { ++ l2tp_session_dec_refcount(session); + break; ++ } ++ l2tp_session_dec_refcount(session); + + si++; + } +diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c +index 26501902d1a7..7bf73091baa2 100644 +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -1560,7 +1560,7 @@ static void pppol2tp_next_tunnel(struct net *net, struct pppol2tp_seq_data *pd) + + static void pppol2tp_next_session(struct net *net, struct pppol2tp_seq_data *pd) + { +- pd->session = l2tp_session_find_nth(pd->tunnel, pd->session_idx); ++ pd->session = l2tp_session_get_nth(pd->tunnel, pd->session_idx, true); + pd->session_idx++; + + if (pd->session == NULL) { +@@ -1687,10 +1687,14 @@ static int pppol2tp_seq_show(struct seq_file *m, void *v) + + /* Show the tunnel or session context. + */ +- if (pd->session == NULL) ++ if (!pd->session) { + pppol2tp_seq_tunnel_show(m, pd->tunnel); +- else ++ } else { + pppol2tp_seq_session_show(m, pd->session); ++ if (pd->session->deref) ++ pd->session->deref(pd->session); ++ l2tp_session_dec_refcount(pd->session); ++ } + + out: + return 0; +-- +2.12.0 + diff --git a/queue/leds-ktd2692-avoid-harmless-maybe-uninitialized-warn.patch b/queue/leds-ktd2692-avoid-harmless-maybe-uninitialized-warn.patch new file mode 100644 index 0000000..4defdae --- /dev/null +++ b/queue/leds-ktd2692-avoid-harmless-maybe-uninitialized-warn.patch @@ -0,0 +1,50 @@ +From cbe99c538d1776009e8710755bb6e726f7fffa9b Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann <arnd@arndb.de> +Date: Wed, 25 Jan 2017 23:22:36 +0100 +Subject: [PATCH] leds: ktd2692: avoid harmless maybe-uninitialized warning + +commit cbe99c538d1776009e8710755bb6e726f7fffa9b upstream. + +gcc gets confused about the control flow in ktd2692_parse_dt(), causing +it to warn about what seems like a potential bug: + +drivers/leds/leds-ktd2692.c: In function 'ktd2692_probe': +drivers/leds/leds-ktd2692.c:244:15: error: '*((void *)&led_cfg+8)' may be used uninitialized in this function [-Werror=maybe-uninitialized] +drivers/leds/leds-ktd2692.c:225:7: error: 'led_cfg.flash_max_microamp' may be used uninitialized in this function [-Werror=maybe-uninitialized] +drivers/leds/leds-ktd2692.c:232:3: error: 'led_cfg.movie_max_microamp' may be used uninitialized in this function [-Werror=maybe-uninitialized] + +The code is fine, and slightly reworking it in an equivalent way lets +gcc figure that out too, which gets rid of the warning. + +Fixes: 77e7915b15bb ("leds: ktd2692: Add missing of_node_put") +Signed-off-by: Arnd Bergmann <arnd@arndb.de> +Acked-by: Pavel Machek <pavel@ucw.cz> +Signed-off-by: Jacek Anaszewski <jacek.anaszewski@gmail.com> + +diff --git a/drivers/leds/leds-ktd2692.c b/drivers/leds/leds-ktd2692.c +index bf23ba191ad0..45296aaca9da 100644 +--- a/drivers/leds/leds-ktd2692.c ++++ b/drivers/leds/leds-ktd2692.c +@@ -270,15 +270,15 @@ static int ktd2692_parse_dt(struct ktd2692_context *led, struct device *dev, + return -ENXIO; + + led->ctrl_gpio = devm_gpiod_get(dev, "ctrl", GPIOD_ASIS); +- if (IS_ERR(led->ctrl_gpio)) { +- ret = PTR_ERR(led->ctrl_gpio); ++ ret = PTR_ERR_OR_ZERO(led->ctrl_gpio); ++ if (ret) { + dev_err(dev, "cannot get ctrl-gpios %d\n", ret); + return ret; + } + + led->aux_gpio = devm_gpiod_get(dev, "aux", GPIOD_ASIS); +- if (IS_ERR(led->aux_gpio)) { +- ret = PTR_ERR(led->aux_gpio); ++ ret = PTR_ERR_OR_ZERO(led->aux_gpio); ++ if (ret) { + dev_err(dev, "cannot get aux-gpios %d\n", ret); + return ret; + } +-- +2.12.0 + diff --git a/queue/libnvdimm-pfn-fix-npfns-vs-section-alignment.patch b/queue/libnvdimm-pfn-fix-npfns-vs-section-alignment.patch new file mode 100644 index 0000000..897f52e --- /dev/null +++ b/queue/libnvdimm-pfn-fix-npfns-vs-section-alignment.patch @@ -0,0 +1,67 @@ +From d5483feda85a8f39ee2e940e279547c686aac30c Mon Sep 17 00:00:00 2001 +From: Dan Williams <dan.j.williams@intel.com> +Date: Thu, 4 May 2017 19:54:42 -0700 +Subject: [PATCH] libnvdimm, pfn: fix 'npfns' vs section alignment + +commit d5483feda85a8f39ee2e940e279547c686aac30c upstream. + +Fix failures to create namespaces due to the vmem_altmap not advertising +enough free space to store the memmap. + + WARNING: CPU: 15 PID: 8022 at arch/x86/mm/init_64.c:656 arch_add_memory+0xde/0xf0 + [..] + Call Trace: + dump_stack+0x63/0x83 + __warn+0xcb/0xf0 + warn_slowpath_null+0x1d/0x20 + arch_add_memory+0xde/0xf0 + devm_memremap_pages+0x244/0x440 + pmem_attach_disk+0x37e/0x490 [nd_pmem] + nd_pmem_probe+0x7e/0xa0 [nd_pmem] + nvdimm_bus_probe+0x71/0x120 [libnvdimm] + driver_probe_device+0x2bb/0x460 + bind_store+0x114/0x160 + drv_attr_store+0x25/0x30 + +In commit 658922e57b84 "libnvdimm, pfn: fix memmap reservation sizing" +we arranged for the capacity to be allocated, but failed to also update +the 'npfns' parameter. This leads to cases where there is enough +capacity reserved to hold all the allocated sections, but +vmemmap_populate_hugepages() still encounters -ENOMEM from +altmap_alloc_block_buf(). + +This fix is a stop-gap until we can teach the core memory hotplug +implementation to permit sub-section hotplug. + +Cc: <stable@vger.kernel.org> +Fixes: 658922e57b84 ("libnvdimm, pfn: fix memmap reservation sizing") +Reported-by: Anisha Allada <anisha.allada@intel.com> +Signed-off-by: Dan Williams <dan.j.williams@intel.com> + +diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c +index c38566f4da7d..335c8175410b 100644 +--- a/drivers/nvdimm/pfn_devs.c ++++ b/drivers/nvdimm/pfn_devs.c +@@ -538,7 +538,8 @@ static struct vmem_altmap *__nvdimm_setup_pfn(struct nd_pfn *nd_pfn, + nd_pfn->npfns = le64_to_cpu(pfn_sb->npfns); + altmap = NULL; + } else if (nd_pfn->mode == PFN_MODE_PMEM) { +- nd_pfn->npfns = (resource_size(res) - offset) / PAGE_SIZE; ++ nd_pfn->npfns = PFN_SECTION_ALIGN_UP((resource_size(res) ++ - offset) / PAGE_SIZE); + if (le64_to_cpu(nd_pfn->pfn_sb->npfns) > nd_pfn->npfns) + dev_info(&nd_pfn->dev, + "number of pfns truncated from %lld to %ld\n", +@@ -625,7 +626,8 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) + */ + start += start_pad; + size = resource_size(&nsio->res); +- npfns = (size - start_pad - end_trunc - SZ_8K) / SZ_4K; ++ npfns = PFN_SECTION_ALIGN_UP((size - start_pad - end_trunc - SZ_8K) ++ / PAGE_SIZE); + if (nd_pfn->mode == PFN_MODE_PMEM) { + /* + * vmemmap_populate_hugepages() allocates the memmap array in +-- +2.12.0 + diff --git a/queue/libnvdimm-pmem-fix-a-NULL-pointer-BUG-in-nd_pmem_not.patch b/queue/libnvdimm-pmem-fix-a-NULL-pointer-BUG-in-nd_pmem_not.patch new file mode 100644 index 0000000..682a587 --- /dev/null +++ b/queue/libnvdimm-pmem-fix-a-NULL-pointer-BUG-in-nd_pmem_not.patch @@ -0,0 +1,100 @@ +From b2518c78ce76896f0f8f7940bf02104b227e1709 Mon Sep 17 00:00:00 2001 +From: Toshi Kani <toshi.kani@hpe.com> +Date: Tue, 25 Apr 2017 17:04:13 -0600 +Subject: [PATCH] libnvdimm, pmem: fix a NULL pointer BUG in nd_pmem_notify + +commit b2518c78ce76896f0f8f7940bf02104b227e1709 upstream. + +The following BUG was observed when nd_pmem_notify() was called +for a BTT device. The use of a pmem_device pointer is not valid +with BTT. + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000030 + IP: nd_pmem_notify+0x30/0xf0 [nd_pmem] + Call Trace: + nd_device_notify+0x40/0x50 + child_notify+0x10/0x20 + device_for_each_child+0x50/0x90 + nd_region_notify+0x20/0x30 + nd_device_notify+0x40/0x50 + nvdimm_region_notify+0x27/0x30 + acpi_nfit_scrub+0x341/0x590 [nfit] + process_one_work+0x197/0x450 + worker_thread+0x4e/0x4a0 + kthread+0x109/0x140 + +Fix nd_pmem_notify() by setting nd_region and badblocks pointers +properly for BTT. + +Cc: <stable@vger.kernel.org> +Cc: Vishal Verma <vishal.l.verma@intel.com> +Fixes: 719994660c24 ("libnvdimm: async notification support") +Signed-off-by: Toshi Kani <toshi.kani@hpe.com> +Signed-off-by: Dan Williams <dan.j.williams@intel.com> + +diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c +index 5b536be5a12e..0fc18262a2bc 100644 +--- a/drivers/nvdimm/pmem.c ++++ b/drivers/nvdimm/pmem.c +@@ -388,12 +388,12 @@ static void nd_pmem_shutdown(struct device *dev) + + static void nd_pmem_notify(struct device *dev, enum nvdimm_event event) + { +- struct pmem_device *pmem = dev_get_drvdata(dev); +- struct nd_region *nd_region = to_region(pmem); ++ struct nd_region *nd_region; + resource_size_t offset = 0, end_trunc = 0; + struct nd_namespace_common *ndns; + struct nd_namespace_io *nsio; + struct resource res; ++ struct badblocks *bb; + + if (event != NVDIMM_REVALIDATE_POISON) + return; +@@ -402,20 +402,33 @@ static void nd_pmem_notify(struct device *dev, enum nvdimm_event event) + struct nd_btt *nd_btt = to_nd_btt(dev); + + ndns = nd_btt->ndns; +- } else if (is_nd_pfn(dev)) { +- struct nd_pfn *nd_pfn = to_nd_pfn(dev); +- struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; ++ nd_region = to_nd_region(ndns->dev.parent); ++ nsio = to_nd_namespace_io(&ndns->dev); ++ bb = &nsio->bb; ++ } else { ++ struct pmem_device *pmem = dev_get_drvdata(dev); + +- ndns = nd_pfn->ndns; +- offset = pmem->data_offset + __le32_to_cpu(pfn_sb->start_pad); +- end_trunc = __le32_to_cpu(pfn_sb->end_trunc); +- } else +- ndns = to_ndns(dev); ++ nd_region = to_region(pmem); ++ bb = &pmem->bb; ++ ++ if (is_nd_pfn(dev)) { ++ struct nd_pfn *nd_pfn = to_nd_pfn(dev); ++ struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; ++ ++ ndns = nd_pfn->ndns; ++ offset = pmem->data_offset + ++ __le32_to_cpu(pfn_sb->start_pad); ++ end_trunc = __le32_to_cpu(pfn_sb->end_trunc); ++ } else { ++ ndns = to_ndns(dev); ++ } ++ ++ nsio = to_nd_namespace_io(&ndns->dev); ++ } + +- nsio = to_nd_namespace_io(&ndns->dev); + res.start = nsio->res.start + offset; + res.end = nsio->res.end - end_trunc; +- nvdimm_badblocks_populate(nd_region, &pmem->bb, &res); ++ nvdimm_badblocks_populate(nd_region, bb, &res); + } + + MODULE_ALIAS("pmem"); +-- +2.12.0 + diff --git a/queue/libnvdimm-region-fix-flush-hint-detection-crash.patch b/queue/libnvdimm-region-fix-flush-hint-detection-crash.patch new file mode 100644 index 0000000..5f11b00 --- /dev/null +++ b/queue/libnvdimm-region-fix-flush-hint-detection-crash.patch @@ -0,0 +1,65 @@ +From bc042fdfbb92b5b13421316b4548e2d6e98eed37 Mon Sep 17 00:00:00 2001 +From: Dan Williams <dan.j.williams@intel.com> +Date: Mon, 24 Apr 2017 15:43:05 -0700 +Subject: [PATCH] libnvdimm, region: fix flush hint detection crash + +commit bc042fdfbb92b5b13421316b4548e2d6e98eed37 upstream. + +In the case where a dimm does not have any associated flush hints the +ndrd->flush_wpq array may be uninitialized leading to crashes with the +following signature: + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000010 + IP: region_visible+0x10f/0x160 [libnvdimm] + + Call Trace: + internal_create_group+0xbe/0x2f0 + sysfs_create_groups+0x40/0x80 + device_add+0x2d8/0x650 + nd_async_device_register+0x12/0x40 [libnvdimm] + async_run_entry_fn+0x39/0x170 + process_one_work+0x212/0x6c0 + ? process_one_work+0x197/0x6c0 + worker_thread+0x4e/0x4a0 + kthread+0x10c/0x140 + ? process_one_work+0x6c0/0x6c0 + ? kthread_create_on_node+0x60/0x60 + ret_from_fork+0x31/0x40 + +Cc: <stable@vger.kernel.org> +Reviewed-by: Jeff Moyer <jmoyer@redhat.com> +Fixes: f284a4f23752 ("libnvdimm: introduce nvdimm_flush() and nvdimm_has_flush()") +Signed-off-by: Dan Williams <dan.j.williams@intel.com> + +diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c +index 8de5a04644a1..24abceda986a 100644 +--- a/drivers/nvdimm/region_devs.c ++++ b/drivers/nvdimm/region_devs.c +@@ -1000,17 +1000,20 @@ EXPORT_SYMBOL_GPL(nvdimm_flush); + */ + int nvdimm_has_flush(struct nd_region *nd_region) + { +- struct nd_region_data *ndrd = dev_get_drvdata(&nd_region->dev); + int i; + + /* no nvdimm == flushing capability unknown */ + if (nd_region->ndr_mappings == 0) + return -ENXIO; + +- for (i = 0; i < nd_region->ndr_mappings; i++) +- /* flush hints present, flushing required */ +- if (ndrd_get_flush_wpq(ndrd, i, 0)) ++ for (i = 0; i < nd_region->ndr_mappings; i++) { ++ struct nd_mapping *nd_mapping = &nd_region->mapping[i]; ++ struct nvdimm *nvdimm = nd_mapping->nvdimm; ++ ++ /* flush hints present / available */ ++ if (nvdimm->num_flush) + return 1; ++ } + + /* + * The platform defines dimm devices without hints, assume +-- +2.12.0 + diff --git a/queue/mac80211-fix-MU-MIMO-follow-MAC-mode.patch b/queue/mac80211-fix-MU-MIMO-follow-MAC-mode.patch new file mode 100644 index 0000000..0da072b --- /dev/null +++ b/queue/mac80211-fix-MU-MIMO-follow-MAC-mode.patch @@ -0,0 +1,123 @@ +From 9e478066eae41211c92a8f63cc69aafc391bd6ab Mon Sep 17 00:00:00 2001 +From: Johannes Berg <johannes.berg@intel.com> +Date: Thu, 13 Apr 2017 14:23:49 +0200 +Subject: [PATCH] mac80211: fix MU-MIMO follow-MAC mode + +commit 9e478066eae41211c92a8f63cc69aafc391bd6ab upstream. + +There are two bugs in the follow-MAC code: + * it treats the radiotap header as the 802.11 header + (therefore it can't possibly work) + * it doesn't verify that the skb data it accesses is actually + present in the header, which is mitigated by the first point + +Fix this by moving all of this out into a separate function. +This function copies the data it needs using skb_copy_bits() +to make sure it can be accessed if it's paged, and offsets +that by the possibly present vendor radiotap header. + +This also makes all those conditions more readable. + +Cc: stable@vger.kernel.org +Signed-off-by: Johannes Berg <johannes.berg@intel.com> + +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index e48724a6725e..4b12c70c85f0 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -208,6 +208,51 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local, + return len; + } + ++static void ieee80211_handle_mu_mimo_mon(struct ieee80211_sub_if_data *sdata, ++ struct sk_buff *skb, ++ int rtap_vendor_space) ++{ ++ struct { ++ struct ieee80211_hdr_3addr hdr; ++ u8 category; ++ u8 action_code; ++ } __packed action; ++ ++ if (!sdata) ++ return; ++ ++ BUILD_BUG_ON(sizeof(action) != IEEE80211_MIN_ACTION_SIZE + 1); ++ ++ if (skb->len < rtap_vendor_space + sizeof(action) + ++ VHT_MUMIMO_GROUPS_DATA_LEN) ++ return; ++ ++ if (!is_valid_ether_addr(sdata->u.mntr.mu_follow_addr)) ++ return; ++ ++ skb_copy_bits(skb, rtap_vendor_space, &action, sizeof(action)); ++ ++ if (!ieee80211_is_action(action.hdr.frame_control)) ++ return; ++ ++ if (action.category != WLAN_CATEGORY_VHT) ++ return; ++ ++ if (action.action_code != WLAN_VHT_ACTION_GROUPID_MGMT) ++ return; ++ ++ if (!ether_addr_equal(action.hdr.addr1, sdata->u.mntr.mu_follow_addr)) ++ return; ++ ++ skb = skb_copy(skb, GFP_ATOMIC); ++ if (!skb) ++ return; ++ ++ skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME; ++ skb_queue_tail(&sdata->skb_queue, skb); ++ ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++} ++ + /* + * ieee80211_add_rx_radiotap_header - add radiotap header + * +@@ -515,7 +560,6 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, + struct net_device *prev_dev = NULL; + int present_fcs_len = 0; + unsigned int rtap_vendor_space = 0; +- struct ieee80211_mgmt *mgmt; + struct ieee80211_sub_if_data *monitor_sdata = + rcu_dereference(local->monitor_sdata); + +@@ -553,6 +597,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, + return remove_monitor_info(local, origskb, rtap_vendor_space); + } + ++ ieee80211_handle_mu_mimo_mon(monitor_sdata, origskb, rtap_vendor_space); ++ + /* room for the radiotap header based on driver features */ + rt_hdrlen = ieee80211_rx_radiotap_hdrlen(local, status, origskb); + needed_headroom = rt_hdrlen - rtap_vendor_space; +@@ -618,23 +664,6 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, + ieee80211_rx_stats(sdata->dev, skb->len); + } + +- mgmt = (void *)skb->data; +- if (monitor_sdata && +- skb->len >= IEEE80211_MIN_ACTION_SIZE + 1 + VHT_MUMIMO_GROUPS_DATA_LEN && +- ieee80211_is_action(mgmt->frame_control) && +- mgmt->u.action.category == WLAN_CATEGORY_VHT && +- mgmt->u.action.u.vht_group_notif.action_code == WLAN_VHT_ACTION_GROUPID_MGMT && +- is_valid_ether_addr(monitor_sdata->u.mntr.mu_follow_addr) && +- ether_addr_equal(mgmt->da, monitor_sdata->u.mntr.mu_follow_addr)) { +- struct sk_buff *mu_skb = skb_copy(skb, GFP_ATOMIC); +- +- if (mu_skb) { +- mu_skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME; +- skb_queue_tail(&monitor_sdata->skb_queue, mu_skb); +- ieee80211_queue_work(&local->hw, &monitor_sdata->work); +- } +- } +- + if (prev_dev) { + skb->dev = prev_dev; + netif_receive_skb(skb); +-- +2.12.0 + diff --git a/queue/mac80211-reject-ToDS-broadcast-data-frames.patch b/queue/mac80211-reject-ToDS-broadcast-data-frames.patch new file mode 100644 index 0000000..b4e47cb --- /dev/null +++ b/queue/mac80211-reject-ToDS-broadcast-data-frames.patch @@ -0,0 +1,64 @@ +From 3018e947d7fd536d57e2b550c33e456d921fff8c Mon Sep 17 00:00:00 2001 +From: Johannes Berg <johannes.berg@intel.com> +Date: Thu, 20 Apr 2017 21:32:16 +0200 +Subject: [PATCH] mac80211: reject ToDS broadcast data frames + +commit 3018e947d7fd536d57e2b550c33e456d921fff8c upstream. + +AP/AP_VLAN modes don't accept any real 802.11 multicast data +frames, but since they do need to accept broadcast management +frames the same is currently permitted for data frames. This +opens a security problem because such frames would be decrypted +with the GTK, and could even contain unicast L3 frames. + +Since the spec says that ToDS frames must always have the BSSID +as the RA (addr1), reject any other data frames. + +The problem was originally reported in "Predicting, Decrypting, +and Abusing WPA2/802.11 Group Keys" at usenix +https://www.usenix.org/conference/usenixsecurity16/technical-sessions/presentation/vanhoef +and brought to my attention by Jouni. + +Cc: stable@vger.kernel.org +Reported-by: Jouni Malinen <j@w1.fi> +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +-- +Dave, I didn't want to send you a new pull request for a single +commit yet again - can you apply this one patch as is? +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 4b12c70c85f0..4d7543d1a62c 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -3639,6 +3639,27 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx) + !ether_addr_equal(bssid, hdr->addr1)) + return false; + } ++ ++ /* ++ * 802.11-2016 Table 9-26 says that for data frames, A1 must be ++ * the BSSID - we've checked that already but may have accepted ++ * the wildcard (ff:ff:ff:ff:ff:ff). ++ * ++ * It also says: ++ * The BSSID of the Data frame is determined as follows: ++ * a) If the STA is contained within an AP or is associated ++ * with an AP, the BSSID is the address currently in use ++ * by the STA contained in the AP. ++ * ++ * So we should not accept data frames with an address that's ++ * multicast. ++ * ++ * Accepting it also opens a security problem because stations ++ * could encrypt it with the GTK and inject traffic that way. ++ */ ++ if (ieee80211_is_data(hdr->frame_control) && multicast) ++ return false; ++ + return true; + case NL80211_IFTYPE_WDS: + if (bssid || !ieee80211_is_data(hdr->frame_control)) +-- +2.12.0 + diff --git a/queue/macsec-avoid-heap-overflow-in-skb_to_sgvec.patch b/queue/macsec-avoid-heap-overflow-in-skb_to_sgvec.patch new file mode 100644 index 0000000..97ecfdd --- /dev/null +++ b/queue/macsec-avoid-heap-overflow-in-skb_to_sgvec.patch @@ -0,0 +1,72 @@ +From 4d6fa57b4dab0d77f4d8e9d9c73d1e63f6fe8fee Mon Sep 17 00:00:00 2001 +From: "Jason A. Donenfeld" <Jason@zx2c4.com> +Date: Fri, 21 Apr 2017 23:14:48 +0200 +Subject: [PATCH] macsec: avoid heap overflow in skb_to_sgvec + +commit 4d6fa57b4dab0d77f4d8e9d9c73d1e63f6fe8fee upstream. + +While this may appear as a humdrum one line change, it's actually quite +important. An sk_buff stores data in three places: + +1. A linear chunk of allocated memory in skb->data. This is the easiest + one to work with, but it precludes using scatterdata since the memory + must be linear. +2. The array skb_shinfo(skb)->frags, which is of maximum length + MAX_SKB_FRAGS. This is nice for scattergather, since these fragments + can point to different pages. +3. skb_shinfo(skb)->frag_list, which is a pointer to another sk_buff, + which in turn can have data in either (1) or (2). + +The first two are rather easy to deal with, since they're of a fixed +maximum length, while the third one is not, since there can be +potentially limitless chains of fragments. Fortunately dealing with +frag_list is opt-in for drivers, so drivers don't actually have to deal +with this mess. For whatever reason, macsec decided it wanted pain, and +so it explicitly specified NETIF_F_FRAGLIST. + +Because dealing with (1), (2), and (3) is insane, most users of sk_buff +doing any sort of crypto or paging operation calls a convenient function +called skb_to_sgvec (which happens to be recursive if (3) is in use!). +This takes a sk_buff as input, and writes into its output pointer an +array of scattergather list items. Sometimes people like to declare a +fixed size scattergather list on the stack; othertimes people like to +allocate a fixed size scattergather list on the heap. However, if you're +doing it in a fixed-size fashion, you really shouldn't be using +NETIF_F_FRAGLIST too (unless you're also ensuring the sk_buff and its +frag_list children arent't shared and then you check the number of +fragments in total required.) + +Macsec specifically does this: + + size += sizeof(struct scatterlist) * (MAX_SKB_FRAGS + 1); + tmp = kmalloc(size, GFP_ATOMIC); + *sg = (struct scatterlist *)(tmp + sg_offset); + ... + sg_init_table(sg, MAX_SKB_FRAGS + 1); + skb_to_sgvec(skb, sg, 0, skb->len); + +Specifying MAX_SKB_FRAGS + 1 is the right answer usually, but not if you're +using NETIF_F_FRAGLIST, in which case the call to skb_to_sgvec will +overflow the heap, and disaster ensues. + +Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> +Cc: stable@vger.kernel.org +Cc: security@kernel.org +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c +index ff0a5ed3ca80..dbab05afcdbe 100644 +--- a/drivers/net/macsec.c ++++ b/drivers/net/macsec.c +@@ -2716,7 +2716,7 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb, + } + + #define MACSEC_FEATURES \ +- (NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST) ++ (NETIF_F_SG | NETIF_F_HIGHDMA) + static struct lock_class_key macsec_netdev_addr_lock_key; + + static int macsec_dev_init(struct net_device *dev) +-- +2.12.0 + diff --git a/queue/macsec-dynamically-allocate-space-for-sglist.patch b/queue/macsec-dynamically-allocate-space-for-sglist.patch new file mode 100644 index 0000000..b80fe06 --- /dev/null +++ b/queue/macsec-dynamically-allocate-space-for-sglist.patch @@ -0,0 +1,116 @@ +From 5294b83086cc1c35b4efeca03644cf9d12282e5b Mon Sep 17 00:00:00 2001 +From: "Jason A. Donenfeld" <Jason@zx2c4.com> +Date: Tue, 25 Apr 2017 19:08:18 +0200 +Subject: [PATCH] macsec: dynamically allocate space for sglist + +commit 5294b83086cc1c35b4efeca03644cf9d12282e5b upstream. + +We call skb_cow_data, which is good anyway to ensure we can actually +modify the skb as such (another error from prior). Now that we have the +number of fragments required, we can safely allocate exactly that amount +of memory. + +Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver") +Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> +Acked-by: Sabrina Dubroca <sd@queasysnail.net> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c +index dbab05afcdbe..49ce4e9f4a0f 100644 +--- a/drivers/net/macsec.c ++++ b/drivers/net/macsec.c +@@ -617,7 +617,8 @@ static void macsec_encrypt_done(struct crypto_async_request *base, int err) + + static struct aead_request *macsec_alloc_req(struct crypto_aead *tfm, + unsigned char **iv, +- struct scatterlist **sg) ++ struct scatterlist **sg, ++ int num_frags) + { + size_t size, iv_offset, sg_offset; + struct aead_request *req; +@@ -629,7 +630,7 @@ static struct aead_request *macsec_alloc_req(struct crypto_aead *tfm, + + size = ALIGN(size, __alignof__(struct scatterlist)); + sg_offset = size; +- size += sizeof(struct scatterlist) * (MAX_SKB_FRAGS + 1); ++ size += sizeof(struct scatterlist) * num_frags; + + tmp = kmalloc(size, GFP_ATOMIC); + if (!tmp) +@@ -649,6 +650,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb, + { + int ret; + struct scatterlist *sg; ++ struct sk_buff *trailer; + unsigned char *iv; + struct ethhdr *eth; + struct macsec_eth_header *hh; +@@ -723,7 +725,14 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb, + return ERR_PTR(-EINVAL); + } + +- req = macsec_alloc_req(tx_sa->key.tfm, &iv, &sg); ++ ret = skb_cow_data(skb, 0, &trailer); ++ if (unlikely(ret < 0)) { ++ macsec_txsa_put(tx_sa); ++ kfree_skb(skb); ++ return ERR_PTR(ret); ++ } ++ ++ req = macsec_alloc_req(tx_sa->key.tfm, &iv, &sg, ret); + if (!req) { + macsec_txsa_put(tx_sa); + kfree_skb(skb); +@@ -732,7 +741,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb, + + macsec_fill_iv(iv, secy->sci, pn); + +- sg_init_table(sg, MAX_SKB_FRAGS + 1); ++ sg_init_table(sg, ret); + skb_to_sgvec(skb, sg, 0, skb->len); + + if (tx_sc->encrypt) { +@@ -917,6 +926,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, + { + int ret; + struct scatterlist *sg; ++ struct sk_buff *trailer; + unsigned char *iv; + struct aead_request *req; + struct macsec_eth_header *hdr; +@@ -927,7 +937,12 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, + if (!skb) + return ERR_PTR(-ENOMEM); + +- req = macsec_alloc_req(rx_sa->key.tfm, &iv, &sg); ++ ret = skb_cow_data(skb, 0, &trailer); ++ if (unlikely(ret < 0)) { ++ kfree_skb(skb); ++ return ERR_PTR(ret); ++ } ++ req = macsec_alloc_req(rx_sa->key.tfm, &iv, &sg, ret); + if (!req) { + kfree_skb(skb); + return ERR_PTR(-ENOMEM); +@@ -936,7 +951,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, + hdr = (struct macsec_eth_header *)skb->data; + macsec_fill_iv(iv, sci, ntohl(hdr->packet_number)); + +- sg_init_table(sg, MAX_SKB_FRAGS + 1); ++ sg_init_table(sg, ret); + skb_to_sgvec(skb, sg, 0, skb->len); + + if (hdr->tci_an & MACSEC_TCI_E) { +@@ -2716,7 +2731,7 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb, + } + + #define MACSEC_FEATURES \ +- (NETIF_F_SG | NETIF_F_HIGHDMA) ++ (NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST) + static struct lock_class_key macsec_netdev_addr_lock_key; + + static int macsec_dev_init(struct net_device *dev) +-- +2.12.0 + diff --git a/queue/macvlan-Fix-device-ref-leak-when-purging-bc_queue.patch b/queue/macvlan-Fix-device-ref-leak-when-purging-bc_queue.patch new file mode 100644 index 0000000..084cdaf --- /dev/null +++ b/queue/macvlan-Fix-device-ref-leak-when-purging-bc_queue.patch @@ -0,0 +1,50 @@ +From f6478218e6edc2a587b8f132f66373baa7b2497c Mon Sep 17 00:00:00 2001 +From: Herbert Xu <herbert@gondor.apana.org.au> +Date: Thu, 20 Apr 2017 20:55:12 +0800 +Subject: [PATCH] macvlan: Fix device ref leak when purging bc_queue + +commit f6478218e6edc2a587b8f132f66373baa7b2497c upstream. + +When a parent macvlan device is destroyed we end up purging its +broadcast queue without dropping the device reference count on +the packet source device. This causes the source device to linger. + +This patch drops that reference count. + +Fixes: 260916dfb48c ("macvlan: Fix potential use-after free for...") +Reported-by: Joe Ghalam <Joe.Ghalam@dell.com> +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c +index 9261722960a7..b34eaaae03fd 100644 +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -1139,6 +1139,7 @@ static int macvlan_port_create(struct net_device *dev) + static void macvlan_port_destroy(struct net_device *dev) + { + struct macvlan_port *port = macvlan_port_get_rtnl(dev); ++ struct sk_buff *skb; + + dev->priv_flags &= ~IFF_MACVLAN_PORT; + netdev_rx_handler_unregister(dev); +@@ -1147,7 +1148,15 @@ static void macvlan_port_destroy(struct net_device *dev) + * but we need to cancel it and purge left skbs if any. + */ + cancel_work_sync(&port->bc_work); +- __skb_queue_purge(&port->bc_queue); ++ ++ while ((skb = __skb_dequeue(&port->bc_queue))) { ++ const struct macvlan_dev *src = MACVLAN_SKB_CB(skb)->src; ++ ++ if (src) ++ dev_put(src->dev); ++ ++ kfree_skb(skb); ++ } + + kfree(port); + } +-- +2.12.0 + diff --git a/queue/mm-prevent-NR_ISOLATE_-stats-from-going-negative.patch b/queue/mm-prevent-NR_ISOLATE_-stats-from-going-negative.patch new file mode 100644 index 0000000..678b8f3 --- /dev/null +++ b/queue/mm-prevent-NR_ISOLATE_-stats-from-going-negative.patch @@ -0,0 +1,57 @@ +From fc280fe871449ead4bdbd1665fa52c7c01c64765 Mon Sep 17 00:00:00 2001 +From: Rabin Vincent <rabinv@axis.com> +Date: Thu, 20 Apr 2017 14:37:46 -0700 +Subject: [PATCH] mm: prevent NR_ISOLATE_* stats from going negative + +commit fc280fe871449ead4bdbd1665fa52c7c01c64765 upstream. + +Commit 6afcf8ef0ca0 ("mm, compaction: fix NR_ISOLATED_* stats for pfn +based migration") moved the dec_node_page_state() call (along with the +page_is_file_cache() call) to after putback_lru_page(). + +But page_is_file_cache() can change after putback_lru_page() is called, +so it should be called before putback_lru_page(), as it was before that +patch, to prevent NR_ISOLATE_* stats from going negative. + +Without this fix, non-CONFIG_SMP kernels end up hanging in the +while(too_many_isolated()) { congestion_wait() } loop in +shrink_active_list() due to the negative stats. + + Mem-Info: + active_anon:32567 inactive_anon:121 isolated_anon:1 + active_file:6066 inactive_file:6639 isolated_file:4294967295 + ^^^^^^^^^^ + unevictable:0 dirty:115 writeback:0 unstable:0 + slab_reclaimable:2086 slab_unreclaimable:3167 + mapped:3398 shmem:18366 pagetables:1145 bounce:0 + free:1798 free_pcp:13 free_cma:0 + +Fixes: 6afcf8ef0ca0 ("mm, compaction: fix NR_ISOLATED_* stats for pfn based migration") +Link: http://lkml.kernel.org/r/1492683865-27549-1-git-send-email-rabin.vincent@axis.com +Signed-off-by: Rabin Vincent <rabinv@axis.com> +Acked-by: Michal Hocko <mhocko@suse.com> +Cc: Ming Ling <ming.ling@spreadtrum.com> +Cc: Minchan Kim <minchan@kernel.org> +Cc: Vlastimil Babka <vbabka@suse.cz> +Cc: <stable@vger.kernel.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> + +diff --git a/mm/migrate.c b/mm/migrate.c +index ed97c2c14fa8..738f1d5f8350 100644 +--- a/mm/migrate.c ++++ b/mm/migrate.c +@@ -184,9 +184,9 @@ void putback_movable_pages(struct list_head *l) + unlock_page(page); + put_page(page); + } else { +- putback_lru_page(page); + dec_node_page_state(page, NR_ISOLATED_ANON + + page_is_file_cache(page)); ++ putback_lru_page(page); + } + } + } +-- +2.12.0 + diff --git a/queue/mm-prevent-potential-recursive-reclaim-due-to-cleari.patch b/queue/mm-prevent-potential-recursive-reclaim-due-to-cleari.patch new file mode 100644 index 0000000..3de8e20 --- /dev/null +++ b/queue/mm-prevent-potential-recursive-reclaim-due-to-cleari.patch @@ -0,0 +1,82 @@ +From 62be1511b1db8066220b18b7d4da2e6b9fdc69fb Mon Sep 17 00:00:00 2001 +From: Vlastimil Babka <vbabka@suse.cz> +Date: Mon, 8 May 2017 15:59:46 -0700 +Subject: [PATCH] mm: prevent potential recursive reclaim due to clearing + PF_MEMALLOC + +commit 62be1511b1db8066220b18b7d4da2e6b9fdc69fb upstream. + +Patch series "more robust PF_MEMALLOC handling" + +This series aims to unify the setting and clearing of PF_MEMALLOC, which +prevents recursive reclaim. There are some places that clear the flag +unconditionally from current->flags, which may result in clearing a +pre-existing flag. This already resulted in a bug report that Patch 1 +fixes (without the new helpers, to make backporting easier). Patch 2 +introduces the new helpers, modelled after existing memalloc_noio_* and +memalloc_nofs_* helpers, and converts mm core to use them. Patches 3 +and 4 convert non-mm code. + +This patch (of 4): + +__alloc_pages_direct_compact() sets PF_MEMALLOC to prevent deadlock +during page migration by lock_page() (see the comment in +__unmap_and_move()). Then it unconditionally clears the flag, which can +clear a pre-existing PF_MEMALLOC flag and result in recursive reclaim. +This was not a problem until commit a8161d1ed609 ("mm, page_alloc: +restructure direct compaction handling in slowpath"), because direct +compation was called only after direct reclaim, which was skipped when +PF_MEMALLOC flag was set. + +Even now it's only a theoretical issue, as the new callsite of +__alloc_pages_direct_compact() is reached only for costly orders and +when gfp_pfmemalloc_allowed() is true, which means either +__GFP_NOMEMALLOC is in gfp_flags or in_interrupt() is true. There is no +such known context, but let's play it safe and make +__alloc_pages_direct_compact() robust for cases where PF_MEMALLOC is +already set. + +Fixes: a8161d1ed609 ("mm, page_alloc: restructure direct compaction handling in slowpath") +Link: http://lkml.kernel.org/r/20170405074700.29871-2-vbabka@suse.cz +Signed-off-by: Vlastimil Babka <vbabka@suse.cz> +Reported-by: Andrey Ryabinin <aryabinin@virtuozzo.com> +Acked-by: Michal Hocko <mhocko@suse.com> +Acked-by: Hillf Danton <hillf.zj@alibaba-inc.com> +Cc: Mel Gorman <mgorman@techsingularity.net> +Cc: Johannes Weiner <hannes@cmpxchg.org> +Cc: Boris Brezillon <boris.brezillon@free-electrons.com> +Cc: Chris Leech <cleech@redhat.com> +Cc: "David S. Miller" <davem@davemloft.net> +Cc: Eric Dumazet <edumazet@google.com> +Cc: Josef Bacik <jbacik@fb.com> +Cc: Lee Duncan <lduncan@suse.com> +Cc: Michal Hocko <mhocko@suse.com> +Cc: Richard Weinberger <richard@nod.at> +Cc: <stable@vger.kernel.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> + +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index e7486afa7fa7..1daf509722c7 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -3283,6 +3283,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, + enum compact_priority prio, enum compact_result *compact_result) + { + struct page *page; ++ unsigned int noreclaim_flag = current->flags & PF_MEMALLOC; + + if (!order) + return NULL; +@@ -3290,7 +3291,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, + current->flags |= PF_MEMALLOC; + *compact_result = try_to_compact_pages(gfp_mask, order, alloc_flags, ac, + prio); +- current->flags &= ~PF_MEMALLOC; ++ current->flags = (current->flags & ~PF_MEMALLOC) | noreclaim_flag; + + if (*compact_result <= COMPACT_INACTIVE) + return NULL; +-- +2.12.0 + diff --git a/queue/mmc-sdhci-esdhc-imx-increase-the-pad-I-O-drive-stren.patch b/queue/mmc-sdhci-esdhc-imx-increase-the-pad-I-O-drive-stren.patch new file mode 100644 index 0000000..e5b309a --- /dev/null +++ b/queue/mmc-sdhci-esdhc-imx-increase-the-pad-I-O-drive-stren.patch @@ -0,0 +1,40 @@ +From 9f327845358d3dd0d8a5a7a5436b0aa5c432e757 Mon Sep 17 00:00:00 2001 +From: Haibo Chen <haibo.chen@nxp.com> +Date: Wed, 19 Apr 2017 10:53:51 +0800 +Subject: [PATCH] mmc: sdhci-esdhc-imx: increase the pad I/O drive strength for + DDR50 card + +commit 9f327845358d3dd0d8a5a7a5436b0aa5c432e757 upstream. + +Currently for DDR50 card, it need tuning in default. We meet tuning fail +issue for DDR50 card and some data CRC error when DDR50 sd card works. + +This is because the default pad I/O drive strength can't make sure DDR50 +card work stable. So increase the pad I/O drive strength for DDR50 card, +and use pins_100mhz. + +This fixes DDR50 card support for IMX since DDR50 tuning was enabled from +commit 9faac7b95ea4 ("mmc: sdhci: enable tuning for DDR50") + +Tested-and-reported-by: Tim Harvey <tharvey@gateworks.com> +Signed-off-by: Haibo Chen <haibo.chen@nxp.com> +Cc: stable@vger.kernel.org # v4.4+ +Acked-by: Dong Aisheng <aisheng.dong@nxp.com> +Acked-by: Adrian Hunter <adrian.hunter@intel.com> +Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> + +diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c +index 7123ef96ed18..445fc47dc3e7 100644 +--- a/drivers/mmc/host/sdhci-esdhc-imx.c ++++ b/drivers/mmc/host/sdhci-esdhc-imx.c +@@ -830,6 +830,7 @@ static int esdhc_change_pinstate(struct sdhci_host *host, + + switch (uhs) { + case MMC_TIMING_UHS_SDR50: ++ case MMC_TIMING_UHS_DDR50: + pinctrl = imx_data->pins_100mhz; + break; + case MMC_TIMING_UHS_SDR104: +-- +2.12.0 + diff --git a/queue/mmc-sdhci-msm-Enable-few-quirks.patch b/queue/mmc-sdhci-msm-Enable-few-quirks.patch new file mode 100644 index 0000000..8f8078c --- /dev/null +++ b/queue/mmc-sdhci-msm-Enable-few-quirks.patch @@ -0,0 +1,33 @@ +From a0e3142869d29688de6f77be31aa7a401a4a88f1 Mon Sep 17 00:00:00 2001 +From: Ritesh Harjani <riteshh@codeaurora.org> +Date: Mon, 21 Nov 2016 12:07:18 +0530 +Subject: [PATCH] mmc: sdhci-msm: Enable few quirks + +commit a0e3142869d29688de6f77be31aa7a401a4a88f1 upstream. + +sdhc-msm controller needs this SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN +& SDHCI_QUIRK2_PRESET_VALUE_BROKEN to be set. Hence setting it. + +Signed-off-by: Sahitya Tummala <stummala@codeaurora.org> +Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org> +Acked-by: Adrian Hunter <adrian.hunter@intel.com> +Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> + +diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c +index aaeaf475e395..15a8b8e70ff9 100644 +--- a/drivers/mmc/host/sdhci-msm.c ++++ b/drivers/mmc/host/sdhci-msm.c +@@ -592,7 +592,9 @@ static const struct sdhci_ops sdhci_msm_ops = { + static const struct sdhci_pltfm_data sdhci_msm_pdata = { + .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | + SDHCI_QUIRK_NO_CARD_NO_RESET | +- SDHCI_QUIRK_SINGLE_POWER_WRITE, ++ SDHCI_QUIRK_SINGLE_POWER_WRITE | ++ SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, ++ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, + .ops = &sdhci_msm_ops, + }; + +-- +2.12.0 + diff --git a/queue/mwifiex-Avoid-skipping-WEP-key-deletion-for-AP.patch b/queue/mwifiex-Avoid-skipping-WEP-key-deletion-for-AP.patch new file mode 100644 index 0000000..e481695 --- /dev/null +++ b/queue/mwifiex-Avoid-skipping-WEP-key-deletion-for-AP.patch @@ -0,0 +1,36 @@ +From a5b60de6972decc6b50a39abb376077c3c3621c8 Mon Sep 17 00:00:00 2001 +From: Ganapathi Bhat <gbhat@marvell.com> +Date: Fri, 3 Feb 2017 18:30:22 +0530 +Subject: [PATCH] mwifiex: Avoid skipping WEP key deletion for AP + +commit a5b60de6972decc6b50a39abb376077c3c3621c8 upstream. + +This patch fixes the issue specific to AP. AP is started with WEP +security and external station is connected to it. Data path works +in this case. Now if AP is restarted with WPA/WPA2 security, +station is able to connect but ping fails. + +Driver skips the deletion of WEP keys if interface type is AP. +Removing that redundant check resolves the issue. + +Fixes: e57f1734d87a ("mwifiex: add key material v2 support") +Signed-off-by: Ganapathi Bhat <gbhat@marvell.com> +Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> + +diff --git a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c +index 644f3a248741..1532ac9cee0b 100644 +--- a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c ++++ b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c +@@ -1159,8 +1159,6 @@ int mwifiex_set_encode(struct mwifiex_private *priv, struct key_params *kp, + encrypt_key.is_rx_seq_valid = true; + } + } else { +- if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) +- return 0; + encrypt_key.key_disable = true; + if (mac_addr) + memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN); +-- +2.12.0 + diff --git a/queue/mwifiex-debugfs-Fix-sometimes-off-by-1-SSID-print.patch b/queue/mwifiex-debugfs-Fix-sometimes-off-by-1-SSID-print.patch new file mode 100644 index 0000000..4d6de92 --- /dev/null +++ b/queue/mwifiex-debugfs-Fix-sometimes-off-by-1-SSID-print.patch @@ -0,0 +1,49 @@ +From 6183468a23fc6b6903f8597982017ad2c7fdefcf Mon Sep 17 00:00:00 2001 +From: Brian Norris <briannorris@chromium.org> +Date: Mon, 9 Jan 2017 15:33:50 -0800 +Subject: [PATCH] mwifiex: debugfs: Fix (sometimes) off-by-1 SSID print + +commit 6183468a23fc6b6903f8597982017ad2c7fdefcf upstream. + +Similar to commit fcd2042e8d36 ("mwifiex: printk() overflow with 32-byte +SSIDs"), we failed to account for the existence of 32-char SSIDs in our +debugfs code. Unlike in that case though, we zeroed out the containing +struct first, and I'm pretty sure we're guaranteed to have some padding +after the 'ssid.ssid' and 'ssid.ssid_len' fields (the struct is 33 bytes +long). + +So, this is the difference between: + + # cat /sys/kernel/debug/mwifiex/mlan0/info + ... + essid="0123456789abcdef0123456789abcdef " + ... + +and the correct output: + + # cat /sys/kernel/debug/mwifiex/mlan0/info + ... + essid="0123456789abcdef0123456789abcdef" + ... + +Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver") +Signed-off-by: Brian Norris <briannorris@chromium.org> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> + +diff --git a/drivers/net/wireless/marvell/mwifiex/debugfs.c b/drivers/net/wireless/marvell/mwifiex/debugfs.c +index b9284b533294..ae2b69db5994 100644 +--- a/drivers/net/wireless/marvell/mwifiex/debugfs.c ++++ b/drivers/net/wireless/marvell/mwifiex/debugfs.c +@@ -114,7 +114,8 @@ mwifiex_info_read(struct file *file, char __user *ubuf, + if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) { + p += sprintf(p, "multicast_count=\"%d\"\n", + netdev_mc_count(netdev)); +- p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid); ++ p += sprintf(p, "essid=\"%.*s\"\n", info.ssid.ssid_len, ++ info.ssid.ssid); + p += sprintf(p, "bssid=\"%pM\"\n", info.bssid); + p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan); + p += sprintf(p, "country_code = \"%s\"\n", info.country_code); +-- +2.12.0 + diff --git a/queue/mwifiex-remove-redundant-dma-padding-in-AMSDU.patch b/queue/mwifiex-remove-redundant-dma-padding-in-AMSDU.patch new file mode 100644 index 0000000..c1e2f84 --- /dev/null +++ b/queue/mwifiex-remove-redundant-dma-padding-in-AMSDU.patch @@ -0,0 +1,93 @@ +From 5f0a221f59ad6b72202ef9c6e232086de8c336f2 Mon Sep 17 00:00:00 2001 +From: Xinming Hu <huxm@marvell.com> +Date: Wed, 11 Jan 2017 21:41:24 +0530 +Subject: [PATCH] mwifiex: remove redundant dma padding in AMSDU + +commit 5f0a221f59ad6b72202ef9c6e232086de8c336f2 upstream. + +We already ensure 64 bytes alignment and add padding if required +during skb_aggr allocation. + +Alignment and padding in mwifiex_11n_form_amsdu_txpd() is redundant. +We may end up accessing more data than allocated size with this. + +This patch fixes following issue by removing redundant padding. + +[ 370.241338] skbuff: skb_over_panic: text:ffffffffc046946a len:3550 +put:72 head:ffff880000110000 data:ffff8800001100e4 tail:0xec2 end:0xec0 dev:<NULL> +[ 370.241374] ------------[ cut here ]------------ +[ 370.241382] kernel BUG at net/core/skbuff.c:104! + 370.244032] Call Trace: +[ 370.244041] [<ffffffff8c3df5ec>] skb_put+0x44/0x45 +[ 370.244055] [<ffffffffc046946a>] +mwifiex_11n_aggregate_pkt+0x1e9/0xa50 [mwifiex] +[ 370.244067] [<ffffffffc0467c16>] mwifiex_wmm_process_tx+0x44a/0x6b7 +[mwifiex] +[ 370.244074] [<ffffffffc0411eb8>] ? 0xffffffffc0411eb8 +[ 370.244084] [<ffffffffc046116b>] mwifiex_main_process+0x476/0x5a5 +[mwifiex] +[ 370.244098] [<ffffffffc0461298>] mwifiex_main_process+0x5a3/0x5a5 +[mwifiex] +[ 370.244113] [<ffffffff8be7e9ff>] process_one_work+0x1a4/0x309 +[ 370.244123] [<ffffffff8be7f4ca>] worker_thread+0x20c/0x2ee +[ 370.244130] [<ffffffff8be7f2be>] ? rescuer_thread+0x383/0x383 +[ 370.244136] [<ffffffff8be7f2be>] ? rescuer_thread+0x383/0x383 +[ 370.244143] [<ffffffff8be83742>] kthread+0x11c/0x124 +[ 370.244150] [<ffffffff8be83626>] ? kthread_parkme+0x24/0x24 +[ 370.244157] [<ffffffff8c4da1ef>] ret_from_fork+0x3f/0x70 +[ 370.244168] [<ffffffff8be83626>] ? kthread_parkme+0x24/0x24 + +Fixes: 84b313b35f8158d ("mwifiex: make tx packet 64 byte DMA aligned") +Signed-off-by: Xinming Hu <huxm@marvell.com> +Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> + +diff --git a/drivers/net/wireless/marvell/mwifiex/11n_aggr.c b/drivers/net/wireless/marvell/mwifiex/11n_aggr.c +index c47d6366875d..a75013ac84d7 100644 +--- a/drivers/net/wireless/marvell/mwifiex/11n_aggr.c ++++ b/drivers/net/wireless/marvell/mwifiex/11n_aggr.c +@@ -101,13 +101,6 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv, + { + struct txpd *local_tx_pd; + struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb); +- unsigned int pad; +- int headroom = (priv->adapter->iface_type == +- MWIFIEX_USB) ? 0 : INTF_HEADER_LEN; +- +- pad = ((void *)skb->data - sizeof(*local_tx_pd) - +- headroom - NULL) & (MWIFIEX_DMA_ALIGN_SZ - 1); +- skb_push(skb, pad); + + skb_push(skb, sizeof(*local_tx_pd)); + +@@ -121,12 +114,10 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv, + local_tx_pd->bss_num = priv->bss_num; + local_tx_pd->bss_type = priv->bss_type; + /* Always zero as the data is followed by struct txpd */ +- local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd) + +- pad); ++ local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd)); + local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU); + local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len - +- sizeof(*local_tx_pd) - +- pad); ++ sizeof(*local_tx_pd)); + + if (tx_info->flags & MWIFIEX_BUF_FLAG_TDLS_PKT) + local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_TDLS_PACKET; +@@ -190,7 +181,11 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, + ra_list_flags); + return -1; + } +- skb_reserve(skb_aggr, MWIFIEX_MIN_DATA_HEADER_LEN); ++ ++ /* skb_aggr->data already 64 byte align, just reserve bus interface ++ * header and txpd. ++ */ ++ skb_reserve(skb_aggr, headroom + sizeof(struct txpd)); + tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr); + + memset(tx_info_aggr, 0, sizeof(*tx_info_aggr)); +-- +2.12.0 + diff --git a/queue/net-can-usb-gs_usb-Fix-buffer-on-stack.patch b/queue/net-can-usb-gs_usb-Fix-buffer-on-stack.patch new file mode 100644 index 0000000..f637c5c --- /dev/null +++ b/queue/net-can-usb-gs_usb-Fix-buffer-on-stack.patch @@ -0,0 +1,58 @@ +From b05c73bd1e3ec60357580eb042ee932a5ed754d5 Mon Sep 17 00:00:00 2001 +From: Maksim Salau <maksim.salau@gmail.com> +Date: Sun, 23 Apr 2017 20:31:40 +0300 +Subject: [PATCH] net: can: usb: gs_usb: Fix buffer on stack + +commit b05c73bd1e3ec60357580eb042ee932a5ed754d5 upstream. + +Allocate buffers on HEAP instead of STACK for local structures +that are to be sent using usb_control_msg(). + +Signed-off-by: Maksim Salau <maksim.salau@gmail.com> +Cc: linux-stable <stable@vger.kernel.org> # >= v4.8 +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> + +diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c +index 300349fe8dc0..eecee7f8dfb7 100644 +--- a/drivers/net/can/usb/gs_usb.c ++++ b/drivers/net/can/usb/gs_usb.c +@@ -739,13 +739,18 @@ static const struct net_device_ops gs_usb_netdev_ops = { + static int gs_usb_set_identify(struct net_device *netdev, bool do_identify) + { + struct gs_can *dev = netdev_priv(netdev); +- struct gs_identify_mode imode; ++ struct gs_identify_mode *imode; + int rc; + ++ imode = kmalloc(sizeof(*imode), GFP_KERNEL); ++ ++ if (!imode) ++ return -ENOMEM; ++ + if (do_identify) +- imode.mode = GS_CAN_IDENTIFY_ON; ++ imode->mode = GS_CAN_IDENTIFY_ON; + else +- imode.mode = GS_CAN_IDENTIFY_OFF; ++ imode->mode = GS_CAN_IDENTIFY_OFF; + + rc = usb_control_msg(interface_to_usbdev(dev->iface), + usb_sndctrlpipe(interface_to_usbdev(dev->iface), +@@ -755,10 +760,12 @@ static int gs_usb_set_identify(struct net_device *netdev, bool do_identify) + USB_RECIP_INTERFACE, + dev->channel, + 0, +- &imode, +- sizeof(imode), ++ imode, ++ sizeof(*imode), + 100); + ++ kfree(imode); ++ + return (rc > 0) ? 0 : rc; + } + +-- +2.12.0 + diff --git a/queue/net-ipv4-fix-multipath-RTM_GETROUTE-behavior-when-ii.patch b/queue/net-ipv4-fix-multipath-RTM_GETROUTE-behavior-when-ii.patch new file mode 100644 index 0000000..e592d73 --- /dev/null +++ b/queue/net-ipv4-fix-multipath-RTM_GETROUTE-behavior-when-ii.patch @@ -0,0 +1,36 @@ +From a8801799c6975601fd58ae62f48964caec2eb83f Mon Sep 17 00:00:00 2001 +From: Florian Larysch <fl@n621.de> +Date: Mon, 3 Apr 2017 16:46:09 +0200 +Subject: [PATCH] net: ipv4: fix multipath RTM_GETROUTE behavior when iif is + given + +commit a8801799c6975601fd58ae62f48964caec2eb83f upstream. + +inet_rtm_getroute synthesizes a skeletal ICMP skb, which is passed to +ip_route_input when iif is given. If a multipath route is present for +the designated destination, ip_multipath_icmp_hash ends up being called, +which uses the source/destination addresses within the skb to calculate +a hash. However, those are not set in the synthetic skb, causing it to +return an arbitrary and incorrect result. + +Instead, use UDP, which gets no such special treatment. + +Signed-off-by: Florian Larysch <fl@n621.de> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index 8471dd116771..acd69cfe2951 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -2620,7 +2620,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh) + skb_reset_network_header(skb); + + /* Bugfix: need to give ip_route_input enough of an IP header to not gag. */ +- ip_hdr(skb)->protocol = IPPROTO_ICMP; ++ ip_hdr(skb)->protocol = IPPROTO_UDP; + skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr)); + + src = tb[RTA_SRC] ? nla_get_in_addr(tb[RTA_SRC]) : 0; +-- +2.12.0 + diff --git a/queue/net-ipv6-Do-not-duplicate-DAD-on-link-up.patch b/queue/net-ipv6-Do-not-duplicate-DAD-on-link-up.patch new file mode 100644 index 0000000..554fc2f --- /dev/null +++ b/queue/net-ipv6-Do-not-duplicate-DAD-on-link-up.patch @@ -0,0 +1,117 @@ +From 6d717134a1a6e1b34a7d0d70e953037bc2642046 Mon Sep 17 00:00:00 2001 +From: David Ahern <dsahern@gmail.com> +Date: Tue, 2 May 2017 14:43:44 -0700 +Subject: [PATCH] net: ipv6: Do not duplicate DAD on link up + +commit 6d717134a1a6e1b34a7d0d70e953037bc2642046 upstream. + +Andrey reported a warning triggered by the rcu code: + +------------[ cut here ]------------ +WARNING: CPU: 1 PID: 5911 at lib/debugobjects.c:289 +debug_print_object+0x175/0x210 +ODEBUG: activate active (active state 1) object type: rcu_head hint: + (null) +Modules linked in: +CPU: 1 PID: 5911 Comm: a.out Not tainted 4.11.0-rc8+ #271 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:16 + dump_stack+0x192/0x22d lib/dump_stack.c:52 + __warn+0x19f/0x1e0 kernel/panic.c:549 + warn_slowpath_fmt+0xe0/0x120 kernel/panic.c:564 + debug_print_object+0x175/0x210 lib/debugobjects.c:286 + debug_object_activate+0x574/0x7e0 lib/debugobjects.c:442 + debug_rcu_head_queue kernel/rcu/rcu.h:75 + __call_rcu.constprop.76+0xff/0x9c0 kernel/rcu/tree.c:3229 + call_rcu_sched+0x12/0x20 kernel/rcu/tree.c:3288 + rt6_rcu_free net/ipv6/ip6_fib.c:158 + rt6_release+0x1ea/0x290 net/ipv6/ip6_fib.c:188 + fib6_del_route net/ipv6/ip6_fib.c:1461 + fib6_del+0xa42/0xdc0 net/ipv6/ip6_fib.c:1500 + __ip6_del_rt+0x100/0x160 net/ipv6/route.c:2174 + ip6_del_rt+0x140/0x1b0 net/ipv6/route.c:2187 + __ipv6_ifa_notify+0x269/0x780 net/ipv6/addrconf.c:5520 + addrconf_ifdown+0xe60/0x1a20 net/ipv6/addrconf.c:3672 +... + +Andrey's reproducer program runs in a very tight loop, calling +'unshare -n' and then spawning 2 sets of 14 threads running random ioctl +calls. The relevant networking sequence: + +1. New network namespace created via unshare -n +- ip6tnl0 device is created in down state + +2. address added to ip6tnl0 +- equivalent to ip -6 addr add dev ip6tnl0 fd00::bb/1 +- DAD is started on the address and when it completes the host + route is inserted into the FIB + +3. ip6tnl0 is brought up +- the new fixup_permanent_addr function restarts DAD on the address + +4. exit namespace +- teardown / cleanup sequence starts +- once in a blue moon, lo teardown appears to happen BEFORE teardown + of ip6tunl0 + + down on 'lo' removes the host route from the FIB since the dst->dev + for the route is loobback + + host route added to rcu callback list + * rcu callback has not run yet, so rt is NOT on the gc list so it has + NOT been marked obsolete + +5. in parallel to 4. worker_thread runs addrconf_dad_completed +- DAD on the address on ip6tnl0 completes +- calls ipv6_ifa_notify which inserts the host route + +All of that happens very quickly. The result is that a host route that +has been deleted from the IPv6 FIB and added to the RCU list is re-inserted +into the FIB. + +The exit namespace eventually gets to cleaning up ip6tnl0 which removes the +host route from the FIB again, calls the rcu function for cleanup -- and +triggers the double rcu trace. + +The root cause is duplicate DAD on the address -- steps 2 and 3. Arguably, +DAD should not be started in step 2. The interface is in the down state, +so it can not really send out requests for the address which makes starting +DAD pointless. + +Since the second DAD was introduced by a recent change, seems appropriate +to use it for the Fixes tag and have the fixup function only start DAD for +addresses in the PREDAD state which occurs in addrconf_ifdown if the +address is retained. + +Big thanks to Andrey for isolating a reliable reproducer for this problem. +Fixes: f1705ec197e7 ("net: ipv6: Make address flushing on ifdown optional") +Reported-by: Andrey Konovalov <andreyknvl@google.com> +Signed-off-by: David Ahern <dsahern@gmail.com> +Tested-by: Andrey Konovalov <andreyknvl@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index b09ac38d8dc4..a2a370b71249 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -3328,7 +3328,8 @@ static int fixup_permanent_addr(struct inet6_dev *idev, + idev->dev, 0, 0); + } + +- addrconf_dad_start(ifp); ++ if (ifp->state == INET6_IFADDR_STATE_PREDAD) ++ addrconf_dad_start(ifp); + + return 0; + } +@@ -3683,7 +3684,7 @@ restart: + if (keep) { + /* set state to skip the notifier below */ + state = INET6_IFADDR_STATE_DEAD; +- ifa->state = 0; ++ ifa->state = INET6_IFADDR_STATE_PREDAD; + if (!(ifa->flags & IFA_F_NODAD)) + ifa->flags |= IFA_F_TENTATIVE; + +-- +2.12.0 + diff --git a/queue/net-ipv6-RTF_PCPU-should-not-be-settable-from-usersp.patch b/queue/net-ipv6-RTF_PCPU-should-not-be-settable-from-usersp.patch new file mode 100644 index 0000000..63bcade --- /dev/null +++ b/queue/net-ipv6-RTF_PCPU-should-not-be-settable-from-usersp.patch @@ -0,0 +1,78 @@ +From 557c44be917c322860665be3d28376afa84aa936 Mon Sep 17 00:00:00 2001 +From: David Ahern <dsa@cumulusnetworks.com> +Date: Wed, 19 Apr 2017 14:19:43 -0700 +Subject: [PATCH] net: ipv6: RTF_PCPU should not be settable from userspace + +commit 557c44be917c322860665be3d28376afa84aa936 upstream. + +Andrey reported a fault in the IPv6 route code: + +kasan: GPF could be caused by NULL-ptr deref or user memory access +general protection fault: 0000 [#1] SMP KASAN +Modules linked in: +CPU: 1 PID: 4035 Comm: a.out Not tainted 4.11.0-rc7+ #250 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 +task: ffff880069809600 task.stack: ffff880062dc8000 +RIP: 0010:ip6_rt_cache_alloc+0xa6/0x560 net/ipv6/route.c:975 +RSP: 0018:ffff880062dced30 EFLAGS: 00010206 +RAX: dffffc0000000000 RBX: ffff8800670561c0 RCX: 0000000000000006 +RDX: 0000000000000003 RSI: ffff880062dcfb28 RDI: 0000000000000018 +RBP: ffff880062dced68 R08: 0000000000000001 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 +R13: ffff880062dcfb28 R14: dffffc0000000000 R15: 0000000000000000 +FS: 00007feebe37e7c0(0000) GS:ffff88006cb00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00000000205a0fe4 CR3: 000000006b5c9000 CR4: 00000000000006e0 +Call Trace: + ip6_pol_route+0x1512/0x1f20 net/ipv6/route.c:1128 + ip6_pol_route_output+0x4c/0x60 net/ipv6/route.c:1212 +... + +Andrey's syzkaller program passes rtmsg.rtmsg_flags with the RTF_PCPU bit +set. Flags passed to the kernel are blindly copied to the allocated +rt6_info by ip6_route_info_create making a newly inserted route appear +as though it is a per-cpu route. ip6_rt_cache_alloc sees the flag set +and expects rt->dst.from to be set - which it is not since it is not +really a per-cpu copy. The subsequent call to __ip6_dst_alloc then +generates the fault. + +Fix by checking for the flag and failing with EINVAL. + +Fixes: d52d3997f843f ("ipv6: Create percpu rt6_info") +Reported-by: Andrey Konovalov <andreyknvl@google.com> +Signed-off-by: David Ahern <dsa@cumulusnetworks.com> +Acked-by: Martin KaFai Lau <kafai@fb.com> +Tested-by: Andrey Konovalov <andreyknvl@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/include/uapi/linux/ipv6_route.h b/include/uapi/linux/ipv6_route.h +index 85bbb1799df3..d496c02e14bc 100644 +--- a/include/uapi/linux/ipv6_route.h ++++ b/include/uapi/linux/ipv6_route.h +@@ -35,7 +35,7 @@ + #define RTF_PREF(pref) ((pref) << 27) + #define RTF_PREF_MASK 0x18000000 + +-#define RTF_PCPU 0x40000000 ++#define RTF_PCPU 0x40000000 /* read-only: can not be set by user */ + #define RTF_LOCAL 0x80000000 + + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 9db1418993f2..fb174b590fd3 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -1854,6 +1854,10 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg) + int addr_type; + int err = -EINVAL; + ++ /* RTF_PCPU is an internal flag; can not be set by userspace */ ++ if (cfg->fc_flags & RTF_PCPU) ++ goto out; ++ + if (cfg->fc_dst_len > 128 || cfg->fc_src_len > 128) + goto out; + #ifndef CONFIG_IPV6_SUBTREES +-- +2.12.0 + diff --git a/queue/net-ipv6-regenerate-host-route-if-moved-to-gc-list.patch b/queue/net-ipv6-regenerate-host-route-if-moved-to-gc-list.patch new file mode 100644 index 0000000..83ba63f --- /dev/null +++ b/queue/net-ipv6-regenerate-host-route-if-moved-to-gc-list.patch @@ -0,0 +1,79 @@ +From 8048ced9beb21a52e3305f3332ae82020619f24e Mon Sep 17 00:00:00 2001 +From: David Ahern <dsa@cumulusnetworks.com> +Date: Tue, 25 Apr 2017 09:17:29 -0700 +Subject: [PATCH] net: ipv6: regenerate host route if moved to gc list + +commit 8048ced9beb21a52e3305f3332ae82020619f24e upstream. + +Taking down the loopback device wreaks havoc on IPv6 routing. By +extension, taking down a VRF device wreaks havoc on its table. + +Dmitry and Andrey both reported heap out-of-bounds reports in the IPv6 +FIB code while running syzkaller fuzzer. The root cause is a dead dst +that is on the garbage list gets reinserted into the IPv6 FIB. While on +the gc (or perhaps when it gets added to the gc list) the dst->next is +set to an IPv4 dst. A subsequent walk of the ipv6 tables causes the +out-of-bounds access. + +Andrey's reproducer was the key to getting to the bottom of this. + +With IPv6, host routes for an address have the dst->dev set to the +loopback device. When the 'lo' device is taken down, rt6_ifdown initiates +a walk of the fib evicting routes with the 'lo' device which means all +host routes are removed. That process moves the dst which is attached to +an inet6_ifaddr to the gc list and marks it as dead. + +The recent change to keep global IPv6 addresses added a new function, +fixup_permanent_addr, that is called on admin up. That function restarts +dad for an inet6_ifaddr and when it completes the host route attached +to it is inserted into the fib. Since the route was marked dead and +moved to the gc list, re-inserting the route causes the reported +out-of-bounds accesses. If the device with the address is taken down +or the address is removed, the WARN_ON in fib6_del is triggered. + +All of those faults are fixed by regenerating the host route if the +existing one has been moved to the gc list, something that can be +determined by checking if the rt6i_ref counter is 0. + +Fixes: f1705ec197e7 ("net: ipv6: Make address flushing on ifdown optional") +Reported-by: Dmitry Vyukov <dvyukov@google.com> +Reported-by: Andrey Konovalov <andreyknvl@google.com> +Signed-off-by: David Ahern <dsa@cumulusnetworks.com> +Acked-by: Martin KaFai Lau <kafai@fb.com> +Acked-by: Eric Dumazet <edumazet@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index 80ce478c4851..0ea96c4d334d 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -3271,14 +3271,24 @@ static void addrconf_gre_config(struct net_device *dev) + static int fixup_permanent_addr(struct inet6_dev *idev, + struct inet6_ifaddr *ifp) + { +- if (!ifp->rt) { +- struct rt6_info *rt; ++ /* rt6i_ref == 0 means the host route was removed from the ++ * FIB, for example, if 'lo' device is taken down. In that ++ * case regenerate the host route. ++ */ ++ if (!ifp->rt || !atomic_read(&ifp->rt->rt6i_ref)) { ++ struct rt6_info *rt, *prev; + + rt = addrconf_dst_alloc(idev, &ifp->addr, false); + if (unlikely(IS_ERR(rt))) + return PTR_ERR(rt); + ++ /* ifp->rt can be accessed outside of rtnl */ ++ spin_lock(&ifp->lock); ++ prev = ifp->rt; + ifp->rt = rt; ++ spin_unlock(&ifp->lock); ++ ++ ip6_rt_put(prev); + } + + if (!(ifp->flags & IFA_F_NOPREFIXROUTE)) { +-- +2.12.0 + diff --git a/queue/net-mdio-mux-bcm-iproc-call-mdiobus_free-in-error-pa.patch b/queue/net-mdio-mux-bcm-iproc-call-mdiobus_free-in-error-pa.patch new file mode 100644 index 0000000..a69c844 --- /dev/null +++ b/queue/net-mdio-mux-bcm-iproc-call-mdiobus_free-in-error-pa.patch @@ -0,0 +1,42 @@ +From 922c60e89d52730050c6ccca218bff40cc8bcd8e Mon Sep 17 00:00:00 2001 +From: Jon Mason <jon.mason@broadcom.com> +Date: Mon, 8 May 2017 17:48:35 -0400 +Subject: [PATCH] net: mdio-mux: bcm-iproc: call mdiobus_free() in error path + +commit 922c60e89d52730050c6ccca218bff40cc8bcd8e upstream. + +If an error is encountered in mdio_mux_init(), the error path will call +mdiobus_free(). Since mdiobus_register() has been called prior to +mdio_mux_init(), the bus->state will not be MDIOBUS_UNREGISTERED. This +causes a BUG_ON() in mdiobus_free(). To correct this issue, add an +error path for mdio_mux_init() which calls mdiobus_unregister() prior to +mdiobus_free(). + +Signed-off-by: Jon Mason <jon.mason@broadcom.com> +Fixes: 98bc865a1ec8 ("net: mdio-mux: Add MDIO mux driver for iProc SoCs") +Acked-by: Florian Fainelli <f.fainelli@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/drivers/net/phy/mdio-mux-bcm-iproc.c b/drivers/net/phy/mdio-mux-bcm-iproc.c +index 0a0412524cec..0a5f62e0efcc 100644 +--- a/drivers/net/phy/mdio-mux-bcm-iproc.c ++++ b/drivers/net/phy/mdio-mux-bcm-iproc.c +@@ -203,11 +203,14 @@ static int mdio_mux_iproc_probe(struct platform_device *pdev) + &md->mux_handle, md, md->mii_bus); + if (rc) { + dev_info(md->dev, "mdiomux initialization failed\n"); +- goto out; ++ goto out_register; + } + + dev_info(md->dev, "iProc mdiomux registered\n"); + return 0; ++ ++out_register: ++ mdiobus_unregister(bus); + out: + mdiobus_free(bus); + return rc; +-- +2.12.0 + diff --git a/queue/net-mlx5-Avoid-dereferencing-uninitialized-pointer.patch b/queue/net-mlx5-Avoid-dereferencing-uninitialized-pointer.patch new file mode 100644 index 0000000..f6d1e93 --- /dev/null +++ b/queue/net-mlx5-Avoid-dereferencing-uninitialized-pointer.patch @@ -0,0 +1,43 @@ +From e497ec680c4cd51e76bfcdd49363d9ab8d32a757 Mon Sep 17 00:00:00 2001 +From: Talat Batheesh <talatb@mellanox.com> +Date: Tue, 28 Mar 2017 16:13:41 +0300 +Subject: [PATCH] net/mlx5: Avoid dereferencing uninitialized pointer + +commit e497ec680c4cd51e76bfcdd49363d9ab8d32a757 upstream. + +In NETDEV_CHANGEUPPER event the upper_info field is valid +only when linking is true. Otherwise it should be ignored. + +Fixes: 7907f23adc18 (net/mlx5: Implement RoCE LAG feature) +Signed-off-by: Talat Batheesh <talatb@mellanox.com> +Reviewed-by: Aviv Heller <avivh@mellanox.com> +Reviewed-by: Moni Shoua <monis@mellanox.com> +Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag.c +index 55957246c0e8..b5d5519542e8 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lag.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag.c +@@ -294,7 +294,7 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev, + struct netdev_notifier_changeupper_info *info) + { + struct net_device *upper = info->upper_dev, *ndev_tmp; +- struct netdev_lag_upper_info *lag_upper_info; ++ struct netdev_lag_upper_info *lag_upper_info = NULL; + bool is_bonded; + int bond_status = 0; + int num_slaves = 0; +@@ -303,7 +303,8 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev, + if (!netif_is_lag_master(upper)) + return 0; + +- lag_upper_info = info->upper_info; ++ if (info->linking) ++ lag_upper_info = info->upper_info; + + /* The event may still be of interest if the slave does not belong to + * us, but is enslaved to a master which has one or more of our netdevs +-- +2.12.0 + diff --git a/queue/net-mlx5-Fix-driver-load-bad-flow-when-having-fw-ini.patch b/queue/net-mlx5-Fix-driver-load-bad-flow-when-having-fw-ini.patch new file mode 100644 index 0000000..265b041 --- /dev/null +++ b/queue/net-mlx5-Fix-driver-load-bad-flow-when-having-fw-ini.patch @@ -0,0 +1,32 @@ +From 55378a238e04b39cc82957d91d16499704ea719b Mon Sep 17 00:00:00 2001 +From: Mohamad Haj Yahia <mohamad@mellanox.com> +Date: Thu, 30 Mar 2017 17:00:25 +0300 +Subject: [PATCH] net/mlx5: Fix driver load bad flow when having fw + initializing timeout + +commit 55378a238e04b39cc82957d91d16499704ea719b upstream. + +If FW is stuck in initializing state we will skip the driver load, but +current error handling flow doesn't clean previously allocated command +interface resources. + +Fixes: e3297246c2c8 ('net/mlx5_core: Wait for FW readiness on startup') +Signed-off-by: Mohamad Haj Yahia <mohamad@mellanox.com> +Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c +index 60154a175bd3..0ad66324247f 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c +@@ -1029,7 +1029,7 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv, + if (err) { + dev_err(&dev->pdev->dev, "Firmware over %d MS in initializing state, aborting\n", + FW_INIT_TIMEOUT_MILI); +- goto out_err; ++ goto err_cmd_cleanup; + } + + err = mlx5_core_enable_hca(dev, 0); +-- +2.12.0 + diff --git a/queue/net-mlx5e-Fix-ETHTOOL_GRXCLSRLALL-handling.patch b/queue/net-mlx5e-Fix-ETHTOOL_GRXCLSRLALL-handling.patch new file mode 100644 index 0000000..7d56b0a --- /dev/null +++ b/queue/net-mlx5e-Fix-ETHTOOL_GRXCLSRLALL-handling.patch @@ -0,0 +1,42 @@ +From 5e82c9e4ed60beba83f46a1a5a8307b99a23e982 Mon Sep 17 00:00:00 2001 +From: Ilan Tayari <ilant@mellanox.com> +Date: Thu, 2 Mar 2017 15:49:45 +0200 +Subject: [PATCH] net/mlx5e: Fix ETHTOOL_GRXCLSRLALL handling + +commit 5e82c9e4ed60beba83f46a1a5a8307b99a23e982 upstream. + +Handler for ETHTOOL_GRXCLSRLALL must set info->data to the size +of the table, regardless of the amount of entries in it. +Existing code does not do that, and this breaks all usage of ethtool -N +or -n without explicit location, with this error: +rmgr: Invalid RX class rules table size: Success + +Set info->data to the table size. + +Tested: +ethtool -n ens8 +ethtool -N ens8 flow-type ip4 src-ip 1.1.1.1 dst-ip 2.2.2.2 action 1 +ethtool -N ens8 flow-type ip4 src-ip 1.1.1.1 dst-ip 2.2.2.2 action 1 loc 55 +ethtool -n ens8 +ethtool -N ens8 delete 1023 +ethtool -N ens8 delete 55 + +Fixes: f913a72aa008 ("net/mlx5e: Add support to get ethtool flow rules") +Signed-off-by: Ilan Tayari <ilant@mellanox.com> +Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c +index d55fff0ba388..26fc77e80f7b 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c +@@ -564,6 +564,7 @@ int mlx5e_ethtool_get_all_flows(struct mlx5e_priv *priv, struct ethtool_rxnfc *i + int idx = 0; + int err = 0; + ++ info->data = MAX_NUM_OF_ETHTOOL_RULES; + while ((!err || err == -ENOENT) && idx < info->rule_cnt) { + err = mlx5e_ethtool_get_flow(priv, info, location); + if (!err) +-- +2.12.0 + diff --git a/queue/net-mlx5e-Fix-small-packet-threshold.patch b/queue/net-mlx5e-Fix-small-packet-threshold.patch new file mode 100644 index 0000000..819bc8b --- /dev/null +++ b/queue/net-mlx5e-Fix-small-packet-threshold.patch @@ -0,0 +1,39 @@ +From cbad8cddb6ed7ef3a5f0a9a70f1711d4d7fb9a8f Mon Sep 17 00:00:00 2001 +From: Eugenia Emantayev <eugenia@mellanox.com> +Date: Wed, 22 Mar 2017 11:44:14 +0200 +Subject: [PATCH] net/mlx5e: Fix small packet threshold + +commit cbad8cddb6ed7ef3a5f0a9a70f1711d4d7fb9a8f upstream. + +RX packet headers are meant to be contained in SKB linear part, +and chose a threshold of 128. +It turns out this is not enough, i.e. for IPv6 packet over VxLAN. +In this case, UDP/IPv4 needs 42 bytes, GENEVE header is 8 bytes, +and 86 bytes for TCP/IPv6. In total 136 bytes that is more than +current 128 bytes. In this case expand header flow is reached. +The warning in skb_try_coalesce() caused by a wrong truesize +was already fixed here: +commit 158f323b9868 ("net: adjust skb->truesize in pskb_expand_head()"). +Still, we prefer to totally avoid the expand header flow for performance reasons. +Tested regular TCP_STREAM with iperf for 1 and 8 streams, no degradation was found. + +Fixes: 461017cb006a ("net/mlx5e: Support RX multi-packet WQE (Striding RQ)") +Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com> +Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h +index dc52053128bc..3d9490cd2db1 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h +@@ -90,7 +90,7 @@ + #define MLX5E_VALID_NUM_MTTS(num_mtts) (MLX5_MTT_OCTW(num_mtts) - 1 <= U16_MAX) + + #define MLX5_UMR_ALIGN (2048) +-#define MLX5_MPWRQ_SMALL_PACKET_THRESHOLD (128) ++#define MLX5_MPWRQ_SMALL_PACKET_THRESHOLD (256) + + #define MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ (64 * 1024) + #define MLX5E_DEFAULT_LRO_TIMEOUT 32 +-- +2.12.0 + diff --git a/queue/net-neigh-guard-against-NULL-solicit-method.patch b/queue/net-neigh-guard-against-NULL-solicit-method.patch new file mode 100644 index 0000000..87de93f --- /dev/null +++ b/queue/net-neigh-guard-against-NULL-solicit-method.patch @@ -0,0 +1,36 @@ +From 48481c8fa16410ffa45939b13b6c53c2ca609e5f Mon Sep 17 00:00:00 2001 +From: Eric Dumazet <edumazet@google.com> +Date: Thu, 23 Mar 2017 12:39:21 -0700 +Subject: [PATCH] net: neigh: guard against NULL solicit() method + +commit 48481c8fa16410ffa45939b13b6c53c2ca609e5f upstream. + +Dmitry posted a nice reproducer of a bug triggering in neigh_probe() +when dereferencing a NULL neigh->ops->solicit method. + +This can happen for arp_direct_ops/ndisc_direct_ops and similar, +which can be used for NUD_NOARP neighbours (created when dev->header_ops +is NULL). Admin can then force changing nud_state to some other state +that would fire neigh timer. + +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: Dmitry Vyukov <dvyukov@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/core/neighbour.c b/net/core/neighbour.c +index e7c12caa20c8..4526cbd7e28a 100644 +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -860,7 +860,8 @@ static void neigh_probe(struct neighbour *neigh) + if (skb) + skb = skb_clone(skb, GFP_ATOMIC); + write_unlock(&neigh->lock); +- neigh->ops->solicit(neigh, skb); ++ if (neigh->ops->solicit) ++ neigh->ops->solicit(neigh, skb); + atomic_inc(&neigh->probes); + kfree_skb(skb); + } +-- +2.12.0 + diff --git a/queue/net-packet-fix-overflow-in-check-for-tp_frame_nr.patch b/queue/net-packet-fix-overflow-in-check-for-tp_frame_nr.patch new file mode 100644 index 0000000..8d6df87 --- /dev/null +++ b/queue/net-packet-fix-overflow-in-check-for-tp_frame_nr.patch @@ -0,0 +1,35 @@ +From 8f8d28e4d6d815a391285e121c3a53a0b6cb9e7b Mon Sep 17 00:00:00 2001 +From: Andrey Konovalov <andreyknvl@google.com> +Date: Wed, 29 Mar 2017 16:11:21 +0200 +Subject: [PATCH] net/packet: fix overflow in check for tp_frame_nr + +commit 8f8d28e4d6d815a391285e121c3a53a0b6cb9e7b upstream. + +When calculating rb->frames_per_block * req->tp_block_nr the result +can overflow. + +Add a check that tp_block_size * tp_block_nr <= UINT_MAX. + +Since frames_per_block <= tp_block_size, the expression would +never overflow. + +Signed-off-by: Andrey Konovalov <andreyknvl@google.com> +Acked-by: Eric Dumazet <edumazet@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 2323ee35dc09..3ac286ebb2f4 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -4205,6 +4205,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, + rb->frames_per_block = req->tp_block_size / req->tp_frame_size; + if (unlikely(rb->frames_per_block == 0)) + goto out; ++ if (unlikely(req->tp_block_size > UINT_MAX / req->tp_block_nr)) ++ goto out; + if (unlikely((rb->frames_per_block * req->tp_block_nr) != + req->tp_frame_nr)) + goto out; +-- +2.12.0 + diff --git a/queue/net-packet-fix-overflow-in-check-for-tp_reserve.patch b/queue/net-packet-fix-overflow-in-check-for-tp_reserve.patch new file mode 100644 index 0000000..0a6dfef --- /dev/null +++ b/queue/net-packet-fix-overflow-in-check-for-tp_reserve.patch @@ -0,0 +1,31 @@ +From bcc5364bdcfe131e6379363f089e7b4108d35b70 Mon Sep 17 00:00:00 2001 +From: Andrey Konovalov <andreyknvl@google.com> +Date: Wed, 29 Mar 2017 16:11:22 +0200 +Subject: [PATCH] net/packet: fix overflow in check for tp_reserve + +commit bcc5364bdcfe131e6379363f089e7b4108d35b70 upstream. + +When calculating po->tp_hdrlen + po->tp_reserve the result can overflow. + +Fix by checking that tp_reserve <= INT_MAX on assign. + +Signed-off-by: Andrey Konovalov <andreyknvl@google.com> +Acked-by: Eric Dumazet <edumazet@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 3ac286ebb2f4..8489beff5c25 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -3665,6 +3665,8 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv + return -EBUSY; + if (copy_from_user(&val, optval, sizeof(val))) + return -EFAULT; ++ if (val > INT_MAX) ++ return -EINVAL; + po->tp_reserve = val; + return 0; + } +-- +2.12.0 + diff --git a/queue/net-phy-fix-auto-negotiation-stall-due-to-unavailabl.patch b/queue/net-phy-fix-auto-negotiation-stall-due-to-unavailabl.patch new file mode 100644 index 0000000..8f19bd8 --- /dev/null +++ b/queue/net-phy-fix-auto-negotiation-stall-due-to-unavailabl.patch @@ -0,0 +1,129 @@ +From f555f34fdc586a56204cd16d9a7c104ec6cb6650 Mon Sep 17 00:00:00 2001 +From: Alexander Kochetkov <al.kochet@gmail.com> +Date: Thu, 20 Apr 2017 14:00:04 +0300 +Subject: [PATCH] net: phy: fix auto-negotiation stall due to unavailable + interrupt + +commit f555f34fdc586a56204cd16d9a7c104ec6cb6650 upstream. + +The Ethernet link on an interrupt driven PHY was not coming up if the Ethernet +cable was plugged before the Ethernet interface was brought up. + +The patch trigger PHY state machine to update link state if PHY was requested to +do auto-negotiation and auto-negotiation complete flag already set. + +During power-up cycle the PHY do auto-negotiation, generate interrupt and set +auto-negotiation complete flag. Interrupt is handled by PHY state machine but +doesn't update link state because PHY is in PHY_READY state. After some time +MAC bring up, start and request PHY to do auto-negotiation. If there are no new +settings to advertise genphy_config_aneg() doesn't start PHY auto-negotiation. +PHY continue to stay in auto-negotiation complete state and doesn't fire +interrupt. At the same time PHY state machine expect that PHY started +auto-negotiation and is waiting for interrupt from PHY and it won't get it. + +Fixes: 321beec5047a ("net: phy: Use interrupts when available in NOLINK state") +Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com> +Cc: stable <stable@vger.kernel.org> # v4.9+ +Tested-by: Roger Quadros <rogerq@ti.com> +Tested-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c +index a2bfc82e95d7..97ff1278167b 100644 +--- a/drivers/net/phy/phy.c ++++ b/drivers/net/phy/phy.c +@@ -591,16 +591,18 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd) + EXPORT_SYMBOL(phy_mii_ioctl); + + /** +- * phy_start_aneg - start auto-negotiation for this PHY device ++ * phy_start_aneg_priv - start auto-negotiation for this PHY device + * @phydev: the phy_device struct ++ * @sync: indicate whether we should wait for the workqueue cancelation + * + * Description: Sanitizes the settings (if we're not autonegotiating + * them), and then calls the driver's config_aneg function. + * If the PHYCONTROL Layer is operating, we change the state to + * reflect the beginning of Auto-negotiation or forcing. + */ +-int phy_start_aneg(struct phy_device *phydev) ++static int phy_start_aneg_priv(struct phy_device *phydev, bool sync) + { ++ bool trigger = 0; + int err; + + if (!phydev->drv) +@@ -628,10 +630,40 @@ int phy_start_aneg(struct phy_device *phydev) + } + } + ++ /* Re-schedule a PHY state machine to check PHY status because ++ * negotiation may already be done and aneg interrupt may not be ++ * generated. ++ */ ++ if (phy_interrupt_is_valid(phydev) && (phydev->state == PHY_AN)) { ++ err = phy_aneg_done(phydev); ++ if (err > 0) { ++ trigger = true; ++ err = 0; ++ } ++ } ++ + out_unlock: + mutex_unlock(&phydev->lock); ++ ++ if (trigger) ++ phy_trigger_machine(phydev, sync); ++ + return err; + } ++ ++/** ++ * phy_start_aneg - start auto-negotiation for this PHY device ++ * @phydev: the phy_device struct ++ * ++ * Description: Sanitizes the settings (if we're not autonegotiating ++ * them), and then calls the driver's config_aneg function. ++ * If the PHYCONTROL Layer is operating, we change the state to ++ * reflect the beginning of Auto-negotiation or forcing. ++ */ ++int phy_start_aneg(struct phy_device *phydev) ++{ ++ return phy_start_aneg_priv(phydev, true); ++} + EXPORT_SYMBOL(phy_start_aneg); + + /** +@@ -659,7 +691,7 @@ void phy_start_machine(struct phy_device *phydev) + * state machine runs. + */ + +-static void phy_trigger_machine(struct phy_device *phydev, bool sync) ++void phy_trigger_machine(struct phy_device *phydev, bool sync) + { + if (sync) + cancel_delayed_work_sync(&phydev->state_queue); +@@ -1154,7 +1186,7 @@ void phy_state_machine(struct work_struct *work) + mutex_unlock(&phydev->lock); + + if (needs_aneg) +- err = phy_start_aneg(phydev); ++ err = phy_start_aneg_priv(phydev, false); + else if (do_suspend) + phy_suspend(phydev); + +diff --git a/include/linux/phy.h b/include/linux/phy.h +index 43a774873aa9..fb3857337151 100644 +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -852,6 +852,7 @@ void phy_change_work(struct work_struct *work); + void phy_mac_interrupt(struct phy_device *phydev, int new_link); + void phy_start_machine(struct phy_device *phydev); + void phy_stop_machine(struct phy_device *phydev); ++void phy_trigger_machine(struct phy_device *phydev, bool sync); + int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd); + int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd); + int phy_ethtool_ksettings_get(struct phy_device *phydev, +-- +2.12.0 + diff --git a/queue/net-phy-handle-state-correctly-in-phy_stop_machine.patch b/queue/net-phy-handle-state-correctly-in-phy_stop_machine.patch new file mode 100644 index 0000000..f2b6ffc --- /dev/null +++ b/queue/net-phy-handle-state-correctly-in-phy_stop_machine.patch @@ -0,0 +1,35 @@ +From 49d52e8108a21749dc2114b924c907db43358984 Mon Sep 17 00:00:00 2001 +From: Nathan Sullivan <nathan.sullivan@ni.com> +Date: Wed, 22 Mar 2017 15:27:01 -0500 +Subject: [PATCH] net: phy: handle state correctly in phy_stop_machine + +commit 49d52e8108a21749dc2114b924c907db43358984 upstream. + +If the PHY is halted on stop, then do not set the state to PHY_UP. This +ensures the phy will be restarted later in phy_start when the machine is +started again. + +Fixes: 00db8189d984 ("This patch adds a PHY Abstraction Layer to the Linux Kernel, enabling ethernet drivers to remain as ignorant as is reasonable of the connected PHY's design and operation details.") +Signed-off-by: Nathan Sullivan <nathan.sullivan@ni.com> +Signed-off-by: Brad Mouring <brad.mouring@ni.com> +Acked-by: Xander Huff <xander.huff@ni.com> +Acked-by: Kyle Roeschley <kyle.roeschley@ni.com> +Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c +index 1be69d8bc909..a2bfc82e95d7 100644 +--- a/drivers/net/phy/phy.c ++++ b/drivers/net/phy/phy.c +@@ -681,7 +681,7 @@ void phy_stop_machine(struct phy_device *phydev) + cancel_delayed_work_sync(&phydev->state_queue); + + mutex_lock(&phydev->lock); +- if (phydev->state > PHY_UP) ++ if (phydev->state > PHY_UP && phydev->state != PHY_HALTED) + phydev->state = PHY_UP; + mutex_unlock(&phydev->lock); + } +-- +2.12.0 + diff --git a/queue/net-timestamp-avoid-use-after-free-in-ip_recv_error.patch b/queue/net-timestamp-avoid-use-after-free-in-ip_recv_error.patch new file mode 100644 index 0000000..d837d27 --- /dev/null +++ b/queue/net-timestamp-avoid-use-after-free-in-ip_recv_error.patch @@ -0,0 +1,105 @@ +From 1862d6208db0aeca9c8ace44915b08d5ab2cd667 Mon Sep 17 00:00:00 2001 +From: Willem de Bruijn <willemb@google.com> +Date: Wed, 12 Apr 2017 19:24:35 -0400 +Subject: [PATCH] net-timestamp: avoid use-after-free in ip_recv_error + +commit 1862d6208db0aeca9c8ace44915b08d5ab2cd667 upstream. + +Syzkaller reported a use-after-free in ip_recv_error at line + + info->ipi_ifindex = skb->dev->ifindex; + +This function is called on dequeue from the error queue, at which +point the device pointer may no longer be valid. + +Save ifindex on enqueue in __skb_complete_tx_timestamp, when the +pointer is valid or NULL. Store it in temporary storage skb->cb. + +It is safe to reference skb->dev here, as called from device drivers +or dev_queue_xmit. The exception is when called from tcp_ack_tstamp; +in that case it is NULL and ifindex is set to 0 (invalid). + +Do not return a pktinfo cmsg if ifindex is 0. This maintains the +current behavior of not returning a cmsg if skb->dev was NULL. + +On dequeue, the ipv4 path will cast from sock_exterr_skb to +in_pktinfo. Both have ifindex as their first element, so no explicit +conversion is needed. This is by design, introduced in commit +0b922b7a829c ("net: original ingress device index in PKTINFO"). For +ipv6 ip6_datagram_support_cmsg converts to in6_pktinfo. + +Fixes: 829ae9d61165 ("net-timestamp: allow reading recv cmsg on errqueue with origin tstamp") +Reported-by: Andrey Konovalov <andreyknvl@google.com> +Signed-off-by: Willem de Bruijn <willemb@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 9f781092fda9..35c1e2460206 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -3807,6 +3807,7 @@ static void __skb_complete_tx_timestamp(struct sk_buff *skb, + serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; + serr->ee.ee_info = tstype; + serr->opt_stats = opt_stats; ++ serr->header.h4.iif = skb->dev ? skb->dev->ifindex : 0; + if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) { + serr->ee.ee_data = skb_shinfo(skb)->tskey; + if (sk->sk_protocol == IPPROTO_TCP && +diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c +index bda318ae9876..1d46d05efb0f 100644 +--- a/net/ipv4/ip_sockglue.c ++++ b/net/ipv4/ip_sockglue.c +@@ -488,16 +488,15 @@ static bool ipv4_datagram_support_cmsg(const struct sock *sk, + return false; + + /* Support IP_PKTINFO on tstamp packets if requested, to correlate +- * timestamp with egress dev. Not possible for packets without dev ++ * timestamp with egress dev. Not possible for packets without iif + * or without payload (SOF_TIMESTAMPING_OPT_TSONLY). + */ +- if ((!(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_CMSG)) || +- (!skb->dev)) ++ info = PKTINFO_SKB_CB(skb); ++ if (!(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_CMSG) || ++ !info->ipi_ifindex) + return false; + +- info = PKTINFO_SKB_CB(skb); + info->ipi_spec_dst.s_addr = ip_hdr(skb)->saddr; +- info->ipi_ifindex = skb->dev->ifindex; + return true; + } + +diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c +index eec27f87efac..e011122ebd43 100644 +--- a/net/ipv6/datagram.c ++++ b/net/ipv6/datagram.c +@@ -405,9 +405,6 @@ static inline bool ipv6_datagram_support_addr(struct sock_exterr_skb *serr) + * At one point, excluding local errors was a quick test to identify icmp/icmp6 + * errors. This is no longer true, but the test remained, so the v6 stack, + * unlike v4, also honors cmsg requests on all wifi and timestamp errors. +- * +- * Timestamp code paths do not initialize the fields expected by cmsg: +- * the PKTINFO fields in skb->cb[]. Fill those in here. + */ + static bool ip6_datagram_support_cmsg(struct sk_buff *skb, + struct sock_exterr_skb *serr) +@@ -419,14 +416,9 @@ static bool ip6_datagram_support_cmsg(struct sk_buff *skb, + if (serr->ee.ee_origin == SO_EE_ORIGIN_LOCAL) + return false; + +- if (!skb->dev) ++ if (!IP6CB(skb)->iif) + return false; + +- if (skb->protocol == htons(ETH_P_IPV6)) +- IP6CB(skb)->iif = skb->dev->ifindex; +- else +- PKTINFO_SKB_CB(skb)->ipi_ifindex = skb->dev->ifindex; +- + return true; + } + +-- +2.12.0 + diff --git a/queue/net-usb-qmi_wwan-add-Telit-ME910-support.patch b/queue/net-usb-qmi_wwan-add-Telit-ME910-support.patch new file mode 100644 index 0000000..4e90816 --- /dev/null +++ b/queue/net-usb-qmi_wwan-add-Telit-ME910-support.patch @@ -0,0 +1,31 @@ +From 4c54dc0277d0d55a9248c43aebd31858f926a056 Mon Sep 17 00:00:00 2001 +From: Daniele Palmas <dnlplm@gmail.com> +Date: Wed, 3 May 2017 10:30:11 +0200 +Subject: [PATCH] net: usb: qmi_wwan: add Telit ME910 support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 4c54dc0277d0d55a9248c43aebd31858f926a056 upstream. + +This patch adds support for Telit ME910 PID 0x1100. + +Signed-off-by: Daniele Palmas <dnlplm@gmail.com> +Acked-by: Bjørn Mork <bjorn@mork.no> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index a3ed8115747c..d7165767ca9d 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -1201,6 +1201,7 @@ static const struct usb_device_id products[] = { + {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ + {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */ ++ {QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */ + {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x1201, 2)}, /* Telit LE920, LE920A4 */ + {QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)}, /* XS Stick W100-2 from 4G Systems */ +-- +2.12.0 + diff --git a/queue/net-vrf-Fix-setting-NLM_F_EXCL-flag-when-adding-l3md.patch b/queue/net-vrf-Fix-setting-NLM_F_EXCL-flag-when-adding-l3md.patch new file mode 100644 index 0000000..fa9413e --- /dev/null +++ b/queue/net-vrf-Fix-setting-NLM_F_EXCL-flag-when-adding-l3md.patch @@ -0,0 +1,29 @@ +From 426c87caa2b4578b43cd3f689f02c65b743b2559 Mon Sep 17 00:00:00 2001 +From: David Ahern <dsa@cumulusnetworks.com> +Date: Thu, 13 Apr 2017 10:57:15 -0600 +Subject: [PATCH] net: vrf: Fix setting NLM_F_EXCL flag when adding l3mdev rule + +commit 426c87caa2b4578b43cd3f689f02c65b743b2559 upstream. + +Only need 1 l3mdev FIB rule. Fix setting NLM_F_EXCL in the nlmsghdr. + +Fixes: 1aa6c4f6b8cd8 ("net: vrf: Add l3mdev rules on first device create") +Signed-off-by: David Ahern <dsa@cumulusnetworks.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c +index d6988db1930d..7d909c8183e9 100644 +--- a/drivers/net/vrf.c ++++ b/drivers/net/vrf.c +@@ -1128,7 +1128,7 @@ static int vrf_fib_rule(const struct net_device *dev, __u8 family, bool add_it) + goto nla_put_failure; + + /* rule only needs to appear once */ +- nlh->nlmsg_flags &= NLM_F_EXCL; ++ nlh->nlmsg_flags |= NLM_F_EXCL; + + frh = nlmsg_data(nlh); + memset(frh, 0, sizeof(*frh)); +-- +2.12.0 + diff --git a/queue/netpoll-Check-for-skb-queue_mapping.patch b/queue/netpoll-Check-for-skb-queue_mapping.patch new file mode 100644 index 0000000..8f2e5c2 --- /dev/null +++ b/queue/netpoll-Check-for-skb-queue_mapping.patch @@ -0,0 +1,102 @@ +From c70b17b775edb21280e9de7531acf6db3b365274 Mon Sep 17 00:00:00 2001 +From: Tushar Dave <tushar.n.dave@oracle.com> +Date: Thu, 20 Apr 2017 15:57:31 -0700 +Subject: [PATCH] netpoll: Check for skb->queue_mapping + +commit c70b17b775edb21280e9de7531acf6db3b365274 upstream. + +Reducing real_num_tx_queues needs to be in sync with skb queue_mapping +otherwise skbs with queue_mapping greater than real_num_tx_queues +can be sent to the underlying driver and can result in kernel panic. + +One such event is running netconsole and enabling VF on the same +device. Or running netconsole and changing number of tx queues via +ethtool on same device. + +e.g. +Unable to handle kernel NULL pointer dereference +tsk->{mm,active_mm}->context = 0000000000001525 +tsk->{mm,active_mm}->pgd = fff800130ff9a000 + \|/ ____ \|/ + "@'/ .. \`@" + /_| \__/ |_\ + \__U_/ +kworker/48:1(475): Oops [#1] +CPU: 48 PID: 475 Comm: kworker/48:1 Tainted: G OE +4.11.0-rc3-davem-net+ #7 +Workqueue: events queue_process +task: fff80013113299c0 task.stack: fff800131132c000 +TSTATE: 0000004480e01600 TPC: 00000000103f9e3c TNPC: 00000000103f9e40 Y: +00000000 Tainted: G OE +TPC: <ixgbe_xmit_frame_ring+0x7c/0x6c0 [ixgbe]> +g0: 0000000000000000 g1: 0000000000003fff g2: 0000000000000000 g3: +0000000000000001 +g4: fff80013113299c0 g5: fff8001fa6808000 g6: fff800131132c000 g7: +00000000000000c0 +o0: fff8001fa760c460 o1: fff8001311329a50 o2: fff8001fa7607504 o3: +0000000000000003 +o4: fff8001f96e63a40 o5: fff8001311d77ec0 sp: fff800131132f0e1 ret_pc: +000000000049ed94 +RPC: <set_next_entity+0x34/0xb80> +l0: 0000000000000000 l1: 0000000000000800 l2: 0000000000000000 l3: +0000000000000000 +l4: 000b2aa30e34b10d l5: 0000000000000000 l6: 0000000000000000 l7: +fff8001fa7605028 +i0: fff80013111a8a00 i1: fff80013155a0780 i2: 0000000000000000 i3: +0000000000000000 +i4: 0000000000000000 i5: 0000000000100000 i6: fff800131132f1a1 i7: +00000000103fa4b0 +I7: <ixgbe_xmit_frame+0x30/0xa0 [ixgbe]> +Call Trace: + [00000000103fa4b0] ixgbe_xmit_frame+0x30/0xa0 [ixgbe] + [0000000000998c74] netpoll_start_xmit+0xf4/0x200 + [0000000000998e10] queue_process+0x90/0x160 + [0000000000485fa8] process_one_work+0x188/0x480 + [0000000000486410] worker_thread+0x170/0x4c0 + [000000000048c6b8] kthread+0xd8/0x120 + [0000000000406064] ret_from_fork+0x1c/0x2c + [0000000000000000] (null) +Disabling lock debugging due to kernel taint +Caller[00000000103fa4b0]: ixgbe_xmit_frame+0x30/0xa0 [ixgbe] +Caller[0000000000998c74]: netpoll_start_xmit+0xf4/0x200 +Caller[0000000000998e10]: queue_process+0x90/0x160 +Caller[0000000000485fa8]: process_one_work+0x188/0x480 +Caller[0000000000486410]: worker_thread+0x170/0x4c0 +Caller[000000000048c6b8]: kthread+0xd8/0x120 +Caller[0000000000406064]: ret_from_fork+0x1c/0x2c +Caller[0000000000000000]: (null) + +Signed-off-by: Tushar Dave <tushar.n.dave@oracle.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/core/netpoll.c b/net/core/netpoll.c +index 9424673009c1..29be2466970c 100644 +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -105,15 +105,21 @@ static void queue_process(struct work_struct *work) + while ((skb = skb_dequeue(&npinfo->txq))) { + struct net_device *dev = skb->dev; + struct netdev_queue *txq; ++ unsigned int q_index; + + if (!netif_device_present(dev) || !netif_running(dev)) { + kfree_skb(skb); + continue; + } + +- txq = skb_get_tx_queue(dev, skb); +- + local_irq_save(flags); ++ /* check if skb->queue_mapping is still valid */ ++ q_index = skb_get_queue_mapping(skb); ++ if (unlikely(q_index >= dev->real_num_tx_queues)) { ++ q_index = q_index % dev->real_num_tx_queues; ++ skb_set_queue_mapping(skb, q_index); ++ } ++ txq = netdev_get_tx_queue(dev, q_index); + HARD_TX_LOCK(dev, txq, smp_processor_id()); + if (netif_xmit_frozen_or_stopped(txq) || + netpoll_start_xmit(skb, dev, txq) != NETDEV_TX_OK) { +-- +2.12.0 + diff --git a/queue/nfsd-check-for-oversized-NFSv2-v3-arguments.patch b/queue/nfsd-check-for-oversized-NFSv2-v3-arguments.patch new file mode 100644 index 0000000..a56b6d5 --- /dev/null +++ b/queue/nfsd-check-for-oversized-NFSv2-v3-arguments.patch @@ -0,0 +1,102 @@ +From e6838a29ecb484c97e4efef9429643b9851fba6e Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" <bfields@redhat.com> +Date: Fri, 21 Apr 2017 16:10:18 -0400 +Subject: [PATCH] nfsd: check for oversized NFSv2/v3 arguments +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit e6838a29ecb484c97e4efef9429643b9851fba6e upstream. + +A client can append random data to the end of an NFSv2 or NFSv3 RPC call +without our complaining; we'll just stop parsing at the end of the +expected data and ignore the rest. + +Encoded arguments and replies are stored together in an array of pages, +and if a call is too large it could leave inadequate space for the +reply. This is normally OK because NFS RPC's typically have either +short arguments and long replies (like READ) or long arguments and short +replies (like WRITE). But a client that sends an incorrectly long reply +can violate those assumptions. This was observed to cause crashes. + +Also, several operations increment rq_next_page in the decode routine +before checking the argument size, which can leave rq_next_page pointing +well past the end of the page array, causing trouble later in +svc_free_pages. + +So, following a suggestion from Neil Brown, add a central check to +enforce our expectation that no NFSv2/v3 call has both a large call and +a large reply. + +As followup we may also want to rewrite the encoding routines to check +more carefully that they aren't running off the end of the page array. + +We may also consider rejecting calls that have any extra garbage +appended. That would be safer, and within our rights by spec, but given +the age of our server and the NFS protocol, and the fact that we've +never enforced this before, we may need to balance that against the +possibility of breaking some oddball client. + +Reported-by: Tuomas Haanpää <thaan@synopsys.com> +Reported-by: Ari Kauppi <ari@synopsys.com> +Cc: stable@vger.kernel.org +Reviewed-by: NeilBrown <neilb@suse.com> +Signed-off-by: J. Bruce Fields <bfields@redhat.com> + +diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c +index 31e1f9593457..59979f0bbd4b 100644 +--- a/fs/nfsd/nfssvc.c ++++ b/fs/nfsd/nfssvc.c +@@ -747,6 +747,37 @@ static __be32 map_new_errors(u32 vers, __be32 nfserr) + return nfserr; + } + ++/* ++ * A write procedure can have a large argument, and a read procedure can ++ * have a large reply, but no NFSv2 or NFSv3 procedure has argument and ++ * reply that can both be larger than a page. The xdr code has taken ++ * advantage of this assumption to be a sloppy about bounds checking in ++ * some cases. Pending a rewrite of the NFSv2/v3 xdr code to fix that ++ * problem, we enforce these assumptions here: ++ */ ++static bool nfs_request_too_big(struct svc_rqst *rqstp, ++ struct svc_procedure *proc) ++{ ++ /* ++ * The ACL code has more careful bounds-checking and is not ++ * susceptible to this problem: ++ */ ++ if (rqstp->rq_prog != NFS_PROGRAM) ++ return false; ++ /* ++ * Ditto NFSv4 (which can in theory have argument and reply both ++ * more than a page): ++ */ ++ if (rqstp->rq_vers >= 4) ++ return false; ++ /* The reply will be small, we're OK: */ ++ if (proc->pc_xdrressize > 0 && ++ proc->pc_xdrressize < XDR_QUADLEN(PAGE_SIZE)) ++ return false; ++ ++ return rqstp->rq_arg.len > PAGE_SIZE; ++} ++ + int + nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) + { +@@ -759,6 +790,11 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) + rqstp->rq_vers, rqstp->rq_proc); + proc = rqstp->rq_procinfo; + ++ if (nfs_request_too_big(rqstp, proc)) { ++ dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers); ++ *statp = rpc_garbage_args; ++ return 1; ++ } + /* + * Give the xdr decoder a chance to change this if it wants + * (necessary in the NFSv4.0 compound case) +-- +2.12.0 + diff --git a/queue/nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch b/queue/nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch new file mode 100644 index 0000000..374c606 --- /dev/null +++ b/queue/nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch @@ -0,0 +1,60 @@ +From 13bf9fbff0e5e099e2b6f003a0ab8ae145436309 Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" <bfields@redhat.com> +Date: Fri, 21 Apr 2017 15:26:30 -0400 +Subject: [PATCH] nfsd: stricter decoding of write-like NFSv2/v3 ops +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 13bf9fbff0e5e099e2b6f003a0ab8ae145436309 upstream. + +The NFSv2/v3 code does not systematically check whether we decode past +the end of the buffer. This generally appears to be harmless, but there +are a few places where we do arithmetic on the pointers involved and +don't account for the possibility that a length could be negative. Add +checks to catch these. + +Reported-by: Tuomas Haanpää <thaan@synopsys.com> +Reported-by: Ari Kauppi <ari@synopsys.com> +Reviewed-by: NeilBrown <neilb@suse.com> +Cc: stable@vger.kernel.org +Signed-off-by: J. Bruce Fields <bfields@redhat.com> + +diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c +index d18cfddbe115..452334694a5d 100644 +--- a/fs/nfsd/nfs3xdr.c ++++ b/fs/nfsd/nfs3xdr.c +@@ -369,6 +369,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + args->count = ntohl(*p++); + args->stable = ntohl(*p++); + len = args->len = ntohl(*p++); ++ if ((void *)p > head->iov_base + head->iov_len) ++ return 0; + /* + * The count must equal the amount of data passed. + */ +@@ -472,6 +474,8 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, + /* first copy and check from the first page */ + old = (char*)p; + vec = &rqstp->rq_arg.head[0]; ++ if ((void *)old > vec->iov_base + vec->iov_len) ++ return 0; + avail = vec->iov_len - (old - (char*)vec->iov_base); + while (len && avail && *old) { + *new++ = *old++; +diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c +index 59bd88a23a3d..de07ff625777 100644 +--- a/fs/nfsd/nfsxdr.c ++++ b/fs/nfsd/nfsxdr.c +@@ -302,6 +302,8 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + * bytes. + */ + hdr = (void*)p - head->iov_base; ++ if (hdr > head->iov_len) ++ return 0; + dlen = head->iov_len + rqstp->rq_arg.page_len - hdr; + + /* +-- +2.12.0 + diff --git a/queue/nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch b/queue/nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch new file mode 100644 index 0000000..7c04e72 --- /dev/null +++ b/queue/nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch @@ -0,0 +1,82 @@ +From db44bac41bbfc0c0d9dd943092d8bded3c9db19b Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" <bfields@redhat.com> +Date: Tue, 25 Apr 2017 16:21:34 -0400 +Subject: [PATCH] nfsd4: minor NFSv2/v3 write decoding cleanup + +commit db44bac41bbfc0c0d9dd943092d8bded3c9db19b upstream. + +Use a couple shortcuts that will simplify a following bugfix. + +Cc: stable@vger.kernel.org +Signed-off-by: J. Bruce Fields <bfields@redhat.com> + +diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c +index dba2ff8eaa68..d18cfddbe115 100644 +--- a/fs/nfsd/nfs3xdr.c ++++ b/fs/nfsd/nfs3xdr.c +@@ -358,6 +358,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + { + unsigned int len, v, hdr, dlen; + u32 max_blocksize = svc_max_payload(rqstp); ++ struct kvec *head = rqstp->rq_arg.head; ++ struct kvec *tail = rqstp->rq_arg.tail; + + p = decode_fh(p, &args->fh); + if (!p) +@@ -377,9 +379,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + * Check to make sure that we got the right number of + * bytes. + */ +- hdr = (void*)p - rqstp->rq_arg.head[0].iov_base; +- dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len +- + rqstp->rq_arg.tail[0].iov_len - hdr; ++ hdr = (void*)p - head->iov_base; ++ dlen = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len - hdr; + /* + * Round the length of the data which was specified up to + * the next multiple of XDR units and then compare that +@@ -396,7 +397,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + len = args->len = max_blocksize; + } + rqstp->rq_vec[0].iov_base = (void*)p; +- rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr; ++ rqstp->rq_vec[0].iov_len = head->iov_len - hdr; + v = 0; + while (len > rqstp->rq_vec[v].iov_len) { + len -= rqstp->rq_vec[v].iov_len; +diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c +index 41b468a6a90f..59bd88a23a3d 100644 +--- a/fs/nfsd/nfsxdr.c ++++ b/fs/nfsd/nfsxdr.c +@@ -280,6 +280,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + struct nfsd_writeargs *args) + { + unsigned int len, hdr, dlen; ++ struct kvec *head = rqstp->rq_arg.head; + int v; + + p = decode_fh(p, &args->fh); +@@ -300,9 +301,8 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + * Check to make sure that we got the right number of + * bytes. + */ +- hdr = (void*)p - rqstp->rq_arg.head[0].iov_base; +- dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len +- - hdr; ++ hdr = (void*)p - head->iov_base; ++ dlen = head->iov_len + rqstp->rq_arg.page_len - hdr; + + /* + * Round the length of the data which was specified up to +@@ -316,7 +316,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + return 0; + + rqstp->rq_vec[0].iov_base = (void*)p; +- rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr; ++ rqstp->rq_vec[0].iov_len = head->iov_len - hdr; + v = 0; + while (len > rqstp->rq_vec[v].iov_len) { + len -= rqstp->rq_vec[v].iov_len; +-- +2.12.0 + diff --git a/queue/orangefs-clean-up-oversize-xattr-validation.patch b/queue/orangefs-clean-up-oversize-xattr-validation.patch new file mode 100644 index 0000000..8b3ba62 --- /dev/null +++ b/queue/orangefs-clean-up-oversize-xattr-validation.patch @@ -0,0 +1,77 @@ +From e675c5ec51fe2554719a7b6bcdbef0a770f2c19b Mon Sep 17 00:00:00 2001 +From: Martin Brandenburg <martin@omnibond.com> +Date: Tue, 25 Apr 2017 15:37:57 -0400 +Subject: [PATCH] orangefs: clean up oversize xattr validation + +commit e675c5ec51fe2554719a7b6bcdbef0a770f2c19b upstream. + +Also don't check flags as this has been validated by the VFS already. + +Fix an off-by-one error in the max size checking. + +Stop logging just because userspace wants to write attributes which do +not fit. + +This and the previous commit fix xfstests generic/020. + +Signed-off-by: Martin Brandenburg <martin@omnibond.com> +Cc: stable@vger.kernel.org +Signed-off-by: Mike Marshall <hubcap@omnibond.com> + +diff --git a/fs/orangefs/xattr.c b/fs/orangefs/xattr.c +index fba4db7d0512..237c9c04dc3b 100644 +--- a/fs/orangefs/xattr.c ++++ b/fs/orangefs/xattr.c +@@ -76,11 +76,8 @@ ssize_t orangefs_inode_getxattr(struct inode *inode, const char *name, + if (S_ISLNK(inode->i_mode)) + return -EOPNOTSUPP; + +- if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN) { +- gossip_err("Invalid key length (%d)\n", +- (int)strlen(name)); ++ if (strlen(name) > ORANGEFS_MAX_XATTR_NAMELEN) + return -EINVAL; +- } + + fsuid = from_kuid(&init_user_ns, current_fsuid()); + fsgid = from_kgid(&init_user_ns, current_fsgid()); +@@ -172,6 +169,9 @@ static int orangefs_inode_removexattr(struct inode *inode, const char *name, + struct orangefs_kernel_op_s *new_op = NULL; + int ret = -ENOMEM; + ++ if (strlen(name) > ORANGEFS_MAX_XATTR_NAMELEN) ++ return -EINVAL; ++ + down_write(&orangefs_inode->xattr_sem); + new_op = op_alloc(ORANGEFS_VFS_OP_REMOVEXATTR); + if (!new_op) +@@ -231,23 +231,13 @@ int orangefs_inode_setxattr(struct inode *inode, const char *name, + "%s: name %s, buffer_size %zd\n", + __func__, name, size); + +- if (size >= ORANGEFS_MAX_XATTR_VALUELEN || +- flags < 0) { +- gossip_err("orangefs_inode_setxattr: bogus values of size(%d), flags(%d)\n", +- (int)size, +- flags); ++ if (size > ORANGEFS_MAX_XATTR_VALUELEN) ++ return -EINVAL; ++ if (strlen(name) > ORANGEFS_MAX_XATTR_NAMELEN) + return -EINVAL; +- } + + internal_flag = convert_to_internal_xattr_flags(flags); + +- if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN) { +- gossip_err +- ("orangefs_inode_setxattr: bogus key size (%d)\n", +- (int)(strlen(name))); +- return -EINVAL; +- } +- + /* This is equivalent to a removexattr */ + if (size == 0 && value == NULL) { + gossip_debug(GOSSIP_XATTR_DEBUG, +-- +2.12.0 + diff --git a/queue/orangefs-do-not-check-possibly-stale-size-on-truncat.patch b/queue/orangefs-do-not-check-possibly-stale-size-on-truncat.patch new file mode 100644 index 0000000..73128af --- /dev/null +++ b/queue/orangefs-do-not-check-possibly-stale-size-on-truncat.patch @@ -0,0 +1,42 @@ +From 53950ef541675df48c219a8d665111a0e68dfc2f Mon Sep 17 00:00:00 2001 +From: Martin Brandenburg <martin@omnibond.com> +Date: Tue, 25 Apr 2017 15:38:04 -0400 +Subject: [PATCH] orangefs: do not check possibly stale size on truncate + +commit 53950ef541675df48c219a8d665111a0e68dfc2f upstream. + +Let the server figure this out because our size might be out of date or +not present. + +The bug was that + + xfs_io -f -t -c "pread -v 0 100" /mnt/foo + echo "Test" > /mnt/foo + xfs_io -f -t -c "pread -v 0 100" /mnt/foo + +fails because the second truncate did not happen if nothing had +requested the size after the write in echo. Thus i_size was zero (not +present) and the orangefs_setattr though i_size was zero and there was +nothing to do. + +Signed-off-by: Martin Brandenburg <martin@omnibond.com> +Cc: stable@vger.kernel.org +Signed-off-by: Mike Marshall <hubcap@omnibond.com> + +diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c +index 8baf5458cecf..9428ea0aac16 100644 +--- a/fs/orangefs/inode.c ++++ b/fs/orangefs/inode.c +@@ -218,8 +218,7 @@ int orangefs_setattr(struct dentry *dentry, struct iattr *iattr) + if (ret) + goto out; + +- if ((iattr->ia_valid & ATTR_SIZE) && +- iattr->ia_size != i_size_read(inode)) { ++ if (iattr->ia_valid & ATTR_SIZE) { + ret = orangefs_setattr_size(inode, iattr); + if (ret) + goto out; +-- +2.12.0 + diff --git a/queue/orangefs-do-not-set-getattr_time-on-orangefs_lookup.patch b/queue/orangefs-do-not-set-getattr_time-on-orangefs_lookup.patch new file mode 100644 index 0000000..1b06ad7 --- /dev/null +++ b/queue/orangefs-do-not-set-getattr_time-on-orangefs_lookup.patch @@ -0,0 +1,30 @@ +From 17930b252cd6f31163c259eaa99dd8aa630fb9ba Mon Sep 17 00:00:00 2001 +From: Martin Brandenburg <martin@omnibond.com> +Date: Tue, 25 Apr 2017 15:37:58 -0400 +Subject: [PATCH] orangefs: do not set getattr_time on orangefs_lookup + +commit 17930b252cd6f31163c259eaa99dd8aa630fb9ba upstream. + +Since orangefs_lookup calls orangefs_iget which calls +orangefs_inode_getattr, getattr_time will get set. + +Signed-off-by: Martin Brandenburg <martin@omnibond.com> +Cc: stable@vger.kernel.org +Signed-off-by: Mike Marshall <hubcap@omnibond.com> + +diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c +index a290ff6ec756..7c315938e9c2 100644 +--- a/fs/orangefs/namei.c ++++ b/fs/orangefs/namei.c +@@ -193,8 +193,6 @@ static struct dentry *orangefs_lookup(struct inode *dir, struct dentry *dentry, + goto out; + } + +- ORANGEFS_I(inode)->getattr_time = jiffies - 1; +- + gossip_debug(GOSSIP_NAME_DEBUG, + "%s:%s:%d " + "Found good inode [%lu] with count [%d]\n", +-- +2.12.0 + diff --git a/queue/orangefs-fix-bounds-check-for-listxattr.patch b/queue/orangefs-fix-bounds-check-for-listxattr.patch new file mode 100644 index 0000000..5c3ebf9 --- /dev/null +++ b/queue/orangefs-fix-bounds-check-for-listxattr.patch @@ -0,0 +1,27 @@ +From a956af337b9ff25822d9ce1a59c6ed0c09fc14b9 Mon Sep 17 00:00:00 2001 +From: Martin Brandenburg <martin@omnibond.com> +Date: Tue, 25 Apr 2017 15:37:56 -0400 +Subject: [PATCH] orangefs: fix bounds check for listxattr + +commit a956af337b9ff25822d9ce1a59c6ed0c09fc14b9 upstream. + +Signed-off-by: Martin Brandenburg <martin@omnibond.com> +Cc: stable@vger.kernel.org +Signed-off-by: Mike Marshall <hubcap@omnibond.com> + +diff --git a/fs/orangefs/xattr.c b/fs/orangefs/xattr.c +index 74a81b1daaac..fba4db7d0512 100644 +--- a/fs/orangefs/xattr.c ++++ b/fs/orangefs/xattr.c +@@ -358,7 +358,7 @@ try_again: + + returned_count = new_op->downcall.resp.listxattr.returned_count; + if (returned_count < 0 || +- returned_count >= ORANGEFS_MAX_XATTR_LISTLEN) { ++ returned_count > ORANGEFS_MAX_XATTR_LISTLEN) { + gossip_err("%s: impossible value for returned_count:%d:\n", + __func__, + returned_count); +-- +2.12.0 + diff --git a/queue/p9_client_readdir-fix.patch b/queue/p9_client_readdir-fix.patch new file mode 100644 index 0000000..f55b6cd --- /dev/null +++ b/queue/p9_client_readdir-fix.patch @@ -0,0 +1,31 @@ +From 71d6ad08379304128e4bdfaf0b4185d54375423e Mon Sep 17 00:00:00 2001 +From: Al Viro <viro@zeniv.linux.org.uk> +Date: Fri, 14 Apr 2017 17:22:18 -0400 +Subject: [PATCH] p9_client_readdir() fix + +commit 71d6ad08379304128e4bdfaf0b4185d54375423e upstream. + +Don't assume that server is sane and won't return more data than +asked for. + +Cc: stable@vger.kernel.org +Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> + +diff --git a/net/9p/client.c b/net/9p/client.c +index 3ce672af1596..8e5c6a8d0a37 100644 +--- a/net/9p/client.c ++++ b/net/9p/client.c +@@ -2101,6 +2101,10 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset) + trace_9p_protocol_dump(clnt, req->rc); + goto free_and_error; + } ++ if (rsize < count) { ++ pr_err("bogus RREADDIR count (%d > %d)\n", count, rsize); ++ count = rsize; ++ } + + p9_debug(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count); + +-- +2.12.0 + diff --git a/queue/padata-free-correct-variable.patch b/queue/padata-free-correct-variable.patch new file mode 100644 index 0000000..d1b1944 --- /dev/null +++ b/queue/padata-free-correct-variable.patch @@ -0,0 +1,31 @@ +From 07a77929ba672d93642a56dc2255dd21e6e2290b Mon Sep 17 00:00:00 2001 +From: "Jason A. Donenfeld" <Jason@zx2c4.com> +Date: Fri, 7 Apr 2017 02:33:30 +0200 +Subject: [PATCH] padata: free correct variable + +commit 07a77929ba672d93642a56dc2255dd21e6e2290b upstream. + +The author meant to free the variable that was just allocated, instead +of the one that failed to be allocated, but made a simple typo. This +patch rectifies that. + +Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> +Cc: stable@vger.kernel.org +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> + +diff --git a/kernel/padata.c b/kernel/padata.c +index 3202aa17492c..f1aef1639204 100644 +--- a/kernel/padata.c ++++ b/kernel/padata.c +@@ -354,7 +354,7 @@ static int padata_setup_cpumasks(struct parallel_data *pd, + + cpumask_and(pd->cpumask.pcpu, pcpumask, cpu_online_mask); + if (!alloc_cpumask_var(&pd->cpumask.cbcpu, GFP_KERNEL)) { +- free_cpumask_var(pd->cpumask.cbcpu); ++ free_cpumask_var(pd->cpumask.pcpu); + return -ENOMEM; + } + +-- +2.12.0 + diff --git a/queue/perf-auxtrace-Fix-no_size-logic-in-addr_filter__reso.patch b/queue/perf-auxtrace-Fix-no_size-logic-in-addr_filter__reso.patch new file mode 100644 index 0000000..62acbda --- /dev/null +++ b/queue/perf-auxtrace-Fix-no_size-logic-in-addr_filter__reso.patch @@ -0,0 +1,43 @@ +From c3a0bbc7ad7598dec5a204868bdf8a2b1b51df14 Mon Sep 17 00:00:00 2001 +From: Adrian Hunter <adrian.hunter@intel.com> +Date: Fri, 24 Mar 2017 14:15:52 +0200 +Subject: [PATCH] perf auxtrace: Fix no_size logic in + addr_filter__resolve_kernel_syms() + +commit c3a0bbc7ad7598dec5a204868bdf8a2b1b51df14 upstream. + +Address filtering with kernel symbols incorrectly resulted in the error +"Cannot determine size of symbol" because the no_size logic was the wrong +way around. + +Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> +Tested-by: Andi Kleen <ak@linux.intel.com> +Cc: stable@vger.kernel.org # v4.9+ +Link: http://lkml.kernel.org/r/1490357752-27942-1-git-send-email-adrian.hunter@intel.com +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> + +diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c +index c5a6e0b12452..78bd632f144d 100644 +--- a/tools/perf/util/auxtrace.c ++++ b/tools/perf/util/auxtrace.c +@@ -1826,7 +1826,7 @@ static int addr_filter__resolve_kernel_syms(struct addr_filter *filt) + filt->addr = start; + if (filt->range && !filt->size && !filt->sym_to) { + filt->size = size; +- no_size = !!size; ++ no_size = !size; + } + } + +@@ -1840,7 +1840,7 @@ static int addr_filter__resolve_kernel_syms(struct addr_filter *filt) + if (err) + return err; + filt->size = start + size - filt->addr; +- no_size = !!size; ++ no_size = !size; + } + + /* The very last symbol in kallsyms does not imply a particular size */ +-- +2.12.0 + diff --git a/queue/perf-x86-Fix-Broadwell-EP-DRAM-RAPL-events.patch b/queue/perf-x86-Fix-Broadwell-EP-DRAM-RAPL-events.patch new file mode 100644 index 0000000..d352a0a --- /dev/null +++ b/queue/perf-x86-Fix-Broadwell-EP-DRAM-RAPL-events.patch @@ -0,0 +1,46 @@ +From 33b88e708e7dfa58dc896da2a98f5719d2eb315c Mon Sep 17 00:00:00 2001 +From: Vince Weaver <vincent.weaver@maine.edu> +Date: Tue, 2 May 2017 14:08:50 -0400 +Subject: [PATCH] perf/x86: Fix Broadwell-EP DRAM RAPL events + +commit 33b88e708e7dfa58dc896da2a98f5719d2eb315c upstream. + +It appears as though the Broadwell-EP DRAM units share the special +units quirk with Haswell-EP/KNL. + +Without this patch, you get really high results (a single DRAM using 20W +of power). + +The powercap driver in drivers/powercap/intel_rapl.c already has this +change. + +Signed-off-by: Vince Weaver <vincent.weaver@maine.edu> +Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> +Cc: Arnaldo Carvalho de Melo <acme@redhat.com> +Cc: Jiri Olsa <jolsa@redhat.com> +Cc: Kan Liang <kan.liang@intel.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Stephane Eranian <eranian@gmail.com> +Cc: Stephane Eranian <eranian@google.com> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: linux-kernel@vger.kernel.org +Cc: <stable@vger.kernel.org> +Signed-off-by: Ingo Molnar <mingo@kernel.org> + +diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c +index 9d05c7e67f60..a45e2114a846 100644 +--- a/arch/x86/events/intel/rapl.c ++++ b/arch/x86/events/intel/rapl.c +@@ -761,7 +761,7 @@ static const struct x86_cpu_id rapl_cpu_match[] __initconst = { + + X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_CORE, hsw_rapl_init), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_GT3E, hsw_rapl_init), +- X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_X, hsw_rapl_init), ++ X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_X, hsx_rapl_init), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_XEON_D, hsw_rapl_init), + + X86_RAPL_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNL, knl_rapl_init), +-- +2.12.0 + diff --git a/queue/perf-x86-intel-pt-Add-format-strings-for-PTWRITE-and.patch b/queue/perf-x86-intel-pt-Add-format-strings-for-PTWRITE-and.patch new file mode 100644 index 0000000..4ff8c85 --- /dev/null +++ b/queue/perf-x86-intel-pt-Add-format-strings-for-PTWRITE-and.patch @@ -0,0 +1,65 @@ +From 5443624bedd0d23e112d5f2a919435182875bce9 Mon Sep 17 00:00:00 2001 +From: Alexander Shishkin <alexander.shishkin@linux.intel.com> +Date: Fri, 27 Jan 2017 17:16:43 +0200 +Subject: [PATCH] perf/x86/intel/pt: Add format strings for PTWRITE and power + event tracing + +commit 5443624bedd0d23e112d5f2a919435182875bce9 upstream. + +Commit: + + 8ee83b2ab3 ("perf/x86/intel/pt: Add support for PTWRITE and power event tracing") + +forgot to add format strings to the PT driver. So one could enable these features +by setting corresponding bits in the event config, but not by their mnemonic names. + +This patch adds the format strings. + +Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> +Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Cc: Arnaldo Carvalho de Melo <acme@infradead.org> +Cc: Arnaldo Carvalho de Melo <acme@redhat.com> +Cc: Borislav Petkov <bp@suse.de> +Cc: Jiri Olsa <jolsa@redhat.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Stephane Eranian <eranian@google.com> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: Vince Weaver <vincent.weaver@maine.edu> +Cc: vince@deater.net +Fixes: 8ee83b2ab3 ("perf/x86/intel/pt: Add support for PTWRITE...") +Link: http://lkml.kernel.org/r/20170127151644.8585-2-alexander.shishkin@linux.intel.com +Signed-off-by: Ingo Molnar <mingo@kernel.org> + +diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c +index 1c1b9fe705c8..5900471ee508 100644 +--- a/arch/x86/events/intel/pt.c ++++ b/arch/x86/events/intel/pt.c +@@ -99,18 +99,24 @@ static struct attribute_group pt_cap_group = { + }; + + PMU_FORMAT_ATTR(cyc, "config:1" ); ++PMU_FORMAT_ATTR(pwr_evt, "config:4" ); ++PMU_FORMAT_ATTR(fup_on_ptw, "config:5" ); + PMU_FORMAT_ATTR(mtc, "config:9" ); + PMU_FORMAT_ATTR(tsc, "config:10" ); + PMU_FORMAT_ATTR(noretcomp, "config:11" ); ++PMU_FORMAT_ATTR(ptw, "config:12" ); + PMU_FORMAT_ATTR(mtc_period, "config:14-17" ); + PMU_FORMAT_ATTR(cyc_thresh, "config:19-22" ); + PMU_FORMAT_ATTR(psb_period, "config:24-27" ); + + static struct attribute *pt_formats_attr[] = { + &format_attr_cyc.attr, ++ &format_attr_pwr_evt.attr, ++ &format_attr_fup_on_ptw.attr, + &format_attr_mtc.attr, + &format_attr_tsc.attr, + &format_attr_noretcomp.attr, ++ &format_attr_ptw.attr, + &format_attr_mtc_period.attr, + &format_attr_cyc_thresh.attr, + &format_attr_psb_period.attr, +-- +2.12.0 + diff --git a/queue/phy-qcom-usb-hs-Add-depends-on-EXTCON.patch b/queue/phy-qcom-usb-hs-Add-depends-on-EXTCON.patch new file mode 100644 index 0000000..4b06776 --- /dev/null +++ b/queue/phy-qcom-usb-hs-Add-depends-on-EXTCON.patch @@ -0,0 +1,40 @@ +From 1a09b6a7c10e22c489a8b212dd6862b1fd9674ad Mon Sep 17 00:00:00 2001 +From: Stephen Boyd <stephen.boyd@linaro.org> +Date: Thu, 9 Mar 2017 13:45:44 +0530 +Subject: [PATCH] phy: qcom-usb-hs: Add depends on EXTCON + +commit 1a09b6a7c10e22c489a8b212dd6862b1fd9674ad upstream. + +We get the following compile errors if EXTCON is enabled as a +module but this driver is builtin: + +drivers/built-in.o: In function `qcom_usb_hs_phy_power_off': +phy-qcom-usb-hs.c:(.text+0x1089): undefined reference to `extcon_unregister_notifier' +drivers/built-in.o: In function `qcom_usb_hs_phy_probe': +phy-qcom-usb-hs.c:(.text+0x11b5): undefined reference to `extcon_get_edev_by_phandle' +drivers/built-in.o: In function `qcom_usb_hs_phy_power_on': +phy-qcom-usb-hs.c:(.text+0x128e): undefined reference to `extcon_get_state' +phy-qcom-usb-hs.c:(.text+0x12a9): undefined reference to `extcon_register_notifier' + +so let's mark this as needing to follow the modular status of +the extcon framework. + +Fixes: 9994a33865f4 e2427b09ba929c2b9 (phy: Add support for Qualcomm's USB HS phy") +Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org> +Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> + +diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig +index c11044439fd4..005cadb7a3f8 100644 +--- a/drivers/phy/Kconfig ++++ b/drivers/phy/Kconfig +@@ -449,6 +449,7 @@ config PHY_QCOM_UFS + config PHY_QCOM_USB_HS + tristate "Qualcomm USB HS PHY module" + depends on USB_ULPI_BUS ++ depends on EXTCON || !EXTCON # if EXTCON=m, this cannot be built-in + select GENERIC_PHY + help + Support for the USB high-speed ULPI compliant phy on Qualcomm +-- +2.12.0 + diff --git a/queue/ping-implement-proper-locking.patch b/queue/ping-implement-proper-locking.patch new file mode 100644 index 0000000..79f0dec --- /dev/null +++ b/queue/ping-implement-proper-locking.patch @@ -0,0 +1,52 @@ +From 43a6684519ab0a6c52024b5e25322476cabad893 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet <edumazet@google.com> +Date: Fri, 24 Mar 2017 19:36:13 -0700 +Subject: [PATCH] ping: implement proper locking + +commit 43a6684519ab0a6c52024b5e25322476cabad893 upstream. + +We got a report of yet another bug in ping + +http://www.openwall.com/lists/oss-security/2017/03/24/6 + +->disconnect() is not called with socket lock held. + +Fix this by acquiring ping rwlock earlier. + +Thanks to Daniel, Alexander and Andrey for letting us know this problem. + +Fixes: c319b4d76b9e ("net: ipv4: add IPPROTO_ICMP socket kind") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: Daniel Jiang <danieljiang0415@gmail.com> +Reported-by: Solar Designer <solar@openwall.com> +Reported-by: Andrey Konovalov <andreyknvl@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c +index 2af6244b83e2..ccfbce13a633 100644 +--- a/net/ipv4/ping.c ++++ b/net/ipv4/ping.c +@@ -156,17 +156,18 @@ int ping_hash(struct sock *sk) + void ping_unhash(struct sock *sk) + { + struct inet_sock *isk = inet_sk(sk); ++ + pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num); ++ write_lock_bh(&ping_table.lock); + if (sk_hashed(sk)) { +- write_lock_bh(&ping_table.lock); + hlist_nulls_del(&sk->sk_nulls_node); + sk_nulls_node_init(&sk->sk_nulls_node); + sock_put(sk); + isk->inet_num = 0; + isk->inet_sport = 0; + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); +- write_unlock_bh(&ping_table.lock); + } ++ write_unlock_bh(&ping_table.lock); + } + EXPORT_SYMBOL_GPL(ping_unhash); + +-- +2.12.0 + diff --git a/queue/power-supply-bq24190_charger-Call-power_supply_chang.patch b/queue/power-supply-bq24190_charger-Call-power_supply_chang.patch new file mode 100644 index 0000000..bd886c9 --- /dev/null +++ b/queue/power-supply-bq24190_charger-Call-power_supply_chang.patch @@ -0,0 +1,142 @@ +From 2d9fee6a42ea170e4378b3363a7ad385d0e67281 Mon Sep 17 00:00:00 2001 +From: Liam Breck <liam@networkimprov.net> +Date: Wed, 18 Jan 2017 09:26:52 -0800 +Subject: [PATCH] power: supply: bq24190_charger: Call power_supply_changed() + for relevant component + +commit 2d9fee6a42ea170e4378b3363a7ad385d0e67281 upstream. + +We wrongly get uevents for bq24190-charger and bq24190-battery on every +register change. + +Fix by checking the association with charger and battery before +emitting uevent(s). + +Fixes: d7bf353fd0aa3 ("bq24190_charger: Add support for TI BQ24190 Battery Charger") +Signed-off-by: Liam Breck <kernel@networkimprov.net> +Acked-by: Mark Greer <mgreer@animalcreek.com> +Acked-by: Tony Lindgren <tony@atomide.com> +Signed-off-by: Sebastian Reichel <sre@kernel.org> + +diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c +index 63ea948dc8fc..bf7c30a4acfb 100644 +--- a/drivers/power/supply/bq24190_charger.c ++++ b/drivers/power/supply/bq24190_charger.c +@@ -159,7 +159,6 @@ struct bq24190_dev_info { + unsigned int gpio_int; + unsigned int irq; + struct mutex f_reg_lock; +- bool first_time; + bool charger_health_valid; + bool battery_health_valid; + bool battery_status_valid; +@@ -1197,7 +1196,10 @@ static const struct power_supply_desc bq24190_battery_desc = { + static irqreturn_t bq24190_irq_handler_thread(int irq, void *data) + { + struct bq24190_dev_info *bdi = data; +- bool alert_userspace = false; ++ const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK; ++ const u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK ++ | BQ24190_REG_F_NTC_FAULT_MASK; ++ bool alert_charger = false, alert_battery = false; + u8 ss_reg = 0, f_reg = 0; + int ret; + +@@ -1225,8 +1227,12 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data) + ret); + } + ++ if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss)) ++ alert_battery = true; ++ if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss)) ++ alert_charger = true; ++ + bdi->ss_reg = ss_reg; +- alert_userspace = true; + } + + mutex_lock(&bdi->f_reg_lock); +@@ -1239,33 +1245,23 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data) + } + + if (f_reg != bdi->f_reg) { ++ if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f)) ++ alert_battery = true; ++ if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f)) ++ alert_charger = true; ++ + bdi->f_reg = f_reg; + bdi->charger_health_valid = true; + bdi->battery_health_valid = true; + bdi->battery_status_valid = true; +- +- alert_userspace = true; + } + + mutex_unlock(&bdi->f_reg_lock); + +- /* +- * Sometimes bq24190 gives a steady trickle of interrupts even +- * though the watchdog timer is turned off and neither the STATUS +- * nor FAULT registers have changed. Weed out these sprurious +- * interrupts so userspace isn't alerted for no reason. +- * In addition, the chip always generates an interrupt after +- * register reset so we should ignore that one (the very first +- * interrupt received). +- */ +- if (alert_userspace) { +- if (!bdi->first_time) { +- power_supply_changed(bdi->charger); +- power_supply_changed(bdi->battery); +- } else { +- bdi->first_time = false; +- } +- } ++ if (alert_charger) ++ power_supply_changed(bdi->charger); ++ if (alert_battery) ++ power_supply_changed(bdi->battery); + + out: + pm_runtime_put_sync(bdi->dev); +@@ -1300,6 +1296,10 @@ static int bq24190_hw_init(struct bq24190_dev_info *bdi) + goto out; + + ret = bq24190_set_mode_host(bdi); ++ if (ret < 0) ++ goto out; ++ ++ ret = bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg); + out: + pm_runtime_put_sync(bdi->dev); + return ret; +@@ -1375,7 +1375,8 @@ static int bq24190_probe(struct i2c_client *client, + bdi->model = id->driver_data; + strncpy(bdi->model_name, id->name, I2C_NAME_SIZE); + mutex_init(&bdi->f_reg_lock); +- bdi->first_time = true; ++ bdi->f_reg = 0; ++ bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */ + bdi->charger_health_valid = false; + bdi->battery_health_valid = false; + bdi->battery_status_valid = false; +@@ -1489,6 +1490,8 @@ static int bq24190_pm_resume(struct device *dev) + struct i2c_client *client = to_i2c_client(dev); + struct bq24190_dev_info *bdi = i2c_get_clientdata(client); + ++ bdi->f_reg = 0; ++ bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */ + bdi->charger_health_valid = false; + bdi->battery_health_valid = false; + bdi->battery_status_valid = false; +@@ -1496,6 +1499,7 @@ static int bq24190_pm_resume(struct device *dev) + pm_runtime_get_sync(bdi->dev); + bq24190_register_reset(bdi); + bq24190_set_mode_host(bdi); ++ bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg); + pm_runtime_put_sync(bdi->dev); + + /* Things may have changed while suspended so alert upper layer */ +-- +2.12.0 + diff --git a/queue/power-supply-bq24190_charger-Call-set_mode_host-on-p.patch b/queue/power-supply-bq24190_charger-Call-set_mode_host-on-p.patch new file mode 100644 index 0000000..e192ee1 --- /dev/null +++ b/queue/power-supply-bq24190_charger-Call-set_mode_host-on-p.patch @@ -0,0 +1,33 @@ +From e05ad7e0741ce0505e1df157c62b22b95172bb97 Mon Sep 17 00:00:00 2001 +From: Liam Breck <liam@networkimprov.net> +Date: Wed, 18 Jan 2017 09:26:49 -0800 +Subject: [PATCH] power: supply: bq24190_charger: Call set_mode_host() on + pm_resume() + +commit e05ad7e0741ce0505e1df157c62b22b95172bb97 upstream. + +pm_resume() does a register_reset() which clears charger host mode. + +Fix by calling set_mode_host() after the reset. + +Fixes: d7bf353fd0aa3 ("bq24190_charger: Add support for TI BQ24190 Battery Charger") +Signed-off-by: Liam Breck <kernel@networkimprov.net> +Acked-by: Mark Greer <mgreer@animalcreek.com> +Acked-by: Tony Lindgren <tony@atomide.com> +Signed-off-by: Sebastian Reichel <sre@kernel.org> + +diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c +index 0f959bafed8d..9efb5e668658 100644 +--- a/drivers/power/supply/bq24190_charger.c ++++ b/drivers/power/supply/bq24190_charger.c +@@ -1494,6 +1494,7 @@ static int bq24190_pm_resume(struct device *dev) + + pm_runtime_get_sync(bdi->dev); + bq24190_register_reset(bdi); ++ bq24190_set_mode_host(bdi); + pm_runtime_put_sync(bdi->dev); + + /* Things may have changed while suspended so alert upper layer */ +-- +2.12.0 + diff --git a/queue/power-supply-bq24190_charger-Don-t-read-fault-regist.patch b/queue/power-supply-bq24190_charger-Don-t-read-fault-regist.patch new file mode 100644 index 0000000..de087fb --- /dev/null +++ b/queue/power-supply-bq24190_charger-Don-t-read-fault-regist.patch @@ -0,0 +1,211 @@ +From 68abfb8015832ddf728b911769659468efaf8bd9 Mon Sep 17 00:00:00 2001 +From: Liam Breck <liam@networkimprov.net> +Date: Wed, 18 Jan 2017 09:26:53 -0800 +Subject: [PATCH] power: supply: bq24190_charger: Don't read fault register + outside irq_handle_thread() + +commit 68abfb8015832ddf728b911769659468efaf8bd9 upstream. + +Caching the fault register after a single I2C read may not keep an accurate +value. + +Fix by doing two reads in irq_handle_thread() and using the cached value +elsewhere. If a safety timer fault later clears itself, we apparently don't get +an interrupt (INT), however other interrupts would refresh the register cache. + +From the data sheet: "When a fault occurs, the charger device sends out INT + and keeps the fault state in REG09 until the host reads the fault register. + Before the host reads REG09 and all the faults are cleared, the charger + device would not send any INT upon new faults. In order to read the + current fault status, the host has to read REG09 two times consecutively. + The 1st reads fault register status from the last read [1] and the 2nd reads + the current fault register status." + +[1] presumably a typo; should be "last fault" + +Fixes: d7bf353fd0aa3 ("bq24190_charger: Add support for TI BQ24190 Battery Charger") +Signed-off-by: Liam Breck <kernel@networkimprov.net> +Acked-by: Mark Greer <mgreer@animalcreek.com> +Acked-by: Tony Lindgren <tony@atomide.com> +Signed-off-by: Sebastian Reichel <sre@kernel.org> + +diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c +index bf7c30a4acfb..c70ce192ec1e 100644 +--- a/drivers/power/supply/bq24190_charger.c ++++ b/drivers/power/supply/bq24190_charger.c +@@ -144,10 +144,7 @@ + * so the first read after a fault returns the latched value and subsequent + * reads return the current value. In order to return the fault status + * to the user, have the interrupt handler save the reg's value and retrieve +- * it in the appropriate health/status routine. Each routine has its own +- * flag indicating whether it should use the value stored by the last run +- * of the interrupt handler or do an actual reg read. That way each routine +- * can report back whatever fault may have occured. ++ * it in the appropriate health/status routine. + */ + struct bq24190_dev_info { + struct i2c_client *client; +@@ -159,9 +156,6 @@ struct bq24190_dev_info { + unsigned int gpio_int; + unsigned int irq; + struct mutex f_reg_lock; +- bool charger_health_valid; +- bool battery_health_valid; +- bool battery_status_valid; + u8 f_reg; + u8 ss_reg; + u8 watchdog; +@@ -635,21 +629,11 @@ static int bq24190_charger_get_health(struct bq24190_dev_info *bdi, + union power_supply_propval *val) + { + u8 v; +- int health, ret; ++ int health; + + mutex_lock(&bdi->f_reg_lock); +- +- if (bdi->charger_health_valid) { +- v = bdi->f_reg; +- bdi->charger_health_valid = false; +- mutex_unlock(&bdi->f_reg_lock); +- } else { +- mutex_unlock(&bdi->f_reg_lock); +- +- ret = bq24190_read(bdi, BQ24190_REG_F, &v); +- if (ret < 0) +- return ret; +- } ++ v = bdi->f_reg; ++ mutex_unlock(&bdi->f_reg_lock); + + if (v & BQ24190_REG_F_BOOST_FAULT_MASK) { + /* +@@ -936,18 +920,8 @@ static int bq24190_battery_get_status(struct bq24190_dev_info *bdi, + int status, ret; + + mutex_lock(&bdi->f_reg_lock); +- +- if (bdi->battery_status_valid) { +- chrg_fault = bdi->f_reg; +- bdi->battery_status_valid = false; +- mutex_unlock(&bdi->f_reg_lock); +- } else { +- mutex_unlock(&bdi->f_reg_lock); +- +- ret = bq24190_read(bdi, BQ24190_REG_F, &chrg_fault); +- if (ret < 0) +- return ret; +- } ++ chrg_fault = bdi->f_reg; ++ mutex_unlock(&bdi->f_reg_lock); + + chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK; + chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT; +@@ -995,21 +969,11 @@ static int bq24190_battery_get_health(struct bq24190_dev_info *bdi, + union power_supply_propval *val) + { + u8 v; +- int health, ret; ++ int health; + + mutex_lock(&bdi->f_reg_lock); +- +- if (bdi->battery_health_valid) { +- v = bdi->f_reg; +- bdi->battery_health_valid = false; +- mutex_unlock(&bdi->f_reg_lock); +- } else { +- mutex_unlock(&bdi->f_reg_lock); +- +- ret = bq24190_read(bdi, BQ24190_REG_F, &v); +- if (ret < 0) +- return ret; +- } ++ v = bdi->f_reg; ++ mutex_unlock(&bdi->f_reg_lock); + + if (v & BQ24190_REG_F_BAT_FAULT_MASK) { + health = POWER_SUPPLY_HEALTH_OVERVOLTAGE; +@@ -1201,7 +1165,7 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data) + | BQ24190_REG_F_NTC_FAULT_MASK; + bool alert_charger = false, alert_battery = false; + u8 ss_reg = 0, f_reg = 0; +- int ret; ++ int i, ret; + + pm_runtime_get_sync(bdi->dev); + +@@ -1231,33 +1195,35 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data) + alert_battery = true; + if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss)) + alert_charger = true; +- + bdi->ss_reg = ss_reg; + } + +- mutex_lock(&bdi->f_reg_lock); +- +- ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg); +- if (ret < 0) { +- mutex_unlock(&bdi->f_reg_lock); +- dev_err(bdi->dev, "Can't read F reg: %d\n", ret); +- goto out; +- } ++ i = 0; ++ do { ++ ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg); ++ if (ret < 0) { ++ dev_err(bdi->dev, "Can't read F reg: %d\n", ret); ++ goto out; ++ } ++ } while (f_reg && ++i < 2); + + if (f_reg != bdi->f_reg) { ++ dev_info(bdi->dev, ++ "Fault: boost %d, charge %d, battery %d, ntc %d\n", ++ !!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK), ++ !!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK), ++ !!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK), ++ !!(f_reg & BQ24190_REG_F_NTC_FAULT_MASK)); ++ ++ mutex_lock(&bdi->f_reg_lock); + if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f)) + alert_battery = true; + if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f)) + alert_charger = true; +- + bdi->f_reg = f_reg; +- bdi->charger_health_valid = true; +- bdi->battery_health_valid = true; +- bdi->battery_status_valid = true; ++ mutex_unlock(&bdi->f_reg_lock); + } + +- mutex_unlock(&bdi->f_reg_lock); +- + if (alert_charger) + power_supply_changed(bdi->charger); + if (alert_battery) +@@ -1377,9 +1343,6 @@ static int bq24190_probe(struct i2c_client *client, + mutex_init(&bdi->f_reg_lock); + bdi->f_reg = 0; + bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */ +- bdi->charger_health_valid = false; +- bdi->battery_health_valid = false; +- bdi->battery_status_valid = false; + + i2c_set_clientdata(client, bdi); + +@@ -1492,9 +1455,6 @@ static int bq24190_pm_resume(struct device *dev) + + bdi->f_reg = 0; + bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */ +- bdi->charger_health_valid = false; +- bdi->battery_health_valid = false; +- bdi->battery_status_valid = false; + + pm_runtime_get_sync(bdi->dev); + bq24190_register_reset(bdi); +-- +2.12.0 + diff --git a/queue/power-supply-bq24190_charger-Fix-irq-trigger-to-IRQF.patch b/queue/power-supply-bq24190_charger-Fix-irq-trigger-to-IRQF.patch new file mode 100644 index 0000000..698b147 --- /dev/null +++ b/queue/power-supply-bq24190_charger-Fix-irq-trigger-to-IRQF.patch @@ -0,0 +1,38 @@ +From 767eee362fd72bb2ca44cc80419ca4b38c6d8369 Mon Sep 17 00:00:00 2001 +From: Liam Breck <liam@networkimprov.net> +Date: Wed, 18 Jan 2017 09:26:48 -0800 +Subject: [PATCH] power: supply: bq24190_charger: Fix irq trigger to + IRQF_TRIGGER_FALLING + +commit 767eee362fd72bb2ca44cc80419ca4b38c6d8369 upstream. + +The interrupt signal is TRIGGER_FALLING. This is is specified in the +data sheet PIN FUNCTIONS: "The INT pin sends active low, 256us +pulse to host to report charger device status and fault." + +Also the direction can be seen in the data sheet Figure 37 "BQ24190 +with D+/D- Detection and USB On-The-Go (OTG)" which shows a 10k +pull-up resistor installed for the sample configurations. + +Fixes: d7bf353fd0aa3 ("bq24190_charger: Add support for TI BQ24190 Battery Charger") +Signed-off-by: Liam Breck <kernel@networkimprov.net> +Acked-by: Mark Greer <mgreer@animalcreek.com> +Acked-by: Tony Lindgren <tony@atomide.com> +Signed-off-by: Sebastian Reichel <sre@kernel.org> + +diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c +index 2f333efa24ab..0f959bafed8d 100644 +--- a/drivers/power/supply/bq24190_charger.c ++++ b/drivers/power/supply/bq24190_charger.c +@@ -1394,7 +1394,7 @@ static int bq24190_probe(struct i2c_client *client, + + ret = devm_request_threaded_irq(dev, bdi->irq, NULL, + bq24190_irq_handler_thread, +- IRQF_TRIGGER_RISING | IRQF_ONESHOT, ++ IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + "bq24190-charger", bdi); + if (ret < 0) { + dev_err(dev, "Can't set up irq handler\n"); +-- +2.12.0 + diff --git a/queue/power-supply-bq24190_charger-Handle-fault-before-sta.patch b/queue/power-supply-bq24190_charger-Handle-fault-before-sta.patch new file mode 100644 index 0000000..45f6efb --- /dev/null +++ b/queue/power-supply-bq24190_charger-Handle-fault-before-sta.patch @@ -0,0 +1,86 @@ +From ba52e75718784fda1b683ee0bfded72a0b83b047 Mon Sep 17 00:00:00 2001 +From: Liam Breck <liam@networkimprov.net> +Date: Wed, 18 Jan 2017 09:26:54 -0800 +Subject: [PATCH] power: supply: bq24190_charger: Handle fault before status on + interrupt + +commit ba52e75718784fda1b683ee0bfded72a0b83b047 upstream. + +Reading both fault and status registers and logging any fault should +take priority over handling status register update. + +Fix by moving the status handling to later in interrupt routine. + +Fixes: d7bf353fd0aa3 ("bq24190_charger: Add support for TI BQ24190 Battery Charger") +Signed-off-by: Liam Breck <kernel@networkimprov.net> +Acked-by: Mark Greer <mgreer@animalcreek.com> +Acked-by: Tony Lindgren <tony@atomide.com> +Signed-off-by: Sebastian Reichel <sre@kernel.org> + +diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c +index c70ce192ec1e..881f481d5f14 100644 +--- a/drivers/power/supply/bq24190_charger.c ++++ b/drivers/power/supply/bq24190_charger.c +@@ -1175,29 +1175,6 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data) + goto out; + } + +- if (ss_reg != bdi->ss_reg) { +- /* +- * The device is in host mode so when PG_STAT goes from 1->0 +- * (i.e., power removed) HIZ needs to be disabled. +- */ +- if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) && +- !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) { +- ret = bq24190_write_mask(bdi, BQ24190_REG_ISC, +- BQ24190_REG_ISC_EN_HIZ_MASK, +- BQ24190_REG_ISC_EN_HIZ_SHIFT, +- 0); +- if (ret < 0) +- dev_err(bdi->dev, "Can't access ISC reg: %d\n", +- ret); +- } +- +- if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss)) +- alert_battery = true; +- if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss)) +- alert_charger = true; +- bdi->ss_reg = ss_reg; +- } +- + i = 0; + do { + ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg); +@@ -1224,6 +1201,29 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data) + mutex_unlock(&bdi->f_reg_lock); + } + ++ if (ss_reg != bdi->ss_reg) { ++ /* ++ * The device is in host mode so when PG_STAT goes from 1->0 ++ * (i.e., power removed) HIZ needs to be disabled. ++ */ ++ if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) && ++ !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) { ++ ret = bq24190_write_mask(bdi, BQ24190_REG_ISC, ++ BQ24190_REG_ISC_EN_HIZ_MASK, ++ BQ24190_REG_ISC_EN_HIZ_SHIFT, ++ 0); ++ if (ret < 0) ++ dev_err(bdi->dev, "Can't access ISC reg: %d\n", ++ ret); ++ } ++ ++ if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss)) ++ alert_battery = true; ++ if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss)) ++ alert_charger = true; ++ bdi->ss_reg = ss_reg; ++ } ++ + if (alert_charger) + power_supply_changed(bdi->charger); + if (alert_battery) +-- +2.12.0 + diff --git a/queue/power-supply-bq24190_charger-Install-irq_handler_thr.patch b/queue/power-supply-bq24190_charger-Install-irq_handler_thr.patch new file mode 100644 index 0000000..060aaa4 --- /dev/null +++ b/queue/power-supply-bq24190_charger-Install-irq_handler_thr.patch @@ -0,0 +1,99 @@ +From d62acc5ef0621463446091ebd7a345e06e9ab80c Mon Sep 17 00:00:00 2001 +From: Liam Breck <liam@networkimprov.net> +Date: Wed, 18 Jan 2017 09:26:50 -0800 +Subject: [PATCH] power: supply: bq24190_charger: Install irq_handler_thread() + at end of probe() + +commit d62acc5ef0621463446091ebd7a345e06e9ab80c upstream. + +The device specific data is not fully initialized on +request_threaded_irq(). This may cause a crash when the IRQ handler +tries to reference them. + +Fix the issue by installing IRQ handler at the end of the probe. + +Fixes: d7bf353fd0aa3 ("bq24190_charger: Add support for TI BQ24190 Battery Charger") +Signed-off-by: Liam Breck <kernel@networkimprov.net> +Acked-by: Mark Greer <mgreer@animalcreek.com> +Acked-by: Tony Lindgren <tony@atomide.com> +Signed-off-by: Sebastian Reichel <sre@kernel.org> + +diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c +index 9efb5e668658..63ea948dc8fc 100644 +--- a/drivers/power/supply/bq24190_charger.c ++++ b/drivers/power/supply/bq24190_charger.c +@@ -1392,22 +1392,13 @@ static int bq24190_probe(struct i2c_client *client, + return -EINVAL; + } + +- ret = devm_request_threaded_irq(dev, bdi->irq, NULL, +- bq24190_irq_handler_thread, +- IRQF_TRIGGER_FALLING | IRQF_ONESHOT, +- "bq24190-charger", bdi); +- if (ret < 0) { +- dev_err(dev, "Can't set up irq handler\n"); +- goto out1; +- } +- + pm_runtime_enable(dev); + pm_runtime_resume(dev); + + ret = bq24190_hw_init(bdi); + if (ret < 0) { + dev_err(dev, "Hardware init failed\n"); +- goto out2; ++ goto out1; + } + + charger_cfg.drv_data = bdi; +@@ -1418,7 +1409,7 @@ static int bq24190_probe(struct i2c_client *client, + if (IS_ERR(bdi->charger)) { + dev_err(dev, "Can't register charger\n"); + ret = PTR_ERR(bdi->charger); +- goto out2; ++ goto out1; + } + + battery_cfg.drv_data = bdi; +@@ -1427,24 +1418,34 @@ static int bq24190_probe(struct i2c_client *client, + if (IS_ERR(bdi->battery)) { + dev_err(dev, "Can't register battery\n"); + ret = PTR_ERR(bdi->battery); +- goto out3; ++ goto out2; + } + + ret = bq24190_sysfs_create_group(bdi); + if (ret) { + dev_err(dev, "Can't create sysfs entries\n"); ++ goto out3; ++ } ++ ++ ret = devm_request_threaded_irq(dev, bdi->irq, NULL, ++ bq24190_irq_handler_thread, ++ IRQF_TRIGGER_FALLING | IRQF_ONESHOT, ++ "bq24190-charger", bdi); ++ if (ret < 0) { ++ dev_err(dev, "Can't set up irq handler\n"); + goto out4; + } + + return 0; + + out4: +- power_supply_unregister(bdi->battery); ++ bq24190_sysfs_remove_group(bdi); + out3: +- power_supply_unregister(bdi->charger); ++ power_supply_unregister(bdi->battery); + out2: +- pm_runtime_disable(dev); ++ power_supply_unregister(bdi->charger); + out1: ++ pm_runtime_disable(dev); + if (bdi->gpio_int) + gpio_free(bdi->gpio_int); + +-- +2.12.0 + diff --git a/queue/power-supply-lp8788-prevent-out-of-bounds-array-acce.patch b/queue/power-supply-lp8788-prevent-out-of-bounds-array-acce.patch new file mode 100644 index 0000000..545968c --- /dev/null +++ b/queue/power-supply-lp8788-prevent-out-of-bounds-array-acce.patch @@ -0,0 +1,37 @@ +From bdd9968d35f7fcdb76089347d1529bf079534214 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Giedrius=20Statkevi=C4=8Dius?= + <giedrius.statkevicius@gmail.com> +Date: Sat, 25 Mar 2017 18:00:49 +0200 +Subject: [PATCH] power: supply: lp8788: prevent out of bounds array access +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit bdd9968d35f7fcdb76089347d1529bf079534214 upstream. + +val might become 7 in which case stime[7] (array of length 7) would be +accessed during the scnprintf call later and that will cause issues. +Obviously, string concatenation is not intended here so just a comma needs +to be added to fix the issue. + +Fixes: 98a276649358 ("power_supply: Add new lp8788 charger driver") +Signed-off-by: Giedrius Statkevičius <giedrius.statkevicius@gmail.com> +Acked-by: Milo Kim <milo.kim@ti.com> +Signed-off-by: Sebastian Reichel <sre@kernel.org> + +diff --git a/drivers/power/supply/lp8788-charger.c b/drivers/power/supply/lp8788-charger.c +index 509e2b341bd6..677f7c40b25a 100644 +--- a/drivers/power/supply/lp8788-charger.c ++++ b/drivers/power/supply/lp8788-charger.c +@@ -651,7 +651,7 @@ static ssize_t lp8788_show_eoc_time(struct device *dev, + { + struct lp8788_charger *pchg = dev_get_drvdata(dev); + char *stime[] = { "400ms", "5min", "10min", "15min", +- "20min", "25min", "30min" "No timeout" }; ++ "20min", "25min", "30min", "No timeout" }; + u8 val; + + lp8788_read_byte(pchg->lp, LP8788_CHG_EOC, &val); +-- +2.12.0 + diff --git a/queue/powerpc-Correctly-disable-latent-entropy-GCC-plugin-.patch b/queue/powerpc-Correctly-disable-latent-entropy-GCC-plugin-.patch new file mode 100644 index 0000000..636e559 --- /dev/null +++ b/queue/powerpc-Correctly-disable-latent-entropy-GCC-plugin-.patch @@ -0,0 +1,34 @@ +From eac6f8b0c7adb003776dbad9d037ee2fc64f9d62 Mon Sep 17 00:00:00 2001 +From: Andrew Donnellan <andrew.donnellan@au1.ibm.com> +Date: Tue, 6 Dec 2016 17:27:59 +1100 +Subject: [PATCH] powerpc: Correctly disable latent entropy GCC plugin on + prom_init.o + +commit eac6f8b0c7adb003776dbad9d037ee2fc64f9d62 upstream. + +Commit 38addce8b600 ("gcc-plugins: Add latent_entropy plugin") excludes +certain powerpc early boot code from the latent entropy plugin by adding +appropriate CFLAGS. It looks like this was supposed to cover +prom_init.o, but ended up saying init.o (which doesn't exist) instead. +Fix the typo. + +Fixes: 38addce8b600 ("gcc-plugins: Add latent_entropy plugin") +Signed-off-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com> +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> + +diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile +index 23f8082d7bfa..f4898e6ad18d 100644 +--- a/arch/powerpc/kernel/Makefile ++++ b/arch/powerpc/kernel/Makefile +@@ -15,7 +15,7 @@ CFLAGS_btext.o += -fPIC + endif + + CFLAGS_cputable.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) +-CFLAGS_init.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) ++CFLAGS_prom_init.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) + CFLAGS_btext.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) + CFLAGS_prom.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) + +-- +2.12.0 + diff --git a/queue/powerpc-ftrace-Fix-confusing-help-text-for-DISABLE_M.patch b/queue/powerpc-ftrace-Fix-confusing-help-text-for-DISABLE_M.patch new file mode 100644 index 0000000..52c7267 --- /dev/null +++ b/queue/powerpc-ftrace-Fix-confusing-help-text-for-DISABLE_M.patch @@ -0,0 +1,34 @@ +From 496e9cb5b2aa2ba303d2bbd08518f9be2219ab4b Mon Sep 17 00:00:00 2001 +From: Anton Blanchard <anton@samba.org> +Date: Fri, 10 Feb 2017 12:16:59 +1100 +Subject: [PATCH] powerpc/ftrace: Fix confusing help text for + DISABLE_MPROFILE_KERNEL + +commit 496e9cb5b2aa2ba303d2bbd08518f9be2219ab4b upstream. + +The final paragraph of the help text is reversed. We want to enable +this option by default, and disable it if the toolchain has a working +-mprofile-kernel. + +Fixes: 8c50b72a3b4f ("powerpc/ftrace: Add Kconfig & Make glue for mprofile-kernel") +Signed-off-by: Anton Blanchard <anton@samba.org> +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> + +diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig +index f26c2253fdf2..260dd6a371e0 100644 +--- a/arch/powerpc/Kconfig ++++ b/arch/powerpc/Kconfig +@@ -394,8 +394,8 @@ config DISABLE_MPROFILE_KERNEL + be disabled also. + + If you have a toolchain which supports mprofile-kernel, then you can +- enable this. Otherwise leave it disabled. If you're not sure, say +- "N". ++ disable this. Otherwise leave it enabled. If you're not sure, say ++ "Y". + + config MPROFILE_KERNEL + depends on PPC64 && CPU_LITTLE_ENDIAN +-- +2.12.0 + diff --git a/queue/powerpc-kprobe-Fix-oops-when-kprobed-on-stdu-instruc.patch b/queue/powerpc-kprobe-Fix-oops-when-kprobed-on-stdu-instruc.patch new file mode 100644 index 0000000..8df61fe --- /dev/null +++ b/queue/powerpc-kprobe-Fix-oops-when-kprobed-on-stdu-instruc.patch @@ -0,0 +1,63 @@ +From 9e1ba4f27f018742a1aa95d11e35106feba08ec1 Mon Sep 17 00:00:00 2001 +From: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> +Date: Tue, 11 Apr 2017 10:38:13 +0530 +Subject: [PATCH] powerpc/kprobe: Fix oops when kprobed on 'stdu' instruction + +commit 9e1ba4f27f018742a1aa95d11e35106feba08ec1 upstream. + +If we set a kprobe on a 'stdu' instruction on powerpc64, we see a kernel +OOPS: + + Bad kernel stack pointer cd93c840 at c000000000009868 + Oops: Bad kernel stack pointer, sig: 6 [#1] + ... + GPR00: c000001fcd93cb30 00000000cd93c840 c0000000015c5e00 00000000cd93c840 + ... + NIP [c000000000009868] resume_kernel+0x2c/0x58 + LR [c000000000006208] program_check_common+0x108/0x180 + +On a 64-bit system when the user probes on a 'stdu' instruction, the kernel does +not emulate actual store in emulate_step() because it may corrupt the exception +frame. So the kernel does the actual store operation in exception return code +i.e. resume_kernel(). + +resume_kernel() loads the saved stack pointer from memory using lwz, which only +loads the low 32-bits of the address, causing the kernel crash. + +Fix this by loading the 64-bit value instead. + +Fixes: be96f63375a1 ("powerpc: Split out instruction analysis part of emulate_step()") +Cc: stable@vger.kernel.org # v3.18+ +Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> +Reviewed-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> +Reviewed-by: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com> +[mpe: Change log massage, add stable tag] +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> + +diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S +index 6432d4bf08c8..767ef6d68c9e 100644 +--- a/arch/powerpc/kernel/entry_64.S ++++ b/arch/powerpc/kernel/entry_64.S +@@ -689,7 +689,7 @@ resume_kernel: + + addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */ + +- lwz r3,GPR1(r1) ++ ld r3,GPR1(r1) + subi r3,r3,INT_FRAME_SIZE /* dst: Allocate a trampoline exception frame */ + mr r4,r1 /* src: current exception frame */ + mr r1,r3 /* Reroute the trampoline frame to r1 */ +@@ -703,8 +703,8 @@ resume_kernel: + addi r6,r6,8 + bdnz 2b + +- /* Do real store operation to complete stwu */ +- lwz r5,GPR1(r1) ++ /* Do real store operation to complete stdu */ ++ ld r5,GPR1(r1) + std r8,0(r5) + + /* Clear _TIF_EMULATE_STACK_STORE flag */ +-- +2.12.0 + diff --git a/queue/powerpc-mm-Fixup-wrong-LPCR_VRMASD-value.patch b/queue/powerpc-mm-Fixup-wrong-LPCR_VRMASD-value.patch new file mode 100644 index 0000000..b58fbc2 --- /dev/null +++ b/queue/powerpc-mm-Fixup-wrong-LPCR_VRMASD-value.patch @@ -0,0 +1,43 @@ +From 4ab2537c4204b976e4ca350bbdc193b4649cad28 Mon Sep 17 00:00:00 2001 +From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> +Date: Thu, 8 Dec 2016 09:12:13 +0530 +Subject: [PATCH] powerpc/mm: Fixup wrong LPCR_VRMASD value + +commit 4ab2537c4204b976e4ca350bbdc193b4649cad28 upstream. + +In commit a4b349540a26af ("powerpc/mm: Cleanup LPCR defines") we updated +LPCR_VRMASD wrongly as below. + +-#define LPCR_VRMASD (0x1ful << (63-16)) ++#define LPCR_VRMASD_SH 47 ++#define LPCR_VRMASD (ASM_CONST(1) << LPCR_VRMASD_SH) + +We initialize the VRMA bits in LPCR to 0x00 in kvm. Hence using a +different mask value as above while updating lpcr should not have any +impact. + +This patch updates it to the correct value. + +Fixes: a4b349540a26 ("powerpc/mm: Cleanup LPCR defines") +Reported-by: Ram Pai <linuxram@us.ibm.com> +Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> +Signed-off-by: Jia He <hejianet@gmail.com> +Acked-by: Paul Mackerras <paulus@ozlabs.org> +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> + +diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h +index 0d4531aa2052..818c4e878e60 100644 +--- a/arch/powerpc/include/asm/reg.h ++++ b/arch/powerpc/include/asm/reg.h +@@ -338,7 +338,7 @@ + #define LPCR_DPFD_SH 52 + #define LPCR_DPFD (ASM_CONST(7) << LPCR_DPFD_SH) + #define LPCR_VRMASD_SH 47 +-#define LPCR_VRMASD (ASM_CONST(1) << LPCR_VRMASD_SH) ++#define LPCR_VRMASD (ASM_CONST(0x1f) << LPCR_VRMASD_SH) + #define LPCR_VRMA_L ASM_CONST(0x0008000000000000) + #define LPCR_VRMA_LP0 ASM_CONST(0x0001000000000000) + #define LPCR_VRMA_LP1 ASM_CONST(0x0000800000000000) +-- +2.12.0 + diff --git a/queue/powerpc-powernv-Fix-opal_exit-tracepoint-opcode.patch b/queue/powerpc-powernv-Fix-opal_exit-tracepoint-opcode.patch new file mode 100644 index 0000000..12211fd --- /dev/null +++ b/queue/powerpc-powernv-Fix-opal_exit-tracepoint-opcode.patch @@ -0,0 +1,43 @@ +From a7e0fb6c2029a780444d09560f739e020d54fe4d Mon Sep 17 00:00:00 2001 +From: Michael Ellerman <mpe@ellerman.id.au> +Date: Tue, 7 Feb 2017 21:01:01 +1100 +Subject: [PATCH] powerpc/powernv: Fix opal_exit tracepoint opcode + +commit a7e0fb6c2029a780444d09560f739e020d54fe4d upstream. + +Currently the opal_exit tracepoint usually shows the opcode as 0: + + <idle>-0 [047] d.h. 635.654292: opal_entry: opcode=63 + <idle>-0 [047] d.h. 635.654296: opal_exit: opcode=0 retval=0 + kopald-1209 [019] d... 636.420943: opal_entry: opcode=10 + kopald-1209 [019] d... 636.420959: opal_exit: opcode=0 retval=0 + +This is because we incorrectly load the opcode into r0 before calling +__trace_opal_exit(), whereas it expects the opcode in r3 (first function +parameter). In fact we are leaving the retval in r3, so opcode and +retval will always show the same value. + +Instead load the opcode into r3, resulting in: + + <idle>-0 [040] d.h. 636.618625: opal_entry: opcode=63 + <idle>-0 [040] d.h. 636.618627: opal_exit: opcode=63 retval=0 + +Fixes: c49f63530bb6 ("powernv: Add OPAL tracepoints") +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> + +diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S +index f7c19c9c57ed..63fe1b2b1175 100644 +--- a/arch/powerpc/platforms/powernv/opal-wrappers.S ++++ b/arch/powerpc/platforms/powernv/opal-wrappers.S +@@ -146,7 +146,7 @@ opal_tracepoint_entry: + opal_tracepoint_return: + std r3,STK_REG(R31)(r1) + mr r4,r3 +- ld r0,STK_REG(R23)(r1) ++ ld r3,STK_REG(R23)(r1) + bl __trace_opal_exit + ld r3,STK_REG(R31)(r1) + addi r1,r1,STACKFRAMESIZE +-- +2.12.0 + diff --git a/queue/pstore-Fix-flags-to-enable-dumps-on-powerpc.patch b/queue/pstore-Fix-flags-to-enable-dumps-on-powerpc.patch new file mode 100644 index 0000000..e4f1069 --- /dev/null +++ b/queue/pstore-Fix-flags-to-enable-dumps-on-powerpc.patch @@ -0,0 +1,35 @@ +From 041939c1ec54208b42f5cd819209173d52a29d34 Mon Sep 17 00:00:00 2001 +From: Ankit Kumar <ankit@linux.vnet.ibm.com> +Date: Thu, 27 Apr 2017 17:03:13 +0530 +Subject: [PATCH] pstore: Fix flags to enable dumps on powerpc + +commit 041939c1ec54208b42f5cd819209173d52a29d34 upstream. + +After commit c950fd6f201a kernel registers pstore write based on flag set. +Pstore write for powerpc is broken as flags(PSTORE_FLAGS_DMESG) is not set for +powerpc architecture. On panic, kernel doesn't write message to +/fs/pstore/dmesg*(Entry doesn't gets created at all). + +This patch enables pstore write for powerpc architecture by setting +PSTORE_FLAGS_DMESG flag. + +Fixes: c950fd6f201a ("pstore: Split pstore fragile flags") +Cc: stable@vger.kernel.org # v4.9+ +Signed-off-by: Ankit Kumar <ankit@linux.vnet.ibm.com> +Signed-off-by: Kees Cook <keescook@chromium.org> + +diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c +index caf2e1f36d6b..eae61b044e9e 100644 +--- a/arch/powerpc/kernel/nvram_64.c ++++ b/arch/powerpc/kernel/nvram_64.c +@@ -547,6 +547,7 @@ static ssize_t nvram_pstore_read(struct pstore_record *record) + static struct pstore_info nvram_pstore_info = { + .owner = THIS_MODULE, + .name = "nvram", ++ .flags = PSTORE_FLAGS_DMESG, + .open = nvram_pstore_open, + .read = nvram_pstore_read, + .write = nvram_pstore_write, +-- +2.12.0 + diff --git a/queue/pstore-Shut-down-worker-when-unregistering.patch b/queue/pstore-Shut-down-worker-when-unregistering.patch new file mode 100644 index 0000000..83cd020 --- /dev/null +++ b/queue/pstore-Shut-down-worker-when-unregistering.patch @@ -0,0 +1,52 @@ +From 6330d5534786d5315d56d558aa6d20740f97d80a Mon Sep 17 00:00:00 2001 +From: Kees Cook <keescook@chromium.org> +Date: Mon, 6 Mar 2017 12:42:12 -0800 +Subject: [PATCH] pstore: Shut down worker when unregistering + +commit 6330d5534786d5315d56d558aa6d20740f97d80a upstream. + +When built as a module and running with update_ms >= 0, pstore will Oops +during module unload since the work timer is still running. This makes sure +the worker is stopped before unloading. + +Signed-off-by: Kees Cook <keescook@chromium.org> +Cc: stable@vger.kernel.org + +diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c +index cfc1abd264d9..074fe85a2078 100644 +--- a/fs/pstore/platform.c ++++ b/fs/pstore/platform.c +@@ -709,6 +709,7 @@ int pstore_register(struct pstore_info *psi) + if (psi->flags & PSTORE_FLAGS_PMSG) + pstore_register_pmsg(); + ++ /* Start watching for new records, if desired. */ + if (pstore_update_ms >= 0) { + pstore_timer.expires = jiffies + + msecs_to_jiffies(pstore_update_ms); +@@ -731,6 +732,11 @@ EXPORT_SYMBOL_GPL(pstore_register); + + void pstore_unregister(struct pstore_info *psi) + { ++ /* Stop timer and make sure all work has finished. */ ++ pstore_update_ms = -1; ++ del_timer_sync(&pstore_timer); ++ flush_work(&pstore_work); ++ + if (psi->flags & PSTORE_FLAGS_PMSG) + pstore_unregister_pmsg(); + if (psi->flags & PSTORE_FLAGS_FTRACE) +@@ -830,7 +836,9 @@ static void pstore_timefunc(unsigned long dummy) + schedule_work(&pstore_work); + } + +- mod_timer(&pstore_timer, jiffies + msecs_to_jiffies(pstore_update_ms)); ++ if (pstore_update_ms >= 0) ++ mod_timer(&pstore_timer, ++ jiffies + msecs_to_jiffies(pstore_update_ms)); + } + + module_param(backend, charp, 0444); +-- +2.12.0 + diff --git a/queue/ring-buffer-Have-ring_buffer_iter_empty-return-true-.patch b/queue/ring-buffer-Have-ring_buffer_iter_empty-return-true-.patch new file mode 100644 index 0000000..12f3277 --- /dev/null +++ b/queue/ring-buffer-Have-ring_buffer_iter_empty-return-true-.patch @@ -0,0 +1,86 @@ +From 78f7a45dac2a2d2002f98a3a95f7979867868d73 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" <rostedt@goodmis.org> +Date: Wed, 19 Apr 2017 14:29:46 -0400 +Subject: [PATCH] ring-buffer: Have ring_buffer_iter_empty() return true when + empty + +commit 78f7a45dac2a2d2002f98a3a95f7979867868d73 upstream. + +I noticed that reading the snapshot file when it is empty no longer gives a +status. It suppose to show the status of the snapshot buffer as well as how +to allocate and use it. For example: + + ># cat snapshot + # tracer: nop + # + # + # * Snapshot is allocated * + # + # Snapshot commands: + # echo 0 > snapshot : Clears and frees snapshot buffer + # echo 1 > snapshot : Allocates snapshot buffer, if not already allocated. + # Takes a snapshot of the main buffer. + # echo 2 > snapshot : Clears snapshot buffer (but does not allocate or free) + # (Doesn't have to be '2' works with any number that + # is not a '0' or '1') + +But instead it just showed an empty buffer: + + ># cat snapshot + # tracer: nop + # + # entries-in-buffer/entries-written: 0/0 #P:4 + # + # _-----=> irqs-off + # / _----=> need-resched + # | / _---=> hardirq/softirq + # || / _--=> preempt-depth + # ||| / delay + # TASK-PID CPU# |||| TIMESTAMP FUNCTION + # | | | |||| | | + +What happened was that it was using the ring_buffer_iter_empty() function to +see if it was empty, and if it was, it showed the status. But that function +was returning false when it was empty. The reason was that the iter header +page was on the reader page, and the reader page was empty, but so was the +buffer itself. The check only tested to see if the iter was on the commit +page, but the commit page was no longer pointing to the reader page, but as +all pages were empty, the buffer is also. + +Cc: stable@vger.kernel.org +Fixes: 651e22f2701b ("ring-buffer: Always reset iterator to reader page") +Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> + +diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c +index 54e7a90db848..ca47a4fa2986 100644 +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -3405,11 +3405,23 @@ EXPORT_SYMBOL_GPL(ring_buffer_iter_reset); + int ring_buffer_iter_empty(struct ring_buffer_iter *iter) + { + struct ring_buffer_per_cpu *cpu_buffer; ++ struct buffer_page *reader; ++ struct buffer_page *head_page; ++ struct buffer_page *commit_page; ++ unsigned commit; + + cpu_buffer = iter->cpu_buffer; + +- return iter->head_page == cpu_buffer->commit_page && +- iter->head == rb_commit_index(cpu_buffer); ++ /* Remember, trace recording is off when iterator is in use */ ++ reader = cpu_buffer->reader_page; ++ head_page = cpu_buffer->head_page; ++ commit_page = cpu_buffer->commit_page; ++ commit = rb_page_commit(commit_page); ++ ++ return ((iter->head_page == commit_page && iter->head == commit) || ++ (iter->head_page == reader && commit_page == head_page && ++ head_page->read == commit && ++ iter->head == rb_page_commit(cpu_buffer->reader_page))); + } + EXPORT_SYMBOL_GPL(ring_buffer_iter_empty); + +-- +2.12.0 + diff --git a/queue/rtnetlink-NUL-terminate-IFLA_PHYS_PORT_NAME-string.patch b/queue/rtnetlink-NUL-terminate-IFLA_PHYS_PORT_NAME-string.patch new file mode 100644 index 0000000..ba23b3d --- /dev/null +++ b/queue/rtnetlink-NUL-terminate-IFLA_PHYS_PORT_NAME-string.patch @@ -0,0 +1,35 @@ +From 77ef033b687c3e030017c94a29bf6ea3aaaef678 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt <mschmidt@redhat.com> +Date: Thu, 4 May 2017 16:48:58 +0200 +Subject: [PATCH] rtnetlink: NUL-terminate IFLA_PHYS_PORT_NAME string + +commit 77ef033b687c3e030017c94a29bf6ea3aaaef678 upstream. + +IFLA_PHYS_PORT_NAME is a string attribute, so terminate it with \0. +Otherwise libnl3 fails to validate netlink messages with this attribute. +"ip -detail a" assumes too that the attribute is NUL-terminated when +printing it. It often was, due to padding. + +I noticed this as libvirtd failing to start on a system with sfc driver +after upgrading it to Linux 4.11, i.e. when sfc added support for +phys_port_name. + +Signed-off-by: Michal Schmidt <mschmidt@redhat.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index 6e67315ec368..bcb0f610ee42 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -1054,7 +1054,7 @@ static int rtnl_phys_port_name_fill(struct sk_buff *skb, struct net_device *dev) + return err; + } + +- if (nla_put(skb, IFLA_PHYS_PORT_NAME, strlen(name), name)) ++ if (nla_put_string(skb, IFLA_PHYS_PORT_NAME, name)) + return -EMSGSIZE; + + return 0; +-- +2.12.0 + diff --git a/queue/s390-mm-fix-CMMA-vs-KSM-vs-others.patch b/queue/s390-mm-fix-CMMA-vs-KSM-vs-others.patch new file mode 100644 index 0000000..2dca8f4 --- /dev/null +++ b/queue/s390-mm-fix-CMMA-vs-KSM-vs-others.patch @@ -0,0 +1,35 @@ +From a8f60d1fadf7b8b54449fcc9d6b15248917478ba Mon Sep 17 00:00:00 2001 +From: Christian Borntraeger <borntraeger@de.ibm.com> +Date: Sun, 9 Apr 2017 22:09:38 +0200 +Subject: [PATCH] s390/mm: fix CMMA vs KSM vs others + +commit a8f60d1fadf7b8b54449fcc9d6b15248917478ba upstream. + +On heavy paging with KSM I see guest data corruption. Turns out that +KSM will add pages to its tree, where the mapping return true for +pte_unused (or might become as such later). KSM will unmap such pages +and reinstantiate with different attributes (e.g. write protected or +special, e.g. in replace_page or write_protect_page)). This uncovered +a bug in our pagetable handling: We must remove the unused flag as +soon as an entry becomes present again. + +Cc: stable@vger.kernel.org +Signed-of-by: Christian Borntraeger <borntraeger@de.ibm.com> +Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> + +diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h +index 93e37b12e882..ecec682bb516 100644 +--- a/arch/s390/include/asm/pgtable.h ++++ b/arch/s390/include/asm/pgtable.h +@@ -1051,6 +1051,8 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, + { + if (!MACHINE_HAS_NX) + pte_val(entry) &= ~_PAGE_NOEXEC; ++ if (pte_present(entry)) ++ pte_val(entry) &= ~_PAGE_UNUSED; + if (mm_has_pgste(mm)) + ptep_set_pte_at(mm, addr, ptep, entry); + else +-- +2.12.0 + diff --git a/queue/scsi-mac_scsi-Fix-MAC_SCSI-m-option-when-SCSI-m.patch b/queue/scsi-mac_scsi-Fix-MAC_SCSI-m-option-when-SCSI-m.patch new file mode 100644 index 0000000..146bef2 --- /dev/null +++ b/queue/scsi-mac_scsi-Fix-MAC_SCSI-m-option-when-SCSI-m.patch @@ -0,0 +1,30 @@ +From 2559a1ef688f933835912c731bed2254146a9b04 Mon Sep 17 00:00:00 2001 +From: Finn Thain <fthain@telegraphics.com.au> +Date: Thu, 23 Feb 2017 09:08:02 +1100 +Subject: [PATCH] scsi: mac_scsi: Fix MAC_SCSI=m option when SCSI=m + +commit 2559a1ef688f933835912c731bed2254146a9b04 upstream. + +The mac_scsi driver still gets disabled when SCSI=m. This should have +been fixed back when I enabled the tristate but I didn't see the bug. + +Fixes: 6e9ae6d560e1 ("[PATCH] mac_scsi: Add module option to Kconfig") +Signed-off-by: Finn Thain <fthain@telegraphics.com.au> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> + +diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig +index 8aa9bd34123e..230043c1c90f 100644 +--- a/drivers/scsi/Kconfig ++++ b/drivers/scsi/Kconfig +@@ -1480,7 +1480,7 @@ config ATARI_SCSI + + config MAC_SCSI + tristate "Macintosh NCR5380 SCSI" +- depends on MAC && SCSI=y ++ depends on MAC && SCSI + select SCSI_SPI_ATTRS + help + This is the NCR 5380 SCSI controller included on most of the 68030 +-- +2.12.0 + diff --git a/queue/scsi-qla2xxx-Fix-crash-in-qla2xxx_eh_abort-on-bad-pt.patch b/queue/scsi-qla2xxx-Fix-crash-in-qla2xxx_eh_abort-on-bad-pt.patch new file mode 100644 index 0000000..aaa1a88 --- /dev/null +++ b/queue/scsi-qla2xxx-Fix-crash-in-qla2xxx_eh_abort-on-bad-pt.patch @@ -0,0 +1,33 @@ +From 5f7c2beef819d9ea2d1b814edf6f5981420e9cf8 Mon Sep 17 00:00:00 2001 +From: Bill Kuzeja <William.Kuzeja@stratus.com> +Date: Tue, 14 Mar 2017 13:28:44 -0400 +Subject: [PATCH] scsi: qla2xxx: Fix crash in qla2xxx_eh_abort on bad ptr + +commit 5f7c2beef819d9ea2d1b814edf6f5981420e9cf8 upstream. + +After a Qlogic card breaks when initializing (test case), the system can +crash in qla2xxx_eh_abort if processing anything but a scsi command type +srb. + +Fixes: 1535aa75a3d8 ("scsi: qla2xxx: fix invalid DMA access after command aborts in PCI device remove") +Signed-off-by: Bill Kuzeja <william.kuzeja@stratus.com> +Acked-By: Himanshu Madhani <himanshu.madhani@cavium.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> + +diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c +index 71b6b20ae82b..579363a6f44f 100644 +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -1617,7 +1617,8 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) + /* Don't abort commands in adapter during EEH + * recovery as it's not accessible/responding. + */ +- if (GET_CMD_SP(sp) && !ha->flags.eeh_busy) { ++ if (GET_CMD_SP(sp) && !ha->flags.eeh_busy && ++ (sp->type == SRB_SCSI_CMD)) { + /* Get a reference to the sp and drop the lock. + * The reference ensures this sp->done() call + * - and not the call in qla2xxx_eh_abort() - +-- +2.12.0 + diff --git a/queue/scsi-smartpqi-fix-time-handling.patch b/queue/scsi-smartpqi-fix-time-handling.patch new file mode 100644 index 0000000..744d948 --- /dev/null +++ b/queue/scsi-smartpqi-fix-time-handling.patch @@ -0,0 +1,51 @@ +From ed10858eadd4988260c6bc7d75fc25176342b5a7 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann <arnd@arndb.de> +Date: Fri, 17 Feb 2017 16:03:52 +0100 +Subject: [PATCH] scsi: smartpqi: fix time handling + +commit ed10858eadd4988260c6bc7d75fc25176342b5a7 upstream. + +When we have turned off RTC support, the smartpqi driver fails to build: + +ERROR: "rtc_time64_to_tm" [drivers/scsi/smartpqi/smartpqi.ko] undefined! + +This is easily avoided by using the generic 'struct tm' based helper rather +than the RTC specific one. While fixing this, I noticed that even though +the driver uses time64_t for storing seconds, it gets them from the +old 32-bit struct timeval. To address this, we can simplify the code +by calling ktime_get_real_seconds() directly. + +Fixes: 6c223761eb54 ("smartpqi: initial commit of Microsemi smartpqi driver") +Signed-off-by: Arnd Bergmann <arnd@arndb.de> +Acked-by: Don Brace <don.brace@microsemi.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> + +diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c +index 11c0dfb3dfa3..657ad15682a3 100644 +--- a/drivers/scsi/smartpqi/smartpqi_init.c ++++ b/drivers/scsi/smartpqi/smartpqi_init.c +@@ -534,8 +534,7 @@ static int pqi_write_current_time_to_host_wellness( + size_t buffer_length; + time64_t local_time; + unsigned int year; +- struct timeval time; +- struct rtc_time tm; ++ struct tm tm; + + buffer_length = sizeof(*buffer); + +@@ -552,9 +551,8 @@ static int pqi_write_current_time_to_host_wellness( + put_unaligned_le16(sizeof(buffer->time), + &buffer->time_length); + +- do_gettimeofday(&time); +- local_time = time.tv_sec - (sys_tz.tz_minuteswest * 60); +- rtc_time64_to_tm(local_time, &tm); ++ local_time = ktime_get_real_seconds(); ++ time64_to_tm(local_time, -sys_tz.tz_minuteswest * 60, &tm); + year = tm.tm_year + 1900; + + buffer->time[0] = bin2bcd(tm.tm_hour); +-- +2.12.0 + diff --git a/queue/scsi-storvsc-Workaround-for-virtual-DVD-SCSI-version.patch b/queue/scsi-storvsc-Workaround-for-virtual-DVD-SCSI-version.patch new file mode 100644 index 0000000..9b8c93a --- /dev/null +++ b/queue/scsi-storvsc-Workaround-for-virtual-DVD-SCSI-version.patch @@ -0,0 +1,92 @@ +From f1c635b439a5c01776fe3a25b1e2dc546ea82e6f Mon Sep 17 00:00:00 2001 +From: Stephen Hemminger <stephen@networkplumber.org> +Date: Tue, 7 Mar 2017 09:15:53 -0800 +Subject: [PATCH] scsi: storvsc: Workaround for virtual DVD SCSI version + +commit f1c635b439a5c01776fe3a25b1e2dc546ea82e6f upstream. + +Hyper-V host emulation of SCSI for virtual DVD device reports SCSI +version 0 (UNKNOWN) but is still capable of supporting REPORTLUN. + +Without this patch, a GEN2 Linux guest on Hyper-V will not boot 4.11 +successfully with virtual DVD ROM device. What happens is that the SCSI +scan process falls back to doing sequential probing by INQUIRY. But the +storvsc driver has a previous workaround that masks/blocks all errors +reports from INQUIRY (or MODE_SENSE) commands. This workaround causes +the scan to then populate a full set of bogus LUN's on the target and +then sends kernel spinning off into a death spiral doing block reads on +the non-existent LUNs. + +By setting the correct blacklist flags, the target with the DVD device +is scanned with REPORTLUN and that works correctly. + +Patch needs to go in current 4.11, it is safe but not necessary in older +kernels. + +Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com> +Reviewed-by: K. Y. Srinivasan <kys@microsoft.com> +Reviewed-by: Christoph Hellwig <hch@lst.de> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> + +diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c +index 585e54f6512c..f555174f2cb7 100644 +--- a/drivers/scsi/storvsc_drv.c ++++ b/drivers/scsi/storvsc_drv.c +@@ -400,8 +400,6 @@ MODULE_PARM_DESC(storvsc_vcpus_per_sub_channel, "Ratio of VCPUs to subchannels") + */ + static int storvsc_timeout = 180; + +-static int msft_blist_flags = BLIST_TRY_VPD_PAGES; +- + #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + static struct scsi_transport_template *fc_transport_template; + #endif +@@ -1383,6 +1381,22 @@ static int storvsc_do_io(struct hv_device *device, + return ret; + } + ++static int storvsc_device_alloc(struct scsi_device *sdevice) ++{ ++ /* ++ * Set blist flag to permit the reading of the VPD pages even when ++ * the target may claim SPC-2 compliance. MSFT targets currently ++ * claim SPC-2 compliance while they implement post SPC-2 features. ++ * With this flag we can correctly handle WRITE_SAME_16 issues. ++ * ++ * Hypervisor reports SCSI_UNKNOWN type for DVD ROM device but ++ * still supports REPORT LUN. ++ */ ++ sdevice->sdev_bflags = BLIST_REPORTLUN2 | BLIST_TRY_VPD_PAGES; ++ ++ return 0; ++} ++ + static int storvsc_device_configure(struct scsi_device *sdevice) + { + +@@ -1396,14 +1410,6 @@ static int storvsc_device_configure(struct scsi_device *sdevice) + sdevice->no_write_same = 1; + + /* +- * Add blist flags to permit the reading of the VPD pages even when +- * the target may claim SPC-2 compliance. MSFT targets currently +- * claim SPC-2 compliance while they implement post SPC-2 features. +- * With this patch we can correctly handle WRITE_SAME_16 issues. +- */ +- sdevice->sdev_bflags |= msft_blist_flags; +- +- /* + * If the host is WIN8 or WIN8 R2, claim conformance to SPC-3 + * if the device is a MSFT virtual device. If the host is + * WIN10 or newer, allow write_same. +@@ -1661,6 +1667,7 @@ static struct scsi_host_template scsi_driver = { + .eh_host_reset_handler = storvsc_host_reset_handler, + .proc_name = "storvsc_host", + .eh_timed_out = storvsc_eh_timed_out, ++ .slave_alloc = storvsc_device_alloc, + .slave_configure = storvsc_device_configure, + .cmd_per_lun = 255, + .this_id = -1, +-- +2.12.0 + diff --git a/queue/sctp-listen-on-the-sock-only-when-it-s-state-is-list.patch b/queue/sctp-listen-on-the-sock-only-when-it-s-state-is-list.patch new file mode 100644 index 0000000..e997ed2 --- /dev/null +++ b/queue/sctp-listen-on-the-sock-only-when-it-s-state-is-list.patch @@ -0,0 +1,38 @@ +From 34b2789f1d9bf8dcca9b5cb553d076ca2cd898ee Mon Sep 17 00:00:00 2001 +From: Xin Long <lucien.xin@gmail.com> +Date: Thu, 6 Apr 2017 13:10:52 +0800 +Subject: [PATCH] sctp: listen on the sock only when it's state is listening or + closed + +commit 34b2789f1d9bf8dcca9b5cb553d076ca2cd898ee upstream. + +Now sctp doesn't check sock's state before listening on it. It could +even cause changing a sock with any state to become a listening sock +when doing sctp_listen. + +This patch is to fix it by checking sock's state in sctp_listen, so +that it will listen on the sock with right state. + +Reported-by: Andrey Konovalov <andreyknvl@google.com> +Tested-by: Andrey Konovalov <andreyknvl@google.com> +Signed-off-by: Xin Long <lucien.xin@gmail.com> +Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index c1401f43d40f..d9d4c92e06b3 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -7034,6 +7034,9 @@ int sctp_inet_listen(struct socket *sock, int backlog) + if (sock->state != SS_UNCONNECTED) + goto out; + ++ if (!sctp_sstate(sk, LISTENING) && !sctp_sstate(sk, CLOSED)) ++ goto out; ++ + /* If backlog is zero, disable listening. */ + if (!backlog) { + if (sctp_sstate(sk, CLOSED)) +-- +2.12.0 + diff --git a/queue/selftests-x86-ldt_gdt_32-Work-around-a-glibc-sigacti.patch b/queue/selftests-x86-ldt_gdt_32-Work-around-a-glibc-sigacti.patch new file mode 100644 index 0000000..43aff9e --- /dev/null +++ b/queue/selftests-x86-ldt_gdt_32-Work-around-a-glibc-sigacti.patch @@ -0,0 +1,106 @@ +From 65973dd3fd31151823f4b8c289eebbb3fb7e6bc0 Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski <luto@kernel.org> +Date: Wed, 22 Mar 2017 14:32:29 -0700 +Subject: [PATCH] selftests/x86/ldt_gdt_32: Work around a glibc sigaction() bug + +commit 65973dd3fd31151823f4b8c289eebbb3fb7e6bc0 upstream. + +i386 glibc is buggy and calls the sigaction syscall incorrectly. + +This is asymptomatic for normal programs, but it blows up on +programs that do evil things with segmentation. The ldt_gdt +self-test is an example of such an evil program. + +This doesn't appear to be a regression -- I think I just got lucky +with the uninitialized memory that glibc threw at the kernel when I +wrote the test. + +This hackish fix manually issues sigaction(2) syscalls to undo the +damage. Without the fix, ldt_gdt_32 segfaults; with the fix, it +passes for me. + +See: https://sourceware.org/bugzilla/show_bug.cgi?id=21269 + +Signed-off-by: Andy Lutomirski <luto@kernel.org> +Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com> +Cc: Borislav Petkov <bp@alien8.de> +Cc: Brian Gerst <brgerst@gmail.com> +Cc: Denys Vlasenko <dvlasenk@redhat.com> +Cc: H. Peter Anvin <hpa@zytor.com> +Cc: Josh Poimboeuf <jpoimboe@redhat.com> +Cc: Juergen Gross <jgross@suse.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Garnier <thgarnie@google.com> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: stable@vger.kernel.org +Link: http://lkml.kernel.org/r/aaab0f9f93c9af25396f01232608c163a760a668.1490218061.git.luto@kernel.org +Signed-off-by: Ingo Molnar <mingo@kernel.org> + +diff --git a/tools/testing/selftests/x86/ldt_gdt.c b/tools/testing/selftests/x86/ldt_gdt.c +index f6121612e769..b9a22f18566a 100644 +--- a/tools/testing/selftests/x86/ldt_gdt.c ++++ b/tools/testing/selftests/x86/ldt_gdt.c +@@ -409,6 +409,51 @@ static void *threadproc(void *ctx) + } + } + ++#ifdef __i386__ ++ ++#ifndef SA_RESTORE ++#define SA_RESTORER 0x04000000 ++#endif ++ ++/* ++ * The UAPI header calls this 'struct sigaction', which conflicts with ++ * glibc. Sigh. ++ */ ++struct fake_ksigaction { ++ void *handler; /* the real type is nasty */ ++ unsigned long sa_flags; ++ void (*sa_restorer)(void); ++ unsigned char sigset[8]; ++}; ++ ++static void fix_sa_restorer(int sig) ++{ ++ struct fake_ksigaction ksa; ++ ++ if (syscall(SYS_rt_sigaction, sig, NULL, &ksa, 8) == 0) { ++ /* ++ * glibc has a nasty bug: it sometimes writes garbage to ++ * sa_restorer. This interacts quite badly with anything ++ * that fiddles with SS because it can trigger legacy ++ * stack switching. Patch it up. See: ++ * ++ * https://sourceware.org/bugzilla/show_bug.cgi?id=21269 ++ */ ++ if (!(ksa.sa_flags & SA_RESTORER) && ksa.sa_restorer) { ++ ksa.sa_restorer = NULL; ++ if (syscall(SYS_rt_sigaction, sig, &ksa, NULL, ++ sizeof(ksa.sigset)) != 0) ++ err(1, "rt_sigaction"); ++ } ++ } ++} ++#else ++static void fix_sa_restorer(int sig) ++{ ++ /* 64-bit glibc works fine. */ ++} ++#endif ++ + static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), + int flags) + { +@@ -420,6 +465,7 @@ static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), + if (sigaction(sig, &sa, 0)) + err(1, "sigaction"); + ++ fix_sa_restorer(sig); + } + + static jmp_buf jmpbuf; +-- +2.12.0 + diff --git a/queue/serial-8250_omap-Fix-probe-and-remove-for-PM-runtime.patch b/queue/serial-8250_omap-Fix-probe-and-remove-for-PM-runtime.patch new file mode 100644 index 0000000..67dfd04 --- /dev/null +++ b/queue/serial-8250_omap-Fix-probe-and-remove-for-PM-runtime.patch @@ -0,0 +1,58 @@ +From 4e0f5cc65098ea32a1e77baae74215b9bd5276b1 Mon Sep 17 00:00:00 2001 +From: Tony Lindgren <tony@atomide.com> +Date: Fri, 20 Jan 2017 12:22:31 -0800 +Subject: [PATCH] serial: 8250_omap: Fix probe and remove for PM runtime + +commit 4e0f5cc65098ea32a1e77baae74215b9bd5276b1 upstream. + +Otherwise the interconnect related code implementing PM runtime will +produce these errors on a failed probe: + +omap_uart 48066000.serial: omap_device: omap_device_enable() called from invalid state 1 +omap_uart 48066000.serial: use pm_runtime_put_sync_suspend() in driver? + +Note that we now also need to check for priv in omap8250_runtime_suspend() +as it has not yet been registered if probe fails. And we need to use +pm_runtime_put_sync() to properly idle the device like we already do +in omap8250_remove(). + +Fixes: 61929cf0169d ("tty: serial: Add 8250-core based omap driver") +Signed-off-by: Tony Lindgren <tony@atomide.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c +index 68a6393d9636..e7e64913a748 100644 +--- a/drivers/tty/serial/8250/8250_omap.c ++++ b/drivers/tty/serial/8250/8250_omap.c +@@ -1235,7 +1235,8 @@ static int omap8250_probe(struct platform_device *pdev) + pm_runtime_put_autosuspend(&pdev->dev); + return 0; + err: +- pm_runtime_put(&pdev->dev); ++ pm_runtime_dont_use_autosuspend(&pdev->dev); ++ pm_runtime_put_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); + return ret; + } +@@ -1244,6 +1245,7 @@ static int omap8250_remove(struct platform_device *pdev) + { + struct omap8250_priv *priv = platform_get_drvdata(pdev); + ++ pm_runtime_dont_use_autosuspend(&pdev->dev); + pm_runtime_put_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); + serial8250_unregister_port(priv->line); +@@ -1343,6 +1345,10 @@ static int omap8250_runtime_suspend(struct device *dev) + struct omap8250_priv *priv = dev_get_drvdata(dev); + struct uart_8250_port *up; + ++ /* In case runtime-pm tries this before we are setup */ ++ if (!priv) ++ return 0; ++ + up = serial8250_get_port(priv->line); + /* + * When using 'no_console_suspend', the console UART must not be +-- +2.12.0 + diff --git a/queue/serial-omap-fix-runtime-pm-handling-on-unbind.patch b/queue/serial-omap-fix-runtime-pm-handling-on-unbind.patch new file mode 100644 index 0000000..4cdbc1a --- /dev/null +++ b/queue/serial-omap-fix-runtime-pm-handling-on-unbind.patch @@ -0,0 +1,66 @@ +From 099bd73dc17ed77aa8c98323e043613b6e8f54fc Mon Sep 17 00:00:00 2001 +From: Johan Hovold <johan@kernel.org> +Date: Mon, 10 Apr 2017 11:21:38 +0200 +Subject: [PATCH] serial: omap: fix runtime-pm handling on unbind + +commit 099bd73dc17ed77aa8c98323e043613b6e8f54fc upstream. + +An unbalanced and misplaced synchronous put was used to suspend the +device on driver unbind, something which with a likewise misplaced +pm_runtime_disable leads to external aborts when an open port is being +removed. + +Unhandled fault: external abort on non-linefetch (0x1028) at 0xfa024010 +... +[<c046e760>] (serial_omap_set_mctrl) from [<c046a064>] (uart_update_mctrl+0x50/0x60) +[<c046a064>] (uart_update_mctrl) from [<c046a400>] (uart_shutdown+0xbc/0x138) +[<c046a400>] (uart_shutdown) from [<c046bd2c>] (uart_hangup+0x94/0x190) +[<c046bd2c>] (uart_hangup) from [<c045b760>] (__tty_hangup+0x404/0x41c) +[<c045b760>] (__tty_hangup) from [<c045b794>] (tty_vhangup+0x1c/0x20) +[<c045b794>] (tty_vhangup) from [<c046ccc8>] (uart_remove_one_port+0xec/0x260) +[<c046ccc8>] (uart_remove_one_port) from [<c046ef4c>] (serial_omap_remove+0x40/0x60) +[<c046ef4c>] (serial_omap_remove) from [<c04845e8>] (platform_drv_remove+0x34/0x4c) + +Fix this up by resuming the device before deregistering the port and by +suspending and disabling runtime pm only after the port has been +removed. + +Also make sure to disable autosuspend before disabling runtime pm so +that the usage count is balanced and device actually suspended before +returning. + +Note that due to a negative autosuspend delay being set in probe, the +unbalanced put would actually suspend the device on first driver unbind, +while rebinding and again unbinding would result in a negative +power.usage_count. + +Fixes: 7e9c8e7dbf3b ("serial: omap: make sure to suspend device before remove") +Cc: Felipe Balbi <balbi@kernel.org> +Cc: Santosh Shilimkar <santosh.shilimkar@ti.com> +Signed-off-by: Johan Hovold <johan@kernel.org> +Acked-by: Tony Lindgren <tony@atomide.com> +Cc: stable <stable@vger.kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c +index a4734649a0f0..50f2c5a5e450 100644 +--- a/drivers/tty/serial/omap-serial.c ++++ b/drivers/tty/serial/omap-serial.c +@@ -1783,9 +1783,13 @@ static int serial_omap_remove(struct platform_device *dev) + { + struct uart_omap_port *up = platform_get_drvdata(dev); + ++ pm_runtime_get_sync(up->dev); ++ ++ uart_remove_one_port(&serial_omap_reg, &up->port); ++ ++ pm_runtime_dont_use_autosuspend(up->dev); + pm_runtime_put_sync(up->dev); + pm_runtime_disable(up->dev); +- uart_remove_one_port(&serial_omap_reg, &up->port); + pm_qos_remove_request(&up->pm_qos_request); + device_init_wakeup(&dev->dev, false); + +-- +2.12.0 + diff --git a/queue/serial-omap-suspend-device-on-probe-errors.patch b/queue/serial-omap-suspend-device-on-probe-errors.patch new file mode 100644 index 0000000..4d27292 --- /dev/null +++ b/queue/serial-omap-suspend-device-on-probe-errors.patch @@ -0,0 +1,38 @@ +From 77e6fe7fd2b7cba0bf2f2dc8cde51d7b9a35bf74 Mon Sep 17 00:00:00 2001 +From: Johan Hovold <johan@kernel.org> +Date: Mon, 10 Apr 2017 11:21:39 +0200 +Subject: [PATCH] serial: omap: suspend device on probe errors + +commit 77e6fe7fd2b7cba0bf2f2dc8cde51d7b9a35bf74 upstream. + +Make sure to actually suspend the device before returning after a failed +(or deferred) probe. + +Note that autosuspend must be disabled before runtime pm is disabled in +order to balance the usage count due to a negative autosuspend delay as +well as to make the final put suspend the device synchronously. + +Fixes: 388bc2622680 ("omap-serial: Fix the error handling in the omap_serial probe") +Cc: Shubhrajyoti D <shubhrajyoti@ti.com> +Signed-off-by: Johan Hovold <johan@kernel.org> +Acked-by: Tony Lindgren <tony@atomide.com> +Cc: stable <stable@vger.kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c +index 50f2c5a5e450..1ea05ac57aa7 100644 +--- a/drivers/tty/serial/omap-serial.c ++++ b/drivers/tty/serial/omap-serial.c +@@ -1770,7 +1770,8 @@ static int serial_omap_probe(struct platform_device *pdev) + return 0; + + err_add_port: +- pm_runtime_put(&pdev->dev); ++ pm_runtime_dont_use_autosuspend(&pdev->dev); ++ pm_runtime_put_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); + pm_qos_remove_request(&up->pm_qos_request); + device_init_wakeup(up->dev, false); +-- +2.12.0 + diff --git a/queue/serial-samsung-Use-right-device-for-DMA-mapping-call.patch b/queue/serial-samsung-Use-right-device-for-DMA-mapping-call.patch new file mode 100644 index 0000000..3e70d22 --- /dev/null +++ b/queue/serial-samsung-Use-right-device-for-DMA-mapping-call.patch @@ -0,0 +1,78 @@ +From 768d64f491a530062ddad50e016fb27125f8bd7c Mon Sep 17 00:00:00 2001 +From: Marek Szyprowski <m.szyprowski@samsung.com> +Date: Mon, 3 Apr 2017 08:20:59 +0200 +Subject: [PATCH] serial: samsung: Use right device for DMA-mapping calls + +commit 768d64f491a530062ddad50e016fb27125f8bd7c upstream. + +Driver should provide its own struct device for all DMA-mapping calls instead +of extracting device pointer from DMA engine channel. Although this is harmless +from the driver operation perspective on ARM architecture, it is always good +to use the DMA mapping API in a proper way. This patch fixes following DMA API +debug warning: + +WARNING: CPU: 0 PID: 0 at lib/dma-debug.c:1241 check_sync+0x520/0x9f4 +samsung-uart 12c20000.serial: DMA-API: device driver tries to sync DMA memory it has not allocated [device address=0x000000006df0f580] [size=64 bytes] +Modules linked in: +CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.11.0-rc1-00137-g07ca963 #51 +Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) +[<c011aaa4>] (unwind_backtrace) from [<c01127c0>] (show_stack+0x20/0x24) +[<c01127c0>] (show_stack) from [<c06ba5d8>] (dump_stack+0x84/0xa0) +[<c06ba5d8>] (dump_stack) from [<c0139528>] (__warn+0x14c/0x180) +[<c0139528>] (__warn) from [<c01395a4>] (warn_slowpath_fmt+0x48/0x50) +[<c01395a4>] (warn_slowpath_fmt) from [<c0729058>] (check_sync+0x520/0x9f4) +[<c0729058>] (check_sync) from [<c072967c>] (debug_dma_sync_single_for_device+0x88/0xc8) +[<c072967c>] (debug_dma_sync_single_for_device) from [<c0803c10>] (s3c24xx_serial_start_tx_dma+0x100/0x2f8) +[<c0803c10>] (s3c24xx_serial_start_tx_dma) from [<c0804338>] (s3c24xx_serial_tx_chars+0x198/0x33c) + +Reported-by: Seung-Woo Kim <sw0312.kim@samsung.com> +Fixes: 62c37eedb74c8 ("serial: samsung: add dma reqest/release functions") +CC: stable@vger.kernel.org # v4.0+ +Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> +Reviewed-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> +Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org> +Reviewed-by: Shuah Khan <shuahkh@osg.samsung.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c +index 7a17aedbf902..9f3759bdb44f 100644 +--- a/drivers/tty/serial/samsung.c ++++ b/drivers/tty/serial/samsung.c +@@ -901,14 +901,13 @@ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p) + return -ENOMEM; + } + +- dma->rx_addr = dma_map_single(dma->rx_chan->device->dev, dma->rx_buf, ++ dma->rx_addr = dma_map_single(p->port.dev, dma->rx_buf, + dma->rx_size, DMA_FROM_DEVICE); + + spin_lock_irqsave(&p->port.lock, flags); + + /* TX buffer */ +- dma->tx_addr = dma_map_single(dma->tx_chan->device->dev, +- p->port.state->xmit.buf, ++ dma->tx_addr = dma_map_single(p->port.dev, p->port.state->xmit.buf, + UART_XMIT_SIZE, DMA_TO_DEVICE); + + spin_unlock_irqrestore(&p->port.lock, flags); +@@ -922,7 +921,7 @@ static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p) + + if (dma->rx_chan) { + dmaengine_terminate_all(dma->rx_chan); +- dma_unmap_single(dma->rx_chan->device->dev, dma->rx_addr, ++ dma_unmap_single(p->port.dev, dma->rx_addr, + dma->rx_size, DMA_FROM_DEVICE); + kfree(dma->rx_buf); + dma_release_channel(dma->rx_chan); +@@ -931,7 +930,7 @@ static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p) + + if (dma->tx_chan) { + dmaengine_terminate_all(dma->tx_chan); +- dma_unmap_single(dma->tx_chan->device->dev, dma->tx_addr, ++ dma_unmap_single(p->port.dev, dma->tx_addr, + UART_XMIT_SIZE, DMA_TO_DEVICE); + dma_release_channel(dma->tx_chan); + dma->tx_chan = NULL; +-- +2.12.0 + diff --git a/queue/series b/queue/series new file mode 100644 index 0000000..b6a6cfa --- /dev/null +++ b/queue/series @@ -0,0 +1,264 @@ +KEYS-Disallow-keyrings-beginning-with-.-to-be-joined.patch +KEYS-Change-the-name-of-the-dead-type-to-.dead-to-pr.patch +KEYS-fix-keyctl_set_reqkey_keyring-to-not-leak-threa.patch +tracing-Allocate-the-snapshot-buffer-before-enabling.patch +ring-buffer-Have-ring_buffer_iter_empty-return-true-.patch +mm-prevent-NR_ISOLATE_-stats-from-going-negative.patch +cifs-Do-not-send-echoes-before-Negotiate-is-complete.patch +CIFS-remove-bad_network_name-flag.patch +s390-mm-fix-CMMA-vs-KSM-vs-others.patch +Input-elantech-add-Fujitsu-Lifebook-E547-to-force-cr.patch +ACPI-power-Avoid-maybe-uninitialized-warning.patch +mmc-sdhci-esdhc-imx-increase-the-pad-I-O-drive-stren.patch +ubifs-Fix-RENAME_WHITEOUT-support.patch +ubifs-Fix-O_TMPFILE-corner-case-in-ubifs_link.patch +mac80211-reject-ToDS-broadcast-data-frames.patch +mac80211-fix-MU-MIMO-follow-MAC-mode.patch +ubi-upd-Always-flush-after-prepared-for-an-update.patch +powerpc-kprobe-Fix-oops-when-kprobed-on-stdu-instruc.patch +x86-mce-AMD-Give-a-name-to-MCA-bank-3-when-accessed-.patch +x86-mce-Make-the-MCE-notifier-a-blocking-one.patch +device-dax-switch-to-srcu-fix-rcu_read_lock-vs-pte-a.patch +Revert-mmc-sdhci-msm-Enable-few-quirks.patch +ping-implement-proper-locking.patch +sparc64-kern_addr_valid-regression.patch +sparc64-Fix-kernel-panic-due-to-erroneous-ifdef-surr.patch +net-neigh-guard-against-NULL-solicit-method.patch +net-phy-handle-state-correctly-in-phy_stop_machine.patch +kcm-return-immediately-after-copy_from_user-failure.patch +bpf-improve-verifier-packet-range-checks.patch +net-mlx5-Avoid-dereferencing-uninitialized-pointer.patch +l2tp-hold-tunnel-socket-when-handling-control-frames.patch +l2tp-purge-socket-queues-in-the-.destruct-callback.patch +net-packet-fix-overflow-in-check-for-tp_frame_nr.patch +net-packet-fix-overflow-in-check-for-tp_reserve.patch +l2tp-take-reference-on-sessions-being-dumped.patch +l2tp-fix-PPP-pseudo-wire-auto-loading.patch +net-ipv4-fix-multipath-RTM_GETROUTE-behavior-when-ii.patch +sctp-listen-on-the-sock-only-when-it-s-state-is-list.patch +tcp-clear-saved_syn-in-tcp_disconnect.patch +ipv6-Fix-idev-addr_list-corruption.patch +net-timestamp-avoid-use-after-free-in-ip_recv_error.patch +net-vrf-Fix-setting-NLM_F_EXCL-flag-when-adding-l3md.patch +sh_eth-unmap-DMA-buffers-when-freeing-rings.patch +dp83640-don-t-recieve-time-stamps-twice.patch +gso-Validate-assumption-of-frag_list-segementation.patch +net-ipv6-RTF_PCPU-should-not-be-settable-from-usersp.patch +netpoll-Check-for-skb-queue_mapping.patch +ip6mr-fix-notification-device-destruction.patch +net-mlx5-Fix-driver-load-bad-flow-when-having-fw-ini.patch +net-mlx5e-Fix-small-packet-threshold.patch +net-mlx5e-Fix-ETHTOOL_GRXCLSRLALL-handling.patch +macvlan-Fix-device-ref-leak-when-purging-bc_queue.patch +net-ipv6-regenerate-host-route-if-moved-to-gc-list.patch +net-phy-fix-auto-negotiation-stall-due-to-unavailabl.patch +ipv6-check-skb-protocol-before-lookup-for-nexthop.patch +tcp-memset-ca_priv-data-to-0-properly.patch +ipv6-check-raw-payload-size-correctly-in-ioctl.patch +ALSA-oxfw-fix-regression-to-handle-Stanton-SCS.1m-1d.patch +ALSA-firewire-lib-fix-inappropriate-assignment-betwe.patch +ALSA-seq-Don-t-break-snd_use_lock_sync-loop-by-timeo.patch +ARC-plat-eznps-Fix-build-error.patch +MIPS-KGDB-Use-kernel-context-for-sleeping-threads.patch +MIPS-cevt-r4k-Fix-out-of-bounds-array-access.patch +MIPS-Avoid-BUG-warning-in-arch_check_elf.patch +p9_client_readdir-fix.patch +ASoC-intel-Fix-PM-and-non-atomic-crash-in-bytcr-driv.patch +Input-i8042-add-Clevo-P650RS-to-the-i8042-reset-list.patch +nfsd-check-for-oversized-NFSv2-v3-arguments.patch +nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch +nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch +ceph-fix-recursion-between-ceph_set_acl-and-__ceph_s.patch +macsec-avoid-heap-overflow-in-skb_to_sgvec.patch +net-can-usb-gs_usb-Fix-buffer-on-stack.patch +ARCv2-save-r30-on-kernel-entry-as-gcc-uses-it-for-co.patch +ftrace-x86-Fix-triple-fault-with-graph-tracing-and-s.patch +timerfd-Protect-the-might-cancel-mechanism-proper.patch +Handle-mismatched-open-calls.patch +tpm_tis-use-default-timeout-value-if-chip-reports-it.patch +scsi-storvsc-Workaround-for-virtual-DVD-SCSI-version.patch +hwmon-it87-Avoid-registering-the-same-chip-on-both-S.patch +8250_pci-Fix-potential-use-after-free-in-error-path.patch +ceph-try-getting-buffer-capability-for-readahead-fad.patch +cpu-hotplug-Serialize-callback-invocations-proper.patch +dm-ioctl-prevent-stack-leak-in-dm-ioctl-call.patch +9p-fix-a-potential-acl-leak.patch +drm-sti-fix-GDP-size-to-support-up-to-UHD-resolution.patch +hwmon-it87-Fix-pwm4-detection-for-IT8620-and-IT8628.patch +tpm-fix-RC-value-check-in-tpm2_seal_trusted.patch +tmp-use-pdev-for-parent-device-in-tpm_chip_alloc.patch +crypto-caam-fix-error-path-for-ctx_dma-mapping-failu.patch +power-supply-lp8788-prevent-out-of-bounds-array-acce.patch +cpupower-Fix-turbo-frequency-reporting-for-pre-Sandy.patch +powerpc-mm-Fixup-wrong-LPCR_VRMASD-value.patch +powerpc-powernv-Fix-opal_exit-tracepoint-opcode.patch +powerpc-ftrace-Fix-confusing-help-text-for-DISABLE_M.patch +powerpc-Correctly-disable-latent-entropy-GCC-plugin-.patch +perf-x86-intel-pt-Add-format-strings-for-PTWRITE-and.patch +power-supply-bq24190_charger-Fix-irq-trigger-to-IRQF.patch +power-supply-bq24190_charger-Call-set_mode_host-on-p.patch +power-supply-bq24190_charger-Install-irq_handler_thr.patch +power-supply-bq24190_charger-Call-power_supply_chang.patch +power-supply-bq24190_charger-Don-t-read-fault-regist.patch +power-supply-bq24190_charger-Handle-fault-before-sta.patch +arm64-dts-r8a7795-Mark-EthernetAVB-device-node-disab.patch +arm-dts-qcom-Fix-ipq-board-clock-rates.patch +arm64-Improve-detection-of-user-non-user-mappings-in.patch +leds-ktd2692-avoid-harmless-maybe-uninitialized-warn.patch +ARM-dts-NSP-GPIO-reboot-open-source.patch +ARM-OMAP5-DRA7-Fix-HYP-mode-boot-for-thumb2-build.patch +ARM-dts-sun7i-lamobo-r1-Fix-CPU-port-RGMII-settings.patch +mwifiex-debugfs-Fix-sometimes-off-by-1-SSID-print.patch +mwifiex-remove-redundant-dma-padding-in-AMSDU.patch +mwifiex-Avoid-skipping-WEP-key-deletion-for-AP.patch +iwlwifi-fix-MODULE_FIRMWARE-for-6030.patch +iwlwifi-mvm-don-t-restart-HW-if-suspend-fails-with-u.patch +iwlwifi-mvm-overwrite-skb-info-later.patch +iwlwifi-pcie-don-t-increment-decrement-a-bool.patch +iwlwifi-pcie-trans-Remove-unused-shift_param.patch +iwlwifi-pcie-fix-the-set-of-DMA-memory-mask.patch +iwlwifi-mvm-fix-reorder-timer-re-arming.patch +iwlwifi-mvm-Use-aux-queue-for-offchannel-frames-in-d.patch +iwlwifi-mvm-pcie-adjust-A-MSDU-tx_cmd-length-in-PCIe.patch +iwlwifi-mvm-fix-pending-frame-counter-calculation.patch +iwlwifi-mvm-fix-references-to-first_agg_queue-in-DQA.patch +iwlwifi-mvm-synchronize-firmware-DMA-paging-memory.patch +iwlwifi-mvm-writing-zero-bytes-to-debugfs-causes-a-c.patch +x86-ioapic-Restore-IO-APIC-irq_chip-retrigger-callba.patch +x86-pci-calgary-Fix-iommu_free-comparison-of-unsigne.patch +x86-mpx-Re-add-MPX-to-selftests-Makefile.patch +clk-Make-x86-conditional-on-CONFIG_COMMON_CLK.patch +kprobes-x86-Fix-kernel-panic-when-certain-exception-.patch +x86-platform-intel-mid-Correct-MSI-IRQ-line-for-watc.patch +Revert-KVM-nested-VMX-disable-perf-cpuid-reporting.patch +KVM-nVMX-initialize-PML-fields-in-vmcs02.patch +KVM-nVMX-do-not-leak-PML-full-vmexit-to-L1.patch +usb-dwc2-host-use-msleep-for-long-delay.patch +usb-host-ehci-exynos-Decrese-node-refcount-on-exynos.patch +usb-host-ohci-exynos-Decrese-node-refcount-on-exynos.patch +usb-chipidea-Only-read-write-OTGSC-from-one-place.patch +usb-chipidea-Handle-extcon-events-properly.patch +USB-serial-keyspan_pda-fix-receive-sanity-checks.patch +USB-serial-digi_acceleport-fix-incomplete-rx-sanity-.patch +USB-serial-ssu100-fix-control-message-error-handling.patch +USB-serial-io_edgeport-fix-epic-descriptor-handling.patch +USB-serial-ti_usb_3410_5052-fix-control-message-erro.patch +USB-serial-ark3116-fix-open-error-handling.patch +USB-serial-ftdi_sio-fix-latency-timer-error-handling.patch +USB-serial-quatech2-fix-control-message-error-handli.patch +USB-serial-mct_u232-fix-modem-status-error-handling.patch +USB-serial-io_edgeport-fix-descriptor-error-handling.patch +clk-rockchip-add-to-mux_pll_src_apll_dpll_gpll_usb48.patch +phy-qcom-usb-hs-Add-depends-on-EXTCON.patch +serial-8250_omap-Fix-probe-and-remove-for-PM-runtime.patch +scsi-qla2xxx-Fix-crash-in-qla2xxx_eh_abort-on-bad-pt.patch +scsi-mac_scsi-Fix-MAC_SCSI-m-option-when-SCSI-m.patch +scsi-smartpqi-fix-time-handling.patch +MIPS-R2-on-R6-MULTU-MADDU-MSUBU-emulation-bugfix.patch +brcmfmac-Ensure-pointer-correctly-set-if-skb-data-lo.patch +brcmfmac-Make-skb-header-writable-before-use.patch +staging-lustre-llite-move-root_squash-from-sysfs-to-.patch +staging-wlan-ng-add-missing-byte-order-conversion.patch +staging-emxx_udc-remove-incorrect-__init-annotations.patch +ALSA-hda-Fix-deadlock-of-controller-device-lock-at-u.patch +sparc64-fix-fault-handling-in-NGbzero.S-and-GENbzero.patch +macsec-dynamically-allocate-space-for-sglist.patch +tcp-do-not-underestimate-skb-truesize-in-tcp_trim_he.patch +bpf-enhance-verifier-to-understand-stack-pointer-ari.patch +bpf-arm64-fix-jit-branch-offset-related-to-ldimm64.patch +tcp-fix-wraparound-issue-in-tcp_lp.patch +net-ipv6-Do-not-duplicate-DAD-on-link-up.patch +net-usb-qmi_wwan-add-Telit-ME910-support.patch +tcp-do-not-inherit-fastopen_req-from-parent.patch +ipv4-ipv6-ensure-raw-socket-message-is-big-enough-to.patch +rtnetlink-NUL-terminate-IFLA_PHYS_PORT_NAME-string.patch +ipv6-initialize-route-null-entry-in-addrconf_init.patch +ipv6-reorder-ip6_route_dev_notifier-after-ipv6_dev_n.patch +bnxt_en-allocate-enough-space-for-ntp_fltr_bmap.patch +bpf-don-t-let-ldimm64-leak-map-addresses-on-unprivil.patch +net-mdio-mux-bcm-iproc-call-mdiobus_free-in-error-pa.patch +f2fs-sanity-check-segment-count.patch +xen-Revert-commits-da72ff5bfcb0-and-72a9b186292d.patch +wlcore-Pass-win_size-taken-from-ieee80211_sta-to-FW.patch +wlcore-Add-RX_BA_WIN_SIZE_CHANGE_EVENT-event.patch +drm-ttm-fix-use-after-free-races-in-vm-fault-handlin.patch +block-get-rid-of-blk_integrity_revalidate.patch +xen-adjust-early-dom0-p2m-handling-to-xen-hypervisor.patch +target-Fix-compare_and_write_callback-handling-for-n.patch +target-fileio-Fix-zero-length-READ-and-WRITE-handlin.patch +iscsi-target-Set-session_fall_back_to_erl0-when-forc.patch +usb-xhci-bInterval-quirk-for-TI-TUSB73x0.patch +usb-host-xhci-print-correct-command-ring-address.patch +USB-serial-ftdi_sio-add-device-ID-for-Microsemi-Arro.patch +USB-Proper-handling-of-Race-Condition-when-two-USB-c.patch +USB-Revert-cdc-wdm-fix-out-of-sync-due-to-missing-no.patch +staging-vt6656-use-off-stack-for-in-buffer-USB-trans.patch +staging-vt6656-use-off-stack-for-out-buffer-USB-tran.patch +staging-gdm724x-gdm_mux-fix-use-after-free-on-module.patch +staging-comedi-jr3_pci-fix-possible-null-pointer-der.patch +staging-comedi-jr3_pci-cope-with-jiffies-wraparound.patch +usb-misc-add-missing-continue-in-switch.patch +usb-gadget-legacy-gadgets-are-optional.patch +usb-Make-sure-usb-phy-of-gets-built-in.patch +usb-hub-Fix-error-loop-seen-after-hub-communication-.patch +usb-hub-Do-not-attempt-to-autosuspend-disconnected-d.patch +x86-boot-Fix-BSS-corruption-overwrite-bug-in-early-x.patch +selftests-x86-ldt_gdt_32-Work-around-a-glibc-sigacti.patch +x86-pmem-Fix-cache-flushing-for-iovec-write-8-bytes.patch +um-Fix-PTRACE_POKEUSER-on-x86_64.patch +perf-x86-Fix-Broadwell-EP-DRAM-RAPL-events.patch +KVM-x86-fix-user-triggerable-warning-in-kvm_apic_acc.patch +KVM-arm-arm64-fix-races-in-kvm_psci_vcpu_on.patch +arm64-KVM-Fix-decoding-of-Rt-Rt2-when-trapping-AArch.patch +block-fix-blk_integrity_register-to-use-template-s-i.patch +crypto-algif_aead-Require-setkey-before-accept-2.patch +crypto-ccp-Use-only-the-relevant-interrupt-bits.patch +crypto-ccp-Disable-interrupts-early-on-unload.patch +crypto-ccp-Change-ISR-handler-method-for-a-v3-CCP.patch +crypto-ccp-Change-ISR-handler-method-for-a-v5-CCP.patch +dm-era-save-spacemap-metadata-root-after-the-pre-com.patch +dm-rq-check-blk_mq_register_dev-return-value-in-dm_m.patch +dm-thin-fix-a-memory-leak-when-passing-discard-bio-d.patch +vfio-type1-Remove-locked-page-accounting-workqueue.patch +iov_iter-don-t-revert-iov-buffer-if-csum-error.patch +IB-core-Fix-sysfs-registration-error-flow.patch +IB-core-For-multicast-functions-verify-that-LIDs-are.patch +IB-IPoIB-ibX-failed-to-create-mcg-debug-file.patch +IB-mlx4-Fix-ib-device-initialization-error-flow.patch +IB-mlx4-Reduce-SRIOV-multicast-cleanup-warning-messa.patch +IB-hfi1-Prevent-kernel-QP-post-send-hard-lockups.patch +perf-auxtrace-Fix-no_size-logic-in-addr_filter__reso.patch +ext4-evict-inline-data-when-writing-to-memory-map.patch +orangefs-fix-bounds-check-for-listxattr.patch +orangefs-clean-up-oversize-xattr-validation.patch +orangefs-do-not-set-getattr_time-on-orangefs_lookup.patch +orangefs-do-not-check-possibly-stale-size-on-truncat.patch +fs-xattr.c-zero-out-memory-copied-to-userspace-in-ge.patch +ceph-fix-memory-leak-in-__ceph_setxattr.patch +fs-block_dev-always-invalidate-cleancache-in-invalid.patch +mm-prevent-potential-recursive-reclaim-due-to-cleari.patch +Fix-match_prepath.patch +Set-unicode-flag-on-cifs-echo-request-to-avoid-Mac-e.patch +SMB3-Work-around-mount-failure-when-using-SMB3-diale.patch +CIFS-fix-mapping-of-SFM_SPACE-and-SFM_PERIOD.patch +cifs-fix-leak-in-FSCTL_ENUM_SNAPS-response-handling.patch +cifs-fix-CIFS_ENUMERATE_SNAPSHOTS-oops.patch +CIFS-fix-oplock-break-deadlocks.patch +cifs-fix-CIFS_IOC_GET_MNT_INFO-oops.patch +CIFS-add-misssing-SFM-mapping-for-doublequote.patch +padata-free-correct-variable.patch +device-dax-fix-cdev-leak.patch +fscrypt-fix-context-consistency-check-when-key-s-una.patch +serial-samsung-Use-right-device-for-DMA-mapping-call.patch +serial-omap-fix-runtime-pm-handling-on-unbind.patch +serial-omap-suspend-device-on-probe-errors.patch +tty-pty-Fix-ldisc-flush-after-userspace-become-aware.patch +Bluetooth-Fix-user-channel-for-32bit-userspace-on-64.patch +Bluetooth-hci_bcm-add-missing-tty-device-sanity-chec.patch +Bluetooth-hci_intel-add-missing-tty-device-sanity-ch.patch +ipmi-Fix-kernel-panic-at-ipmi_ssif_thread.patch +libnvdimm-region-fix-flush-hint-detection-crash.patch +libnvdimm-pmem-fix-a-NULL-pointer-BUG-in-nd_pmem_not.patch +libnvdimm-pfn-fix-npfns-vs-section-alignment.patch +pstore-Fix-flags-to-enable-dumps-on-powerpc.patch +pstore-Shut-down-worker-when-unregistering.patch diff --git a/queue/sh_eth-unmap-DMA-buffers-when-freeing-rings.patch b/queue/sh_eth-unmap-DMA-buffers-when-freeing-rings.patch new file mode 100644 index 0000000..123683f --- /dev/null +++ b/queue/sh_eth-unmap-DMA-buffers-when-freeing-rings.patch @@ -0,0 +1,209 @@ +From 1debdc8f9ebd07daf140e417b3841596911e0066 Mon Sep 17 00:00:00 2001 +From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Date: Mon, 17 Apr 2017 15:55:22 +0300 +Subject: [PATCH] sh_eth: unmap DMA buffers when freeing rings + +commit 1debdc8f9ebd07daf140e417b3841596911e0066 upstream. + +The DMA API debugging (when enabled) causes: + +WARNING: CPU: 0 PID: 1445 at lib/dma-debug.c:519 add_dma_entry+0xe0/0x12c +DMA-API: exceeded 7 overlapping mappings of cacheline 0x01b2974d + +to be printed after repeated initialization of the Ether device, e.g. +suspend/resume or 'ifconfig' up/down. This is because DMA buffers mapped +using dma_map_single() in sh_eth_ring_format() and sh_eth_start_xmit() are +never unmapped. Resolve this problem by unmapping the buffers when freeing +the descriptor rings; in order to do it right, we'd have to add an extra +parameter to sh_eth_txfree() (we rename this function to sh_eth_tx_free(), +while at it). + +Based on the commit a47b70ea86bd ("ravb: unmap descriptors when freeing +rings"). + +Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c +index 54248775f227..f68c4db656ed 100644 +--- a/drivers/net/ethernet/renesas/sh_eth.c ++++ b/drivers/net/ethernet/renesas/sh_eth.c +@@ -1127,12 +1127,70 @@ static struct mdiobb_ops bb_ops = { + .get_mdio_data = sh_get_mdio, + }; + ++/* free Tx skb function */ ++static int sh_eth_tx_free(struct net_device *ndev, bool sent_only) ++{ ++ struct sh_eth_private *mdp = netdev_priv(ndev); ++ struct sh_eth_txdesc *txdesc; ++ int free_num = 0; ++ int entry; ++ bool sent; ++ ++ for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) { ++ entry = mdp->dirty_tx % mdp->num_tx_ring; ++ txdesc = &mdp->tx_ring[entry]; ++ sent = !(txdesc->status & cpu_to_le32(TD_TACT)); ++ if (sent_only && !sent) ++ break; ++ /* TACT bit must be checked before all the following reads */ ++ dma_rmb(); ++ netif_info(mdp, tx_done, ndev, ++ "tx entry %d status 0x%08x\n", ++ entry, le32_to_cpu(txdesc->status)); ++ /* Free the original skb. */ ++ if (mdp->tx_skbuff[entry]) { ++ dma_unmap_single(&ndev->dev, le32_to_cpu(txdesc->addr), ++ le32_to_cpu(txdesc->len) >> 16, ++ DMA_TO_DEVICE); ++ dev_kfree_skb_irq(mdp->tx_skbuff[entry]); ++ mdp->tx_skbuff[entry] = NULL; ++ free_num++; ++ } ++ txdesc->status = cpu_to_le32(TD_TFP); ++ if (entry >= mdp->num_tx_ring - 1) ++ txdesc->status |= cpu_to_le32(TD_TDLE); ++ ++ if (sent) { ++ ndev->stats.tx_packets++; ++ ndev->stats.tx_bytes += le32_to_cpu(txdesc->len) >> 16; ++ } ++ } ++ return free_num; ++} ++ + /* free skb and descriptor buffer */ + static void sh_eth_ring_free(struct net_device *ndev) + { + struct sh_eth_private *mdp = netdev_priv(ndev); + int ringsize, i; + ++ if (mdp->rx_ring) { ++ for (i = 0; i < mdp->num_rx_ring; i++) { ++ if (mdp->rx_skbuff[i]) { ++ struct sh_eth_rxdesc *rxdesc = &mdp->rx_ring[i]; ++ ++ dma_unmap_single(&ndev->dev, ++ le32_to_cpu(rxdesc->addr), ++ ALIGN(mdp->rx_buf_sz, 32), ++ DMA_FROM_DEVICE); ++ } ++ } ++ ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring; ++ dma_free_coherent(NULL, ringsize, mdp->rx_ring, ++ mdp->rx_desc_dma); ++ mdp->rx_ring = NULL; ++ } ++ + /* Free Rx skb ringbuffer */ + if (mdp->rx_skbuff) { + for (i = 0; i < mdp->num_rx_ring; i++) +@@ -1141,27 +1199,18 @@ static void sh_eth_ring_free(struct net_device *ndev) + kfree(mdp->rx_skbuff); + mdp->rx_skbuff = NULL; + +- /* Free Tx skb ringbuffer */ +- if (mdp->tx_skbuff) { +- for (i = 0; i < mdp->num_tx_ring; i++) +- dev_kfree_skb(mdp->tx_skbuff[i]); +- } +- kfree(mdp->tx_skbuff); +- mdp->tx_skbuff = NULL; +- +- if (mdp->rx_ring) { +- ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring; +- dma_free_coherent(NULL, ringsize, mdp->rx_ring, +- mdp->rx_desc_dma); +- mdp->rx_ring = NULL; +- } +- + if (mdp->tx_ring) { ++ sh_eth_tx_free(ndev, false); ++ + ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring; + dma_free_coherent(NULL, ringsize, mdp->tx_ring, + mdp->tx_desc_dma); + mdp->tx_ring = NULL; + } ++ ++ /* Free Tx skb ringbuffer */ ++ kfree(mdp->tx_skbuff); ++ mdp->tx_skbuff = NULL; + } + + /* format skb and descriptor buffer */ +@@ -1409,43 +1458,6 @@ static void sh_eth_dev_exit(struct net_device *ndev) + update_mac_address(ndev); + } + +-/* free Tx skb function */ +-static int sh_eth_txfree(struct net_device *ndev) +-{ +- struct sh_eth_private *mdp = netdev_priv(ndev); +- struct sh_eth_txdesc *txdesc; +- int free_num = 0; +- int entry; +- +- for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) { +- entry = mdp->dirty_tx % mdp->num_tx_ring; +- txdesc = &mdp->tx_ring[entry]; +- if (txdesc->status & cpu_to_le32(TD_TACT)) +- break; +- /* TACT bit must be checked before all the following reads */ +- dma_rmb(); +- netif_info(mdp, tx_done, ndev, +- "tx entry %d status 0x%08x\n", +- entry, le32_to_cpu(txdesc->status)); +- /* Free the original skb. */ +- if (mdp->tx_skbuff[entry]) { +- dma_unmap_single(&ndev->dev, le32_to_cpu(txdesc->addr), +- le32_to_cpu(txdesc->len) >> 16, +- DMA_TO_DEVICE); +- dev_kfree_skb_irq(mdp->tx_skbuff[entry]); +- mdp->tx_skbuff[entry] = NULL; +- free_num++; +- } +- txdesc->status = cpu_to_le32(TD_TFP); +- if (entry >= mdp->num_tx_ring - 1) +- txdesc->status |= cpu_to_le32(TD_TDLE); +- +- ndev->stats.tx_packets++; +- ndev->stats.tx_bytes += le32_to_cpu(txdesc->len) >> 16; +- } +- return free_num; +-} +- + /* Packet receive function */ + static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) + { +@@ -1690,7 +1702,7 @@ static void sh_eth_error(struct net_device *ndev, u32 intr_status) + intr_status, mdp->cur_tx, mdp->dirty_tx, + (u32)ndev->state, edtrr); + /* dirty buffer free */ +- sh_eth_txfree(ndev); ++ sh_eth_tx_free(ndev, true); + + /* SH7712 BUG */ + if (edtrr ^ sh_eth_get_edtrr_trns(mdp)) { +@@ -1751,7 +1763,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) + /* Clear Tx interrupts */ + sh_eth_write(ndev, intr_status & cd->tx_check, EESR); + +- sh_eth_txfree(ndev); ++ sh_eth_tx_free(ndev, true); + netif_wake_queue(ndev); + } + +@@ -2412,7 +2424,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) + + spin_lock_irqsave(&mdp->lock, flags); + if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) { +- if (!sh_eth_txfree(ndev)) { ++ if (!sh_eth_tx_free(ndev, true)) { + netif_warn(mdp, tx_queued, ndev, "TxFD exhausted.\n"); + netif_stop_queue(ndev); + spin_unlock_irqrestore(&mdp->lock, flags); +-- +2.12.0 + diff --git a/queue/sparc64-Fix-kernel-panic-due-to-erroneous-ifdef-surr.patch b/queue/sparc64-Fix-kernel-panic-due-to-erroneous-ifdef-surr.patch new file mode 100644 index 0000000..1629e5c --- /dev/null +++ b/queue/sparc64-Fix-kernel-panic-due-to-erroneous-ifdef-surr.patch @@ -0,0 +1,100 @@ +From 9ae34dbd8afd790cb5f52467e4f816434379eafa Mon Sep 17 00:00:00 2001 +From: Tom Hromatka <tom.hromatka@oracle.com> +Date: Fri, 31 Mar 2017 16:31:42 -0600 +Subject: [PATCH] sparc64: Fix kernel panic due to erroneous #ifdef surrounding + pmd_write() + +commit 9ae34dbd8afd790cb5f52467e4f816434379eafa upstream. + +This commit moves sparc64's prototype of pmd_write() outside +of the CONFIG_TRANSPARENT_HUGEPAGE ifdef. + +In 2013, commit a7b9403f0e6d ("sparc64: Encode huge PMDs using PTE +encoding.") exposed a path where pmd_write() could be called without +CONFIG_TRANSPARENT_HUGEPAGE defined. This can result in the panic below. + +The diff is awkward to read, but the changes are straightforward. +pmd_write() was moved outside of #ifdef CONFIG_TRANSPARENT_HUGEPAGE. +Also, __HAVE_ARCH_PMD_WRITE was defined. + +kernel BUG at include/asm-generic/pgtable.h:576! + \|/ ____ \|/ + "@'/ .. \`@" + /_| \__/ |_\ + \__U_/ +oracle_8114_cdb(8114): Kernel bad sw trap 5 [#1] +CPU: 120 PID: 8114 Comm: oracle_8114_cdb Not tainted +4.1.12-61.7.1.el6uek.rc1.sparc64 #1 +task: fff8400700a24d60 ti: fff8400700bc4000 task.ti: fff8400700bc4000 +TSTATE: 0000004411e01607 TPC: 00000000004609f8 TNPC: 00000000004609fc Y: +00000005 Not tainted +TPC: <gup_huge_pmd+0x198/0x1e0> +g0: 000000000001c000 g1: 0000000000ef3954 g2: 0000000000000000 g3: 0000000000000001 +g4: fff8400700a24d60 g5: fff8001fa5c10000 g6: fff8400700bc4000 g7: 0000000000000720 +o0: 0000000000bc5058 o1: 0000000000000240 o2: 0000000000006000 o3: 0000000000001c00 +o4: 0000000000000000 o5: 0000048000080000 sp: fff8400700bc6ab1 ret_pc: 00000000004609f0 +RPC: <gup_huge_pmd+0x190/0x1e0> +l0: fff8400700bc74fc l1: 0000000000020000 l2: 0000000000002000 l3: 0000000000000000 +l4: fff8001f93250950 l5: 000000000113f800 l6: 0000000000000004 l7: 0000000000000000 +i0: fff8400700ca46a0 i1: bd0000085e800453 i2: 000000026a0c4000 i3: 000000026a0c6000 +i4: 0000000000000001 i5: fff800070c958de8 i6: fff8400700bc6b61 i7: 0000000000460dd0 +I7: <gup_pud_range+0x170/0x1a0> +Call Trace: + [0000000000460dd0] gup_pud_range+0x170/0x1a0 + [0000000000460e84] get_user_pages_fast+0x84/0x120 + [00000000006f5a18] iov_iter_get_pages+0x98/0x240 + [00000000005fa744] do_direct_IO+0xf64/0x1e00 + [00000000005fbbc0] __blockdev_direct_IO+0x360/0x15a0 + [00000000101f74fc] ext4_ind_direct_IO+0xdc/0x400 [ext4] + [00000000101af690] ext4_ext_direct_IO+0x1d0/0x2c0 [ext4] + [00000000101af86c] ext4_direct_IO+0xec/0x220 [ext4] + [0000000000553bd4] generic_file_read_iter+0x114/0x140 + [00000000005bdc2c] __vfs_read+0xac/0x100 + [00000000005bf254] vfs_read+0x54/0x100 + [00000000005bf368] SyS_pread64+0x68/0x80 + +Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h +index 8a598528ec1f..6fbd931f0570 100644 +--- a/arch/sparc/include/asm/pgtable_64.h ++++ b/arch/sparc/include/asm/pgtable_64.h +@@ -679,26 +679,27 @@ static inline unsigned long pmd_pfn(pmd_t pmd) + return pte_pfn(pte); + } + +-#ifdef CONFIG_TRANSPARENT_HUGEPAGE +-static inline unsigned long pmd_dirty(pmd_t pmd) ++#define __HAVE_ARCH_PMD_WRITE ++static inline unsigned long pmd_write(pmd_t pmd) + { + pte_t pte = __pte(pmd_val(pmd)); + +- return pte_dirty(pte); ++ return pte_write(pte); + } + +-static inline unsigned long pmd_young(pmd_t pmd) ++#ifdef CONFIG_TRANSPARENT_HUGEPAGE ++static inline unsigned long pmd_dirty(pmd_t pmd) + { + pte_t pte = __pte(pmd_val(pmd)); + +- return pte_young(pte); ++ return pte_dirty(pte); + } + +-static inline unsigned long pmd_write(pmd_t pmd) ++static inline unsigned long pmd_young(pmd_t pmd) + { + pte_t pte = __pte(pmd_val(pmd)); + +- return pte_write(pte); ++ return pte_young(pte); + } + + static inline unsigned long pmd_trans_huge(pmd_t pmd) +-- +2.12.0 + diff --git a/queue/sparc64-fix-fault-handling-in-NGbzero.S-and-GENbzero.patch b/queue/sparc64-fix-fault-handling-in-NGbzero.S-and-GENbzero.patch new file mode 100644 index 0000000..8881107 --- /dev/null +++ b/queue/sparc64-fix-fault-handling-in-NGbzero.S-and-GENbzero.patch @@ -0,0 +1,67 @@ +From 3c7f62212018b904ae17f5636ead18a4dca3a88f Mon Sep 17 00:00:00 2001 +From: Dave Aldridge <david.j.aldridge@oracle.com> +Date: Tue, 9 May 2017 02:57:35 -0600 +Subject: [PATCH] sparc64: fix fault handling in NGbzero.S and GENbzero.S + +commit 3c7f62212018b904ae17f5636ead18a4dca3a88f upstream. + +When any of the functions contained in NGbzero.S and GENbzero.S +vector through *bzero_from_clear_user, we may end up taking a +fault when executing one of the store alternate address space +instructions. If this happens, the exception handler does not +restore the %asi register. + +This commit fixes the issue by introducing a new exception +handler that ensures the %asi register is restored when +a fault is handled. + +Orabug: 25577560 + +Signed-off-by: Dave Aldridge <david.j.aldridge@oracle.com> +Reviewed-by: Rob Gardner <rob.gardner@oracle.com> +Reviewed-by: Babu Moger <babu.moger@oracle.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S +index 44101196d02b..41a407328667 100644 +--- a/arch/sparc/kernel/head_64.S ++++ b/arch/sparc/kernel/head_64.S +@@ -939,3 +939,9 @@ ENTRY(__retl_o1) + retl + mov %o1, %o0 + ENDPROC(__retl_o1) ++ ++ENTRY(__retl_o1_asi) ++ wr %o5, 0x0, %asi ++ retl ++ mov %o1, %o0 ++ENDPROC(__retl_o1_asi) +diff --git a/arch/sparc/lib/GENbzero.S b/arch/sparc/lib/GENbzero.S +index 8e7a843ddd88..2fbf6297d57c 100644 +--- a/arch/sparc/lib/GENbzero.S ++++ b/arch/sparc/lib/GENbzero.S +@@ -8,7 +8,7 @@ + 98: x,y; \ + .section __ex_table,"a";\ + .align 4; \ +- .word 98b, __retl_o1; \ ++ .word 98b, __retl_o1_asi;\ + .text; \ + .align 4; + +diff --git a/arch/sparc/lib/NGbzero.S b/arch/sparc/lib/NGbzero.S +index beab29bf419b..33053bdf3766 100644 +--- a/arch/sparc/lib/NGbzero.S ++++ b/arch/sparc/lib/NGbzero.S +@@ -8,7 +8,7 @@ + 98: x,y; \ + .section __ex_table,"a";\ + .align 4; \ +- .word 98b, __retl_o1; \ ++ .word 98b, __retl_o1_asi;\ + .text; \ + .align 4; + +-- +2.12.0 + diff --git a/queue/sparc64-kern_addr_valid-regression.patch b/queue/sparc64-kern_addr_valid-regression.patch new file mode 100644 index 0000000..09b0156 --- /dev/null +++ b/queue/sparc64-kern_addr_valid-regression.patch @@ -0,0 +1,36 @@ +From adfae8a5d833fa2b46577a8081f350e408851f5b Mon Sep 17 00:00:00 2001 +From: bob picco <bob.picco@oracle.com> +Date: Fri, 10 Mar 2017 14:31:19 -0500 +Subject: [PATCH] sparc64: kern_addr_valid regression + +commit adfae8a5d833fa2b46577a8081f350e408851f5b upstream. + +I encountered this bug when using /proc/kcore to examine the kernel. Plus a +coworker inquired about debugging tools. We computed pa but did +not use it during the maximum physical address bits test. Instead we used +the identity mapped virtual address which will always fail this test. + +I believe the defect came in here: +[bpicco@zareason linus.git]$ git describe --contains bb4e6e85daa52 +v3.18-rc1~87^2~4 +. + +Signed-off-by: Bob Picco <bob.picco@oracle.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c +index 3328043e990c..0cda653ae007 100644 +--- a/arch/sparc/mm/init_64.c ++++ b/arch/sparc/mm/init_64.c +@@ -1567,7 +1567,7 @@ bool kern_addr_valid(unsigned long addr) + if ((long)addr < 0L) { + unsigned long pa = __pa(addr); + +- if ((addr >> max_phys_bits) != 0UL) ++ if ((pa >> max_phys_bits) != 0UL) + return false; + + return pfn_valid(pa >> PAGE_SHIFT); +-- +2.12.0 + diff --git a/queue/staging-comedi-jr3_pci-cope-with-jiffies-wraparound.patch b/queue/staging-comedi-jr3_pci-cope-with-jiffies-wraparound.patch new file mode 100644 index 0000000..063d718 --- /dev/null +++ b/queue/staging-comedi-jr3_pci-cope-with-jiffies-wraparound.patch @@ -0,0 +1,34 @@ +From 8ec04a491825e08068e92bed0bba7821893b6433 Mon Sep 17 00:00:00 2001 +From: Ian Abbott <abbotti@mev.co.uk> +Date: Fri, 17 Feb 2017 11:09:09 +0000 +Subject: [PATCH] staging: comedi: jr3_pci: cope with jiffies wraparound + +commit 8ec04a491825e08068e92bed0bba7821893b6433 upstream. + +The timer expiry routine `jr3_pci_poll_dev()` checks for expiry by +checking whether the absolute value of `jiffies` (stored in local +variable `now`) is greater than the expected expiry time in jiffy units. +This will fail when `jiffies` wraps around. Also, it seems to make +sense to handle the expiry one jiffy earlier than the current test. Use +`time_after_eq()` to check for expiry. + +Cc: <stable@vger.kernel.org> # 3.15+ +Signed-off-by: Ian Abbott <abbotti@mev.co.uk> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c +index 25909a936e7c..eb0a095efe9c 100644 +--- a/drivers/staging/comedi/drivers/jr3_pci.c ++++ b/drivers/staging/comedi/drivers/jr3_pci.c +@@ -611,7 +611,7 @@ static void jr3_pci_poll_dev(unsigned long data) + s = &dev->subdevices[i]; + spriv = s->private; + +- if (now > spriv->next_time_min) { ++ if (time_after_eq(now, spriv->next_time_min)) { + struct jr3_pci_poll_delay sub_delay; + + sub_delay = jr3_pci_poll_subdevice(s); +-- +2.12.0 + diff --git a/queue/staging-comedi-jr3_pci-fix-possible-null-pointer-der.patch b/queue/staging-comedi-jr3_pci-fix-possible-null-pointer-der.patch new file mode 100644 index 0000000..469f63e --- /dev/null +++ b/queue/staging-comedi-jr3_pci-fix-possible-null-pointer-der.patch @@ -0,0 +1,52 @@ +From 45292be0b3db0b7f8286683b376e2d9f949d11f9 Mon Sep 17 00:00:00 2001 +From: Ian Abbott <abbotti@mev.co.uk> +Date: Fri, 17 Feb 2017 11:09:08 +0000 +Subject: [PATCH] staging: comedi: jr3_pci: fix possible null pointer + dereference + +commit 45292be0b3db0b7f8286683b376e2d9f949d11f9 upstream. + +For some reason, the driver does not consider allocation of the +subdevice private data to be a fatal error when attaching the COMEDI +device. It tests the subdevice private data pointer for validity at +certain points, but omits some crucial tests. In particular, +`jr3_pci_auto_attach()` calls `jr3_pci_alloc_spriv()` to allocate and +initialize the subdevice private data, but the same function +subsequently dereferences the pointer to access the `next_time_min` and +`next_time_max` members without checking it first. The other missing +test is in the timer expiry routine `jr3_pci_poll_dev()`, but it will +crash before it gets that far. + +Fix the bug by returning `-ENOMEM` from `jr3_pci_auto_attach()` as soon +as one of the calls to `jr3_pci_alloc_spriv()` returns `NULL`. The +COMEDI core will subsequently call `jr3_pci_detach()` to clean up. + +Cc: <stable@vger.kernel.org> # 3.15+ +Signed-off-by: Ian Abbott <abbotti@mev.co.uk> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c +index 70390de66e0e..25909a936e7c 100644 +--- a/drivers/staging/comedi/drivers/jr3_pci.c ++++ b/drivers/staging/comedi/drivers/jr3_pci.c +@@ -727,11 +727,12 @@ static int jr3_pci_auto_attach(struct comedi_device *dev, + s->insn_read = jr3_pci_ai_insn_read; + + spriv = jr3_pci_alloc_spriv(dev, s); +- if (spriv) { +- /* Channel specific range and maxdata */ +- s->range_table_list = spriv->range_table_list; +- s->maxdata_list = spriv->maxdata_list; +- } ++ if (!spriv) ++ return -ENOMEM; ++ ++ /* Channel specific range and maxdata */ ++ s->range_table_list = spriv->range_table_list; ++ s->maxdata_list = spriv->maxdata_list; + } + + /* Reset DSP card */ +-- +2.12.0 + diff --git a/queue/staging-emxx_udc-remove-incorrect-__init-annotations.patch b/queue/staging-emxx_udc-remove-incorrect-__init-annotations.patch new file mode 100644 index 0000000..6eae82a --- /dev/null +++ b/queue/staging-emxx_udc-remove-incorrect-__init-annotations.patch @@ -0,0 +1,45 @@ +From 4f3445067d5f78fb8d1970b02610f85c2f377ea4 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann <arnd@arndb.de> +Date: Fri, 16 Dec 2016 10:09:39 +0100 +Subject: [PATCH] staging: emxx_udc: remove incorrect __init annotations + +commit 4f3445067d5f78fb8d1970b02610f85c2f377ea4 upstream. + +The probe function is not marked __init, but some other functions +are. This leads to a warning on older compilers (e.g. gcc-4.3), +and can cause executing freed memory when built with those +compilers: + +WARNING: drivers/staging/emxx_udc/emxx_udc.o(.text+0x2d78): Section mismatch in reference from the function nbu2ss_drv_probe() to the function .init.text:nbu2ss_drv_contest_init() + +This removes the annotations. + +Fixes: 33aa8d45a4fe ("staging: emxx_udc: Add Emma Mobile USB Gadget driver") +Signed-off-by: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c +index 3f42fa8b0bf3..4a3da2406f48 100644 +--- a/drivers/staging/emxx_udc/emxx_udc.c ++++ b/drivers/staging/emxx_udc/emxx_udc.c +@@ -3137,7 +3137,7 @@ static const struct { + }; + + /*-------------------------------------------------------------------------*/ +-static void __init nbu2ss_drv_ep_init(struct nbu2ss_udc *udc) ++static void nbu2ss_drv_ep_init(struct nbu2ss_udc *udc) + { + int i; + +@@ -3168,7 +3168,7 @@ static void __init nbu2ss_drv_ep_init(struct nbu2ss_udc *udc) + + /*-------------------------------------------------------------------------*/ + /* platform_driver */ +-static int __init nbu2ss_drv_contest_init( ++static int nbu2ss_drv_contest_init( + struct platform_device *pdev, + struct nbu2ss_udc *udc) + { +-- +2.12.0 + diff --git a/queue/staging-gdm724x-gdm_mux-fix-use-after-free-on-module.patch b/queue/staging-gdm724x-gdm_mux-fix-use-after-free-on-module.patch new file mode 100644 index 0000000..87da91f --- /dev/null +++ b/queue/staging-gdm724x-gdm_mux-fix-use-after-free-on-module.patch @@ -0,0 +1,36 @@ +From b58f45c8fc301fe83ee28cad3e64686c19e78f1c Mon Sep 17 00:00:00 2001 +From: Johan Hovold <johan@kernel.org> +Date: Wed, 26 Apr 2017 12:23:04 +0200 +Subject: [PATCH] staging: gdm724x: gdm_mux: fix use-after-free on module + unload + +commit b58f45c8fc301fe83ee28cad3e64686c19e78f1c upstream. + +Make sure to deregister the USB driver before releasing the tty driver +to avoid use-after-free in the USB disconnect callback where the tty +devices are deregistered. + +Fixes: 61e121047645 ("staging: gdm7240: adding LTE USB driver") +Cc: stable <stable@vger.kernel.org> # 3.12 +Cc: Won Kang <wkang77@gmail.com> +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/staging/gdm724x/gdm_mux.c b/drivers/staging/gdm724x/gdm_mux.c +index aba32e22db0c..996b1f538aae 100644 +--- a/drivers/staging/gdm724x/gdm_mux.c ++++ b/drivers/staging/gdm724x/gdm_mux.c +@@ -664,9 +664,8 @@ static int __init gdm_usb_mux_init(void) + + static void __exit gdm_usb_mux_exit(void) + { +- unregister_lte_tty_driver(); +- + usb_deregister(&gdm_mux_driver); ++ unregister_lte_tty_driver(); + } + + module_init(gdm_usb_mux_init); +-- +2.12.0 + diff --git a/queue/staging-lustre-llite-move-root_squash-from-sysfs-to-.patch b/queue/staging-lustre-llite-move-root_squash-from-sysfs-to-.patch new file mode 100644 index 0000000..73d6c9b --- /dev/null +++ b/queue/staging-lustre-llite-move-root_squash-from-sysfs-to-.patch @@ -0,0 +1,84 @@ +From 4c13990e35b9f053857d4ad83bf0f58e612ec414 Mon Sep 17 00:00:00 2001 +From: Oleg Drokin <green@linuxhacker.ru> +Date: Wed, 7 Dec 2016 17:41:27 -0500 +Subject: [PATCH] staging/lustre/llite: move root_squash from sysfs to debugfs + +commit 4c13990e35b9f053857d4ad83bf0f58e612ec414 upstream. + +root_squash control got accidentally moved to sysfs instead of +debugfs, and the write side of it was also broken expecting a +userspace buffer. +It contains both uid and gid values in a single file, so debugfs +is a clear place for it. + +Reported-by: Al Viro <viro@ZenIV.linux.org.uk> +Fixes: c948390f10ccc "fix inconsistencies of root squash feature" +Signed-off-by: Oleg Drokin <green@linuxhacker.ru> +Reviewed-by: James Simmons <jsimmons@infradead.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c +index 03682c10fc9e..f3ee584157e0 100644 +--- a/drivers/staging/lustre/lustre/llite/lproc_llite.c ++++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c +@@ -924,27 +924,29 @@ static ssize_t ll_unstable_stats_seq_write(struct file *file, + } + LPROC_SEQ_FOPS(ll_unstable_stats); + +-static ssize_t root_squash_show(struct kobject *kobj, struct attribute *attr, +- char *buf) ++static int ll_root_squash_seq_show(struct seq_file *m, void *v) + { +- struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, +- ll_kobj); ++ struct super_block *sb = m->private; ++ struct ll_sb_info *sbi = ll_s2sbi(sb); + struct root_squash_info *squash = &sbi->ll_squash; + +- return sprintf(buf, "%u:%u\n", squash->rsi_uid, squash->rsi_gid); ++ seq_printf(m, "%u:%u\n", squash->rsi_uid, squash->rsi_gid); ++ return 0; + } + +-static ssize_t root_squash_store(struct kobject *kobj, struct attribute *attr, +- const char *buffer, size_t count) ++static ssize_t ll_root_squash_seq_write(struct file *file, ++ const char __user *buffer, ++ size_t count, loff_t *off) + { +- struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, +- ll_kobj); ++ struct seq_file *m = file->private_data; ++ struct super_block *sb = m->private; ++ struct ll_sb_info *sbi = ll_s2sbi(sb); + struct root_squash_info *squash = &sbi->ll_squash; + + return lprocfs_wr_root_squash(buffer, count, squash, +- ll_get_fsname(sbi->ll_sb, NULL, 0)); ++ ll_get_fsname(sb, NULL, 0)); + } +-LUSTRE_RW_ATTR(root_squash); ++LPROC_SEQ_FOPS(ll_root_squash); + + static int ll_nosquash_nids_seq_show(struct seq_file *m, void *v) + { +@@ -997,6 +999,8 @@ static struct lprocfs_vars lprocfs_llite_obd_vars[] = { + { "statahead_stats", &ll_statahead_stats_fops, NULL, 0 }, + { "unstable_stats", &ll_unstable_stats_fops, NULL }, + { "sbi_flags", &ll_sbi_flags_fops, NULL, 0 }, ++ { .name = "root_squash", ++ .fops = &ll_root_squash_fops }, + { .name = "nosquash_nids", + .fops = &ll_nosquash_nids_fops }, + { NULL } +@@ -1027,7 +1031,6 @@ static struct attribute *llite_attrs[] = { + &lustre_attr_max_easize.attr, + &lustre_attr_default_easize.attr, + &lustre_attr_xattr_cache.attr, +- &lustre_attr_root_squash.attr, + NULL, + }; + +-- +2.12.0 + diff --git a/queue/staging-vt6656-use-off-stack-for-in-buffer-USB-trans.patch b/queue/staging-vt6656-use-off-stack-for-in-buffer-USB-trans.patch new file mode 100644 index 0000000..300effb --- /dev/null +++ b/queue/staging-vt6656-use-off-stack-for-in-buffer-USB-trans.patch @@ -0,0 +1,54 @@ +From 05c0cf88bec588a7cb34de569acd871ceef26760 Mon Sep 17 00:00:00 2001 +From: Malcolm Priestley <tvboxspy@gmail.com> +Date: Sat, 22 Apr 2017 11:14:58 +0100 +Subject: [PATCH] staging: vt6656: use off stack for in buffer USB transfers. + +commit 05c0cf88bec588a7cb34de569acd871ceef26760 upstream. + +Since 4.9 mandated USB buffers to be heap allocated. This causes +the driver to fail. + +Create buffer for USB transfers. + +Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com> +Cc: <stable@vger.kernel.org> # v4.9+ +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c +index ea5a7c65ad1b..dc11a05be8c4 100644 +--- a/drivers/staging/vt6656/usbpipe.c ++++ b/drivers/staging/vt6656/usbpipe.c +@@ -85,15 +85,28 @@ int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, + u16 index, u16 length, u8 *buffer) + { + int status; ++ u8 *usb_buffer; + + if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) + return STATUS_FAILURE; + + mutex_lock(&priv->usb_lock); + ++ usb_buffer = kmalloc(length, GFP_KERNEL); ++ if (!usb_buffer) { ++ mutex_unlock(&priv->usb_lock); ++ return -ENOMEM; ++ } ++ + status = usb_control_msg(priv->usb, +- usb_rcvctrlpipe(priv->usb, 0), request, 0xc0, +- value, index, buffer, length, USB_CTL_WAIT); ++ usb_rcvctrlpipe(priv->usb, 0), ++ request, 0xc0, value, ++ index, usb_buffer, length, USB_CTL_WAIT); ++ ++ if (status == length) ++ memcpy(buffer, usb_buffer, length); ++ ++ kfree(usb_buffer); + + mutex_unlock(&priv->usb_lock); + +-- +2.12.0 + diff --git a/queue/staging-vt6656-use-off-stack-for-out-buffer-USB-tran.patch b/queue/staging-vt6656-use-off-stack-for-out-buffer-USB-tran.patch new file mode 100644 index 0000000..d2c4cda --- /dev/null +++ b/queue/staging-vt6656-use-off-stack-for-out-buffer-USB-tran.patch @@ -0,0 +1,52 @@ +From 12ecd24ef93277e4e5feaf27b0b18f2d3828bc5e Mon Sep 17 00:00:00 2001 +From: Malcolm Priestley <tvboxspy@gmail.com> +Date: Sat, 22 Apr 2017 11:14:57 +0100 +Subject: [PATCH] staging: vt6656: use off stack for out buffer USB transfers. + +commit 12ecd24ef93277e4e5feaf27b0b18f2d3828bc5e upstream. + +Since 4.9 mandated USB buffers be heap allocated this causes the driver +to fail. + +Since there is a wide range of buffer sizes use kmemdup to create +allocated buffer. + +Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com> +Cc: <stable@vger.kernel.org> # v4.9+ +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c +index 9ad8503d2589..ea5a7c65ad1b 100644 +--- a/drivers/staging/vt6656/usbpipe.c ++++ b/drivers/staging/vt6656/usbpipe.c +@@ -47,15 +47,25 @@ int vnt_control_out(struct vnt_private *priv, u8 request, u16 value, + u16 index, u16 length, u8 *buffer) + { + int status = 0; ++ u8 *usb_buffer; + + if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) + return STATUS_FAILURE; + + mutex_lock(&priv->usb_lock); + ++ usb_buffer = kmemdup(buffer, length, GFP_KERNEL); ++ if (!usb_buffer) { ++ mutex_unlock(&priv->usb_lock); ++ return -ENOMEM; ++ } ++ + status = usb_control_msg(priv->usb, +- usb_sndctrlpipe(priv->usb, 0), request, 0x40, value, +- index, buffer, length, USB_CTL_WAIT); ++ usb_sndctrlpipe(priv->usb, 0), ++ request, 0x40, value, ++ index, usb_buffer, length, USB_CTL_WAIT); ++ ++ kfree(usb_buffer); + + mutex_unlock(&priv->usb_lock); + +-- +2.12.0 + diff --git a/queue/staging-wlan-ng-add-missing-byte-order-conversion.patch b/queue/staging-wlan-ng-add-missing-byte-order-conversion.patch new file mode 100644 index 0000000..41ecdc7 --- /dev/null +++ b/queue/staging-wlan-ng-add-missing-byte-order-conversion.patch @@ -0,0 +1,34 @@ +From 2c474b8579e9b67ff72b2bcefce9f53c7f4469d4 Mon Sep 17 00:00:00 2001 +From: Igor Pylypiv <igor.pylypiv@gmail.com> +Date: Mon, 30 Jan 2017 21:39:54 -0800 +Subject: [PATCH] staging: wlan-ng: add missing byte order conversion + +commit 2c474b8579e9b67ff72b2bcefce9f53c7f4469d4 upstream. + +Conversion macros le16_to_cpu was removed and that caused new sparse warning + +sparse output: +drivers/staging/wlan-ng/p80211netdev.c:241:44: warning: incorrect type in argument 2 (different base types) +drivers/staging/wlan-ng/p80211netdev.c:241:44: expected unsigned short [unsigned] [usertype] fc +drivers/staging/wlan-ng/p80211netdev.c:241:44: got restricted __le16 [usertype] fc + +Fixes: 7ad82572348c ("staging:wlan-ng:Fix sparse warning") +Signed-off-by: Igor Pylypiv <igor.pylypiv@gmail.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c +index 73fcf07254fe..eea50b614638 100644 +--- a/drivers/staging/wlan-ng/p80211netdev.c ++++ b/drivers/staging/wlan-ng/p80211netdev.c +@@ -237,7 +237,7 @@ static int p80211_convert_to_ether(struct wlandevice *wlandev, + struct p80211_hdr_a3 *hdr; + + hdr = (struct p80211_hdr_a3 *)skb->data; +- if (p80211_rx_typedrop(wlandev, hdr->fc)) ++ if (p80211_rx_typedrop(wlandev, le16_to_cpu(hdr->fc))) + return CONV_TO_ETHER_SKIPPED; + + /* perform mcast filtering: allow my local address through but reject +-- +2.12.0 + diff --git a/queue/target-Fix-compare_and_write_callback-handling-for-n.patch b/queue/target-Fix-compare_and_write_callback-handling-for-n.patch new file mode 100644 index 0000000..6db2158 --- /dev/null +++ b/queue/target-Fix-compare_and_write_callback-handling-for-n.patch @@ -0,0 +1,48 @@ +From a71a5dc7f833943998e97ca8fa6a4c708a0ed1a9 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger <nab@linux-iscsi.org> +Date: Tue, 11 Apr 2017 16:24:16 -0700 +Subject: [PATCH] target: Fix compare_and_write_callback handling for non GOOD + status + +commit a71a5dc7f833943998e97ca8fa6a4c708a0ed1a9 upstream. + +Following the bugfix for handling non SAM_STAT_GOOD COMPARE_AND_WRITE +status during COMMIT phase in commit 9b2792c3da1, the same bug exists +for the READ phase as well. + +This would manifest first as a lost SCSI response, and eventual +hung task during fabric driver logout or re-login, as existing +shutdown logic waited for the COMPARE_AND_WRITE se_cmd->cmd_kref +to reach zero. + +To address this bug, compare_and_write_callback() has been changed +to set post_ret = 1 and return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE +as necessary to signal failure status. + +Reported-by: Bill Borsari <wgb@datera.io> +Cc: Bill Borsari <wgb@datera.io> +Tested-by: Gary Guo <ghg@datera.io> +Cc: Gary Guo <ghg@datera.io> +Cc: <stable@vger.kernel.org> # v4.1+ +Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> + +diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c +index f9250b3c3fd4..a0ad618f1b1a 100644 +--- a/drivers/target/target_core_sbc.c ++++ b/drivers/target/target_core_sbc.c +@@ -507,8 +507,11 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool succes + * been failed with a non-zero SCSI status. + */ + if (cmd->scsi_status) { +- pr_err("compare_and_write_callback: non zero scsi_status:" ++ pr_debug("compare_and_write_callback: non zero scsi_status:" + " 0x%02x\n", cmd->scsi_status); ++ *post_ret = 1; ++ if (cmd->scsi_status == SAM_STAT_CHECK_CONDITION) ++ ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; + goto out; + } + +-- +2.12.0 + diff --git a/queue/target-fileio-Fix-zero-length-READ-and-WRITE-handlin.patch b/queue/target-fileio-Fix-zero-length-READ-and-WRITE-handlin.patch new file mode 100644 index 0000000..19483b8 --- /dev/null +++ b/queue/target-fileio-Fix-zero-length-READ-and-WRITE-handlin.patch @@ -0,0 +1,49 @@ +From 59ac9c078141b8fd0186c0b18660a1b2c24e724e Mon Sep 17 00:00:00 2001 +From: Bart Van Assche <bart.vanassche@sandisk.com> +Date: Thu, 4 May 2017 15:50:47 -0700 +Subject: [PATCH] target/fileio: Fix zero-length READ and WRITE handling + +commit 59ac9c078141b8fd0186c0b18660a1b2c24e724e upstream. + +This patch fixes zero-length READ and WRITE handling in target/FILEIO, +which was broken a long time back by: + +Since: + + commit d81cb44726f050d7cf1be4afd9cb45d153b52066 + Author: Paolo Bonzini <pbonzini@redhat.com> + Date: Mon Sep 17 16:36:11 2012 -0700 + + target: go through normal processing for all zero-length commands + +which moved zero-length READ and WRITE completion out of target-core, +to doing submission into backend driver code. + +To address this, go ahead and invoke target_complete_cmd() for any +non negative return value in fd_do_rw(). + +Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> +Reviewed-by: Hannes Reinecke <hare@suse.com> +Reviewed-by: Christoph Hellwig <hch@lst.de> +Cc: Andy Grover <agrover@redhat.com> +Cc: David Disseldorp <ddiss@suse.de> +Cc: <stable@vger.kernel.org> # v3.7+ +Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> + +diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c +index 1bf6c31e4c21..73b8f93a5fef 100644 +--- a/drivers/target/target_core_file.c ++++ b/drivers/target/target_core_file.c +@@ -608,8 +608,7 @@ fd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, + if (ret < 0) + return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; + +- if (ret) +- target_complete_cmd(cmd, SAM_STAT_GOOD); ++ target_complete_cmd(cmd, SAM_STAT_GOOD); + return 0; + } + +-- +2.12.0 + diff --git a/queue/tcp-clear-saved_syn-in-tcp_disconnect.patch b/queue/tcp-clear-saved_syn-in-tcp_disconnect.patch new file mode 100644 index 0000000..8f79a5e --- /dev/null +++ b/queue/tcp-clear-saved_syn-in-tcp_disconnect.patch @@ -0,0 +1,54 @@ +From 17c3060b1701fc69daedb4c90be6325d3d9fca8e Mon Sep 17 00:00:00 2001 +From: Eric Dumazet <edumazet@google.com> +Date: Sat, 8 Apr 2017 08:07:33 -0700 +Subject: [PATCH] tcp: clear saved_syn in tcp_disconnect() + +commit 17c3060b1701fc69daedb4c90be6325d3d9fca8e upstream. + +In the (very unlikely) case a passive socket becomes a listener, +we do not want to duplicate its saved SYN headers. + +This would lead to double frees, use after free, and please hackers and +various fuzzers + +Tested: + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 + +0 setsockopt(3, IPPROTO_TCP, TCP_SAVE_SYN, [1], 4) = 0 + +0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 + + +0 bind(3, ..., ...) = 0 + +0 listen(3, 5) = 0 + + +0 < S 0:0(0) win 32972 <mss 1460,nop,wscale 7> + +0 > S. 0:0(0) ack 1 <...> + +.1 < . 1:1(0) ack 1 win 257 + +0 accept(3, ..., ...) = 4 + + +0 connect(4, AF_UNSPEC, ...) = 0 + +0 close(3) = 0 + +0 bind(4, ..., ...) = 0 + +0 listen(4, 5) = 0 + + +0 < S 0:0(0) win 32972 <mss 1460,nop,wscale 7> + +0 > S. 0:0(0) ack 1 <...> + +.1 < . 1:1(0) ack 1 win 257 + +Fixes: cd8ae85299d5 ("tcp: provide SYN headers for passive connections") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 1e319a525d51..40ba4249a586 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2322,6 +2322,7 @@ int tcp_disconnect(struct sock *sk, int flags) + tcp_init_send_head(sk); + memset(&tp->rx_opt, 0, sizeof(tp->rx_opt)); + __sk_dst_reset(sk); ++ tcp_saved_syn_free(tp); + + /* Clean up fastopen related fields */ + tcp_free_fastopen_req(tp); +-- +2.12.0 + diff --git a/queue/tcp-do-not-inherit-fastopen_req-from-parent.patch b/queue/tcp-do-not-inherit-fastopen_req-from-parent.patch new file mode 100644 index 0000000..b532c70 --- /dev/null +++ b/queue/tcp-do-not-inherit-fastopen_req-from-parent.patch @@ -0,0 +1,147 @@ +From 8b485ce69876c65db12ed390e7f9c0d2a64eff2c Mon Sep 17 00:00:00 2001 +From: Eric Dumazet <edumazet@google.com> +Date: Wed, 3 May 2017 06:39:31 -0700 +Subject: [PATCH] tcp: do not inherit fastopen_req from parent + +commit 8b485ce69876c65db12ed390e7f9c0d2a64eff2c upstream. + +Under fuzzer stress, it is possible that a child gets a non NULL +fastopen_req pointer from its parent at accept() time, when/if parent +morphs from listener to active session. + +We need to make sure this can not happen, by clearing the field after +socket cloning. + +BUG: Double free or freeing an invalid pointer +Unexpected shadow byte: 0xFB +CPU: 3 PID: 20933 Comm: syz-executor3 Not tainted 4.11.0+ #306 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs +01/01/2011 +Call Trace: + <IRQ> + __dump_stack lib/dump_stack.c:16 [inline] + dump_stack+0x292/0x395 lib/dump_stack.c:52 + kasan_object_err+0x1c/0x70 mm/kasan/report.c:164 + kasan_report_double_free+0x5c/0x70 mm/kasan/report.c:185 + kasan_slab_free+0x9d/0xc0 mm/kasan/kasan.c:580 + 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+0xe8/0x2b0 mm/slub.c:3882 + tcp_free_fastopen_req net/ipv4/tcp.c:1077 [inline] + tcp_disconnect+0xc15/0x13e0 net/ipv4/tcp.c:2328 + inet_child_forget+0xb8/0x600 net/ipv4/inet_connection_sock.c:898 + inet_csk_reqsk_queue_add+0x1e7/0x250 +net/ipv4/inet_connection_sock.c:928 + tcp_get_cookie_sock+0x21a/0x510 net/ipv4/syncookies.c:217 + cookie_v4_check+0x1a19/0x28b0 net/ipv4/syncookies.c:384 + tcp_v4_cookie_check net/ipv4/tcp_ipv4.c:1384 [inline] + tcp_v4_do_rcv+0x731/0x940 net/ipv4/tcp_ipv4.c:1421 + tcp_v4_rcv+0x2dc0/0x31c0 net/ipv4/tcp_ipv4.c:1715 + ip_local_deliver_finish+0x4cc/0xc20 net/ipv4/ip_input.c:216 + NF_HOOK include/linux/netfilter.h:257 [inline] + ip_local_deliver+0x1ce/0x700 net/ipv4/ip_input.c:257 + dst_input include/net/dst.h:492 [inline] + ip_rcv_finish+0xb1d/0x20b0 net/ipv4/ip_input.c:396 + NF_HOOK include/linux/netfilter.h:257 [inline] + ip_rcv+0xd8c/0x19c0 net/ipv4/ip_input.c:487 + __netif_receive_skb_core+0x1ad1/0x3400 net/core/dev.c:4210 + __netif_receive_skb+0x2a/0x1a0 net/core/dev.c:4248 + process_backlog+0xe5/0x6c0 net/core/dev.c:4868 + napi_poll net/core/dev.c:5270 [inline] + net_rx_action+0xe70/0x18e0 net/core/dev.c:5335 + __do_softirq+0x2fb/0xb99 kernel/softirq.c:284 + do_softirq_own_stack+0x1c/0x30 arch/x86/entry/entry_64.S:899 + </IRQ> + do_softirq.part.17+0x1e8/0x230 kernel/softirq.c:328 + do_softirq kernel/softirq.c:176 [inline] + __local_bh_enable_ip+0x1cf/0x1e0 kernel/softirq.c:181 + local_bh_enable include/linux/bottom_half.h:31 [inline] + rcu_read_unlock_bh include/linux/rcupdate.h:931 [inline] + ip_finish_output2+0x9ab/0x15e0 net/ipv4/ip_output.c:230 + ip_finish_output+0xa35/0xdf0 net/ipv4/ip_output.c:316 + NF_HOOK_COND include/linux/netfilter.h:246 [inline] + ip_output+0x1f6/0x7b0 net/ipv4/ip_output.c:404 + dst_output include/net/dst.h:486 [inline] + ip_local_out+0x95/0x160 net/ipv4/ip_output.c:124 + ip_queue_xmit+0x9a8/0x1a10 net/ipv4/ip_output.c:503 + tcp_transmit_skb+0x1ade/0x3470 net/ipv4/tcp_output.c:1057 + tcp_write_xmit+0x79e/0x55b0 net/ipv4/tcp_output.c:2265 + __tcp_push_pending_frames+0xfa/0x3a0 net/ipv4/tcp_output.c:2450 + tcp_push+0x4ee/0x780 net/ipv4/tcp.c:683 + tcp_sendmsg+0x128d/0x39b0 net/ipv4/tcp.c:1342 + inet_sendmsg+0x164/0x5b0 net/ipv4/af_inet.c:762 + sock_sendmsg_nosec net/socket.c:633 [inline] + sock_sendmsg+0xca/0x110 net/socket.c:643 + SYSC_sendto+0x660/0x810 net/socket.c:1696 + SyS_sendto+0x40/0x50 net/socket.c:1664 + entry_SYSCALL_64_fastpath+0x1f/0xbe +RIP: 0033:0x446059 +RSP: 002b:00007faa6761fb58 EFLAGS: 00000282 ORIG_RAX: 000000000000002c +RAX: ffffffffffffffda RBX: 0000000000000017 RCX: 0000000000446059 +RDX: 0000000000000001 RSI: 0000000020ba3fcd RDI: 0000000000000017 +RBP: 00000000006e40a0 R08: 0000000020ba4ff0 R09: 0000000000000010 +R10: 0000000020000000 R11: 0000000000000282 R12: 0000000000708150 +R13: 0000000000000000 R14: 00007faa676209c0 R15: 00007faa67620700 +Object at ffff88003b5bbcb8, in cache kmalloc-64 size: 64 +Allocated: +PID = 20909 + save_stack_trace+0x16/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:616 + kmem_cache_alloc_trace+0x82/0x270 mm/slub.c:2745 + kmalloc include/linux/slab.h:490 [inline] + kzalloc include/linux/slab.h:663 [inline] + tcp_sendmsg_fastopen net/ipv4/tcp.c:1094 [inline] + tcp_sendmsg+0x221a/0x39b0 net/ipv4/tcp.c:1139 + inet_sendmsg+0x164/0x5b0 net/ipv4/af_inet.c:762 + sock_sendmsg_nosec net/socket.c:633 [inline] + sock_sendmsg+0xca/0x110 net/socket.c:643 + SYSC_sendto+0x660/0x810 net/socket.c:1696 + SyS_sendto+0x40/0x50 net/socket.c:1664 + entry_SYSCALL_64_fastpath+0x1f/0xbe +Freed: +PID = 20909 + save_stack_trace+0x16/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+0x73/0xc0 mm/kasan/kasan.c:589 + 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+0xe8/0x2b0 mm/slub.c:3882 + tcp_free_fastopen_req net/ipv4/tcp.c:1077 [inline] + tcp_disconnect+0xc15/0x13e0 net/ipv4/tcp.c:2328 + __inet_stream_connect+0x20c/0xf90 net/ipv4/af_inet.c:593 + tcp_sendmsg_fastopen net/ipv4/tcp.c:1111 [inline] + tcp_sendmsg+0x23a8/0x39b0 net/ipv4/tcp.c:1139 + inet_sendmsg+0x164/0x5b0 net/ipv4/af_inet.c:762 + sock_sendmsg_nosec net/socket.c:633 [inline] + sock_sendmsg+0xca/0x110 net/socket.c:643 + SYSC_sendto+0x660/0x810 net/socket.c:1696 + SyS_sendto+0x40/0x50 net/socket.c:1664 + entry_SYSCALL_64_fastpath+0x1f/0xbe + +Fixes: e994b2f0fb92 ("tcp: do not lock listener to process SYN packets") +Fixes: 7db92362d2fe ("tcp: fix potential double free issue for fastopen_req") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: Andrey Konovalov <andreyknvl@google.com> +Acked-by: Wei Wang <weiwan@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c +index 8f6373b0cd77..717be4de5324 100644 +--- a/net/ipv4/tcp_minisocks.c ++++ b/net/ipv4/tcp_minisocks.c +@@ -523,6 +523,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, + newicsk->icsk_ack.last_seg_size = skb->len - newtp->tcp_header_len; + newtp->rx_opt.mss_clamp = req->mss; + tcp_ecn_openreq_child(newtp, req); ++ newtp->fastopen_req = NULL; + newtp->fastopen_rsk = NULL; + newtp->syn_data_acked = 0; + newtp->rack.mstamp.v64 = 0; +-- +2.12.0 + diff --git a/queue/tcp-do-not-underestimate-skb-truesize-in-tcp_trim_he.patch b/queue/tcp-do-not-underestimate-skb-truesize-in-tcp_trim_he.patch new file mode 100644 index 0000000..b19ae48 --- /dev/null +++ b/queue/tcp-do-not-underestimate-skb-truesize-in-tcp_trim_he.patch @@ -0,0 +1,84 @@ +From 7162fb242cb8322beb558828fd26b33c3e9fc805 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet <edumazet@google.com> +Date: Wed, 26 Apr 2017 17:15:40 -0700 +Subject: [PATCH] tcp: do not underestimate skb->truesize in tcp_trim_head() + +commit 7162fb242cb8322beb558828fd26b33c3e9fc805 upstream. + +Andrey found a way to trigger the WARN_ON_ONCE(delta < len) in +skb_try_coalesce() using syzkaller and a filter attached to a TCP +socket over loopback interface. + +I believe one issue with looped skbs is that tcp_trim_head() can end up +producing skb with under estimated truesize. + +It hardly matters for normal conditions, since packets sent over +loopback are never truncated. + +Bytes trimmed from skb->head should not change skb truesize, since +skb->head is not reallocated. + +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: Andrey Konovalov <andreyknvl@google.com> +Tested-by: Andrey Konovalov <andreyknvl@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index c3c082ed3879..a85d863c4419 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -1267,7 +1267,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, + * eventually). The difference is that pulled data not copied, but + * immediately discarded. + */ +-static void __pskb_trim_head(struct sk_buff *skb, int len) ++static int __pskb_trim_head(struct sk_buff *skb, int len) + { + struct skb_shared_info *shinfo; + int i, k, eat; +@@ -1277,7 +1277,7 @@ static void __pskb_trim_head(struct sk_buff *skb, int len) + __skb_pull(skb, eat); + len -= eat; + if (!len) +- return; ++ return 0; + } + eat = len; + k = 0; +@@ -1303,23 +1303,28 @@ static void __pskb_trim_head(struct sk_buff *skb, int len) + skb_reset_tail_pointer(skb); + skb->data_len -= len; + skb->len = skb->data_len; ++ return len; + } + + /* Remove acked data from a packet in the transmit queue. */ + int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len) + { ++ u32 delta_truesize; ++ + if (skb_unclone(skb, GFP_ATOMIC)) + return -ENOMEM; + +- __pskb_trim_head(skb, len); ++ delta_truesize = __pskb_trim_head(skb, len); + + TCP_SKB_CB(skb)->seq += len; + skb->ip_summed = CHECKSUM_PARTIAL; + +- skb->truesize -= len; +- sk->sk_wmem_queued -= len; +- sk_mem_uncharge(sk, len); +- sock_set_flag(sk, SOCK_QUEUE_SHRUNK); ++ if (delta_truesize) { ++ skb->truesize -= delta_truesize; ++ sk->sk_wmem_queued -= delta_truesize; ++ sk_mem_uncharge(sk, delta_truesize); ++ sock_set_flag(sk, SOCK_QUEUE_SHRUNK); ++ } + + /* Any change of skb->len requires recalculation of tso factor. */ + if (tcp_skb_pcount(skb) > 1) +-- +2.12.0 + diff --git a/queue/tcp-fix-wraparound-issue-in-tcp_lp.patch b/queue/tcp-fix-wraparound-issue-in-tcp_lp.patch new file mode 100644 index 0000000..719460f --- /dev/null +++ b/queue/tcp-fix-wraparound-issue-in-tcp_lp.patch @@ -0,0 +1,39 @@ +From a9f11f963a546fea9144f6a6d1a307e814a387e7 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet <edumazet@google.com> +Date: Mon, 1 May 2017 15:29:48 -0700 +Subject: [PATCH] tcp: fix wraparound issue in tcp_lp + +commit a9f11f963a546fea9144f6a6d1a307e814a387e7 upstream. + +Be careful when comparing tcp_time_stamp to some u32 quantity, +otherwise result can be surprising. + +Fixes: 7c106d7e782b ("[TCP]: TCP Low Priority congestion control") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/ipv4/tcp_lp.c b/net/ipv4/tcp_lp.c +index 046fd3910873..d6fb6c067af4 100644 +--- a/net/ipv4/tcp_lp.c ++++ b/net/ipv4/tcp_lp.c +@@ -264,13 +264,15 @@ static void tcp_lp_pkts_acked(struct sock *sk, const struct ack_sample *sample) + { + struct tcp_sock *tp = tcp_sk(sk); + struct lp *lp = inet_csk_ca(sk); ++ u32 delta; + + if (sample->rtt_us > 0) + tcp_lp_rtt_sample(sk, sample->rtt_us); + + /* calc inference */ +- if (tcp_time_stamp > tp->rx_opt.rcv_tsecr) +- lp->inference = 3 * (tcp_time_stamp - tp->rx_opt.rcv_tsecr); ++ delta = tcp_time_stamp - tp->rx_opt.rcv_tsecr; ++ if ((s32)delta > 0) ++ lp->inference = 3 * delta; + + /* test if within inference */ + if (lp->last_drop && (tcp_time_stamp - lp->last_drop < lp->inference)) +-- +2.12.0 + diff --git a/queue/tcp-memset-ca_priv-data-to-0-properly.patch b/queue/tcp-memset-ca_priv-data-to-0-properly.patch new file mode 100644 index 0000000..17811d7 --- /dev/null +++ b/queue/tcp-memset-ca_priv-data-to-0-properly.patch @@ -0,0 +1,59 @@ +From c1201444075009507a6818de6518e2822b9a87c8 Mon Sep 17 00:00:00 2001 +From: Wei Wang <weiwan@google.com> +Date: Tue, 25 Apr 2017 17:38:02 -0700 +Subject: [PATCH] tcp: memset ca_priv data to 0 properly + +commit c1201444075009507a6818de6518e2822b9a87c8 upstream. + +Always zero out ca_priv data in tcp_assign_congestion_control() so that +ca_priv data is cleared out during socket creation. +Also always zero out ca_priv data in tcp_reinit_congestion_control() so +that when cc algorithm is changed, ca_priv data is cleared out as well. +We should still zero out ca_priv data even in TCP_CLOSE state because +user could call connect() on AF_UNSPEC to disconnect the socket and +leave it in TCP_CLOSE state and later call setsockopt() to switch cc +algorithm on this socket. + +Fixes: 2b0a8c9ee ("tcp: add CDG congestion control") +Reported-by: Andrey Konovalov <andreyknvl@google.com> +Signed-off-by: Wei Wang <weiwan@google.com> +Acked-by: Eric Dumazet <edumazet@google.com> +Acked-by: Yuchung Cheng <ycheng@google.com> +Acked-by: Neal Cardwell <ncardwell@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c +index 79c4817abc94..6e3c512054a6 100644 +--- a/net/ipv4/tcp_cong.c ++++ b/net/ipv4/tcp_cong.c +@@ -168,12 +168,8 @@ void tcp_assign_congestion_control(struct sock *sk) + } + out: + rcu_read_unlock(); ++ memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); + +- /* Clear out private data before diag gets it and +- * the ca has not been initialized. +- */ +- if (ca->get_info) +- memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); + if (ca->flags & TCP_CONG_NEEDS_ECN) + INET_ECN_xmit(sk); + else +@@ -200,11 +196,10 @@ static void tcp_reinit_congestion_control(struct sock *sk, + tcp_cleanup_congestion_control(sk); + icsk->icsk_ca_ops = ca; + icsk->icsk_ca_setsockopt = 1; ++ memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); + +- if (sk->sk_state != TCP_CLOSE) { +- memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); ++ if (sk->sk_state != TCP_CLOSE) + tcp_init_congestion_control(sk); +- } + } + + /* Manage refcounts on socket close. */ +-- +2.12.0 + diff --git a/queue/timerfd-Protect-the-might-cancel-mechanism-proper.patch b/queue/timerfd-Protect-the-might-cancel-mechanism-proper.patch new file mode 100644 index 0000000..4dc9def --- /dev/null +++ b/queue/timerfd-Protect-the-might-cancel-mechanism-proper.patch @@ -0,0 +1,94 @@ +From 1e38da300e1e395a15048b0af1e5305bd91402f6 Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner <tglx@linutronix.de> +Date: Tue, 31 Jan 2017 15:24:03 +0100 +Subject: [PATCH] timerfd: Protect the might cancel mechanism proper + +commit 1e38da300e1e395a15048b0af1e5305bd91402f6 upstream. + +The handling of the might_cancel queueing is not properly protected, so +parallel operations on the file descriptor can race with each other and +lead to list corruptions or use after free. + +Protect the context for these operations with a seperate lock. + +The wait queue lock cannot be reused for this because that would create a +lock inversion scenario vs. the cancel lock. Replacing might_cancel with an +atomic (atomic_t or atomic bit) does not help either because it still can +race vs. the actual list operation. + +Reported-by: Dmitry Vyukov <dvyukov@google.com> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Cc: "linux-fsdevel@vger.kernel.org" +Cc: syzkaller <syzkaller@googlegroups.com> +Cc: Al Viro <viro@zeniv.linux.org.uk> +Cc: linux-fsdevel@vger.kernel.org +Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1701311521430.3457@nanos +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + +diff --git a/fs/timerfd.c b/fs/timerfd.c +index c173cc196175..384fa759a563 100644 +--- a/fs/timerfd.c ++++ b/fs/timerfd.c +@@ -40,6 +40,7 @@ struct timerfd_ctx { + short unsigned settime_flags; /* to show in fdinfo */ + struct rcu_head rcu; + struct list_head clist; ++ spinlock_t cancel_lock; + bool might_cancel; + }; + +@@ -112,7 +113,7 @@ void timerfd_clock_was_set(void) + rcu_read_unlock(); + } + +-static void timerfd_remove_cancel(struct timerfd_ctx *ctx) ++static void __timerfd_remove_cancel(struct timerfd_ctx *ctx) + { + if (ctx->might_cancel) { + ctx->might_cancel = false; +@@ -122,6 +123,13 @@ static void timerfd_remove_cancel(struct timerfd_ctx *ctx) + } + } + ++static void timerfd_remove_cancel(struct timerfd_ctx *ctx) ++{ ++ spin_lock(&ctx->cancel_lock); ++ __timerfd_remove_cancel(ctx); ++ spin_unlock(&ctx->cancel_lock); ++} ++ + static bool timerfd_canceled(struct timerfd_ctx *ctx) + { + if (!ctx->might_cancel || ctx->moffs != KTIME_MAX) +@@ -132,6 +140,7 @@ static bool timerfd_canceled(struct timerfd_ctx *ctx) + + static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags) + { ++ spin_lock(&ctx->cancel_lock); + if ((ctx->clockid == CLOCK_REALTIME || + ctx->clockid == CLOCK_REALTIME_ALARM) && + (flags & TFD_TIMER_ABSTIME) && (flags & TFD_TIMER_CANCEL_ON_SET)) { +@@ -141,9 +150,10 @@ static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags) + list_add_rcu(&ctx->clist, &cancel_list); + spin_unlock(&cancel_lock); + } +- } else if (ctx->might_cancel) { +- timerfd_remove_cancel(ctx); ++ } else { ++ __timerfd_remove_cancel(ctx); + } ++ spin_unlock(&ctx->cancel_lock); + } + + static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx) +@@ -400,6 +410,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) + return -ENOMEM; + + init_waitqueue_head(&ctx->wqh); ++ spin_lock_init(&ctx->cancel_lock); + ctx->clockid = clockid; + + if (isalarm(ctx)) +-- +2.12.0 + diff --git a/queue/tmp-use-pdev-for-parent-device-in-tpm_chip_alloc.patch b/queue/tmp-use-pdev-for-parent-device-in-tpm_chip_alloc.patch new file mode 100644 index 0000000..642b0b8 --- /dev/null +++ b/queue/tmp-use-pdev-for-parent-device-in-tpm_chip_alloc.patch @@ -0,0 +1,59 @@ +From 2998b02b2fb58f36ccbc318b00513174e9947d8e Mon Sep 17 00:00:00 2001 +From: "Winkler, Tomas" <tomas.winkler@intel.com> +Date: Wed, 23 Nov 2016 12:04:13 +0200 +Subject: [PATCH] tmp: use pdev for parent device in tpm_chip_alloc + +commit 2998b02b2fb58f36ccbc318b00513174e9947d8e upstream. + +The tpm stack uses pdev name convention for the parent device. +Fix that also in tpm_chip_alloc(). + +Fixes: 3897cd9c8d1d ("tpm: Split out the devm stuff from tpmm_chip_alloc")' +Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> +Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> +Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> +Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> + +diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c +index a77262d31911..c406343848da 100644 +--- a/drivers/char/tpm/tpm-chip.c ++++ b/drivers/char/tpm/tpm-chip.c +@@ -141,7 +141,7 @@ static void tpm_dev_release(struct device *dev) + * Allocates a new struct tpm_chip instance and assigns a free + * device number for it. Must be paired with put_device(&chip->dev). + */ +-struct tpm_chip *tpm_chip_alloc(struct device *dev, ++struct tpm_chip *tpm_chip_alloc(struct device *pdev, + const struct tpm_class_ops *ops) + { + struct tpm_chip *chip; +@@ -160,7 +160,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *dev, + rc = idr_alloc(&dev_nums_idr, NULL, 0, TPM_NUM_DEVICES, GFP_KERNEL); + mutex_unlock(&idr_lock); + if (rc < 0) { +- dev_err(dev, "No available tpm device numbers\n"); ++ dev_err(pdev, "No available tpm device numbers\n"); + kfree(chip); + return ERR_PTR(rc); + } +@@ -170,7 +170,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *dev, + + chip->dev.class = tpm_class; + chip->dev.release = tpm_dev_release; +- chip->dev.parent = dev; ++ chip->dev.parent = pdev; + chip->dev.groups = chip->groups; + + if (chip->dev_num == 0) +@@ -182,7 +182,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *dev, + if (rc) + goto out; + +- if (!dev) ++ if (!pdev) + chip->flags |= TPM_CHIP_FLAG_VIRTUAL; + + cdev_init(&chip->cdev, &tpm_fops); +-- +2.12.0 + diff --git a/queue/tpm-fix-RC-value-check-in-tpm2_seal_trusted.patch b/queue/tpm-fix-RC-value-check-in-tpm2_seal_trusted.patch new file mode 100644 index 0000000..563babf --- /dev/null +++ b/queue/tpm-fix-RC-value-check-in-tpm2_seal_trusted.patch @@ -0,0 +1,48 @@ +From 7d761119a914ec0ac05ec2a5378d1f86e680967d Mon Sep 17 00:00:00 2001 +From: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> +Date: Wed, 25 Jan 2017 23:00:22 +0200 +Subject: [PATCH] tpm: fix RC value check in tpm2_seal_trusted + +commit 7d761119a914ec0ac05ec2a5378d1f86e680967d upstream. + +The error code handling is broken as any error code that has the same +bits set as TPM_RC_HASH passes. Implemented tpm2_rc_value() helper to +parse the error value from FMT0 and FMT1 error codes so that these types +of mistakes are prevented in the future. + +Fixes: 5ca4c20cfd37 ("keys, trusted: select hash algorithm for TPM2 chips") +Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> +Reviewed-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> + +diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h +index 244fcffdab6b..dbe0c5a72c67 100644 +--- a/drivers/char/tpm/tpm.h ++++ b/drivers/char/tpm/tpm.h +@@ -519,6 +519,11 @@ static inline void tpm_add_ppi(struct tpm_chip *chip) + } + #endif + ++static inline inline u32 tpm2_rc_value(u32 rc) ++{ ++ return (rc & BIT(7)) ? rc & 0xff : rc; ++} ++ + int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf); + int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash); + int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max); +diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c +index a0199f18f7fb..42fe3dde0d8c 100644 +--- a/drivers/char/tpm/tpm2-cmd.c ++++ b/drivers/char/tpm/tpm2-cmd.c +@@ -546,7 +546,7 @@ out: + tpm_buf_destroy(&buf); + + if (rc > 0) { +- if ((rc & TPM2_RC_HASH) == TPM2_RC_HASH) ++ if (tpm2_rc_value(rc) == TPM2_RC_HASH) + rc = -EINVAL; + else + rc = -EPERM; +-- +2.12.0 + diff --git a/queue/tpm_tis-use-default-timeout-value-if-chip-reports-it.patch b/queue/tpm_tis-use-default-timeout-value-if-chip-reports-it.patch new file mode 100644 index 0000000..612481b --- /dev/null +++ b/queue/tpm_tis-use-default-timeout-value-if-chip-reports-it.patch @@ -0,0 +1,179 @@ +From 1d70fe9d9c3a4c627f9757cbba5d628687b121c1 Mon Sep 17 00:00:00 2001 +From: "Maciej S. Szmigiero" <mail@maciej.szmigiero.name> +Date: Fri, 13 Jan 2017 22:37:00 +0100 +Subject: [PATCH] tpm_tis: use default timeout value if chip reports it as zero + +commit 1d70fe9d9c3a4c627f9757cbba5d628687b121c1 upstream. + +Since commit 1107d065fdf1 ("tpm_tis: Introduce intermediate layer for +TPM access") Atmel 3203 TPM on ThinkPad X61S (TPM firmware version 13.9) +no longer works. The initialization proceeds fine until we get and +start using chip-reported timeouts - and the chip reports C and D +timeouts of zero. + +It turns out that until commit 8e54caf407b98e ("tpm: Provide a generic +means to override the chip returned timeouts") we had actually let +default timeout values remain in this case, so let's bring back this +behavior to make chips like Atmel 3203 work again. + +Use a common code that was introduced by that commit so a warning is +printed in this case and /sys/class/tpm/tpm*/timeouts correctly says the +timeouts aren't chip-original. + +Fixes: 1107d065fdf1 ("tpm_tis: Introduce intermediate layer for TPM access") +Cc: stable@vger.kernel.org +Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name> +Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> +Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> + +diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c +index fecdd3fa8126..a3461cbdde5f 100644 +--- a/drivers/char/tpm/tpm-interface.c ++++ b/drivers/char/tpm/tpm-interface.c +@@ -522,8 +522,7 @@ static int tpm_startup(struct tpm_chip *chip, __be16 startup_type) + int tpm_get_timeouts(struct tpm_chip *chip) + { + cap_t cap; +- unsigned long new_timeout[4]; +- unsigned long old_timeout[4]; ++ unsigned long timeout_old[4], timeout_chip[4], timeout_eff[4]; + ssize_t rc; + + if (chip->flags & TPM_CHIP_FLAG_HAVE_TIMEOUTS) +@@ -564,11 +563,15 @@ int tpm_get_timeouts(struct tpm_chip *chip) + return rc; + } + +- old_timeout[0] = be32_to_cpu(cap.timeout.a); +- old_timeout[1] = be32_to_cpu(cap.timeout.b); +- old_timeout[2] = be32_to_cpu(cap.timeout.c); +- old_timeout[3] = be32_to_cpu(cap.timeout.d); +- memcpy(new_timeout, old_timeout, sizeof(new_timeout)); ++ timeout_old[0] = jiffies_to_usecs(chip->timeout_a); ++ timeout_old[1] = jiffies_to_usecs(chip->timeout_b); ++ timeout_old[2] = jiffies_to_usecs(chip->timeout_c); ++ timeout_old[3] = jiffies_to_usecs(chip->timeout_d); ++ timeout_chip[0] = be32_to_cpu(cap.timeout.a); ++ timeout_chip[1] = be32_to_cpu(cap.timeout.b); ++ timeout_chip[2] = be32_to_cpu(cap.timeout.c); ++ timeout_chip[3] = be32_to_cpu(cap.timeout.d); ++ memcpy(timeout_eff, timeout_chip, sizeof(timeout_eff)); + + /* + * Provide ability for vendor overrides of timeout values in case +@@ -576,16 +579,24 @@ int tpm_get_timeouts(struct tpm_chip *chip) + */ + if (chip->ops->update_timeouts != NULL) + chip->timeout_adjusted = +- chip->ops->update_timeouts(chip, new_timeout); ++ chip->ops->update_timeouts(chip, timeout_eff); + + if (!chip->timeout_adjusted) { +- /* Don't overwrite default if value is 0 */ +- if (new_timeout[0] != 0 && new_timeout[0] < 1000) { +- int i; ++ /* Restore default if chip reported 0 */ ++ int i; + ++ for (i = 0; i < ARRAY_SIZE(timeout_eff); i++) { ++ if (timeout_eff[i]) ++ continue; ++ ++ timeout_eff[i] = timeout_old[i]; ++ chip->timeout_adjusted = true; ++ } ++ ++ if (timeout_eff[0] != 0 && timeout_eff[0] < 1000) { + /* timeouts in msec rather usec */ +- for (i = 0; i != ARRAY_SIZE(new_timeout); i++) +- new_timeout[i] *= 1000; ++ for (i = 0; i != ARRAY_SIZE(timeout_eff); i++) ++ timeout_eff[i] *= 1000; + chip->timeout_adjusted = true; + } + } +@@ -594,16 +605,16 @@ int tpm_get_timeouts(struct tpm_chip *chip) + if (chip->timeout_adjusted) { + dev_info(&chip->dev, + HW_ERR "Adjusting reported timeouts: A %lu->%luus B %lu->%luus C %lu->%luus D %lu->%luus\n", +- old_timeout[0], new_timeout[0], +- old_timeout[1], new_timeout[1], +- old_timeout[2], new_timeout[2], +- old_timeout[3], new_timeout[3]); ++ timeout_chip[0], timeout_eff[0], ++ timeout_chip[1], timeout_eff[1], ++ timeout_chip[2], timeout_eff[2], ++ timeout_chip[3], timeout_eff[3]); + } + +- chip->timeout_a = usecs_to_jiffies(new_timeout[0]); +- chip->timeout_b = usecs_to_jiffies(new_timeout[1]); +- chip->timeout_c = usecs_to_jiffies(new_timeout[2]); +- chip->timeout_d = usecs_to_jiffies(new_timeout[3]); ++ chip->timeout_a = usecs_to_jiffies(timeout_eff[0]); ++ chip->timeout_b = usecs_to_jiffies(timeout_eff[1]); ++ chip->timeout_c = usecs_to_jiffies(timeout_eff[2]); ++ chip->timeout_d = usecs_to_jiffies(timeout_eff[3]); + + rc = tpm_getcap(chip, TPM_CAP_PROP_TIS_DURATION, &cap, + "attempting to determine the durations"); +diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c +index 0127af130cb1..7912dadc39be 100644 +--- a/drivers/char/tpm/tpm_tis.c ++++ b/drivers/char/tpm/tpm_tis.c +@@ -159,7 +159,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info, + irq = tpm_info->irq; + + if (itpm) +- phy->priv.flags |= TPM_TIS_ITPM_POSSIBLE; ++ phy->priv.flags |= TPM_TIS_ITPM_WORKAROUND; + + return tpm_tis_core_init(dev, &phy->priv, irq, &tpm_tcg, + acpi_dev_handle); +diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c +index 7993678954a2..0cfc0eed8525 100644 +--- a/drivers/char/tpm/tpm_tis_core.c ++++ b/drivers/char/tpm/tpm_tis_core.c +@@ -264,7 +264,7 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len) + struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); + int rc, status, burstcnt; + size_t count = 0; +- bool itpm = priv->flags & TPM_TIS_ITPM_POSSIBLE; ++ bool itpm = priv->flags & TPM_TIS_ITPM_WORKAROUND; + + if (request_locality(chip, 0) < 0) + return -EBUSY; +@@ -740,7 +740,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, + (chip->flags & TPM_CHIP_FLAG_TPM2) ? "2.0" : "1.2", + vendor >> 16, rid); + +- if (!(priv->flags & TPM_TIS_ITPM_POSSIBLE)) { ++ if (!(priv->flags & TPM_TIS_ITPM_WORKAROUND)) { + probe = probe_itpm(chip); + if (probe < 0) { + rc = -ENODEV; +@@ -748,7 +748,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, + } + + if (!!probe) +- priv->flags |= TPM_TIS_ITPM_POSSIBLE; ++ priv->flags |= TPM_TIS_ITPM_WORKAROUND; + } + + /* Figure out the capabilities */ +diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h +index 9191aabbf9c2..e2212f021a02 100644 +--- a/drivers/char/tpm/tpm_tis_core.h ++++ b/drivers/char/tpm/tpm_tis_core.h +@@ -80,7 +80,7 @@ enum tis_defaults { + #define TPM_RID(l) (0x0F04 | ((l) << 12)) + + enum tpm_tis_flags { +- TPM_TIS_ITPM_POSSIBLE = BIT(0), ++ TPM_TIS_ITPM_WORKAROUND = BIT(0), + }; + + struct tpm_tis_data { +-- +2.12.0 + diff --git a/queue/tracing-Allocate-the-snapshot-buffer-before-enabling.patch b/queue/tracing-Allocate-the-snapshot-buffer-before-enabling.patch new file mode 100644 index 0000000..8f68197 --- /dev/null +++ b/queue/tracing-Allocate-the-snapshot-buffer-before-enabling.patch @@ -0,0 +1,44 @@ +From df62db5be2e5f070ecd1a5ece5945b590ee112e0 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" <rostedt@goodmis.org> +Date: Wed, 19 Apr 2017 12:07:08 -0400 +Subject: [PATCH] tracing: Allocate the snapshot buffer before enabling probe + +commit df62db5be2e5f070ecd1a5ece5945b590ee112e0 upstream. + +Currently the snapshot trigger enables the probe and then allocates the +snapshot. If the probe triggers before the allocation, it could cause the +snapshot to fail and turn tracing off. It's best to allocate the snapshot +buffer first, and then enable the trigger. If something goes wrong in the +enabling of the trigger, the snapshot buffer is still allocated, but it can +also be freed by the user by writting zero into the snapshot buffer file. + +Also add a check of the return status of alloc_snapshot(). + +Cc: stable@vger.kernel.org +Fixes: 77fd5c15e3 ("tracing: Add snapshot trigger to function probes") +Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> + +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index d484452ae648..0ad75e9698f6 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -6733,11 +6733,13 @@ ftrace_trace_snapshot_callback(struct ftrace_hash *hash, + return ret; + + out_reg: +- ret = register_ftrace_function_probe(glob, ops, count); ++ ret = alloc_snapshot(&global_trace); ++ if (ret < 0) ++ goto out; + +- if (ret >= 0) +- alloc_snapshot(&global_trace); ++ ret = register_ftrace_function_probe(glob, ops, count); + ++ out: + return ret < 0 ? ret : 0; + } + +-- +2.12.0 + diff --git a/queue/tty-pty-Fix-ldisc-flush-after-userspace-become-aware.patch b/queue/tty-pty-Fix-ldisc-flush-after-userspace-become-aware.patch new file mode 100644 index 0000000..373811b --- /dev/null +++ b/queue/tty-pty-Fix-ldisc-flush-after-userspace-become-aware.patch @@ -0,0 +1,84 @@ +From 77dae6134440420bac334581a3ccee94cee1c054 Mon Sep 17 00:00:00 2001 +From: Wang YanQing <udknight@gmail.com> +Date: Wed, 22 Feb 2017 19:37:08 +0800 +Subject: [PATCH] tty: pty: Fix ldisc flush after userspace become aware of the + data already + +commit 77dae6134440420bac334581a3ccee94cee1c054 upstream. + +While using emacs, cat or others' commands in konsole with recent +kernels, I have met many times that CTRL-C freeze konsole. After +konsole freeze I can't type anything, then I have to open a new one, +it is very annoying. + +See bug report: +https://bugs.kde.org/show_bug.cgi?id=175283 + +The platform in that bug report is Solaris, but now the pty in linux +has the same problem or the same behavior as Solaris :) + +It has high possibility to trigger the problem follow steps below: +Note: In my test, BigFile is a text file whose size is bigger than 1G +1:open konsole +1:cat BigFile +2:CTRL-C + +After some digging, I find out the reason is that commit 1d1d14da12e7 +("pty: Fix buffer flush deadlock") changes the behavior of pty_flush_buffer. + +Thread A Thread B +-------- -------- +1:n_tty_poll return POLLIN + 2:CTRL-C trigger pty_flush_buffer + tty_buffer_flush + n_tty_flush_buffer +3:attempt to check count of chars: + ioctl(fd, TIOCINQ, &available) + available is equal to 0 + +4:read(fd, buffer, avaiable) + return 0 + +5:konsole close fd + +Yes, I know we could use the same patch included in the BUG report as +a workaround for linux platform too. But I think the data in ldisc is +belong to application of another side, we shouldn't clear it when we +want to flush write buffer of this side in pty_flush_buffer. So I think +it is better to disable ldisc flush in pty_flush_buffer, because its new +hehavior bring no benefit except that it mess up the behavior between +POLLIN, and TIOCINQ or FIONREAD. + +Also I find no flush_buffer function in others' tty driver has the +same behavior as current pty_flush_buffer. + +Fixes: 1d1d14da12e7 ("pty: Fix buffer flush deadlock") +CC: stable@vger.kernel.org # v4.0+ +Signed-off-by: Wang YanQing <udknight@gmail.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c +index 66b59a15780d..65799575c666 100644 +--- a/drivers/tty/pty.c ++++ b/drivers/tty/pty.c +@@ -216,16 +216,11 @@ static int pty_signal(struct tty_struct *tty, int sig) + static void pty_flush_buffer(struct tty_struct *tty) + { + struct tty_struct *to = tty->link; +- struct tty_ldisc *ld; + + if (!to) + return; + +- ld = tty_ldisc_ref(to); +- tty_buffer_flush(to, ld); +- if (ld) +- tty_ldisc_deref(ld); +- ++ tty_buffer_flush(to, NULL); + if (to->packet) { + spin_lock_irq(&tty->ctrl_lock); + tty->ctrl_status |= TIOCPKT_FLUSHWRITE; +-- +2.12.0 + diff --git a/queue/ubi-upd-Always-flush-after-prepared-for-an-update.patch b/queue/ubi-upd-Always-flush-after-prepared-for-an-update.patch new file mode 100644 index 0000000..c1cc6be --- /dev/null +++ b/queue/ubi-upd-Always-flush-after-prepared-for-an-update.patch @@ -0,0 +1,63 @@ +From 9cd9a21ce070be8a918ffd3381468315a7a76ba6 Mon Sep 17 00:00:00 2001 +From: Sebastian Siewior <bigeasy@linutronix.de> +Date: Wed, 22 Feb 2017 17:15:21 +0100 +Subject: [PATCH] ubi/upd: Always flush after prepared for an update + +commit 9cd9a21ce070be8a918ffd3381468315a7a76ba6 upstream. + +In commit 6afaf8a484cb ("UBI: flush wl before clearing update marker") I +managed to trigger and fix a similar bug. Now here is another version of +which I assumed it wouldn't matter back then but it turns out UBI has a +check for it and will error out like this: + +|ubi0 warning: validate_vid_hdr: inconsistent used_ebs +|ubi0 error: validate_vid_hdr: inconsistent VID header at PEB 592 + +All you need to trigger this is? "ubiupdatevol /dev/ubi0_0 file" + a +powercut in the middle of the operation. +ubi_start_update() sets the update-marker and puts all EBs on the erase +list. After that userland can proceed to write new data while the old EB +aren't erased completely. A powercut at this point is usually not that +much of a tragedy. UBI won't give read access to the static volume +because it has the update marker. It will most likely set the corrupted +flag because it misses some EBs. +So we are all good. Unless the size of the image that has been written +differs from the old image in the magnitude of at least one EB. In that +case UBI will find two different values for `used_ebs' and refuse to +attach the image with the error message mentioned above. + +So in order not to get in the situation, the patch will ensure that we +wait until everything is removed before it tries to write any data. +The alternative would be to detect such a case and remove all EBs at the +attached time after we processed the volume-table and see the +update-marker set. The patch looks bigger and I doubt it is worth it +since usually the write() will wait from time to time for a new EB since +usually there not that many spare EB that can be used. + +Cc: stable@vger.kernel.org +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Signed-off-by: Richard Weinberger <richard@nod.at> + +diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c +index 0134ba32a057..39712560b4c1 100644 +--- a/drivers/mtd/ubi/upd.c ++++ b/drivers/mtd/ubi/upd.c +@@ -148,11 +148,11 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, + return err; + } + +- if (bytes == 0) { +- err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL); +- if (err) +- return err; ++ err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL); ++ if (err) ++ return err; + ++ if (bytes == 0) { + err = clear_update_marker(ubi, vol, 0); + if (err) + return err; +-- +2.12.0 + diff --git a/queue/ubifs-Fix-O_TMPFILE-corner-case-in-ubifs_link.patch b/queue/ubifs-Fix-O_TMPFILE-corner-case-in-ubifs_link.patch new file mode 100644 index 0000000..8e7c338 --- /dev/null +++ b/queue/ubifs-Fix-O_TMPFILE-corner-case-in-ubifs_link.patch @@ -0,0 +1,52 @@ +From 32fe905c17f001c0eee13c59afddd0bf2eed509c Mon Sep 17 00:00:00 2001 +From: Richard Weinberger <richard@nod.at> +Date: Thu, 30 Mar 2017 10:50:49 +0200 +Subject: [PATCH] ubifs: Fix O_TMPFILE corner case in ubifs_link() + +commit 32fe905c17f001c0eee13c59afddd0bf2eed509c upstream. + +It is perfectly fine to link a tmpfile back using linkat(). +Since tmpfiles are created with a link count of 0 they appear +on the orphan list, upon re-linking the inode has to be removed +from the orphan list again. + +Ralph faced a filesystem corruption in combination with overlayfs +due to this bug. + +Cc: <stable@vger.kernel.org> +Cc: Ralph Sennhauser <ralph.sennhauser@gmail.com> +Cc: Amir Goldstein <amir73il@gmail.com> +Reported-by: Ralph Sennhauser <ralph.sennhauser@gmail.com> +Tested-by: Ralph Sennhauser <ralph.sennhauser@gmail.com> +Reported-by: Amir Goldstein <amir73il@gmail.com> +Fixes: 474b93704f321 ("ubifs: Implement O_TMPFILE") +Signed-off-by: Richard Weinberger <richard@nod.at> + +diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c +index 0858213a4e63..b777bddaa1dd 100644 +--- a/fs/ubifs/dir.c ++++ b/fs/ubifs/dir.c +@@ -748,6 +748,11 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir, + goto out_fname; + + lock_2_inodes(dir, inode); ++ ++ /* Handle O_TMPFILE corner case, it is allowed to link a O_TMPFILE. */ ++ if (inode->i_nlink == 0) ++ ubifs_delete_orphan(c, inode->i_ino); ++ + inc_nlink(inode); + ihold(inode); + inode->i_ctime = ubifs_current_time(inode); +@@ -768,6 +773,8 @@ out_cancel: + dir->i_size -= sz_change; + dir_ui->ui_size = dir->i_size; + drop_nlink(inode); ++ if (inode->i_nlink == 0) ++ ubifs_add_orphan(c, inode->i_ino); + unlock_2_inodes(dir, inode); + ubifs_release_budget(c, &req); + iput(inode); +-- +2.12.0 + diff --git a/queue/ubifs-Fix-RENAME_WHITEOUT-support.patch b/queue/ubifs-Fix-RENAME_WHITEOUT-support.patch new file mode 100644 index 0000000..1d409c9 --- /dev/null +++ b/queue/ubifs-Fix-RENAME_WHITEOUT-support.patch @@ -0,0 +1,35 @@ +From c3d9fda688742c06e89aa1f0f8fd943fc11468cb Mon Sep 17 00:00:00 2001 +From: Felix Fietkau <nbd@nbd.name> +Date: Mon, 6 Mar 2017 10:04:25 +0100 +Subject: [PATCH] ubifs: Fix RENAME_WHITEOUT support + +commit c3d9fda688742c06e89aa1f0f8fd943fc11468cb upstream. + +Remove faulty leftover check in do_rename(), apparently introduced in a +merge that combined whiteout support changes with commit f03b8ad8d386 +("fs: support RENAME_NOREPLACE for local filesystems") + +Fixes: f03b8ad8d386 ("fs: support RENAME_NOREPLACE for local +filesystems") +Fixes: 9e0a1fff8db5 ("ubifs: Implement RENAME_WHITEOUT") +Cc: stable@vger.kernel.org +Signed-off-by: Felix Fietkau <nbd@nbd.name> +Signed-off-by: Richard Weinberger <richard@nod.at> + +diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c +index 87b04dc3a86e..0858213a4e63 100644 +--- a/fs/ubifs/dir.c ++++ b/fs/ubifs/dir.c +@@ -1318,9 +1318,6 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry, + unsigned int uninitialized_var(saved_nlink); + struct fscrypt_name old_nm, new_nm; + +- if (flags & ~RENAME_NOREPLACE) +- return -EINVAL; +- + /* + * Budget request settings: deletion direntry, new direntry, removing + * the old inode, and changing old and new parent directory inodes. +-- +2.12.0 + diff --git a/queue/um-Fix-PTRACE_POKEUSER-on-x86_64.patch b/queue/um-Fix-PTRACE_POKEUSER-on-x86_64.patch new file mode 100644 index 0000000..625552e --- /dev/null +++ b/queue/um-Fix-PTRACE_POKEUSER-on-x86_64.patch @@ -0,0 +1,35 @@ +From 9abc74a22d85ab29cef9896a2582a530da7e79bf Mon Sep 17 00:00:00 2001 +From: Richard Weinberger <richard@nod.at> +Date: Sat, 1 Apr 2017 00:41:57 +0200 +Subject: [PATCH] um: Fix PTRACE_POKEUSER on x86_64 + +commit 9abc74a22d85ab29cef9896a2582a530da7e79bf upstream. + +This is broken since ever but sadly nobody noticed. +Recent versions of GDB set DR_CONTROL unconditionally and +UML dies due to a heap corruption. It turns out that +the PTRACE_POKEUSER was copy&pasted from i386 and assumes +that addresses are 4 bytes long. + +Fix that by using 8 as address size in the calculation. + +Cc: <stable@vger.kernel.org> +Reported-by: jie cao <cj3054@gmail.com> +Signed-off-by: Richard Weinberger <richard@nod.at> + +diff --git a/arch/x86/um/ptrace_64.c b/arch/x86/um/ptrace_64.c +index a5c9910d234f..09a085bde0d4 100644 +--- a/arch/x86/um/ptrace_64.c ++++ b/arch/x86/um/ptrace_64.c +@@ -125,7 +125,7 @@ int poke_user(struct task_struct *child, long addr, long data) + else if ((addr >= offsetof(struct user, u_debugreg[0])) && + (addr <= offsetof(struct user, u_debugreg[7]))) { + addr -= offsetof(struct user, u_debugreg[0]); +- addr = addr >> 2; ++ addr = addr >> 3; + if ((addr == 4) || (addr == 5)) + return -EIO; + child->thread.arch.debugregs[addr] = data; +-- +2.12.0 + diff --git a/queue/usb-Make-sure-usb-phy-of-gets-built-in.patch b/queue/usb-Make-sure-usb-phy-of-gets-built-in.patch new file mode 100644 index 0000000..49d092d --- /dev/null +++ b/queue/usb-Make-sure-usb-phy-of-gets-built-in.patch @@ -0,0 +1,53 @@ +From 3d6159640da9c9175d1ca42f151fc1a14caded59 Mon Sep 17 00:00:00 2001 +From: Alexey Brodkin <Alexey.Brodkin@synopsys.com> +Date: Thu, 13 Apr 2017 15:33:34 +0300 +Subject: [PATCH] usb: Make sure usb/phy/of gets built-in + +commit 3d6159640da9c9175d1ca42f151fc1a14caded59 upstream. + +DWC3 driver uses of_usb_get_phy_mode() which is +implemented in drivers/usb/phy/of.c and in bare minimal +configuration it might not be pulled in kernel binary. + +In case of ARC or ARM this could be easily reproduced with +"allnodefconfig" +CONFIG_USB=m +CONFIG_USB_DWC3=m. + +On building all ends-up with: +---------------------->8------------------ + Kernel: arch/arm/boot/Image is ready + Kernel: arch/arm/boot/zImage is ready + Building modules, stage 2. + MODPOST 5 modules +ERROR: "of_usb_get_phy_mode" [drivers/usb/dwc3/dwc3.ko] undefined! +make[1]: *** [__modpost] Error 1 +make: *** [modules] Error 2 +---------------------->8------------------ + +Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com> +Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Cc: Masahiro Yamada <yamada.masahiro@socionext.com> +Cc: Geert Uytterhoeven <geert+renesas@glider.be> +Cc: Nicolas Pitre <nicolas.pitre@linaro.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: Felipe Balbi <balbi@kernel.org> +Cc: Felix Fietkau <nbd@nbd.name> +Cc: Jeremy Kerr <jk@ozlabs.org> +Cc: linux-snps-arc@lists.infradead.org +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/Makefile b/drivers/Makefile +index 2eced9afba53..8f8bdc9e3d29 100644 +--- a/drivers/Makefile ++++ b/drivers/Makefile +@@ -104,6 +104,7 @@ obj-$(CONFIG_USB_PHY) += usb/ + obj-$(CONFIG_USB) += usb/ + obj-$(CONFIG_PCI) += usb/ + obj-$(CONFIG_USB_GADGET) += usb/ ++obj-$(CONFIG_OF) += usb/ + obj-$(CONFIG_SERIO) += input/serio/ + obj-$(CONFIG_GAMEPORT) += input/gameport/ + obj-$(CONFIG_INPUT) += input/ +-- +2.12.0 + diff --git a/queue/usb-chipidea-Handle-extcon-events-properly.patch b/queue/usb-chipidea-Handle-extcon-events-properly.patch new file mode 100644 index 0000000..11b36de --- /dev/null +++ b/queue/usb-chipidea-Handle-extcon-events-properly.patch @@ -0,0 +1,127 @@ +From a89b94b53371bbfa582787c2fa3378000ea4263d Mon Sep 17 00:00:00 2001 +From: Stephen Boyd <stephen.boyd@linaro.org> +Date: Wed, 28 Dec 2016 14:56:51 -0800 +Subject: [PATCH] usb: chipidea: Handle extcon events properly + +commit a89b94b53371bbfa582787c2fa3378000ea4263d upstream. + +We're currently emulating the vbus and id interrupts in the OTGSC +read API, but we also need to make sure that if we're handling +the events with extcon that we don't enable the interrupts for +those events in the hardware. Therefore, properly emulate this +register if we're using extcon, but don't enable the interrupts. +This allows me to get my cable connect/disconnect working +properly without getting spurious interrupts on my device that +uses an extcon for these two events. + +Acked-by: Peter Chen <peter.chen@nxp.com> +Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Cc: "Ivan T. Ivanov" <iivanov.xz@gmail.com> +Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID detect") +Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org> +Signed-off-by: Peter Chen <peter.chen@nxp.com> + +diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c +index a829607c3e4d..0cf149edddd8 100644 +--- a/drivers/usb/chipidea/otg.c ++++ b/drivers/usb/chipidea/otg.c +@@ -44,12 +44,15 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask) + else + val &= ~OTGSC_BSVIS; + +- cable->changed = false; +- + if (cable->state) + val |= OTGSC_BSV; + else + val &= ~OTGSC_BSV; ++ ++ if (cable->enabled) ++ val |= OTGSC_BSVIE; ++ else ++ val &= ~OTGSC_BSVIE; + } + + cable = &ci->platdata->id_extcon; +@@ -59,15 +62,18 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask) + else + val &= ~OTGSC_IDIS; + +- cable->changed = false; +- + if (cable->state) + val |= OTGSC_ID; + else + val &= ~OTGSC_ID; ++ ++ if (cable->enabled) ++ val |= OTGSC_IDIE; ++ else ++ val &= ~OTGSC_IDIE; + } + +- return val; ++ return val & mask; + } + + /** +@@ -77,6 +83,36 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask) + */ + void hw_write_otgsc(struct ci_hdrc *ci, u32 mask, u32 data) + { ++ struct ci_hdrc_cable *cable; ++ ++ cable = &ci->platdata->vbus_extcon; ++ if (!IS_ERR(cable->edev)) { ++ if (data & mask & OTGSC_BSVIS) ++ cable->changed = false; ++ ++ /* Don't enable vbus interrupt if using external notifier */ ++ if (data & mask & OTGSC_BSVIE) { ++ cable->enabled = true; ++ data &= ~OTGSC_BSVIE; ++ } else if (mask & OTGSC_BSVIE) { ++ cable->enabled = false; ++ } ++ } ++ ++ cable = &ci->platdata->id_extcon; ++ if (!IS_ERR(cable->edev)) { ++ if (data & mask & OTGSC_IDIS) ++ cable->changed = false; ++ ++ /* Don't enable id interrupt if using external notifier */ ++ if (data & mask & OTGSC_IDIE) { ++ cable->enabled = true; ++ data &= ~OTGSC_IDIE; ++ } else if (mask & OTGSC_IDIE) { ++ cable->enabled = false; ++ } ++ } ++ + hw_write(ci, OP_OTGSC, mask | OTGSC_INT_STATUS_BITS, data); + } + +diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h +index 5dd75fa47dd8..f9be467d6695 100644 +--- a/include/linux/usb/chipidea.h ++++ b/include/linux/usb/chipidea.h +@@ -14,6 +14,7 @@ struct ci_hdrc; + * struct ci_hdrc_cable - structure for external connector cable state tracking + * @state: current state of the line + * @changed: set to true when extcon event happen ++ * @enabled: set to true if we've enabled the vbus or id interrupt + * @edev: device which generate events + * @ci: driver state of the chipidea device + * @nb: hold event notification callback +@@ -22,6 +23,7 @@ struct ci_hdrc; + struct ci_hdrc_cable { + bool state; + bool changed; ++ bool enabled; + struct extcon_dev *edev; + struct ci_hdrc *ci; + struct notifier_block nb; +-- +2.12.0 + diff --git a/queue/usb-chipidea-Only-read-write-OTGSC-from-one-place.patch b/queue/usb-chipidea-Only-read-write-OTGSC-from-one-place.patch new file mode 100644 index 0000000..a1551f3 --- /dev/null +++ b/queue/usb-chipidea-Only-read-write-OTGSC-from-one-place.patch @@ -0,0 +1,134 @@ +From f60f8ccd54e03c1afafb2b20ceb029a0eaf7a134 Mon Sep 17 00:00:00 2001 +From: Stephen Boyd <stephen.boyd@linaro.org> +Date: Wed, 28 Dec 2016 14:56:50 -0800 +Subject: [PATCH] usb: chipidea: Only read/write OTGSC from one place + +commit f60f8ccd54e03c1afafb2b20ceb029a0eaf7a134 upstream. + +With the id and vbus detection done via extcon we need to make +sure we poll the status of OTGSC properly by considering what the +extcon is saying, and not just what the register is saying. Let's +move this hw_wait_reg() function to the only place it's used and +simplify it for polling the OTGSC register. Then we can make +certain we only use the hw_read_otgsc() API to read OTGSC, which +will make sure we properly handle extcon events. + +Acked-by: Peter Chen <peter.chen@nxp.com> +Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Cc: "Ivan T. Ivanov" <iivanov.xz@gmail.com> +Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID detect") +Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org> +Signed-off-by: Peter Chen <peter.chen@nxp.com> + +diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h +index cd414559040f..05bc4d631cb9 100644 +--- a/drivers/usb/chipidea/ci.h ++++ b/drivers/usb/chipidea/ci.h +@@ -428,9 +428,6 @@ int hw_port_test_set(struct ci_hdrc *ci, u8 mode); + + u8 hw_port_test_get(struct ci_hdrc *ci); + +-int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask, +- u32 value, unsigned int timeout_ms); +- + void ci_platform_configure(struct ci_hdrc *ci); + + int dbg_create_files(struct ci_hdrc *ci); +diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c +index 5c35f25e9bce..24859b44c45c 100644 +--- a/drivers/usb/chipidea/core.c ++++ b/drivers/usb/chipidea/core.c +@@ -516,38 +516,6 @@ int hw_device_reset(struct ci_hdrc *ci) + return 0; + } + +-/** +- * hw_wait_reg: wait the register value +- * +- * Sometimes, it needs to wait register value before going on. +- * Eg, when switch to device mode, the vbus value should be lower +- * than OTGSC_BSV before connects to host. +- * +- * @ci: the controller +- * @reg: register index +- * @mask: mast bit +- * @value: the bit value to wait +- * @timeout_ms: timeout in millisecond +- * +- * This function returns an error code if timeout +- */ +-int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask, +- u32 value, unsigned int timeout_ms) +-{ +- unsigned long elapse = jiffies + msecs_to_jiffies(timeout_ms); +- +- while (hw_read(ci, reg, mask) != value) { +- if (time_after(jiffies, elapse)) { +- dev_err(ci->dev, "timeout waiting for %08x in %d\n", +- mask, reg); +- return -ETIMEDOUT; +- } +- msleep(20); +- } +- +- return 0; +-} +- + static irqreturn_t ci_irq(int irq, void *data) + { + struct ci_hdrc *ci = data; +diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c +index 03b6743461d1..a829607c3e4d 100644 +--- a/drivers/usb/chipidea/otg.c ++++ b/drivers/usb/chipidea/otg.c +@@ -104,7 +104,31 @@ void ci_handle_vbus_change(struct ci_hdrc *ci) + usb_gadget_vbus_disconnect(&ci->gadget); + } + +-#define CI_VBUS_STABLE_TIMEOUT_MS 5000 ++/** ++ * When we switch to device mode, the vbus value should be lower ++ * than OTGSC_BSV before connecting to host. ++ * ++ * @ci: the controller ++ * ++ * This function returns an error code if timeout ++ */ ++static int hw_wait_vbus_lower_bsv(struct ci_hdrc *ci) ++{ ++ unsigned long elapse = jiffies + msecs_to_jiffies(5000); ++ u32 mask = OTGSC_BSV; ++ ++ while (hw_read_otgsc(ci, mask)) { ++ if (time_after(jiffies, elapse)) { ++ dev_err(ci->dev, "timeout waiting for %08x in OTGSC\n", ++ mask); ++ return -ETIMEDOUT; ++ } ++ msleep(20); ++ } ++ ++ return 0; ++} ++ + static void ci_handle_id_switch(struct ci_hdrc *ci) + { + enum ci_role role = ci_otg_role(ci); +@@ -116,9 +140,11 @@ static void ci_handle_id_switch(struct ci_hdrc *ci) + ci_role_stop(ci); + + if (role == CI_ROLE_GADGET) +- /* wait vbus lower than OTGSC_BSV */ +- hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0, +- CI_VBUS_STABLE_TIMEOUT_MS); ++ /* ++ * wait vbus lower than OTGSC_BSV before connecting ++ * to host ++ */ ++ hw_wait_vbus_lower_bsv(ci); + + ci_role_start(ci, role); + } +-- +2.12.0 + diff --git a/queue/usb-dwc2-host-use-msleep-for-long-delay.patch b/queue/usb-dwc2-host-use-msleep-for-long-delay.patch new file mode 100644 index 0000000..a93a1b2 --- /dev/null +++ b/queue/usb-dwc2-host-use-msleep-for-long-delay.patch @@ -0,0 +1,33 @@ +From d3fe81d2ccc41b355e494413115c0c7c18426fa1 Mon Sep 17 00:00:00 2001 +From: Nicholas Mc Guire <hofrat@osadl.org> +Date: Mon, 23 Jan 2017 15:00:40 -0800 +Subject: [PATCH] usb: dwc2: host: use msleep() for long delay + +commit d3fe81d2ccc41b355e494413115c0c7c18426fa1 upstream. + +ulseep_range() uses hrtimers and provides no advantage over msleep() +for larger delays. Fix up the 100ms delays here passing the adjusted "min" +value to msleep(). This helps reduce the load on the hrtimer subsystem. + +Link: http://lkml.org/lkml/2017/1/11/377 +Fixes: commit 2938fc63e0c2 ("usb: dwc2: Properly account for the force mode delays") +Signed-off-by: Nicholas Mc Guire <hofrat@osadl.org> +Signed-off-by: John Youn <johnyoun@synopsys.com> +Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com> + +diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c +index 7195366e26bf..1b6612c2cdda 100644 +--- a/drivers/usb/dwc2/core.c ++++ b/drivers/usb/dwc2/core.c +@@ -455,7 +455,7 @@ void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg) + dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); + + if (dwc2_iddig_filter_enabled(hsotg)) +- usleep_range(100000, 110000); ++ msleep(100); + } + + /* +-- +2.12.0 + diff --git a/queue/usb-gadget-legacy-gadgets-are-optional.patch b/queue/usb-gadget-legacy-gadgets-are-optional.patch new file mode 100644 index 0000000..34078f2 --- /dev/null +++ b/queue/usb-gadget-legacy-gadgets-are-optional.patch @@ -0,0 +1,38 @@ +From 6e253d0fbc665b36192b8ed3cecdbb65b413a1eb Mon Sep 17 00:00:00 2001 +From: Romain Izard <romain.izard.pro@gmail.com> +Date: Fri, 10 Mar 2017 14:11:41 +0100 +Subject: [PATCH] usb: gadget: legacy gadgets are optional + +commit 6e253d0fbc665b36192b8ed3cecdbb65b413a1eb upstream. + +With commit bc49d1d17dcf ("usb: gadget: don't couple configfs to legacy +gadgets"),it is possible to build a modular kernel with both built-in +configfs support and modular legacy gadget drivers. + +But when building a kernel without modules, it is also necessary to be +able to build with configfs but without any legacy gadget driver. This +was a possible configuration when the USB_CONFIGFS was a part of the +choice options, but not anymore. + +Mark the choice for legacy gadget drivers as optional restores this. + +Fixes: bc49d1d17dcf ("usb: gadget: don't couple configfs to legacy gadgets") +Cc: <stable@vger.kernel.org> # 4.9+ +Signed-off-by: Romain Izard <romain.izard.pro@gmail.com> +Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com> + +diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig +index 8ad203296079..f3ee80ece682 100644 +--- a/drivers/usb/gadget/Kconfig ++++ b/drivers/usb/gadget/Kconfig +@@ -460,6 +460,7 @@ config USB_CONFIGFS_F_TCM + choice + tristate "USB Gadget Drivers" + default USB_ETH ++ optional + help + A Linux "Gadget Driver" talks to the USB Peripheral Controller + driver through the abstract "gadget" API. Some other operating +-- +2.12.0 + diff --git a/queue/usb-host-ehci-exynos-Decrese-node-refcount-on-exynos.patch b/queue/usb-host-ehci-exynos-Decrese-node-refcount-on-exynos.patch new file mode 100644 index 0000000..61189cf --- /dev/null +++ b/queue/usb-host-ehci-exynos-Decrese-node-refcount-on-exynos.patch @@ -0,0 +1,38 @@ +From 3f6026b1dcb3c8ee71198c485a72ac674c6890dd Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski <krzk@kernel.org> +Date: Sat, 7 Jan 2017 10:41:40 +0200 +Subject: [PATCH] usb: host: ehci-exynos: Decrese node refcount on + exynos_ehci_get_phy() error paths + +commit 3f6026b1dcb3c8ee71198c485a72ac674c6890dd upstream. + +Returning from for_each_available_child_of_node() loop requires cleaning +up node refcount. Error paths lacked it so for example in case of +deferred probe, the refcount of phy node was left increased. + +Fixes: 6d40500ac9b6 ("usb: ehci/ohci-exynos: Fix of_node_put() for child when getting PHYs") +Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c +index 42e5b66353ef..7a603f66a9bc 100644 +--- a/drivers/usb/host/ehci-exynos.c ++++ b/drivers/usb/host/ehci-exynos.c +@@ -77,10 +77,12 @@ static int exynos_ehci_get_phy(struct device *dev, + if (IS_ERR(phy)) { + ret = PTR_ERR(phy); + if (ret == -EPROBE_DEFER) { ++ of_node_put(child); + return ret; + } else if (ret != -ENOSYS && ret != -ENODEV) { + dev_err(dev, + "Error retrieving usb2 phy: %d\n", ret); ++ of_node_put(child); + return ret; + } + } +-- +2.12.0 + diff --git a/queue/usb-host-ohci-exynos-Decrese-node-refcount-on-exynos.patch b/queue/usb-host-ohci-exynos-Decrese-node-refcount-on-exynos.patch new file mode 100644 index 0000000..6d2f842 --- /dev/null +++ b/queue/usb-host-ohci-exynos-Decrese-node-refcount-on-exynos.patch @@ -0,0 +1,38 @@ +From 68bd6fc3cfa98ef253e17307ccafd8ef907b5556 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski <krzk@kernel.org> +Date: Sat, 7 Jan 2017 10:41:41 +0200 +Subject: [PATCH] usb: host: ohci-exynos: Decrese node refcount on + exynos_ehci_get_phy() error paths + +commit 68bd6fc3cfa98ef253e17307ccafd8ef907b5556 upstream. + +Returning from for_each_available_child_of_node() loop requires cleaning +up node refcount. Error paths lacked it so for example in case of +deferred probe, the refcount of phy node was left increased. + +Fixes: 6d40500ac9b6 ("usb: ehci/ohci-exynos: Fix of_node_put() for child when getting PHYs") +Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c +index 2cd105be7319..6865b919403f 100644 +--- a/drivers/usb/host/ohci-exynos.c ++++ b/drivers/usb/host/ohci-exynos.c +@@ -66,10 +66,12 @@ static int exynos_ohci_get_phy(struct device *dev, + if (IS_ERR(phy)) { + ret = PTR_ERR(phy); + if (ret == -EPROBE_DEFER) { ++ of_node_put(child); + return ret; + } else if (ret != -ENOSYS && ret != -ENODEV) { + dev_err(dev, + "Error retrieving usb2 phy: %d\n", ret); ++ of_node_put(child); + return ret; + } + } +-- +2.12.0 + diff --git a/queue/usb-host-xhci-print-correct-command-ring-address.patch b/queue/usb-host-xhci-print-correct-command-ring-address.patch new file mode 100644 index 0000000..94a76d5 --- /dev/null +++ b/queue/usb-host-xhci-print-correct-command-ring-address.patch @@ -0,0 +1,30 @@ +From 6fc091fb0459ade939a795bfdcaf645385b951d4 Mon Sep 17 00:00:00 2001 +From: Peter Chen <peter.chen@nxp.com> +Date: Wed, 19 Apr 2017 16:55:52 +0300 +Subject: [PATCH] usb: host: xhci: print correct command ring address + +commit 6fc091fb0459ade939a795bfdcaf645385b951d4 upstream. + +Print correct command ring address using 'val_64'. + +Cc: stable <stable@vger.kernel.org> +Signed-off-by: Peter Chen <peter.chen@nxp.com> +Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c +index f80bd0331935..bbe22bcc550a 100644 +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -2482,7 +2482,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) + (xhci->cmd_ring->first_seg->dma & (u64) ~CMD_RING_RSVD_BITS) | + xhci->cmd_ring->cycle_state; + xhci_dbg_trace(xhci, trace_xhci_dbg_init, +- "// Setting command ring address to 0x%x", val); ++ "// Setting command ring address to 0x%016llx", val_64); + xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring); + xhci_dbg_cmd_ptrs(xhci); + +-- +2.12.0 + diff --git a/queue/usb-hub-Do-not-attempt-to-autosuspend-disconnected-d.patch b/queue/usb-hub-Do-not-attempt-to-autosuspend-disconnected-d.patch new file mode 100644 index 0000000..f21f33e --- /dev/null +++ b/queue/usb-hub-Do-not-attempt-to-autosuspend-disconnected-d.patch @@ -0,0 +1,104 @@ +From f5cccf49428447dfbc9edb7a04bb8fc316269781 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck <linux@roeck-us.net> +Date: Mon, 20 Mar 2017 14:30:50 -0700 +Subject: [PATCH] usb: hub: Do not attempt to autosuspend disconnected devices + +commit f5cccf49428447dfbc9edb7a04bb8fc316269781 upstream. + +While running a bind/unbind stress test with the dwc3 usb driver on rk3399, +the following crash was observed. + +Unable to handle kernel NULL pointer dereference at virtual address 00000218 +pgd = ffffffc00165f000 +[00000218] *pgd=000000000174f003, *pud=000000000174f003, + *pmd=0000000001750003, *pte=00e8000001751713 +Internal error: Oops: 96000005 [#1] PREEMPT SMP +Modules linked in: uinput uvcvideo videobuf2_vmalloc cmac +ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat rfcomm +xt_mark fuse bridge stp llc zram btusb btrtl btbcm btintel bluetooth +ip6table_filter mwifiex_pcie mwifiex cfg80211 cdc_ether usbnet r8152 mii joydev +snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq snd_seq_device ppp_async +ppp_generic slhc tun +CPU: 1 PID: 29814 Comm: kworker/1:1 Not tainted 4.4.52 #507 +Hardware name: Google Kevin (DT) +Workqueue: pm pm_runtime_work +task: ffffffc0ac540000 ti: ffffffc0af4d4000 task.ti: ffffffc0af4d4000 +PC is at autosuspend_check+0x74/0x174 +LR is at autosuspend_check+0x70/0x174 +... +Call trace: +[<ffffffc00080dcc0>] autosuspend_check+0x74/0x174 +[<ffffffc000810500>] usb_runtime_idle+0x20/0x40 +[<ffffffc000785ae0>] __rpm_callback+0x48/0x7c +[<ffffffc000786af0>] rpm_idle+0x1e8/0x498 +[<ffffffc000787cdc>] pm_runtime_work+0x88/0xcc +[<ffffffc000249bb8>] process_one_work+0x390/0x6b8 +[<ffffffc00024abcc>] worker_thread+0x480/0x610 +[<ffffffc000251a80>] kthread+0x164/0x178 +[<ffffffc0002045d0>] ret_from_fork+0x10/0x40 + +Source: + +(gdb) l *0xffffffc00080dcc0 +0xffffffc00080dcc0 is in autosuspend_check +(drivers/usb/core/driver.c:1778). +1773 /* We don't need to check interfaces that are +1774 * disabled for runtime PM. Either they are unbound +1775 * or else their drivers don't support autosuspend +1776 * and so they are permanently active. +1777 */ +1778 if (intf->dev.power.disable_depth) +1779 continue; +1780 if (atomic_read(&intf->dev.power.usage_count) > 0) +1781 return -EBUSY; +1782 w |= intf->needs_remote_wakeup; + +Code analysis shows that intf is set to NULL in usb_disable_device() prior +to setting actconfig to NULL. At the same time, usb_runtime_idle() does not +lock the usb device, and neither does any of the functions in the +traceback. This means that there is no protection against a race condition +where usb_disable_device() is removing dev->actconfig->interface[] pointers +while those are being accessed from autosuspend_check(). + +To solve the problem, synchronize and validate device state between +autosuspend_check() and usb_disconnect(). + +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Guenter Roeck <linux@roeck-us.net> +Cc: stable <stable@vger.kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c +index 7ebdf2a4e8fe..eb87a259d55c 100644 +--- a/drivers/usb/core/driver.c ++++ b/drivers/usb/core/driver.c +@@ -1781,6 +1781,9 @@ static int autosuspend_check(struct usb_device *udev) + int w, i; + struct usb_interface *intf; + ++ if (udev->state == USB_STATE_NOTATTACHED) ++ return -ENODEV; ++ + /* Fail if autosuspend is disabled, or any interfaces are in use, or + * any interface drivers require remote wakeup but it isn't available. + */ +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 735e8ab2cc1f..8f6593d7b68c 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -2087,6 +2087,12 @@ void usb_disconnect(struct usb_device **pdev) + dev_info(&udev->dev, "USB disconnect, device number %d\n", + udev->devnum); + ++ /* ++ * Ensure that the pm runtime code knows that the USB device ++ * is in the process of being disconnected. ++ */ ++ pm_runtime_barrier(&udev->dev); ++ + usb_lock_device(udev); + + hub_disconnect_children(udev); +-- +2.12.0 + diff --git a/queue/usb-hub-Fix-error-loop-seen-after-hub-communication-.patch b/queue/usb-hub-Fix-error-loop-seen-after-hub-communication-.patch new file mode 100644 index 0000000..57fe75a --- /dev/null +++ b/queue/usb-hub-Fix-error-loop-seen-after-hub-communication-.patch @@ -0,0 +1,138 @@ +From 245b2eecee2aac6fdc77dcafaa73c33f9644c3c7 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck <linux@roeck-us.net> +Date: Mon, 20 Mar 2017 11:16:11 -0700 +Subject: [PATCH] usb: hub: Fix error loop seen after hub communication errors + +commit 245b2eecee2aac6fdc77dcafaa73c33f9644c3c7 upstream. + +While stress testing a usb controller using a bind/unbind looop, the +following error loop was observed. + +usb 7-1.2: new low-speed USB device number 3 using xhci-hcd +usb 7-1.2: hub failed to enable device, error -108 +usb 7-1-port2: cannot disable (err = -22) +usb 7-1-port2: couldn't allocate usb_device +usb 7-1-port2: cannot disable (err = -22) +hub 7-1:1.0: hub_ext_port_status failed (err = -22) +hub 7-1:1.0: hub_ext_port_status failed (err = -22) +hub 7-1:1.0: activate --> -22 +hub 7-1:1.0: hub_ext_port_status failed (err = -22) +hub 7-1:1.0: hub_ext_port_status failed (err = -22) +hub 7-1:1.0: activate --> -22 +hub 7-1:1.0: hub_ext_port_status failed (err = -22) +hub 7-1:1.0: hub_ext_port_status failed (err = -22) +hub 7-1:1.0: activate --> -22 +hub 7-1:1.0: hub_ext_port_status failed (err = -22) +hub 7-1:1.0: hub_ext_port_status failed (err = -22) +hub 7-1:1.0: activate --> -22 +hub 7-1:1.0: hub_ext_port_status failed (err = -22) +hub 7-1:1.0: hub_ext_port_status failed (err = -22) +hub 7-1:1.0: activate --> -22 +hub 7-1:1.0: hub_ext_port_status failed (err = -22) +hub 7-1:1.0: hub_ext_port_status failed (err = -22) +hub 7-1:1.0: activate --> -22 +hub 7-1:1.0: hub_ext_port_status failed (err = -22) +hub 7-1:1.0: hub_ext_port_status failed (err = -22) +hub 7-1:1.0: activate --> -22 +hub 7-1:1.0: hub_ext_port_status failed (err = -22) +hub 7-1:1.0: hub_ext_port_status failed (err = -22) +hub 7-1:1.0: activate --> -22 +hub 7-1:1.0: hub_ext_port_status failed (err = -22) +hub 7-1:1.0: hub_ext_port_status failed (err = -22) +** 57 printk messages dropped ** hub 7-1:1.0: activate --> -22 +** 82 printk messages dropped ** hub 7-1:1.0: hub_ext_port_status failed (err = -22) + +This continues forever. After adding tracebacks into the code, +the call sequence leading to this is found to be as follows. + +[<ffffffc0007fc8e0>] hub_activate+0x368/0x7b8 +[<ffffffc0007fceb4>] hub_resume+0x2c/0x3c +[<ffffffc00080b3b8>] usb_resume_interface.isra.6+0x128/0x158 +[<ffffffc00080b5d0>] usb_suspend_both+0x1e8/0x288 +[<ffffffc00080c9c4>] usb_runtime_suspend+0x3c/0x98 +[<ffffffc0007820a0>] __rpm_callback+0x48/0x7c +[<ffffffc00078217c>] rpm_callback+0xa8/0xd4 +[<ffffffc000786234>] rpm_suspend+0x84/0x758 +[<ffffffc000786ca4>] rpm_idle+0x2c8/0x498 +[<ffffffc000786ed4>] __pm_runtime_idle+0x60/0xac +[<ffffffc00080eba8>] usb_autopm_put_interface+0x6c/0x7c +[<ffffffc000803798>] hub_event+0x10ac/0x12ac +[<ffffffc000249bb8>] process_one_work+0x390/0x6b8 +[<ffffffc00024abcc>] worker_thread+0x480/0x610 +[<ffffffc000251a80>] kthread+0x164/0x178 +[<ffffffc0002045d0>] ret_from_fork+0x10/0x40 + +kick_hub_wq() is called from hub_activate() even after failures to +communicate with the hub. This results in an endless sequence of +hub event -> hub activate -> wq trigger -> hub event -> ... + +Provide two solutions for the problem. + +- Only trigger the hub event queue if communication with the hub + is successful. +- After a suspend failure, only resume already suspended interfaces + if the communication with the device is still possible. + +Each of the changes fixes the observed problem. Use both to improve +robustness. + +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Guenter Roeck <linux@roeck-us.net> +Cc: stable <stable@vger.kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c +index cdee5130638b..7ebdf2a4e8fe 100644 +--- a/drivers/usb/core/driver.c ++++ b/drivers/usb/core/driver.c +@@ -1331,6 +1331,24 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) + */ + if (udev->parent && !PMSG_IS_AUTO(msg)) + status = 0; ++ ++ /* ++ * If the device is inaccessible, don't try to resume ++ * suspended interfaces and just return the error. ++ */ ++ if (status && status != -EBUSY) { ++ int err; ++ u16 devstat; ++ ++ err = usb_get_status(udev, USB_RECIP_DEVICE, 0, ++ &devstat); ++ if (err) { ++ dev_err(&udev->dev, ++ "Failed to suspend device, error %d\n", ++ status); ++ goto done; ++ } ++ } + } + + /* If the suspend failed, resume interfaces that did get suspended */ +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index f0dd08198d74..735e8ab2cc1f 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1066,6 +1066,9 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) + + portstatus = portchange = 0; + status = hub_port_status(hub, port1, &portstatus, &portchange); ++ if (status) ++ goto abort; ++ + if (udev || (portstatus & USB_PORT_STAT_CONNECTION)) + dev_dbg(&port_dev->dev, "status %04x change %04x\n", + portstatus, portchange); +@@ -1198,7 +1201,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) + + /* Scan all ports that need attention */ + kick_hub_wq(hub); +- ++ abort: + if (type == HUB_INIT2 || type == HUB_INIT3) { + /* Allow autosuspend if it was suppressed */ + disconnected: +-- +2.12.0 + diff --git a/queue/usb-misc-add-missing-continue-in-switch.patch b/queue/usb-misc-add-missing-continue-in-switch.patch new file mode 100644 index 0000000..242f374 --- /dev/null +++ b/queue/usb-misc-add-missing-continue-in-switch.patch @@ -0,0 +1,30 @@ +From 2c930e3d0aed1505e86e0928d323df5027817740 Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" <garsilva@embeddedor.com> +Date: Mon, 3 Apr 2017 22:48:40 -0500 +Subject: [PATCH] usb: misc: add missing continue in switch + +commit 2c930e3d0aed1505e86e0928d323df5027817740 upstream. + +Add missing continue in switch. + +Addresses-Coverity-ID: 1248733 +Signed-off-by: Gustavo A. R. Silva <garsilva@embeddedor.com> +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Cc: stable <stable@vger.kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c +index 17c081068257..26ae5d1a2a4e 100644 +--- a/drivers/usb/misc/usbtest.c ++++ b/drivers/usb/misc/usbtest.c +@@ -159,6 +159,7 @@ get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf) + case USB_ENDPOINT_XFER_INT: + if (dev->info->intr) + goto try_intr; ++ continue; + case USB_ENDPOINT_XFER_ISOC: + if (dev->info->iso) + goto try_iso; +-- +2.12.0 + diff --git a/queue/usb-xhci-bInterval-quirk-for-TI-TUSB73x0.patch b/queue/usb-xhci-bInterval-quirk-for-TI-TUSB73x0.patch new file mode 100644 index 0000000..ad2aca5 --- /dev/null +++ b/queue/usb-xhci-bInterval-quirk-for-TI-TUSB73x0.patch @@ -0,0 +1,81 @@ +From 69307ccb9ad7ccb653e332de68effdeaaab6907d Mon Sep 17 00:00:00 2001 +From: Roger Quadros <rogerq@ti.com> +Date: Fri, 7 Apr 2017 17:57:12 +0300 +Subject: [PATCH] usb: xhci: bInterval quirk for TI TUSB73x0 + +commit 69307ccb9ad7ccb653e332de68effdeaaab6907d upstream. + +As per [1] issue #4, +"The periodic EP scheduler always tries to schedule the EPs +that have large intervals (interval equal to or greater than +128 microframes) into different microframes. So it maintains +an internal counter and increments for each large interval +EP added. When the counter is greater than 128, the scheduler +rejects the new EP. So when the hub re-enumerated 128 times, +it triggers this condition." + +This results in Bandwidth error when devices with periodic +endpoints (ISO/INT) having bInterval > 7 are plugged and +unplugged several times on a TUSB73x0 XHCI host. + +Workaround this issue by limiting the bInterval to 7 +(i.e. interval to 6) for High-speed or faster periodic endpoints. + +[1] - http://www.ti.com/lit/er/sllz076/sllz076.pdf + +Cc: stable <stable@vger.kernel.org> +Signed-off-by: Roger Quadros <rogerq@ti.com> +Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c +index b88ec9ae5d4c..2954b90e0cda 100644 +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -1503,6 +1503,17 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, + */ + max_esit_payload = xhci_get_max_esit_payload(udev, ep); + interval = xhci_get_endpoint_interval(udev, ep); ++ ++ /* Periodic endpoint bInterval limit quirk */ ++ if (usb_endpoint_xfer_int(&ep->desc) || ++ usb_endpoint_xfer_isoc(&ep->desc)) { ++ if ((xhci->quirks & XHCI_LIMIT_ENDPOINT_INTERVAL_7) && ++ udev->speed >= USB_SPEED_HIGH && ++ interval >= 7) { ++ interval = 6; ++ } ++ } ++ + mult = xhci_get_endpoint_mult(udev, ep); + max_packet = usb_endpoint_maxp(&ep->desc); + max_burst = xhci_get_endpoint_max_burst(udev, ep); +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index fc99f51d12e1..7b86508ac8cf 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -199,6 +199,9 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + pdev->device == 0x1042) + xhci->quirks |= XHCI_BROKEN_STREAMS; + ++ if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241) ++ xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7; ++ + if (xhci->quirks & XHCI_RESET_ON_RESUME) + xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, + "QUIRK: Resetting on resume"); +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index dbe8ba934737..914968c662c9 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1820,6 +1820,7 @@ struct xhci_hcd { + #define XHCI_MISSING_CAS (1 << 24) + /* For controller with a broken Port Disable implementation */ + #define XHCI_BROKEN_PORT_PED (1 << 25) ++#define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26) + + unsigned int num_active_eps; + unsigned int limit_active_eps; +-- +2.12.0 + diff --git a/queue/vfio-type1-Remove-locked-page-accounting-workqueue.patch b/queue/vfio-type1-Remove-locked-page-accounting-workqueue.patch new file mode 100644 index 0000000..2bc013a --- /dev/null +++ b/queue/vfio-type1-Remove-locked-page-accounting-workqueue.patch @@ -0,0 +1,231 @@ +From 0cfef2b7410b64d7a430947e0b533314c4f97153 Mon Sep 17 00:00:00 2001 +From: Alex Williamson <alex.williamson@redhat.com> +Date: Thu, 13 Apr 2017 14:10:15 -0600 +Subject: [PATCH] vfio/type1: Remove locked page accounting workqueue + +commit 0cfef2b7410b64d7a430947e0b533314c4f97153 upstream. + +If the mmap_sem is contented then the vfio type1 IOMMU backend will +defer locked page accounting updates to a workqueue task. This has a +few problems and depending on which side the user tries to play, they +might be over-penalized for unmaps that haven't yet been accounted or +race the workqueue to enter more mappings than they're allowed. The +original intent of this workqueue mechanism seems to be focused on +reducing latency through the ioctl, but we cannot do so at the cost +of correctness. Remove this workqueue mechanism and update the +callers to allow for failure. We can also now recheck the limit under +write lock to make sure we don't exceed it. + +vfio_pin_pages_remote() also now necessarily includes an unwind path +which we can jump to directly if the consecutive page pinning finds +that we're exceeding the user's memory limits. This avoids the +current lazy approach which does accounting and mapping up to the +fault, only to return an error on the next iteration to unwind the +entire vfio_dma. + +Cc: stable@vger.kernel.org +Reviewed-by: Peter Xu <peterx@redhat.com> +Reviewed-by: Kirti Wankhede <kwankhede@nvidia.com> +Signed-off-by: Alex Williamson <alex.williamson@redhat.com> + +diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c +index 32d2633092a3..a8a079ba9477 100644 +--- a/drivers/vfio/vfio_iommu_type1.c ++++ b/drivers/vfio/vfio_iommu_type1.c +@@ -246,69 +246,46 @@ static int vfio_iova_put_vfio_pfn(struct vfio_dma *dma, struct vfio_pfn *vpfn) + return ret; + } + +-struct vwork { +- struct mm_struct *mm; +- long npage; +- struct work_struct work; +-}; +- +-/* delayed decrement/increment for locked_vm */ +-static void vfio_lock_acct_bg(struct work_struct *work) +-{ +- struct vwork *vwork = container_of(work, struct vwork, work); +- struct mm_struct *mm; +- +- mm = vwork->mm; +- down_write(&mm->mmap_sem); +- mm->locked_vm += vwork->npage; +- up_write(&mm->mmap_sem); +- mmput(mm); +- kfree(vwork); +-} +- +-static void vfio_lock_acct(struct task_struct *task, long npage) ++static int vfio_lock_acct(struct task_struct *task, long npage, bool *lock_cap) + { +- struct vwork *vwork; + struct mm_struct *mm; + bool is_current; ++ int ret; + + if (!npage) +- return; ++ return 0; + + is_current = (task->mm == current->mm); + + mm = is_current ? task->mm : get_task_mm(task); + if (!mm) +- return; /* process exited */ ++ return -ESRCH; /* process exited */ + +- if (down_write_trylock(&mm->mmap_sem)) { +- mm->locked_vm += npage; +- up_write(&mm->mmap_sem); +- if (!is_current) +- mmput(mm); +- return; +- } ++ ret = down_write_killable(&mm->mmap_sem); ++ if (!ret) { ++ if (npage > 0) { ++ if (lock_cap ? !*lock_cap : ++ !has_capability(task, CAP_IPC_LOCK)) { ++ unsigned long limit; ++ ++ limit = task_rlimit(task, ++ RLIMIT_MEMLOCK) >> PAGE_SHIFT; ++ ++ if (mm->locked_vm + npage > limit) ++ ret = -ENOMEM; ++ } ++ } ++ ++ if (!ret) ++ mm->locked_vm += npage; + +- if (is_current) { +- mm = get_task_mm(task); +- if (!mm) +- return; ++ up_write(&mm->mmap_sem); + } + +- /* +- * Couldn't get mmap_sem lock, so must setup to update +- * mm->locked_vm later. If locked_vm were atomic, we +- * wouldn't need this silliness +- */ +- vwork = kmalloc(sizeof(struct vwork), GFP_KERNEL); +- if (WARN_ON(!vwork)) { ++ if (!is_current) + mmput(mm); +- return; +- } +- INIT_WORK(&vwork->work, vfio_lock_acct_bg); +- vwork->mm = mm; +- vwork->npage = npage; +- schedule_work(&vwork->work); ++ ++ return ret; + } + + /* +@@ -405,7 +382,7 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned long vaddr, + static long vfio_pin_pages_remote(struct vfio_dma *dma, unsigned long vaddr, + long npage, unsigned long *pfn_base) + { +- unsigned long limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; ++ unsigned long pfn = 0, limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; + bool lock_cap = capable(CAP_IPC_LOCK); + long ret, pinned = 0, lock_acct = 0; + bool rsvd; +@@ -442,8 +419,6 @@ static long vfio_pin_pages_remote(struct vfio_dma *dma, unsigned long vaddr, + /* Lock all the consecutive pages from pfn_base */ + for (vaddr += PAGE_SIZE, iova += PAGE_SIZE; pinned < npage; + pinned++, vaddr += PAGE_SIZE, iova += PAGE_SIZE) { +- unsigned long pfn = 0; +- + ret = vaddr_get_pfn(current->mm, vaddr, dma->prot, &pfn); + if (ret) + break; +@@ -460,14 +435,25 @@ static long vfio_pin_pages_remote(struct vfio_dma *dma, unsigned long vaddr, + put_pfn(pfn, dma->prot); + pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n", + __func__, limit << PAGE_SHIFT); +- break; ++ ret = -ENOMEM; ++ goto unpin_out; + } + lock_acct++; + } + } + + out: +- vfio_lock_acct(current, lock_acct); ++ ret = vfio_lock_acct(current, lock_acct, &lock_cap); ++ ++unpin_out: ++ if (ret) { ++ if (!rsvd) { ++ for (pfn = *pfn_base ; pinned ; pfn++, pinned--) ++ put_pfn(pfn, dma->prot); ++ } ++ ++ return ret; ++ } + + return pinned; + } +@@ -488,7 +474,7 @@ static long vfio_unpin_pages_remote(struct vfio_dma *dma, dma_addr_t iova, + } + + if (do_accounting) +- vfio_lock_acct(dma->task, locked - unlocked); ++ vfio_lock_acct(dma->task, locked - unlocked, NULL); + + return unlocked; + } +@@ -522,8 +508,14 @@ static int vfio_pin_page_external(struct vfio_dma *dma, unsigned long vaddr, + goto pin_page_exit; + } + +- if (!rsvd && do_accounting) +- vfio_lock_acct(dma->task, 1); ++ if (!rsvd && do_accounting) { ++ ret = vfio_lock_acct(dma->task, 1, &lock_cap); ++ if (ret) { ++ put_pfn(*pfn_base, dma->prot); ++ goto pin_page_exit; ++ } ++ } ++ + ret = 1; + + pin_page_exit: +@@ -543,7 +535,7 @@ static int vfio_unpin_page_external(struct vfio_dma *dma, dma_addr_t iova, + unlocked = vfio_iova_put_vfio_pfn(dma, vpfn); + + if (do_accounting) +- vfio_lock_acct(dma->task, -unlocked); ++ vfio_lock_acct(dma->task, -unlocked, NULL); + + return unlocked; + } +@@ -740,7 +732,7 @@ static long vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma, + + dma->iommu_mapped = false; + if (do_accounting) { +- vfio_lock_acct(dma->task, -unlocked); ++ vfio_lock_acct(dma->task, -unlocked, NULL); + return 0; + } + return unlocked; +@@ -1382,7 +1374,7 @@ static void vfio_iommu_unmap_unpin_reaccount(struct vfio_iommu *iommu) + if (!is_invalid_reserved_pfn(vpfn->pfn)) + locked++; + } +- vfio_lock_acct(dma->task, locked - unlocked); ++ vfio_lock_acct(dma->task, locked - unlocked, NULL); + } + } + +-- +2.12.0 + diff --git a/queue/wlcore-Add-RX_BA_WIN_SIZE_CHANGE_EVENT-event.patch b/queue/wlcore-Add-RX_BA_WIN_SIZE_CHANGE_EVENT-event.patch new file mode 100644 index 0000000..dee95f9 --- /dev/null +++ b/queue/wlcore-Add-RX_BA_WIN_SIZE_CHANGE_EVENT-event.patch @@ -0,0 +1,86 @@ +From e7ee74b56f23ba447d3124f2eccc32033cca501d Mon Sep 17 00:00:00 2001 +From: Maxim Altshul <maxim.altshul@ti.com> +Date: Sun, 21 Aug 2016 14:24:25 +0300 +Subject: [PATCH] wlcore: Add RX_BA_WIN_SIZE_CHANGE_EVENT event + +commit e7ee74b56f23ba447d3124f2eccc32033cca501d upstream. + +This event is used by the Firmware to limit the RX BA win size +for a specific link. + +The event handler updates the new size in the mac's sta->sta struct. + +BA sessions opened for that link will use the new restricted +win_size. This limitation remains until a new update is received or +until the link is closed. + +Signed-off-by: Maxim Altshul <maxim.altshul@ti.com> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> + +diff --git a/drivers/net/wireless/ti/wl18xx/event.c b/drivers/net/wireless/ti/wl18xx/event.c +index b36ce185c9f2..86fa0fc69084 100644 +--- a/drivers/net/wireless/ti/wl18xx/event.c ++++ b/drivers/net/wireless/ti/wl18xx/event.c +@@ -218,5 +218,33 @@ int wl18xx_process_mailbox_events(struct wl1271 *wl) + if (vector & FW_LOGGER_INDICATION) + wlcore_event_fw_logger(wl); + ++ if (vector & RX_BA_WIN_SIZE_CHANGE_EVENT_ID) { ++ struct wl12xx_vif *wlvif; ++ struct ieee80211_vif *vif; ++ struct ieee80211_sta *sta; ++ u8 link_id = mbox->rx_ba_link_id; ++ u8 win_size = mbox->rx_ba_win_size; ++ const u8 *addr; ++ ++ wlvif = wl->links[link_id].wlvif; ++ vif = wl12xx_wlvif_to_vif(wlvif); ++ ++ /* Update RX aggregation window size and call ++ * MAC routine to stop active RX aggregations for this link ++ */ ++ if (wlvif->bss_type != BSS_TYPE_AP_BSS) ++ addr = vif->bss_conf.bssid; ++ else ++ addr = wl->links[link_id].addr; ++ ++ sta = ieee80211_find_sta(vif, addr); ++ if (sta) { ++ sta->max_rx_aggregation_subframes = win_size; ++ ieee80211_stop_rx_ba_session(vif, ++ wl->links[link_id].ba_bitmap, ++ addr); ++ } ++ } ++ + return 0; + } +diff --git a/drivers/net/wireless/ti/wl18xx/event.h b/drivers/net/wireless/ti/wl18xx/event.h +index ce8ea9c04052..4af297fbb529 100644 +--- a/drivers/net/wireless/ti/wl18xx/event.h ++++ b/drivers/net/wireless/ti/wl18xx/event.h +@@ -38,6 +38,7 @@ enum { + REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID = BIT(18), + DFS_CHANNELS_CONFIG_COMPLETE_EVENT = BIT(19), + PERIODIC_SCAN_REPORT_EVENT_ID = BIT(20), ++ RX_BA_WIN_SIZE_CHANGE_EVENT_ID = BIT(21), + SMART_CONFIG_SYNC_EVENT_ID = BIT(22), + SMART_CONFIG_DECODE_EVENT_ID = BIT(23), + TIME_SYNC_EVENT_ID = BIT(24), +diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c +index 06d6943b257c..5bdf7a03e3dd 100644 +--- a/drivers/net/wireless/ti/wl18xx/main.c ++++ b/drivers/net/wireless/ti/wl18xx/main.c +@@ -1041,7 +1041,8 @@ static int wl18xx_boot(struct wl1271 *wl) + SMART_CONFIG_SYNC_EVENT_ID | + SMART_CONFIG_DECODE_EVENT_ID | + TIME_SYNC_EVENT_ID | +- FW_LOGGER_INDICATION; ++ FW_LOGGER_INDICATION | ++ RX_BA_WIN_SIZE_CHANGE_EVENT_ID; + + wl->ap_event_mask = MAX_TX_FAILURE_EVENT_ID; + +-- +2.12.0 + diff --git a/queue/wlcore-Pass-win_size-taken-from-ieee80211_sta-to-FW.patch b/queue/wlcore-Pass-win_size-taken-from-ieee80211_sta-to-FW.patch new file mode 100644 index 0000000..b4bf3ac --- /dev/null +++ b/queue/wlcore-Pass-win_size-taken-from-ieee80211_sta-to-FW.patch @@ -0,0 +1,82 @@ +From 42c7372a111630dab200c2f959424f5ec3bf79a4 Mon Sep 17 00:00:00 2001 +From: Maxim Altshul <maxim.altshul@ti.com> +Date: Sun, 21 Aug 2016 14:24:24 +0300 +Subject: [PATCH] wlcore: Pass win_size taken from ieee80211_sta to FW + +commit 42c7372a111630dab200c2f959424f5ec3bf79a4 upstream. + +When starting a new BA session, we must pass the win_size to the FW. + +To do this we take max_rx_aggregation_subframes (BA RX win size) +which is stored in ieee80211_sta structure (e.g per link and not per HW) + +We will use the value stored per link when passing the win_size to +firmware through the ACX_BA_SESSION_RX_SETUP command. + +Signed-off-by: Maxim Altshul <maxim.altshul@ti.com> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> + +diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c +index 26cc23f32241..a4859993db3c 100644 +--- a/drivers/net/wireless/ti/wlcore/acx.c ++++ b/drivers/net/wireless/ti/wlcore/acx.c +@@ -1419,7 +1419,8 @@ out: + + /* setup BA session receiver setting in the FW. */ + int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, +- u16 ssn, bool enable, u8 peer_hlid) ++ u16 ssn, bool enable, u8 peer_hlid, ++ u8 win_size) + { + struct wl1271_acx_ba_receiver_setup *acx; + int ret; +@@ -1435,7 +1436,7 @@ int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, + acx->hlid = peer_hlid; + acx->tid = tid_index; + acx->enable = enable; +- acx->win_size = wl->conf.ht.rx_ba_win_size; ++ acx->win_size = win_size; + acx->ssn = ssn; + + ret = wlcore_cmd_configure_failsafe(wl, ACX_BA_SESSION_RX_SETUP, acx, +diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h +index 6321ed472891..f46d7fdf9a00 100644 +--- a/drivers/net/wireless/ti/wlcore/acx.h ++++ b/drivers/net/wireless/ti/wlcore/acx.h +@@ -1113,7 +1113,8 @@ int wl1271_acx_set_ht_information(struct wl1271 *wl, + int wl12xx_acx_set_ba_initiator_policy(struct wl1271 *wl, + struct wl12xx_vif *wlvif); + int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, +- u16 ssn, bool enable, u8 peer_hlid); ++ u16 ssn, bool enable, u8 peer_hlid, ++ u8 win_size); + int wl12xx_acx_tsf_info(struct wl1271 *wl, struct wl12xx_vif *wlvif, + u64 *mactime); + int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif, +diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c +index 471521a0db7b..5438975c7ff2 100644 +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -5285,7 +5285,9 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw, + } + + ret = wl12xx_acx_set_ba_receiver_session(wl, tid, *ssn, true, +- hlid); ++ hlid, ++ params->buf_size); ++ + if (!ret) { + *ba_bitmap |= BIT(tid); + wl->ba_rx_session_count++; +@@ -5306,7 +5308,7 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw, + } + + ret = wl12xx_acx_set_ba_receiver_session(wl, tid, 0, false, +- hlid); ++ hlid, 0); + if (!ret) { + *ba_bitmap &= ~BIT(tid); + wl->ba_rx_session_count--; +-- +2.12.0 + diff --git a/queue/x86-boot-Fix-BSS-corruption-overwrite-bug-in-early-x.patch b/queue/x86-boot-Fix-BSS-corruption-overwrite-bug-in-early-x.patch new file mode 100644 index 0000000..69837e6 --- /dev/null +++ b/queue/x86-boot-Fix-BSS-corruption-overwrite-bug-in-early-x.patch @@ -0,0 +1,52 @@ +From d594aa0277e541bb997aef0bc0a55172d8138340 Mon Sep 17 00:00:00 2001 +From: Ashish Kalra <ashish@bluestacks.com> +Date: Wed, 19 Apr 2017 20:50:15 +0530 +Subject: [PATCH] x86/boot: Fix BSS corruption/overwrite bug in early x86 + kernel startup + +commit d594aa0277e541bb997aef0bc0a55172d8138340 upstream. + +The minimum size for a new stack (512 bytes) setup for arch/x86/boot components +when the bootloader does not setup/provide a stack for the early boot components +is not "enough". + +The setup code executing as part of early kernel startup code, uses the stack +beyond 512 bytes and accidentally overwrites and corrupts part of the BSS +section. This is exposed mostly in the early video setup code, where +it was corrupting BSS variables like force_x, force_y, which in-turn affected +kernel parameters such as screen_info (screen_info.orig_video_cols) and +later caused an exception/panic in console_init(). + +Most recent boot loaders setup the stack for early boot components, so this +stack overwriting into BSS section issue has not been exposed. + +Signed-off-by: Ashish Kalra <ashish@bluestacks.com> +Cc: <stable@vger.kernel.org> +Cc: Andy Lutomirski <luto@kernel.org> +Cc: Borislav Petkov <bp@alien8.de> +Cc: Brian Gerst <brgerst@gmail.com> +Cc: Denys Vlasenko <dvlasenk@redhat.com> +Cc: H. Peter Anvin <hpa@zytor.com> +Cc: Josh Poimboeuf <jpoimboe@redhat.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Link: http://lkml.kernel.org/r/20170419152015.10011-1-ashishkalra@Ashishs-MacBook-Pro.local +Signed-off-by: Ingo Molnar <mingo@kernel.org> + +diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h +index 9b42b6d1e902..ef5a9cc66fb8 100644 +--- a/arch/x86/boot/boot.h ++++ b/arch/x86/boot/boot.h +@@ -16,7 +16,7 @@ + #ifndef BOOT_BOOT_H + #define BOOT_BOOT_H + +-#define STACK_SIZE 512 /* Minimum number of bytes for stack */ ++#define STACK_SIZE 1024 /* Minimum number of bytes for stack */ + + #ifndef __ASSEMBLY__ + +-- +2.12.0 + diff --git a/queue/x86-ioapic-Restore-IO-APIC-irq_chip-retrigger-callba.patch b/queue/x86-ioapic-Restore-IO-APIC-irq_chip-retrigger-callba.patch new file mode 100644 index 0000000..603b8a3 --- /dev/null +++ b/queue/x86-ioapic-Restore-IO-APIC-irq_chip-retrigger-callba.patch @@ -0,0 +1,44 @@ +From a9b4f08770b415f30f2fb0f8329a370c8f554aa3 Mon Sep 17 00:00:00 2001 +From: Ruslan Ruslichenko <rruslich@cisco.com> +Date: Tue, 17 Jan 2017 16:13:52 +0200 +Subject: [PATCH] x86/ioapic: Restore IO-APIC irq_chip retrigger callback + +commit a9b4f08770b415f30f2fb0f8329a370c8f554aa3 upstream. + +commit d32932d02e18 removed the irq_retrigger callback from the IO-APIC +chip and did not add it to the new IO-APIC-IR irq chip. + +There is no harm because the interrupts are resent in software when the +retrigger callback is NULL, but it's less efficient. So restore them. + +[ tglx: Massaged changelog ] + +Fixes: d32932d02e18 ("x86/irq: Convert IOAPIC to use hierarchical irqdomain interfaces") +Signed-off-by: Ruslan Ruslichenko <rruslich@cisco.com> +Cc: xe-linux-external@cisco.com +Link: http://lkml.kernel.org/r/1484662432-13580-1-git-send-email-rruslich@cisco.com +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + +diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c +index 945e512a112a..1e35dd06b090 100644 +--- a/arch/x86/kernel/apic/io_apic.c ++++ b/arch/x86/kernel/apic/io_apic.c +@@ -1875,6 +1875,7 @@ static struct irq_chip ioapic_chip __read_mostly = { + .irq_ack = irq_chip_ack_parent, + .irq_eoi = ioapic_ack_level, + .irq_set_affinity = ioapic_set_affinity, ++ .irq_retrigger = irq_chip_retrigger_hierarchy, + .flags = IRQCHIP_SKIP_SET_WAKE, + }; + +@@ -1886,6 +1887,7 @@ static struct irq_chip ioapic_ir_chip __read_mostly = { + .irq_ack = irq_chip_ack_parent, + .irq_eoi = ioapic_ir_ack_level, + .irq_set_affinity = ioapic_set_affinity, ++ .irq_retrigger = irq_chip_retrigger_hierarchy, + .flags = IRQCHIP_SKIP_SET_WAKE, + }; + +-- +2.12.0 + diff --git a/queue/x86-mce-AMD-Give-a-name-to-MCA-bank-3-when-accessed-.patch b/queue/x86-mce-AMD-Give-a-name-to-MCA-bank-3-when-accessed-.patch new file mode 100644 index 0000000..6f3a8ef --- /dev/null +++ b/queue/x86-mce-AMD-Give-a-name-to-MCA-bank-3-when-accessed-.patch @@ -0,0 +1,52 @@ +From 29f72ce3e4d18066ec75c79c857bee0618a3504b Mon Sep 17 00:00:00 2001 +From: Yazen Ghannam <yazen.ghannam@amd.com> +Date: Thu, 30 Mar 2017 13:17:14 +0200 +Subject: [PATCH] x86/mce/AMD: Give a name to MCA bank 3 when accessed with + legacy MSRs + +commit 29f72ce3e4d18066ec75c79c857bee0618a3504b upstream. + +MCA bank 3 is reserved on systems pre-Fam17h, so it didn't have a name. +However, MCA bank 3 is defined on Fam17h systems and can be accessed +using legacy MSRs. Without a name we get a stack trace on Fam17h systems +when trying to register sysfs files for bank 3 on kernels that don't +recognize Scalable MCA. + +Call MCA bank 3 "decode_unit" since this is what it represents on +Fam17h. This will allow kernels without SMCA support to see this bank on +Fam17h+ and prevent the stack trace. This will not affect older systems +since this bank is reserved on them, i.e. it'll be ignored. + +Tested on AMD Fam15h and Fam17h systems. + + WARNING: CPU: 26 PID: 1 at lib/kobject.c:210 kobject_add_internal + kobject: (ffff88085bb256c0): attempted to be registered with empty name! + ... + Call Trace: + kobject_add_internal + kobject_add + kobject_create_and_add + threshold_create_device + threshold_init_device + +Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com> +Signed-off-by: Borislav Petkov <bp@suse.de> +Link: http://lkml.kernel.org/r/1490102285-3659-1-git-send-email-Yazen.Ghannam@amd.com +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + +diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c +index 524cc5780a77..6e4a047e4b68 100644 +--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c ++++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c +@@ -60,7 +60,7 @@ static const char * const th_names[] = { + "load_store", + "insn_fetch", + "combined_unit", +- "", ++ "decode_unit", + "northbridge", + "execution_unit", + }; +-- +2.12.0 + diff --git a/queue/x86-mce-Make-the-MCE-notifier-a-blocking-one.patch b/queue/x86-mce-Make-the-MCE-notifier-a-blocking-one.patch new file mode 100644 index 0000000..716c721 --- /dev/null +++ b/queue/x86-mce-Make-the-MCE-notifier-a-blocking-one.patch @@ -0,0 +1,125 @@ +From 0dc9c639e6553e39c13b2c0d54c8a1b098cb95e2 Mon Sep 17 00:00:00 2001 +From: Vishal Verma <vishal.l.verma@intel.com> +Date: Tue, 18 Apr 2017 20:42:35 +0200 +Subject: [PATCH] x86/mce: Make the MCE notifier a blocking one + +commit 0dc9c639e6553e39c13b2c0d54c8a1b098cb95e2 upstream. + +The NFIT MCE handler callback (for handling media errors on NVDIMMs) +takes a mutex to add the location of a memory error to a list. But since +the notifier call chain for machine checks (x86_mce_decoder_chain) is +atomic, we get a lockdep splat like: + + BUG: sleeping function called from invalid context at kernel/locking/mutex.c:620 + in_atomic(): 1, irqs_disabled(): 0, pid: 4, name: kworker/0:0 + [..] + Call Trace: + dump_stack + ___might_sleep + __might_sleep + mutex_lock_nested + ? __lock_acquire + nfit_handle_mce + notifier_call_chain + atomic_notifier_call_chain + ? atomic_notifier_call_chain + mce_gen_pool_process + +Convert the notifier to a blocking one which gets to run only in process +context. + +Boris: remove the notifier call in atomic context in print_mce(). For +now, let's print the MCE on the atomic path so that we can make sure +they go out and get logged at least. + +Fixes: 6839a6d96f4e ("nfit: do an ARS scrub on hitting a latent media error") +Reported-by: Ross Zwisler <ross.zwisler@linux.intel.com> +Signed-off-by: Vishal Verma <vishal.l.verma@intel.com> +Acked-by: Tony Luck <tony.luck@intel.com> +Cc: Dan Williams <dan.j.williams@intel.com> +Cc: linux-edac <linux-edac@vger.kernel.org> +Cc: x86-ml <x86@kernel.org> +Cc: <stable@vger.kernel.org> +Link: http://lkml.kernel.org/r/20170411224457.24777-1-vishal.l.verma@intel.com +Signed-off-by: Borislav Petkov <bp@suse.de> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + +diff --git a/arch/x86/kernel/cpu/mcheck/mce-genpool.c b/arch/x86/kernel/cpu/mcheck/mce-genpool.c +index 1e5a50c11d3c..217cd4449bc9 100644 +--- a/arch/x86/kernel/cpu/mcheck/mce-genpool.c ++++ b/arch/x86/kernel/cpu/mcheck/mce-genpool.c +@@ -85,7 +85,7 @@ void mce_gen_pool_process(struct work_struct *__unused) + head = llist_reverse_order(head); + llist_for_each_entry_safe(node, tmp, head, llnode) { + mce = &node->mce; +- atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, mce); ++ blocking_notifier_call_chain(&x86_mce_decoder_chain, 0, mce); + gen_pool_free(mce_evt_pool, (unsigned long)node, sizeof(*node)); + } + } +diff --git a/arch/x86/kernel/cpu/mcheck/mce-internal.h b/arch/x86/kernel/cpu/mcheck/mce-internal.h +index 903043e6a62b..19592ba1a320 100644 +--- a/arch/x86/kernel/cpu/mcheck/mce-internal.h ++++ b/arch/x86/kernel/cpu/mcheck/mce-internal.h +@@ -13,7 +13,7 @@ enum severity_level { + MCE_PANIC_SEVERITY, + }; + +-extern struct atomic_notifier_head x86_mce_decoder_chain; ++extern struct blocking_notifier_head x86_mce_decoder_chain; + + #define ATTR_LEN 16 + #define INITIAL_CHECK_INTERVAL 5 * 60 /* 5 minutes */ +diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c +index 5accfbdee3f0..af44ebeb593f 100644 +--- a/arch/x86/kernel/cpu/mcheck/mce.c ++++ b/arch/x86/kernel/cpu/mcheck/mce.c +@@ -123,7 +123,7 @@ static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs); + * CPU/chipset specific EDAC code can register a notifier call here to print + * MCE errors in a human-readable form. + */ +-ATOMIC_NOTIFIER_HEAD(x86_mce_decoder_chain); ++BLOCKING_NOTIFIER_HEAD(x86_mce_decoder_chain); + + /* Do initial initialization of a struct mce */ + void mce_setup(struct mce *m) +@@ -220,7 +220,7 @@ void mce_register_decode_chain(struct notifier_block *nb) + + WARN_ON(nb->priority > MCE_PRIO_LOWEST && nb->priority < MCE_PRIO_EDAC); + +- atomic_notifier_chain_register(&x86_mce_decoder_chain, nb); ++ blocking_notifier_chain_register(&x86_mce_decoder_chain, nb); + } + EXPORT_SYMBOL_GPL(mce_register_decode_chain); + +@@ -228,7 +228,7 @@ void mce_unregister_decode_chain(struct notifier_block *nb) + { + atomic_dec(&num_notifiers); + +- atomic_notifier_chain_unregister(&x86_mce_decoder_chain, nb); ++ blocking_notifier_chain_unregister(&x86_mce_decoder_chain, nb); + } + EXPORT_SYMBOL_GPL(mce_unregister_decode_chain); + +@@ -321,18 +321,7 @@ static void __print_mce(struct mce *m) + + static void print_mce(struct mce *m) + { +- int ret = 0; +- + __print_mce(m); +- +- /* +- * Print out human-readable details about the MCE error, +- * (if the CPU has an implementation for that) +- */ +- ret = atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, m); +- if (ret == NOTIFY_STOP) +- return; +- + pr_emerg_ratelimited(HW_ERR "Run the above through 'mcelog --ascii'\n"); + } + +-- +2.12.0 + diff --git a/queue/x86-mpx-Re-add-MPX-to-selftests-Makefile.patch b/queue/x86-mpx-Re-add-MPX-to-selftests-Makefile.patch new file mode 100644 index 0000000..c3b4ebb --- /dev/null +++ b/queue/x86-mpx-Re-add-MPX-to-selftests-Makefile.patch @@ -0,0 +1,37 @@ +From e64d5fbe56259c94df504af8ce804cfc6a022adb Mon Sep 17 00:00:00 2001 +From: Dave Hansen <dave.hansen@linux.intel.com> +Date: Wed, 1 Feb 2017 14:56:29 -0800 +Subject: [PATCH] x86/mpx: Re-add MPX to selftests Makefile + +commit e64d5fbe56259c94df504af8ce804cfc6a022adb upstream. + +Ingo pointed out that the MPX tests were no longer in the selftests +Makefile. It appears that I shot myself in the foot on this one +and accidentally removed them when I added the pkeys tests, probably +from bungling a merge conflict. + +Reported-by: Ingo Molnar <mingo@kernel.org> +Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Fixes: 5f23f6d082a9 ("x86/pkeys: Add self-tests") +Link: http://lkml.kernel.org/r/20170201225629.C3070852@viggo.jf.intel.com +Signed-off-by: Ingo Molnar <mingo@kernel.org> + +diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile +index 8c1cb423cfe6..fefd95043fd7 100644 +--- a/tools/testing/selftests/x86/Makefile ++++ b/tools/testing/selftests/x86/Makefile +@@ -5,7 +5,7 @@ include ../lib.mk + .PHONY: all all_32 all_64 warn_32bit_failure clean + + TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall test_mremap_vdso \ +- check_initial_reg_state sigreturn ldt_gdt iopl \ ++ check_initial_reg_state sigreturn ldt_gdt iopl mpx-mini-test \ + protection_keys test_vdso + TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ + test_FCMOV test_FCOMI test_FISTTP \ +-- +2.12.0 + diff --git a/queue/x86-pci-calgary-Fix-iommu_free-comparison-of-unsigne.patch b/queue/x86-pci-calgary-Fix-iommu_free-comparison-of-unsigne.patch new file mode 100644 index 0000000..3f1e742 --- /dev/null +++ b/queue/x86-pci-calgary-Fix-iommu_free-comparison-of-unsigne.patch @@ -0,0 +1,47 @@ +From 68dee8e2f2cacc54d038394e70d22411dee89da2 Mon Sep 17 00:00:00 2001 +From: Nikola Pajkovsky <npajkovsky@suse.cz> +Date: Tue, 15 Nov 2016 09:47:49 +0100 +Subject: [PATCH] x86/pci-calgary: Fix iommu_free() comparison of unsigned + expression >= 0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 68dee8e2f2cacc54d038394e70d22411dee89da2 upstream. + +commit 8fd524b355da ("x86: Kill bad_dma_address variable") has killed +bad_dma_address variable and used instead of macro DMA_ERROR_CODE +which is always zero. Since dma_addr is unsigned, the statement + + dma_addr >= DMA_ERROR_CODE + +is always true, and not needed. + +arch/x86/kernel/pci-calgary_64.c: In function ‘iommu_free’: +arch/x86/kernel/pci-calgary_64.c:299:2: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits] + if (unlikely((dma_addr >= DMA_ERROR_CODE) && (dma_addr < badend))) { + +Fixes: 8fd524b355da ("x86: Kill bad_dma_address variable") +Signed-off-by: Nikola Pajkovsky <npajkovsky@suse.cz> +Cc: iommu@lists.linux-foundation.org +Cc: Jon Mason <jdmason@kudzu.us> +Cc: Muli Ben-Yehuda <mulix@mulix.org> +Link: http://lkml.kernel.org/r/7612c0f9dd7c1290407dbf8e809def922006920b.1479161177.git.npajkovsky@suse.cz +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + +diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c +index 5d400ba1349d..d47517941bbc 100644 +--- a/arch/x86/kernel/pci-calgary_64.c ++++ b/arch/x86/kernel/pci-calgary_64.c +@@ -296,7 +296,7 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, + + /* were we called with bad_dma_address? */ + badend = DMA_ERROR_CODE + (EMERGENCY_PAGES * PAGE_SIZE); +- if (unlikely((dma_addr >= DMA_ERROR_CODE) && (dma_addr < badend))) { ++ if (unlikely(dma_addr < badend)) { + WARN(1, KERN_ERR "Calgary: driver tried unmapping bad DMA " + "address 0x%Lx\n", dma_addr); + return; +-- +2.12.0 + diff --git a/queue/x86-platform-intel-mid-Correct-MSI-IRQ-line-for-watc.patch b/queue/x86-platform-intel-mid-Correct-MSI-IRQ-line-for-watc.patch new file mode 100644 index 0000000..e6dc163 --- /dev/null +++ b/queue/x86-platform-intel-mid-Correct-MSI-IRQ-line-for-watc.patch @@ -0,0 +1,43 @@ +From 80354c29025833acd72ddac1ffa21c6cb50128cd Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Date: Sun, 12 Mar 2017 17:07:44 +0200 +Subject: [PATCH] x86/platform/intel-mid: Correct MSI IRQ line for watchdog + device + +commit 80354c29025833acd72ddac1ffa21c6cb50128cd upstream. + +The interrupt line used for the watchdog is 12, according to the official +Intel Edison BSP code. + +And indeed after fixing it we start getting an interrupt and thus the +watchdog starts working again: + + [ 191.699951] Kernel panic - not syncing: Kernel Watchdog + +Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Cc: Borislav Petkov <bp@alien8.de> +Cc: David Cohen <david.a.cohen@linux.intel.com> +Cc: H. Peter Anvin <hpa@zytor.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Fixes: 78a3bb9e408b ("x86: intel-mid: add watchdog platform code for Merrifield") +Link: http://lkml.kernel.org/r/20170312150744.45493-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Ingo Molnar <mingo@kernel.org> + +diff --git a/arch/x86/platform/intel-mid/device_libs/platform_mrfld_wdt.c b/arch/x86/platform/intel-mid/device_libs/platform_mrfld_wdt.c +index 86edd1e941eb..9e304e2ea4f5 100644 +--- a/arch/x86/platform/intel-mid/device_libs/platform_mrfld_wdt.c ++++ b/arch/x86/platform/intel-mid/device_libs/platform_mrfld_wdt.c +@@ -19,7 +19,7 @@ + #include <asm/intel_scu_ipc.h> + #include <asm/io_apic.h> + +-#define TANGIER_EXT_TIMER0_MSI 15 ++#define TANGIER_EXT_TIMER0_MSI 12 + + static struct platform_device wdt_dev = { + .name = "intel_mid_wdt", +-- +2.12.0 + diff --git a/queue/x86-pmem-Fix-cache-flushing-for-iovec-write-8-bytes.patch b/queue/x86-pmem-Fix-cache-flushing-for-iovec-write-8-bytes.patch new file mode 100644 index 0000000..eb6a779 --- /dev/null +++ b/queue/x86-pmem-Fix-cache-flushing-for-iovec-write-8-bytes.patch @@ -0,0 +1,34 @@ +From 8376efd31d3d7c44bd05be337adde023cc531fa1 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings <ben.hutchings@codethink.co.uk> +Date: Tue, 9 May 2017 18:00:43 +0100 +Subject: [PATCH] x86, pmem: Fix cache flushing for iovec write < 8 bytes + +commit 8376efd31d3d7c44bd05be337adde023cc531fa1 upstream. + +Commit 11e63f6d920d added cache flushing for unaligned writes from an +iovec, covering the first and last cache line of a >= 8 byte write and +the first cache line of a < 8 byte write. But an unaligned write of +2-7 bytes can still cover two cache lines, so make sure we flush both +in that case. + +Cc: <stable@vger.kernel.org> +Fixes: 11e63f6d920d ("x86, pmem: fix broken __copy_user_nocache ...") +Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk> +Signed-off-by: Dan Williams <dan.j.williams@intel.com> + +diff --git a/arch/x86/include/asm/pmem.h b/arch/x86/include/asm/pmem.h +index d5a22bac9988..0ff8fe71b255 100644 +--- a/arch/x86/include/asm/pmem.h ++++ b/arch/x86/include/asm/pmem.h +@@ -98,7 +98,7 @@ static inline size_t arch_copy_from_iter_pmem(void *addr, size_t bytes, + + if (bytes < 8) { + if (!IS_ALIGNED(dest, 4) || (bytes != 4)) +- arch_wb_cache_pmem(addr, 1); ++ arch_wb_cache_pmem(addr, bytes); + } else { + if (!IS_ALIGNED(dest, 8)) { + dest = ALIGN(dest, boot_cpu_data.x86_clflush_size); +-- +2.12.0 + diff --git a/queue/xen-Revert-commits-da72ff5bfcb0-and-72a9b186292d.patch b/queue/xen-Revert-commits-da72ff5bfcb0-and-72a9b186292d.patch new file mode 100644 index 0000000..a9da1aa --- /dev/null +++ b/queue/xen-Revert-commits-da72ff5bfcb0-and-72a9b186292d.patch @@ -0,0 +1,248 @@ +From 84d582d236dc1f9085e741affc72e9ba061a67c2 Mon Sep 17 00:00:00 2001 +From: Boris Ostrovsky <boris.ostrovsky@oracle.com> +Date: Mon, 24 Apr 2017 15:04:53 -0400 +Subject: [PATCH] xen: Revert commits da72ff5bfcb0 and 72a9b186292d + +commit 84d582d236dc1f9085e741affc72e9ba061a67c2 upstream. + +Recent discussion (http://marc.info/?l=xen-devel&m=149192184523741) +established that commit 72a9b186292d ("xen: Remove event channel +notification through Xen PCI platform device") (and thus commit +da72ff5bfcb0 ("partially revert "xen: Remove event channel +notification through Xen PCI platform device"")) are unnecessary and, +in fact, prevent HVM guests from booting on Xen releases prior to 4.0 + +Therefore we revert both of those commits. + +The summary of that discussion is below: + + Here is the brief summary of the current situation: + + Before the offending commit (72a9b186292): + + 1) INTx does not work because of the reset_watches path. + 2) The reset_watches path is only taken if you have Xen > 4.0 + 3) The Linux Kernel by default will use vector inject if the hypervisor + support. So even INTx does not work no body running the kernel with + Xen > 4.0 would notice. Unless he explicitly disabled this feature + either in the kernel or in Xen (and this can only be disabled by + modifying the code, not user-supported way to do it). + + After the offending commit (+ partial revert): + + 1) INTx is no longer support for HVM (only for PV guests). + 2) Any HVM guest The kernel will not boot on Xen < 4.0 which does + not have vector injection support. Since the only other mode + supported is INTx which. + + So based on this summary, I think before commit (72a9b186292) we were + in much better position from a user point of view. + +Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> +Reviewed-by: Juergen Gross <jgross@suse.com> +Signed-off-by: Juergen Gross <jgross@suse.com> + +diff --git a/arch/x86/include/asm/xen/events.h b/arch/x86/include/asm/xen/events.h +index 608a79d5a466..e6911caf5bbf 100644 +--- a/arch/x86/include/asm/xen/events.h ++++ b/arch/x86/include/asm/xen/events.h +@@ -20,4 +20,15 @@ static inline int xen_irqs_disabled(struct pt_regs *regs) + /* No need for a barrier -- XCHG is a barrier on x86. */ + #define xchg_xen_ulong(ptr, val) xchg((ptr), (val)) + ++extern int xen_have_vector_callback; ++ ++/* ++ * Events delivered via platform PCI interrupts are always ++ * routed to vcpu 0 and hence cannot be rebound. ++ */ ++static inline bool xen_support_evtchn_rebind(void) ++{ ++ return (!xen_hvm_domain() || xen_have_vector_callback); ++} ++ + #endif /* _ASM_X86_XEN_EVENTS_H */ +diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c +index 292ab0364a89..c4b3646bd04c 100644 +--- a/arch/x86/pci/xen.c ++++ b/arch/x86/pci/xen.c +@@ -447,7 +447,7 @@ void __init xen_msi_init(void) + + int __init pci_xen_hvm_init(void) + { +- if (!xen_feature(XENFEAT_hvm_pirqs)) ++ if (!xen_have_vector_callback || !xen_feature(XENFEAT_hvm_pirqs)) + return 0; + + #ifdef CONFIG_ACPI +diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c +index 72df54a481d6..078c512b8720 100644 +--- a/arch/x86/xen/enlighten_hvm.c ++++ b/arch/x86/xen/enlighten_hvm.c +@@ -18,6 +18,9 @@ + #include "mmu.h" + #include "smp.h" + ++__read_mostly int xen_have_vector_callback; ++EXPORT_SYMBOL_GPL(xen_have_vector_callback); ++ + void __ref xen_hvm_init_shared_info(void) + { + int cpu; +@@ -123,7 +126,7 @@ static int xen_cpu_up_prepare_hvm(unsigned int cpu) + per_cpu(xen_vcpu_id, cpu) = cpu; + xen_vcpu_setup(cpu); + +- if (xen_feature(XENFEAT_hvm_safe_pvclock)) ++ if (xen_have_vector_callback && xen_feature(XENFEAT_hvm_safe_pvclock)) + xen_setup_timer(cpu); + + rc = xen_smp_intr_init(cpu); +@@ -139,7 +142,7 @@ static int xen_cpu_dead_hvm(unsigned int cpu) + { + xen_smp_intr_free(cpu); + +- if (xen_feature(XENFEAT_hvm_safe_pvclock)) ++ if (xen_have_vector_callback && xen_feature(XENFEAT_hvm_safe_pvclock)) + xen_teardown_timer(cpu); + + return 0; +@@ -156,7 +159,8 @@ static void __init xen_hvm_guest_init(void) + + xen_panic_handler_init(); + +- BUG_ON(!xen_feature(XENFEAT_hvm_callback_vector)); ++ if (xen_feature(XENFEAT_hvm_callback_vector)) ++ xen_have_vector_callback = 1; + + xen_hvm_smp_init(); + WARN_ON(xen_cpuhp_setup(xen_cpu_up_prepare_hvm, xen_cpu_dead_hvm)); +@@ -189,7 +193,7 @@ bool xen_hvm_need_lapic(void) + return false; + if (!xen_hvm_domain()) + return false; +- if (xen_feature(XENFEAT_hvm_pirqs)) ++ if (xen_feature(XENFEAT_hvm_pirqs) && xen_have_vector_callback) + return false; + return true; + } +diff --git a/arch/x86/xen/smp_hvm.c b/arch/x86/xen/smp_hvm.c +index 8bed434cd7d7..f18561bbf5c9 100644 +--- a/arch/x86/xen/smp_hvm.c ++++ b/arch/x86/xen/smp_hvm.c +@@ -1,5 +1,7 @@ + #include <asm/smp.h> + ++#include <xen/events.h> ++ + #include "xen-ops.h" + #include "smp.h" + +@@ -49,6 +51,9 @@ static void xen_hvm_cpu_die(unsigned int cpu) + + void __init xen_hvm_smp_init(void) + { ++ if (!xen_have_vector_callback) ++ return; ++ + smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus; + smp_ops.smp_send_reschedule = xen_smp_send_reschedule; + smp_ops.cpu_die = xen_hvm_cpu_die; +diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c +index 7a3089285c59..090c7eb4dca9 100644 +--- a/arch/x86/xen/time.c ++++ b/arch/x86/xen/time.c +@@ -436,6 +436,14 @@ static void xen_hvm_setup_cpu_clockevents(void) + + void __init xen_hvm_init_time_ops(void) + { ++ /* ++ * vector callback is needed otherwise we cannot receive interrupts ++ * on cpu > 0 and at this point we don't know how many cpus are ++ * available. ++ */ ++ if (!xen_have_vector_callback) ++ return; ++ + if (!xen_feature(XENFEAT_hvm_safe_pvclock)) { + printk(KERN_INFO "Xen doesn't support pvclock on HVM," + "disable pv timer\n"); +diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c +index 6a53577772c9..b52852f38cff 100644 +--- a/drivers/xen/events/events_base.c ++++ b/drivers/xen/events/events_base.c +@@ -1312,6 +1312,9 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) + if (!VALID_EVTCHN(evtchn)) + return -1; + ++ if (!xen_support_evtchn_rebind()) ++ return -1; ++ + /* Send future instances of this interrupt to other vcpu. */ + bind_vcpu.port = evtchn; + bind_vcpu.vcpu = xen_vcpu_nr(tcpu); +@@ -1646,14 +1649,20 @@ void xen_callback_vector(void) + int rc; + uint64_t callback_via; + +- callback_via = HVM_CALLBACK_VECTOR(HYPERVISOR_CALLBACK_VECTOR); +- rc = xen_set_callback_via(callback_via); +- BUG_ON(rc); +- pr_info("Xen HVM callback vector for event delivery is enabled\n"); +- /* in the restore case the vector has already been allocated */ +- if (!test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors)) +- alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, +- xen_hvm_callback_vector); ++ if (xen_have_vector_callback) { ++ callback_via = HVM_CALLBACK_VECTOR(HYPERVISOR_CALLBACK_VECTOR); ++ rc = xen_set_callback_via(callback_via); ++ if (rc) { ++ pr_err("Request for Xen HVM callback vector failed\n"); ++ xen_have_vector_callback = 0; ++ return; ++ } ++ pr_info("Xen HVM callback vector for event delivery is enabled\n"); ++ /* in the restore case the vector has already been allocated */ ++ if (!test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors)) ++ alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, ++ xen_hvm_callback_vector); ++ } + } + #else + void xen_callback_vector(void) {} +diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c +index 2a165cc8a43c..1275df83070f 100644 +--- a/drivers/xen/platform-pci.c ++++ b/drivers/xen/platform-pci.c +@@ -90,8 +90,10 @@ static int xen_allocate_irq(struct pci_dev *pdev) + static int platform_pci_resume(struct pci_dev *pdev) + { + int err; +- if (!xen_pv_domain()) ++ ++ if (xen_have_vector_callback) + return 0; ++ + err = xen_set_callback_via(callback_via); + if (err) { + dev_err(&pdev->dev, "platform_pci_resume failure!\n"); +@@ -137,15 +139,7 @@ static int platform_pci_probe(struct pci_dev *pdev, + + platform_mmio = mmio_addr; + platform_mmiolen = mmio_len; +- +- /* +- * Xen HVM guests always use the vector callback mechanism. +- * L1 Dom0 in a nested Xen environment is a PV guest inside in an +- * HVM environment. It needs the platform-pci driver to get +- * notifications from L0 Xen, but it cannot use the vector callback +- * as it is not exported by L1 Xen. +- */ +- if (xen_pv_domain()) { ++ if (!xen_have_vector_callback) { + ret = xen_allocate_irq(pdev); + if (ret) { + dev_warn(&pdev->dev, "request_irq failed err=%d\n", ret); +-- +2.12.0 + diff --git a/queue/xen-adjust-early-dom0-p2m-handling-to-xen-hypervisor.patch b/queue/xen-adjust-early-dom0-p2m-handling-to-xen-hypervisor.patch new file mode 100644 index 0000000..3262415 --- /dev/null +++ b/queue/xen-adjust-early-dom0-p2m-handling-to-xen-hypervisor.patch @@ -0,0 +1,57 @@ +From 69861e0a52f8733355ce246f0db15e1b240ad667 Mon Sep 17 00:00:00 2001 +From: Juergen Gross <jgross@suse.com> +Date: Wed, 10 May 2017 06:08:44 +0200 +Subject: [PATCH] xen: adjust early dom0 p2m handling to xen hypervisor + behavior + +commit 69861e0a52f8733355ce246f0db15e1b240ad667 upstream. + +When booted as pv-guest the p2m list presented by the Xen is already +mapped to virtual addresses. In dom0 case the hypervisor might make use +of 2M- or 1G-pages for this mapping. Unfortunately while being properly +aligned in virtual and machine address space, those pages might not be +aligned properly in guest physical address space. + +So when trying to obtain the guest physical address of such a page +pud_pfn() and pmd_pfn() must be avoided as those will mask away guest +physical address bits not being zero in this special case. + +Signed-off-by: Juergen Gross <jgross@suse.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +Signed-off-by: Juergen Gross <jgross@suse.com> + +diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c +index 9d9ae6650aa1..7397d8b8459d 100644 +--- a/arch/x86/xen/mmu_pv.c ++++ b/arch/x86/xen/mmu_pv.c +@@ -2025,7 +2025,8 @@ static unsigned long __init xen_read_phys_ulong(phys_addr_t addr) + + /* + * Translate a virtual address to a physical one without relying on mapped +- * page tables. ++ * page tables. Don't rely on big pages being aligned in (guest) physical ++ * space! + */ + static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr) + { +@@ -2046,7 +2047,7 @@ static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr) + sizeof(pud))); + if (!pud_present(pud)) + return 0; +- pa = pud_pfn(pud) << PAGE_SHIFT; ++ pa = pud_val(pud) & PTE_PFN_MASK; + if (pud_large(pud)) + return pa + (vaddr & ~PUD_MASK); + +@@ -2054,7 +2055,7 @@ static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr) + sizeof(pmd))); + if (!pmd_present(pmd)) + return 0; +- pa = pmd_pfn(pmd) << PAGE_SHIFT; ++ pa = pmd_val(pmd) & PTE_PFN_MASK; + if (pmd_large(pmd)) + return pa + (vaddr & ~PMD_MASK); + +-- +2.12.0 + |