]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Apr 2017 12:34:08 +0000 (14:34 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Apr 2017 12:34:08 +0000 (14:34 +0200)
added patches:
acpi-ec-use-busy-polling-mode-when-gpe-is-not-enabled.patch
asoc-intel-select-dw_dmac_core-since-it-s-mandatory.patch
ath9k-fix-null-pointer-dereference.patch
crypto-ahash-fix-einprogress-notification-callback.patch
crypto-algif_aead-fix-bogus-request-dereference-in-completion-function.patch
cxusb-use-a-dma-capable-buffer-also-for-reading.patch
drm-nouveau-disp-mcp7x-disable-dptmds-workaround.patch
dvb-usb-don-t-use-stack-for-firmware-load.patch
dvb-usb-firmware-don-t-do-dma-on-stack.patch
dvb-usb-v2-avoid-use-after-free.patch
ext4-fix-inode-checksum-calculation-problem-if-i_extra_size-is-small.patch
ftrace-fix-function-pid-filter-on-instances.patch
mm-memcontrol-use-special-workqueue-for-creating-per-memcg-caches.patch
mm-tighten-x86-dev-mem-with-zeroing-reads.patch
nbd-fix-64-bit-division.patch
nbd-use-loff_t-for-blocksize-and-nbd_set_size-args.patch
parisc-fix-get_user-for-64-bit-value-on-32-bit-kernel.patch
platform-x86-acer-wmi-setup-accelerometer-when-machine-has-appropriate-notify-event.patch
rtc-tegra-implement-clock-handling.patch
virtio-console-avoid-dma-from-stack.patch
x86-xen-fix-apic-id-mismatch-warning-on-intel.patch

22 files changed:
queue-4.9/acpi-ec-use-busy-polling-mode-when-gpe-is-not-enabled.patch [new file with mode: 0644]
queue-4.9/asoc-intel-select-dw_dmac_core-since-it-s-mandatory.patch [new file with mode: 0644]
queue-4.9/ath9k-fix-null-pointer-dereference.patch [new file with mode: 0644]
queue-4.9/crypto-ahash-fix-einprogress-notification-callback.patch [new file with mode: 0644]
queue-4.9/crypto-algif_aead-fix-bogus-request-dereference-in-completion-function.patch [new file with mode: 0644]
queue-4.9/cxusb-use-a-dma-capable-buffer-also-for-reading.patch [new file with mode: 0644]
queue-4.9/drm-nouveau-disp-mcp7x-disable-dptmds-workaround.patch [new file with mode: 0644]
queue-4.9/dvb-usb-don-t-use-stack-for-firmware-load.patch [new file with mode: 0644]
queue-4.9/dvb-usb-firmware-don-t-do-dma-on-stack.patch [new file with mode: 0644]
queue-4.9/dvb-usb-v2-avoid-use-after-free.patch [new file with mode: 0644]
queue-4.9/ext4-fix-inode-checksum-calculation-problem-if-i_extra_size-is-small.patch [new file with mode: 0644]
queue-4.9/ftrace-fix-function-pid-filter-on-instances.patch [new file with mode: 0644]
queue-4.9/mm-memcontrol-use-special-workqueue-for-creating-per-memcg-caches.patch [new file with mode: 0644]
queue-4.9/mm-tighten-x86-dev-mem-with-zeroing-reads.patch [new file with mode: 0644]
queue-4.9/nbd-fix-64-bit-division.patch [new file with mode: 0644]
queue-4.9/nbd-use-loff_t-for-blocksize-and-nbd_set_size-args.patch [new file with mode: 0644]
queue-4.9/parisc-fix-get_user-for-64-bit-value-on-32-bit-kernel.patch [new file with mode: 0644]
queue-4.9/platform-x86-acer-wmi-setup-accelerometer-when-machine-has-appropriate-notify-event.patch [new file with mode: 0644]
queue-4.9/rtc-tegra-implement-clock-handling.patch [new file with mode: 0644]
queue-4.9/series
queue-4.9/virtio-console-avoid-dma-from-stack.patch [new file with mode: 0644]
queue-4.9/x86-xen-fix-apic-id-mismatch-warning-on-intel.patch [new file with mode: 0644]

diff --git a/queue-4.9/acpi-ec-use-busy-polling-mode-when-gpe-is-not-enabled.patch b/queue-4.9/acpi-ec-use-busy-polling-mode-when-gpe-is-not-enabled.patch
new file mode 100644 (file)
index 0000000..1370cc9
--- /dev/null
@@ -0,0 +1,165 @@
+From c3a696b6e8f8f75f9f75e556a9f9f6472eae2655 Mon Sep 17 00:00:00 2001
+From: Lv Zheng <lv.zheng@intel.com>
+Date: Fri, 20 Jan 2017 16:42:48 +0800
+Subject: ACPI / EC: Use busy polling mode when GPE is not enabled
+
+From: Lv Zheng <lv.zheng@intel.com>
+
+commit c3a696b6e8f8f75f9f75e556a9f9f6472eae2655 upstream.
+
+When GPE is not enabled, it is not efficient to use the wait polling mode
+as it introduces an unexpected scheduler delay.
+So before the GPE handler is installed, this patch uses busy polling mode
+for all EC(s) and the logic can be applied to non boot EC(s) during the
+suspend/resume process.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=191561
+Tested-by: Jakobus Schurz <jakobus.schurz@gmail.com>
+Tested-by: Chen Yu <yu.c.chen@intel.com>
+Signed-off-by: Lv Zheng <lv.zheng@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/ec.c       |   62 +++++++++++++++++++++++-------------------------
+ drivers/acpi/internal.h |    4 +--
+ 2 files changed, 32 insertions(+), 34 deletions(-)
+
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -729,12 +729,12 @@ static void start_transaction(struct acp
+ static int ec_guard(struct acpi_ec *ec)
+ {
+-      unsigned long guard = usecs_to_jiffies(ec_polling_guard);
++      unsigned long guard = usecs_to_jiffies(ec->polling_guard);
+       unsigned long timeout = ec->timestamp + guard;
+       /* Ensure guarding period before polling EC status */
+       do {
+-              if (ec_busy_polling) {
++              if (ec->busy_polling) {
+                       /* Perform busy polling */
+                       if (ec_transaction_completed(ec))
+                               return 0;
+@@ -998,6 +998,28 @@ static void acpi_ec_stop(struct acpi_ec
+       spin_unlock_irqrestore(&ec->lock, flags);
+ }
++static void acpi_ec_enter_noirq(struct acpi_ec *ec)
++{
++      unsigned long flags;
++
++      spin_lock_irqsave(&ec->lock, flags);
++      ec->busy_polling = true;
++      ec->polling_guard = 0;
++      ec_log_drv("interrupt blocked");
++      spin_unlock_irqrestore(&ec->lock, flags);
++}
++
++static void acpi_ec_leave_noirq(struct acpi_ec *ec)
++{
++      unsigned long flags;
++
++      spin_lock_irqsave(&ec->lock, flags);
++      ec->busy_polling = ec_busy_polling;
++      ec->polling_guard = ec_polling_guard;
++      ec_log_drv("interrupt unblocked");
++      spin_unlock_irqrestore(&ec->lock, flags);
++}
++
+ void acpi_ec_block_transactions(void)
+ {
+       struct acpi_ec *ec = first_ec;
+@@ -1278,7 +1300,7 @@ acpi_ec_space_handler(u32 function, acpi
+       if (function != ACPI_READ && function != ACPI_WRITE)
+               return AE_BAD_PARAMETER;
+-      if (ec_busy_polling || bits > 8)
++      if (ec->busy_polling || bits > 8)
+               acpi_ec_burst_enable(ec);
+       for (i = 0; i < bytes; ++i, ++address, ++value)
+@@ -1286,7 +1308,7 @@ acpi_ec_space_handler(u32 function, acpi
+                       acpi_ec_read(ec, address, value) :
+                       acpi_ec_write(ec, address, *value);
+-      if (ec_busy_polling || bits > 8)
++      if (ec->busy_polling || bits > 8)
+               acpi_ec_burst_disable(ec);
+       switch (result) {
+@@ -1329,6 +1351,8 @@ static struct acpi_ec *acpi_ec_alloc(voi
+       spin_lock_init(&ec->lock);
+       INIT_WORK(&ec->work, acpi_ec_event_handler);
+       ec->timestamp = jiffies;
++      ec->busy_polling = true;
++      ec->polling_guard = 0;
+       return ec;
+ }
+@@ -1390,6 +1414,7 @@ static int ec_install_handlers(struct ac
+       acpi_ec_start(ec, false);
+       if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
++              acpi_ec_enter_noirq(ec);
+               status = acpi_install_address_space_handler(ec->handle,
+                                                           ACPI_ADR_SPACE_EC,
+                                                           &acpi_ec_space_handler,
+@@ -1429,6 +1454,7 @@ static int ec_install_handlers(struct ac
+               /* This is not fatal as we can poll EC events */
+               if (ACPI_SUCCESS(status)) {
+                       set_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags);
++                      acpi_ec_leave_noirq(ec);
+                       if (test_bit(EC_FLAGS_STARTED, &ec->flags) &&
+                           ec->reference_count >= 1)
+                               acpi_ec_enable_gpe(ec, true);
+@@ -1839,34 +1865,6 @@ error:
+ }
+ #ifdef CONFIG_PM_SLEEP
+-static void acpi_ec_enter_noirq(struct acpi_ec *ec)
+-{
+-      unsigned long flags;
+-
+-      if (ec == first_ec) {
+-              spin_lock_irqsave(&ec->lock, flags);
+-              ec->saved_busy_polling = ec_busy_polling;
+-              ec->saved_polling_guard = ec_polling_guard;
+-              ec_busy_polling = true;
+-              ec_polling_guard = 0;
+-              ec_log_drv("interrupt blocked");
+-              spin_unlock_irqrestore(&ec->lock, flags);
+-      }
+-}
+-
+-static void acpi_ec_leave_noirq(struct acpi_ec *ec)
+-{
+-      unsigned long flags;
+-
+-      if (ec == first_ec) {
+-              spin_lock_irqsave(&ec->lock, flags);
+-              ec_busy_polling = ec->saved_busy_polling;
+-              ec_polling_guard = ec->saved_polling_guard;
+-              ec_log_drv("interrupt unblocked");
+-              spin_unlock_irqrestore(&ec->lock, flags);
+-      }
+-}
+-
+ static int acpi_ec_suspend_noirq(struct device *dev)
+ {
+       struct acpi_ec *ec =
+--- a/drivers/acpi/internal.h
++++ b/drivers/acpi/internal.h
+@@ -172,8 +172,8 @@ struct acpi_ec {
+       struct work_struct work;
+       unsigned long timestamp;
+       unsigned long nr_pending_queries;
+-      bool saved_busy_polling;
+-      unsigned int saved_polling_guard;
++      bool busy_polling;
++      unsigned int polling_guard;
+ };
+ extern struct acpi_ec *first_ec;
diff --git a/queue-4.9/asoc-intel-select-dw_dmac_core-since-it-s-mandatory.patch b/queue-4.9/asoc-intel-select-dw_dmac_core-since-it-s-mandatory.patch
new file mode 100644 (file)
index 0000000..90e799e
--- /dev/null
@@ -0,0 +1,113 @@
+From ebf79091bf85d9b2270ab29191de9cd3aaf888c5 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Date: Mon, 16 Jan 2017 15:12:26 +0200
+Subject: ASoC: Intel: select DW_DMAC_CORE since it's mandatory
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+commit ebf79091bf85d9b2270ab29191de9cd3aaf888c5 upstream.
+
+Select DW_DMAC_CORE like the rest of glue drivers do, e.g.
+drivers/dma/dw/Kconfig.
+
+While here group selectors under SND_SOC_INTEL_HASWELL and
+SND_SOC_INTEL_BAYTRAIL.
+
+Make platforms, which are using a common SST firmware driver, to be
+dependent on DMADEVICES.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Acked-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/intel/Kconfig |   31 +++++++++++++------------------
+ 1 file changed, 13 insertions(+), 18 deletions(-)
+
+--- a/sound/soc/intel/Kconfig
++++ b/sound/soc/intel/Kconfig
+@@ -33,11 +33,9 @@ config SND_SOC_INTEL_SST
+       select SND_SOC_INTEL_SST_MATCH if ACPI
+       depends on (X86 || COMPILE_TEST)
+-# firmware stuff depends DW_DMAC_CORE; since there is no depends-on from
+-# the reverse selection, each machine driver needs to select
+-# SND_SOC_INTEL_SST_FIRMWARE carefully depending on DW_DMAC_CORE
+ config SND_SOC_INTEL_SST_FIRMWARE
+       tristate
++      select DW_DMAC_CORE
+ config SND_SOC_INTEL_SST_ACPI
+       tristate
+@@ -47,16 +45,18 @@ config SND_SOC_INTEL_SST_MATCH
+ config SND_SOC_INTEL_HASWELL
+       tristate
++      select SND_SOC_INTEL_SST
+       select SND_SOC_INTEL_SST_FIRMWARE
+ config SND_SOC_INTEL_BAYTRAIL
+       tristate
++      select SND_SOC_INTEL_SST
++      select SND_SOC_INTEL_SST_FIRMWARE
+ config SND_SOC_INTEL_HASWELL_MACH
+       tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint"
+       depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM
+-      depends on DW_DMAC_CORE
+-      select SND_SOC_INTEL_SST
++      depends on DMADEVICES
+       select SND_SOC_INTEL_HASWELL
+       select SND_SOC_RT5640
+       help
+@@ -99,9 +99,8 @@ config SND_SOC_INTEL_BXT_RT298_MACH
+ config SND_SOC_INTEL_BYT_RT5640_MACH
+       tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec"
+       depends on X86_INTEL_LPSS && I2C
+-      depends on DW_DMAC_CORE && (SND_SST_IPC_ACPI = n)
+-      select SND_SOC_INTEL_SST
+-      select SND_SOC_INTEL_SST_FIRMWARE
++      depends on DMADEVICES
++      depends on SND_SST_IPC_ACPI = n
+       select SND_SOC_INTEL_BAYTRAIL
+       select SND_SOC_RT5640
+       help
+@@ -112,9 +111,8 @@ config SND_SOC_INTEL_BYT_RT5640_MACH
+ config SND_SOC_INTEL_BYT_MAX98090_MACH
+       tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec"
+       depends on X86_INTEL_LPSS && I2C
+-      depends on DW_DMAC_CORE && (SND_SST_IPC_ACPI = n)
+-      select SND_SOC_INTEL_SST
+-      select SND_SOC_INTEL_SST_FIRMWARE
++      depends on DMADEVICES
++      depends on SND_SST_IPC_ACPI = n
+       select SND_SOC_INTEL_BAYTRAIL
+       select SND_SOC_MAX98090
+       help
+@@ -123,9 +121,8 @@ config SND_SOC_INTEL_BYT_MAX98090_MACH
+ config SND_SOC_INTEL_BDW_RT5677_MACH
+       tristate "ASoC Audio driver for Intel Broadwell with RT5677 codec"
+-      depends on X86_INTEL_LPSS && GPIOLIB && I2C && DW_DMAC
+-      depends on DW_DMAC_CORE=y
+-      select SND_SOC_INTEL_SST
++      depends on X86_INTEL_LPSS && GPIOLIB && I2C
++      depends on DMADEVICES
+       select SND_SOC_INTEL_HASWELL
+       select SND_SOC_RT5677
+       help
+@@ -134,10 +131,8 @@ config SND_SOC_INTEL_BDW_RT5677_MACH
+ config SND_SOC_INTEL_BROADWELL_MACH
+       tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint"
+-      depends on X86_INTEL_LPSS && I2C && DW_DMAC && \
+-                 I2C_DESIGNWARE_PLATFORM
+-      depends on DW_DMAC_CORE
+-      select SND_SOC_INTEL_SST
++      depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM
++      depends on DMADEVICES
+       select SND_SOC_INTEL_HASWELL
+       select SND_SOC_RT286
+       help
diff --git a/queue-4.9/ath9k-fix-null-pointer-dereference.patch b/queue-4.9/ath9k-fix-null-pointer-dereference.patch
new file mode 100644 (file)
index 0000000..fa543ec
--- /dev/null
@@ -0,0 +1,80 @@
+From 40bea976c72b9ee60f8d097852deb53ccbeaffbe Mon Sep 17 00:00:00 2001
+From: Miaoqing Pan <miaoqing@codeaurora.org>
+Date: Wed, 16 Nov 2016 17:23:08 +0800
+Subject: ath9k: fix NULL pointer dereference
+
+From: Miaoqing Pan <miaoqing@codeaurora.org>
+
+commit 40bea976c72b9ee60f8d097852deb53ccbeaffbe upstream.
+
+relay_open() may return NULL, check the return value to avoid the crash.
+
+BUG: unable to handle kernel NULL pointer dereference at 0000000000000040
+IP: [<ffffffffa01a95c5>] ath_cmn_process_fft+0xd5/0x700 [ath9k_common]
+PGD 41cf28067 PUD 41be92067 PMD 0
+Oops: 0000 [#1] SMP
+CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.8.6+ #35
+Hardware name: Hewlett-Packard h8-1080t/2A86, BIOS 6.15    07/04/2011
+task: ffffffff81e0c4c0 task.stack: ffffffff81e00000
+RIP: 0010:[<ffffffffa01a95c5>] [<ffffffffa01a95c5>] ath_cmn_process_fft+0xd5/0x700 [ath9k_common]
+RSP: 0018:ffff88041f203ca0 EFLAGS: 00010293
+RAX: 0000000000000000 RBX: 000000000000059f RCX: 0000000000000000
+RDX: 0000000000000000 RSI: 0000000000000040 RDI: ffffffff81f0ca98
+RBP: ffff88041f203dc8 R08: ffffffffffffffff R09: 00000000000000ff
+R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
+R13: ffffffff81f0ca98 R14: 0000000000000000 R15: 0000000000000000
+FS:  0000000000000000(0000) GS:ffff88041f200000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000000000000040 CR3: 000000041b6ec000 CR4: 00000000000006f0
+Stack:
+0000000000000363 00000000000003f3 00000000000003f3 00000000000001f9
+000000000000049a 0000000001252c04 ffff88041f203e44 ffff880417b4bfd0
+0000000000000008 ffff88041785b9c0 0000000000000002 ffff88041613dc60
+
+Call Trace:
+<IRQ>
+[<ffffffffa01b6441>] ath9k_tasklet+0x1b1/0x220 [ath9k]
+[<ffffffff8105d8dd>] tasklet_action+0x4d/0xf0
+[<ffffffff8105dde2>] __do_softirq+0x92/0x2a0
+
+Reported-by: Devin Tuchsen <devin.tuchsen@gmail.com>
+Tested-by: Devin Tuchsen <devin.tuchsen@gmail.com>
+Signed-off-by: Miaoqing Pan <miaoqing@codeaurora.org>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/common-spectral.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ath/ath9k/common-spectral.c
++++ b/drivers/net/wireless/ath/ath9k/common-spectral.c
+@@ -528,6 +528,9 @@ int ath_cmn_process_fft(struct ath_spec_
+       if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK))
+               return 0;
++      if (!spec_priv->rfs_chan_spec_scan)
++              return 1;
++
+       /* Output buffers are full, no need to process anything
+        * since there is no space to put the result anyway
+        */
+@@ -1072,7 +1075,7 @@ static struct rchan_callbacks rfs_spec_s
+ void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv)
+ {
+-      if (IS_ENABLED(CONFIG_ATH9K_DEBUGFS)) {
++      if (IS_ENABLED(CONFIG_ATH9K_DEBUGFS) && spec_priv->rfs_chan_spec_scan) {
+               relay_close(spec_priv->rfs_chan_spec_scan);
+               spec_priv->rfs_chan_spec_scan = NULL;
+       }
+@@ -1086,6 +1089,9 @@ void ath9k_cmn_spectral_init_debug(struc
+                                           debugfs_phy,
+                                           1024, 256, &rfs_spec_scan_cb,
+                                           NULL);
++      if (!spec_priv->rfs_chan_spec_scan)
++              return;
++
+       debugfs_create_file("spectral_scan_ctl",
+                           S_IRUSR | S_IWUSR,
+                           debugfs_phy, spec_priv,
diff --git a/queue-4.9/crypto-ahash-fix-einprogress-notification-callback.patch b/queue-4.9/crypto-ahash-fix-einprogress-notification-callback.patch
new file mode 100644 (file)
index 0000000..b0c0234
--- /dev/null
@@ -0,0 +1,230 @@
+From ef0579b64e93188710d48667cb5e014926af9f1b Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Mon, 10 Apr 2017 17:27:57 +0800
+Subject: crypto: ahash - Fix EINPROGRESS notification callback
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+commit ef0579b64e93188710d48667cb5e014926af9f1b upstream.
+
+The ahash API modifies the request's callback function in order
+to clean up after itself in some corner cases (unaligned final
+and missing finup).
+
+When the request is complete ahash will restore the original
+callback and everything is fine.  However, when the request gets
+an EBUSY on a full queue, an EINPROGRESS callback is made while
+the request is still ongoing.
+
+In this case the ahash API will incorrectly call its own callback.
+
+This patch fixes the problem by creating a temporary request
+object on the stack which is used to relay EINPROGRESS back to
+the original completion function.
+
+This patch also adds code to preserve the original flags value.
+
+Fixes: ab6bf4e5e5e4 ("crypto: hash - Fix the pointer voodoo in...")
+Reported-by: Sabrina Dubroca <sd@queasysnail.net>
+Tested-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/ahash.c                 |   79 +++++++++++++++++++++++++----------------
+ include/crypto/internal/hash.h |   10 +++++
+ 2 files changed, 60 insertions(+), 29 deletions(-)
+
+--- a/crypto/ahash.c
++++ b/crypto/ahash.c
+@@ -31,6 +31,7 @@ struct ahash_request_priv {
+       crypto_completion_t complete;
+       void *data;
+       u8 *result;
++      u32 flags;
+       void *ubuf[] CRYPTO_MINALIGN_ATTR;
+ };
+@@ -252,6 +253,8 @@ static int ahash_save_req(struct ahash_r
+       priv->result = req->result;
+       priv->complete = req->base.complete;
+       priv->data = req->base.data;
++      priv->flags = req->base.flags;
++
+       /*
+        * WARNING: We do not backup req->priv here! The req->priv
+        *          is for internal use of the Crypto API and the
+@@ -266,38 +269,44 @@ static int ahash_save_req(struct ahash_r
+       return 0;
+ }
+-static void ahash_restore_req(struct ahash_request *req)
++static void ahash_restore_req(struct ahash_request *req, int err)
+ {
+       struct ahash_request_priv *priv = req->priv;
++      if (!err)
++              memcpy(priv->result, req->result,
++                     crypto_ahash_digestsize(crypto_ahash_reqtfm(req)));
++
+       /* Restore the original crypto request. */
+       req->result = priv->result;
+-      req->base.complete = priv->complete;
+-      req->base.data = priv->data;
++
++      ahash_request_set_callback(req, priv->flags,
++                                 priv->complete, priv->data);
+       req->priv = NULL;
+       /* Free the req->priv.priv from the ADJUSTED request. */
+       kzfree(priv);
+ }
+-static void ahash_op_unaligned_finish(struct ahash_request *req, int err)
++static void ahash_notify_einprogress(struct ahash_request *req)
+ {
+       struct ahash_request_priv *priv = req->priv;
++      struct crypto_async_request oreq;
+-      if (err == -EINPROGRESS)
+-              return;
+-
+-      if (!err)
+-              memcpy(priv->result, req->result,
+-                     crypto_ahash_digestsize(crypto_ahash_reqtfm(req)));
++      oreq.data = priv->data;
+-      ahash_restore_req(req);
++      priv->complete(&oreq, -EINPROGRESS);
+ }
+ static void ahash_op_unaligned_done(struct crypto_async_request *req, int err)
+ {
+       struct ahash_request *areq = req->data;
++      if (err == -EINPROGRESS) {
++              ahash_notify_einprogress(areq);
++              return;
++      }
++
+       /*
+        * Restore the original request, see ahash_op_unaligned() for what
+        * goes where.
+@@ -308,7 +317,7 @@ static void ahash_op_unaligned_done(stru
+        */
+       /* First copy req->result into req->priv.result */
+-      ahash_op_unaligned_finish(areq, err);
++      ahash_restore_req(areq, err);
+       /* Complete the ORIGINAL request. */
+       areq->base.complete(&areq->base, err);
+@@ -324,7 +333,12 @@ static int ahash_op_unaligned(struct aha
+               return err;
+       err = op(req);
+-      ahash_op_unaligned_finish(req, err);
++      if (err == -EINPROGRESS ||
++          (err == -EBUSY && (ahash_request_flags(req) &
++                             CRYPTO_TFM_REQ_MAY_BACKLOG)))
++              return err;
++
++      ahash_restore_req(req, err);
+       return err;
+ }
+@@ -359,25 +373,14 @@ int crypto_ahash_digest(struct ahash_req
+ }
+ EXPORT_SYMBOL_GPL(crypto_ahash_digest);
+-static void ahash_def_finup_finish2(struct ahash_request *req, int err)
++static void ahash_def_finup_done2(struct crypto_async_request *req, int err)
+ {
+-      struct ahash_request_priv *priv = req->priv;
++      struct ahash_request *areq = req->data;
+       if (err == -EINPROGRESS)
+               return;
+-      if (!err)
+-              memcpy(priv->result, req->result,
+-                     crypto_ahash_digestsize(crypto_ahash_reqtfm(req)));
+-
+-      ahash_restore_req(req);
+-}
+-
+-static void ahash_def_finup_done2(struct crypto_async_request *req, int err)
+-{
+-      struct ahash_request *areq = req->data;
+-
+-      ahash_def_finup_finish2(areq, err);
++      ahash_restore_req(areq, err);
+       areq->base.complete(&areq->base, err);
+ }
+@@ -388,11 +391,15 @@ static int ahash_def_finup_finish1(struc
+               goto out;
+       req->base.complete = ahash_def_finup_done2;
+-      req->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
++
+       err = crypto_ahash_reqtfm(req)->final(req);
++      if (err == -EINPROGRESS ||
++          (err == -EBUSY && (ahash_request_flags(req) &
++                             CRYPTO_TFM_REQ_MAY_BACKLOG)))
++              return err;
+ out:
+-      ahash_def_finup_finish2(req, err);
++      ahash_restore_req(req, err);
+       return err;
+ }
+@@ -400,7 +407,16 @@ static void ahash_def_finup_done1(struct
+ {
+       struct ahash_request *areq = req->data;
++      if (err == -EINPROGRESS) {
++              ahash_notify_einprogress(areq);
++              return;
++      }
++
++      areq->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
++
+       err = ahash_def_finup_finish1(areq, err);
++      if (areq->priv)
++              return;
+       areq->base.complete(&areq->base, err);
+ }
+@@ -415,6 +431,11 @@ static int ahash_def_finup(struct ahash_
+               return err;
+       err = tfm->update(req);
++      if (err == -EINPROGRESS ||
++          (err == -EBUSY && (ahash_request_flags(req) &
++                             CRYPTO_TFM_REQ_MAY_BACKLOG)))
++              return err;
++
+       return ahash_def_finup_finish1(req, err);
+ }
+--- a/include/crypto/internal/hash.h
++++ b/include/crypto/internal/hash.h
+@@ -166,6 +166,16 @@ static inline struct ahash_instance *aha
+       return crypto_alloc_instance2(name, alg, ahash_instance_headroom());
+ }
++static inline void ahash_request_complete(struct ahash_request *req, int err)
++{
++      req->base.complete(&req->base, err);
++}
++
++static inline u32 ahash_request_flags(struct ahash_request *req)
++{
++      return req->base.flags;
++}
++
+ static inline struct crypto_ahash *crypto_spawn_ahash(
+       struct crypto_ahash_spawn *spawn)
+ {
diff --git a/queue-4.9/crypto-algif_aead-fix-bogus-request-dereference-in-completion-function.patch b/queue-4.9/crypto-algif_aead-fix-bogus-request-dereference-in-completion-function.patch
new file mode 100644 (file)
index 0000000..676216f
--- /dev/null
@@ -0,0 +1,66 @@
+From e6534aebb26e32fbab14df9c713c65e8507d17e4 Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Mon, 10 Apr 2017 17:59:07 +0800
+Subject: crypto: algif_aead - Fix bogus request dereference in completion function
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+commit e6534aebb26e32fbab14df9c713c65e8507d17e4 upstream.
+
+The algif_aead completion function tries to deduce the aead_request
+from the crypto_async_request argument.  This is broken because
+the API does not guarantee that the same request will be pased to
+the completion function.  Only the value of req->data can be used
+in the completion function.
+
+This patch fixes it by storing a pointer to sk in areq and using
+that instead of passing in sk through req->data.
+
+Fixes: 83094e5e9e49 ("crypto: af_alg - add async support to...")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/algif_aead.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/crypto/algif_aead.c
++++ b/crypto/algif_aead.c
+@@ -39,6 +39,7 @@ struct aead_async_req {
+       struct aead_async_rsgl first_rsgl;
+       struct list_head list;
+       struct kiocb *iocb;
++      struct sock *sk;
+       unsigned int tsgls;
+       char iv[];
+ };
+@@ -379,12 +380,10 @@ unlock:
+ static void aead_async_cb(struct crypto_async_request *_req, int err)
+ {
+-      struct sock *sk = _req->data;
+-      struct alg_sock *ask = alg_sk(sk);
+-      struct aead_ctx *ctx = ask->private;
+-      struct crypto_aead *tfm = crypto_aead_reqtfm(&ctx->aead_req);
+-      struct aead_request *req = aead_request_cast(_req);
++      struct aead_request *req = _req->data;
++      struct crypto_aead *tfm = crypto_aead_reqtfm(req);
+       struct aead_async_req *areq = GET_ASYM_REQ(req, tfm);
++      struct sock *sk = areq->sk;
+       struct scatterlist *sg = areq->tsgl;
+       struct aead_async_rsgl *rsgl;
+       struct kiocb *iocb = areq->iocb;
+@@ -447,11 +446,12 @@ static int aead_recvmsg_async(struct soc
+       memset(&areq->first_rsgl, '\0', sizeof(areq->first_rsgl));
+       INIT_LIST_HEAD(&areq->list);
+       areq->iocb = msg->msg_iocb;
++      areq->sk = sk;
+       memcpy(areq->iv, ctx->iv, crypto_aead_ivsize(tfm));
+       aead_request_set_tfm(req, tfm);
+       aead_request_set_ad(req, ctx->aead_assoclen);
+       aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+-                                aead_async_cb, sk);
++                                aead_async_cb, req);
+       used -= ctx->aead_assoclen;
+       /* take over all tx sgls from ctx */
diff --git a/queue-4.9/cxusb-use-a-dma-capable-buffer-also-for-reading.patch b/queue-4.9/cxusb-use-a-dma-capable-buffer-also-for-reading.patch
new file mode 100644 (file)
index 0000000..601028b
--- /dev/null
@@ -0,0 +1,64 @@
+From 3f190e3aec212fc8c61e202c51400afa7384d4bc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Stefan=20Br=C3=BCns?= <stefan.bruens@rwth-aachen.de>
+Date: Sun, 5 Feb 2017 12:57:59 -0200
+Subject: [media] cxusb: Use a dma capable buffer also for reading
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Stefan Brüns <stefan.bruens@rwth-aachen.de>
+
+commit 3f190e3aec212fc8c61e202c51400afa7384d4bc upstream.
+
+Commit 17ce039b4e54 ("[media] cxusb: don't do DMA on stack")
+added a kmalloc'ed bounce buffer for writes, but missed to do the same
+for reads. As the read only happens after the write is finished, we can
+reuse the same buffer.
+
+As dvb_usb_generic_rw handles a read length of 0 by itself, avoid calling
+it using the dvb_usb_generic_read wrapper function.
+
+Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Cc: Brad Spengler <spender@grsecurity.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/usb/dvb-usb/cxusb.c |   15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+--- a/drivers/media/usb/dvb-usb/cxusb.c
++++ b/drivers/media/usb/dvb-usb/cxusb.c
+@@ -59,23 +59,24 @@ static int cxusb_ctrl_msg(struct dvb_usb
+                         u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+ {
+       struct cxusb_state *st = d->priv;
+-      int ret, wo;
++      int ret;
+       if (1 + wlen > MAX_XFER_SIZE) {
+               warn("i2c wr: len=%d is too big!\n", wlen);
+               return -EOPNOTSUPP;
+       }
+-      wo = (rbuf == NULL || rlen == 0); /* write-only */
++      if (rlen > MAX_XFER_SIZE) {
++              warn("i2c rd: len=%d is too big!\n", rlen);
++              return -EOPNOTSUPP;
++      }
+       mutex_lock(&d->data_mutex);
+       st->data[0] = cmd;
+       memcpy(&st->data[1], wbuf, wlen);
+-      if (wo)
+-              ret = dvb_usb_generic_write(d, st->data, 1 + wlen);
+-      else
+-              ret = dvb_usb_generic_rw(d, st->data, 1 + wlen,
+-                                       rbuf, rlen, 0);
++      ret = dvb_usb_generic_rw(d, st->data, 1 + wlen, st->data, rlen, 0);
++      if (!ret && rbuf && rlen)
++              memcpy(rbuf, st->data, rlen);
+       mutex_unlock(&d->data_mutex);
+       return ret;
diff --git a/queue-4.9/drm-nouveau-disp-mcp7x-disable-dptmds-workaround.patch b/queue-4.9/drm-nouveau-disp-mcp7x-disable-dptmds-workaround.patch
new file mode 100644 (file)
index 0000000..7efe394
--- /dev/null
@@ -0,0 +1,32 @@
+From 7dfee6827780d4228148263545af936d0cae8930 Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Mon, 9 Jan 2017 10:22:15 +1000
+Subject: drm/nouveau/disp/mcp7x: disable dptmds workaround
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit 7dfee6827780d4228148263545af936d0cae8930 upstream.
+
+The workaround appears to cause regressions on these boards, and from
+inspection of RM traces, NVIDIA don't appear to do it on them either.
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Tested-by: Roy Spliet <nouveau@spliet.org>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
+@@ -433,8 +433,6 @@ nv50_disp_dptmds_war(struct nvkm_device
+       case 0x94:
+       case 0x96:
+       case 0x98:
+-      case 0xaa:
+-      case 0xac:
+               return true;
+       default:
+               break;
diff --git a/queue-4.9/dvb-usb-don-t-use-stack-for-firmware-load.patch b/queue-4.9/dvb-usb-don-t-use-stack-for-firmware-load.patch
new file mode 100644 (file)
index 0000000..15abf75
--- /dev/null
@@ -0,0 +1,136 @@
+From 43fab9793c1f44e665b4f98035a14942edf03ddc Mon Sep 17 00:00:00 2001
+From: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+Date: Tue, 24 Jan 2017 08:13:11 -0200
+Subject: [media] dvb-usb: don't use stack for firmware load
+
+From: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+
+commit 43fab9793c1f44e665b4f98035a14942edf03ddc upstream.
+
+As reported by Marc Duponcheel <marc@offline.be>, firmware load on
+dvb-usb is using the stack, with is not allowed anymore on default
+Kernel configurations:
+
+[ 1025.958836] dvb-usb: found a 'WideView WT-220U PenType Receiver (based on ZL353)' in cold state, will try to load a firmware
+[ 1025.958853] dvb-usb: downloading firmware from file 'dvb-usb-wt220u-zl0353-01.fw'
+[ 1025.958855] dvb-usb: could not stop the USB controller CPU.
+[ 1025.958856] dvb-usb: error while transferring firmware (transferred size: -11, block size: 3)
+[ 1025.958856] dvb-usb: firmware download failed at 8 with -22
+[ 1025.958867] usbcore: registered new interface driver dvb_usb_dtt200u
+
+[    2.789902] dvb-usb: downloading firmware from file 'dvb-usb-wt220u-zl0353-01.fw'
+[    2.789905] ------------[ cut here ]------------
+[    2.789911] WARNING: CPU: 3 PID: 2196 at drivers/usb/core/hcd.c:1584 usb_hcd_map_urb_for_dma+0x430/0x560 [usbcore]
+[    2.789912] transfer buffer not dma capable
+[    2.789912] Modules linked in: btusb dvb_usb_dtt200u(+) dvb_usb_af9035(+) btrtl btbcm dvb_usb dvb_usb_v2 btintel dvb_core bluetooth rc_core rfkill x86_pkg_temp_thermal intel_powerclamp coretemp crc32_pclmul aesni_intel aes_x86_64 glue_helper lrw gf128mul ablk_helper cryptd drm_kms_helper syscopyarea sysfillrect pcspkr i2c_i801 sysimgblt fb_sys_fops drm i2c_smbus i2c_core r8169 lpc_ich mfd_core mii thermal fan rtc_cmos video button acpi_cpufreq processor snd_hda_codec_realtek snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd crc32c_intel ahci libahci libata xhci_pci ehci_pci xhci_hcd ehci_hcd usbcore usb_common dm_mirror dm_region_hash dm_log dm_mod
+[    2.789936] CPU: 3 PID: 2196 Comm: systemd-udevd Not tainted 4.9.0-gentoo #1
+[    2.789937] Hardware name: ASUS All Series/H81I-PLUS, BIOS 0401 07/23/2013
+[    2.789938]  ffffc9000339b690 ffffffff812bd397 ffffc9000339b6e0 0000000000000000
+[    2.789939]  ffffc9000339b6d0 ffffffff81055c86 000006300339b6a0 ffff880116c0c000
+[    2.789941]  0000000000000000 0000000000000000 0000000000000001 ffff880116c08000
+[    2.789942] Call Trace:
+[    2.789945]  [<ffffffff812bd397>] dump_stack+0x4d/0x66
+[    2.789947]  [<ffffffff81055c86>] __warn+0xc6/0xe0
+[    2.789948]  [<ffffffff81055cea>] warn_slowpath_fmt+0x4a/0x50
+[    2.789952]  [<ffffffffa006d460>] usb_hcd_map_urb_for_dma+0x430/0x560 [usbcore]
+[    2.789954]  [<ffffffff814ed5a8>] ? io_schedule_timeout+0xd8/0x110
+[    2.789956]  [<ffffffffa006e09c>] usb_hcd_submit_urb+0x9c/0x980 [usbcore]
+[    2.789958]  [<ffffffff812d0ebf>] ? copy_page_to_iter+0x14f/0x2b0
+[    2.789960]  [<ffffffff81126818>] ? pagecache_get_page+0x28/0x240
+[    2.789962]  [<ffffffff8118c2a0>] ? touch_atime+0x20/0xa0
+[    2.789964]  [<ffffffffa006f7c4>] usb_submit_urb+0x2c4/0x520 [usbcore]
+[    2.789967]  [<ffffffffa006feca>] usb_start_wait_urb+0x5a/0xe0 [usbcore]
+[    2.789969]  [<ffffffffa007000c>] usb_control_msg+0xbc/0xf0 [usbcore]
+[    2.789970]  [<ffffffffa067903d>] usb_cypress_writemem+0x3d/0x40 [dvb_usb]
+[    2.789972]  [<ffffffffa06791cf>] usb_cypress_load_firmware+0x4f/0x130 [dvb_usb]
+[    2.789973]  [<ffffffff8109dbbe>] ? console_unlock+0x2fe/0x5d0
+[    2.789974]  [<ffffffff8109e10c>] ? vprintk_emit+0x27c/0x410
+[    2.789975]  [<ffffffff8109e40a>] ? vprintk_default+0x1a/0x20
+[    2.789976]  [<ffffffff81124d76>] ? printk+0x43/0x4b
+[    2.789977]  [<ffffffffa0679310>] dvb_usb_download_firmware+0x60/0xd0 [dvb_usb]
+[    2.789979]  [<ffffffffa0679898>] dvb_usb_device_init+0x3d8/0x610 [dvb_usb]
+[    2.789981]  [<ffffffffa069e302>] dtt200u_usb_probe+0x92/0xd0 [dvb_usb_dtt200u]
+[    2.789984]  [<ffffffffa007420c>] usb_probe_interface+0xfc/0x270 [usbcore]
+[    2.789985]  [<ffffffff8138bf95>] driver_probe_device+0x215/0x2d0
+[    2.789986]  [<ffffffff8138c0e6>] __driver_attach+0x96/0xa0
+[    2.789987]  [<ffffffff8138c050>] ? driver_probe_device+0x2d0/0x2d0
+[    2.789988]  [<ffffffff81389ffb>] bus_for_each_dev+0x5b/0x90
+[    2.789989]  [<ffffffff8138b7b9>] driver_attach+0x19/0x20
+[    2.789990]  [<ffffffff8138b33c>] bus_add_driver+0x11c/0x220
+[    2.789991]  [<ffffffff8138c91b>] driver_register+0x5b/0xd0
+[    2.789994]  [<ffffffffa0072f6c>] usb_register_driver+0x7c/0x130 [usbcore]
+[    2.789994]  [<ffffffffa06a5000>] ? 0xffffffffa06a5000
+[    2.789996]  [<ffffffffa06a501e>] dtt200u_usb_driver_init+0x1e/0x20 [dvb_usb_dtt200u]
+[    2.789997]  [<ffffffff81000408>] do_one_initcall+0x38/0x140
+[    2.789998]  [<ffffffff8116001c>] ? __vunmap+0x7c/0xc0
+[    2.789999]  [<ffffffff81124fb0>] ? do_init_module+0x22/0x1d2
+[    2.790000]  [<ffffffff81124fe8>] do_init_module+0x5a/0x1d2
+[    2.790002]  [<ffffffff810c96b1>] load_module+0x1e11/0x2580
+[    2.790003]  [<ffffffff810c68b0>] ? show_taint+0x30/0x30
+[    2.790004]  [<ffffffff81177250>] ? kernel_read_file+0x100/0x190
+[    2.790005]  [<ffffffff810c9ffa>] SyS_finit_module+0xba/0xc0
+[    2.790007]  [<ffffffff814f13e0>] entry_SYSCALL_64_fastpath+0x13/0x94
+[    2.790008] ---[ end trace c78a74e78baec6fc ]---
+
+So, allocate the structure dynamically.
+
+Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+[bwh: Backported to 4.9: adjust context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/media/usb/dvb-usb/dvb-usb-firmware.c |   19 +++++++++++++------
+ 1 file changed, 13 insertions(+), 6 deletions(-)
+
+--- a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
++++ b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
+@@ -35,29 +35,34 @@ static int usb_cypress_writemem(struct u
+ int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type)
+ {
+-      struct hexline hx;
++      struct hexline *hx;
+       u8 reset;
+       int ret,pos=0;
++      hx = kmalloc(sizeof(*hx), GFP_KERNEL);
++      if (!hx)
++              return -ENOMEM;
++
+       /* stop the CPU */
+       reset = 1;
+       if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
+               err("could not stop the USB controller CPU.");
+-      while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) {
+-              deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk);
+-              ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len);
++      while ((ret = dvb_usb_get_hexline(fw, hx, &pos)) > 0) {
++              deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n", hx->addr, hx->len, hx->chk);
++              ret = usb_cypress_writemem(udev, hx->addr, hx->data, hx->len);
+-              if (ret != hx.len) {
++              if (ret != hx->len) {
+                       err("error while transferring firmware "
+                               "(transferred size: %d, block size: %d)",
+-                              ret,hx.len);
++                              ret, hx->len);
+                       ret = -EINVAL;
+                       break;
+               }
+       }
+       if (ret < 0) {
+               err("firmware download failed at %d with %d",pos,ret);
++              kfree(hx);
+               return ret;
+       }
+@@ -71,6 +76,8 @@ int usb_cypress_load_firmware(struct usb
+       } else
+               ret = -EIO;
++      kfree(hx);
++
+       return ret;
+ }
+ EXPORT_SYMBOL(usb_cypress_load_firmware);
diff --git a/queue-4.9/dvb-usb-firmware-don-t-do-dma-on-stack.patch b/queue-4.9/dvb-usb-firmware-don-t-do-dma-on-stack.patch
new file mode 100644 (file)
index 0000000..f9ed480
--- /dev/null
@@ -0,0 +1,80 @@
+From 67b0503db9c29b04eadfeede6bebbfe5ddad94ef Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Stefan=20Br=C3=BCns?= <stefan.bruens@rwth-aachen.de>
+Date: Sun, 12 Feb 2017 13:02:13 -0200
+Subject: [media] dvb-usb-firmware: don't do DMA on stack
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Stefan Brüns <stefan.bruens@rwth-aachen.de>
+
+commit 67b0503db9c29b04eadfeede6bebbfe5ddad94ef upstream.
+
+The buffer allocation for the firmware data was changed in
+commit 43fab9793c1f ("[media] dvb-usb: don't use stack for firmware load")
+but the same applies for the reset value.
+
+Fixes: 43fab9793c1f ("[media] dvb-usb: don't use stack for firmware load")
+Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Cc: Brad Spengler <spender@grsecurity.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/usb/dvb-usb/dvb-usb-firmware.c |   22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+--- a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
++++ b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
+@@ -36,16 +36,18 @@ static int usb_cypress_writemem(struct u
+ int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type)
+ {
+       struct hexline *hx;
+-      u8 reset;
+-      int ret,pos=0;
++      u8 *buf;
++      int ret, pos = 0;
++      u16 cpu_cs_register = cypress[type].cpu_cs_register;
+-      hx = kmalloc(sizeof(*hx), GFP_KERNEL);
+-      if (!hx)
++      buf = kmalloc(sizeof(*hx), GFP_KERNEL);
++      if (!buf)
+               return -ENOMEM;
++      hx = (struct hexline *)buf;
+       /* stop the CPU */
+-      reset = 1;
+-      if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
++      buf[0] = 1;
++      if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1)
+               err("could not stop the USB controller CPU.");
+       while ((ret = dvb_usb_get_hexline(fw, hx, &pos)) > 0) {
+@@ -62,21 +64,21 @@ int usb_cypress_load_firmware(struct usb
+       }
+       if (ret < 0) {
+               err("firmware download failed at %d with %d",pos,ret);
+-              kfree(hx);
++              kfree(buf);
+               return ret;
+       }
+       if (ret == 0) {
+               /* restart the CPU */
+-              reset = 0;
+-              if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) {
++              buf[0] = 0;
++              if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1) {
+                       err("could not restart the USB controller CPU.");
+                       ret = -EINVAL;
+               }
+       } else
+               ret = -EIO;
+-      kfree(hx);
++      kfree(buf);
+       return ret;
+ }
diff --git a/queue-4.9/dvb-usb-v2-avoid-use-after-free.patch b/queue-4.9/dvb-usb-v2-avoid-use-after-free.patch
new file mode 100644 (file)
index 0000000..d600bce
--- /dev/null
@@ -0,0 +1,59 @@
+From 005145378c9ad7575a01b6ce1ba118fb427f583a Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Thu, 2 Feb 2017 12:36:01 -0200
+Subject: [media] dvb-usb-v2: avoid use-after-free
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit 005145378c9ad7575a01b6ce1ba118fb427f583a upstream.
+
+I ran into a stack frame size warning because of the on-stack copy of
+the USB device structure:
+
+drivers/media/usb/dvb-usb-v2/dvb_usb_core.c: In function 'dvb_usbv2_disconnect':
+drivers/media/usb/dvb-usb-v2/dvb_usb_core.c:1029:1: error: the frame size of 1104 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
+
+Copying a device structure like this is wrong for a number of other reasons
+too aside from the possible stack overflow. One of them is that the
+dev_info() call will print the name of the device later, but AFAICT
+we have only copied a pointer to the name earlier and the actual name
+has been freed by the time it gets printed.
+
+This removes the on-stack copy of the device and instead copies the
+device name using kstrdup(). I'm ignoring the possible failure here
+as both printk() and kfree() are able to deal with NULL pointers.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/usb/dvb-usb-v2/dvb_usb_core.c |    9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
++++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
+@@ -1013,8 +1013,8 @@ EXPORT_SYMBOL(dvb_usbv2_probe);
+ void dvb_usbv2_disconnect(struct usb_interface *intf)
+ {
+       struct dvb_usb_device *d = usb_get_intfdata(intf);
+-      const char *name = d->name;
+-      struct device dev = d->udev->dev;
++      const char *devname = kstrdup(dev_name(&d->udev->dev), GFP_KERNEL);
++      const char *drvname = d->name;
+       dev_dbg(&d->udev->dev, "%s: bInterfaceNumber=%d\n", __func__,
+                       intf->cur_altsetting->desc.bInterfaceNumber);
+@@ -1024,8 +1024,9 @@ void dvb_usbv2_disconnect(struct usb_int
+       dvb_usbv2_exit(d);
+-      dev_info(&dev, "%s: '%s' successfully deinitialized and disconnected\n",
+-                      KBUILD_MODNAME, name);
++      pr_info("%s: '%s:%s' successfully deinitialized and disconnected\n",
++              KBUILD_MODNAME, drvname, devname);
++      kfree(devname);
+ }
+ EXPORT_SYMBOL(dvb_usbv2_disconnect);
diff --git a/queue-4.9/ext4-fix-inode-checksum-calculation-problem-if-i_extra_size-is-small.patch b/queue-4.9/ext4-fix-inode-checksum-calculation-problem-if-i_extra_size-is-small.patch
new file mode 100644 (file)
index 0000000..76e40ea
--- /dev/null
@@ -0,0 +1,42 @@
+From 05ac5aa18abd7db341e54df4ae2b4c98ea0e43b7 Mon Sep 17 00:00:00 2001
+From: Daeho Jeong <daeho.jeong@samsung.com>
+Date: Thu, 1 Dec 2016 11:49:12 -0500
+Subject: ext4: fix inode checksum calculation problem if i_extra_size is small
+
+From: Daeho Jeong <daeho.jeong@samsung.com>
+
+commit 05ac5aa18abd7db341e54df4ae2b4c98ea0e43b7 upstream.
+
+We've fixed the race condition problem in calculating ext4 checksum
+value in commit b47820edd163 ("ext4: avoid modifying checksum fields
+directly during checksum veficationon"). However, by this change,
+when calculating the checksum value of inode whose i_extra_size is
+less than 4, we couldn't calculate the checksum value in a proper way.
+This problem was found and reported by Nix, Thank you.
+
+Reported-by: Nix <nix@esperi.org.uk>
+Signed-off-by: Daeho Jeong <daeho.jeong@samsung.com>
+Signed-off-by: Youngjin Gil <youngjin.gil@samsung.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/inode.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -71,10 +71,9 @@ static __u32 ext4_inode_csum(struct inod
+                       csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum,
+                                          csum_size);
+                       offset += csum_size;
+-                      csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset,
+-                                         EXT4_INODE_SIZE(inode->i_sb) -
+-                                         offset);
+               }
++              csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset,
++                                 EXT4_INODE_SIZE(inode->i_sb) - offset);
+       }
+       return csum;
diff --git a/queue-4.9/ftrace-fix-function-pid-filter-on-instances.patch b/queue-4.9/ftrace-fix-function-pid-filter-on-instances.patch
new file mode 100644 (file)
index 0000000..ce23b54
--- /dev/null
@@ -0,0 +1,103 @@
+From d879d0b8c183aabeb9a65eba91f3f9e3c7e7b905 Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung@kernel.org>
+Date: Mon, 17 Apr 2017 11:44:27 +0900
+Subject: ftrace: Fix function pid filter on instances
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+commit d879d0b8c183aabeb9a65eba91f3f9e3c7e7b905 upstream.
+
+When function tracer has a pid filter, it adds a probe to sched_switch
+to track if current task can be ignored.  The probe checks the
+ftrace_ignore_pid from current tr to filter tasks.  But it misses to
+delete the probe when removing an instance so that it can cause a crash
+due to the invalid tr pointer (use-after-free).
+
+This is easily reproducible with the following:
+
+  # cd /sys/kernel/debug/tracing
+  # mkdir instances/buggy
+  # echo $$ > instances/buggy/set_ftrace_pid
+  # rmdir instances/buggy
+
+  ============================================================================
+  BUG: KASAN: use-after-free in ftrace_filter_pid_sched_switch_probe+0x3d/0x90
+  Read of size 8 by task kworker/0:1/17
+  CPU: 0 PID: 17 Comm: kworker/0:1 Tainted: G    B           4.11.0-rc3  #198
+  Call Trace:
+   dump_stack+0x68/0x9f
+   kasan_object_err+0x21/0x70
+   kasan_report.part.1+0x22b/0x500
+   ? ftrace_filter_pid_sched_switch_probe+0x3d/0x90
+   kasan_report+0x25/0x30
+   __asan_load8+0x5e/0x70
+   ftrace_filter_pid_sched_switch_probe+0x3d/0x90
+   ? fpid_start+0x130/0x130
+   __schedule+0x571/0xce0
+   ...
+
+To fix it, use ftrace_clear_pids() to unregister the probe.  As
+instance_rmdir() already updated ftrace codes, it can just free the
+filter safely.
+
+Link: http://lkml.kernel.org/r/20170417024430.21194-2-namhyung@kernel.org
+
+Fixes: 0c8916c34203 ("tracing: Add rmdir to remove multibuffer instances")
+Cc: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/trace/ftrace.c |    9 +++++++++
+ kernel/trace/trace.c  |    1 +
+ kernel/trace/trace.h  |    2 ++
+ 3 files changed, 12 insertions(+)
+
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -5401,6 +5401,15 @@ static void clear_ftrace_pids(struct tra
+       trace_free_pid_list(pid_list);
+ }
++void ftrace_clear_pids(struct trace_array *tr)
++{
++      mutex_lock(&ftrace_lock);
++
++      clear_ftrace_pids(tr);
++
++      mutex_unlock(&ftrace_lock);
++}
++
+ static void ftrace_pid_reset(struct trace_array *tr)
+ {
+       mutex_lock(&ftrace_lock);
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -7150,6 +7150,7 @@ static int instance_rmdir(const char *na
+       tracing_set_nop(tr);
+       event_trace_del_tracer(tr);
++      ftrace_clear_pids(tr);
+       ftrace_destroy_function_files(tr);
+       tracefs_remove_recursive(tr->dir);
+       free_trace_buffers(tr);
+--- a/kernel/trace/trace.h
++++ b/kernel/trace/trace.h
+@@ -870,6 +870,7 @@ int using_ftrace_ops_list_func(void);
+ void ftrace_init_tracefs(struct trace_array *tr, struct dentry *d_tracer);
+ void ftrace_init_tracefs_toplevel(struct trace_array *tr,
+                                 struct dentry *d_tracer);
++void ftrace_clear_pids(struct trace_array *tr);
+ #else
+ static inline int ftrace_trace_task(struct trace_array *tr)
+ {
+@@ -888,6 +889,7 @@ ftrace_init_global_array_ops(struct trac
+ static inline void ftrace_reset_array_ops(struct trace_array *tr) { }
+ static inline void ftrace_init_tracefs(struct trace_array *tr, struct dentry *d) { }
+ static inline void ftrace_init_tracefs_toplevel(struct trace_array *tr, struct dentry *d) { }
++static inline void ftrace_clear_pids(struct trace_array *tr) { }
+ /* ftace_func_t type is not defined, use macro instead of static inline */
+ #define ftrace_init_array_ops(tr, func) do { } while (0)
+ #endif /* CONFIG_FUNCTION_TRACER */
diff --git a/queue-4.9/mm-memcontrol-use-special-workqueue-for-creating-per-memcg-caches.patch b/queue-4.9/mm-memcontrol-use-special-workqueue-for-creating-per-memcg-caches.patch
new file mode 100644 (file)
index 0000000..213793d
--- /dev/null
@@ -0,0 +1,84 @@
+From 13583c3d3224508582ec03d881d0b68dd3ee8e10 Mon Sep 17 00:00:00 2001
+From: Vladimir Davydov <vdavydov.dev@gmail.com>
+Date: Mon, 12 Dec 2016 16:41:29 -0800
+Subject: mm: memcontrol: use special workqueue for creating per-memcg caches
+
+From: Vladimir Davydov <vdavydov.dev@gmail.com>
+
+commit 13583c3d3224508582ec03d881d0b68dd3ee8e10 upstream.
+
+Creating a lot of cgroups at the same time might stall all worker
+threads with kmem cache creation works, because kmem cache creation is
+done with the slab_mutex held.  The problem was amplified by commits
+801faf0db894 ("mm/slab: lockless decision to grow cache") in case of
+SLAB and 81ae6d03952c ("mm/slub.c: replace kick_all_cpus_sync() with
+synchronize_sched() in kmem_cache_shrink()") in case of SLUB, which
+increased the maximal time the slab_mutex can be held.
+
+To prevent that from happening, let's use a special ordered single
+threaded workqueue for kmem cache creation.  This shouldn't introduce
+any functional changes regarding how kmem caches are created, as the
+work function holds the global slab_mutex during its whole runtime
+anyway, making it impossible to run more than one work at a time.  By
+using a single threaded workqueue, we just avoid creating a thread per
+each work.  Ordering is required to avoid a situation when a cgroup's
+work is put off indefinitely because there are other cgroups to serve,
+in other words to guarantee fairness.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=172981
+Link: http://lkml.kernel.org/r/20161004131417.GC1862@esperanza
+Signed-off-by: Vladimir Davydov <vdavydov.dev@gmail.com>
+Reported-by: Doug Smythies <dsmythies@telus.net>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Christoph Lameter <cl@linux.com>
+Cc: David Rientjes <rientjes@google.com>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
+Cc: Pekka Enberg <penberg@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/memcontrol.c |   15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -2152,6 +2152,8 @@ struct memcg_kmem_cache_create_work {
+       struct work_struct work;
+ };
++static struct workqueue_struct *memcg_kmem_cache_create_wq;
++
+ static void memcg_kmem_cache_create_func(struct work_struct *w)
+ {
+       struct memcg_kmem_cache_create_work *cw =
+@@ -2183,7 +2185,7 @@ static void __memcg_schedule_kmem_cache_
+       cw->cachep = cachep;
+       INIT_WORK(&cw->work, memcg_kmem_cache_create_func);
+-      schedule_work(&cw->work);
++      queue_work(memcg_kmem_cache_create_wq, &cw->work);
+ }
+ static void memcg_schedule_kmem_cache_create(struct mem_cgroup *memcg,
+@@ -5786,6 +5788,17 @@ static int __init mem_cgroup_init(void)
+ {
+       int cpu, node;
++#ifndef CONFIG_SLOB
++      /*
++       * Kmem cache creation is mostly done with the slab_mutex held,
++       * so use a special workqueue to avoid stalling all worker
++       * threads in case lots of cgroups are created simultaneously.
++       */
++      memcg_kmem_cache_create_wq =
++              alloc_ordered_workqueue("memcg_kmem_cache_create", 0);
++      BUG_ON(!memcg_kmem_cache_create_wq);
++#endif
++
+       hotcpu_notifier(memcg_cpu_hotplug_callback, 0);
+       for_each_possible_cpu(cpu)
diff --git a/queue-4.9/mm-tighten-x86-dev-mem-with-zeroing-reads.patch b/queue-4.9/mm-tighten-x86-dev-mem-with-zeroing-reads.patch
new file mode 100644 (file)
index 0000000..59d1413
--- /dev/null
@@ -0,0 +1,210 @@
+From a4866aa812518ed1a37d8ea0c881dc946409de94 Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook@chromium.org>
+Date: Wed, 5 Apr 2017 09:39:08 -0700
+Subject: mm: Tighten x86 /dev/mem with zeroing reads
+
+From: Kees Cook <keescook@chromium.org>
+
+commit a4866aa812518ed1a37d8ea0c881dc946409de94 upstream.
+
+Under CONFIG_STRICT_DEVMEM, reading System RAM through /dev/mem is
+disallowed. However, on x86, the first 1MB was always allowed for BIOS
+and similar things, regardless of it actually being System RAM. It was
+possible for heap to end up getting allocated in low 1MB RAM, and then
+read by things like x86info or dd, which would trip hardened usercopy:
+
+usercopy: kernel memory exposure attempt detected from ffff880000090000 (dma-kmalloc-256) (4096 bytes)
+
+This changes the x86 exception for the low 1MB by reading back zeros for
+System RAM areas instead of blindly allowing them. More work is needed to
+extend this to mmap, but currently mmap doesn't go through usercopy, so
+hardened usercopy won't Oops the kernel.
+
+Reported-by: Tommi Rantala <tommi.t.rantala@nokia.com>
+Tested-by: Tommi Rantala <tommi.t.rantala@nokia.com>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Cc: Brad Spengler <spender@grsecurity.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/mm/init.c |   41 +++++++++++++++++++-------
+ drivers/char/mem.c |   82 +++++++++++++++++++++++++++++++++--------------------
+ 2 files changed, 82 insertions(+), 41 deletions(-)
+
+--- a/arch/x86/mm/init.c
++++ b/arch/x86/mm/init.c
+@@ -643,21 +643,40 @@ void __init init_mem_mapping(void)
+  * devmem_is_allowed() checks to see if /dev/mem access to a certain address
+  * is valid. The argument is a physical page number.
+  *
+- *
+- * On x86, access has to be given to the first megabyte of ram because that area
+- * contains BIOS code and data regions used by X and dosemu and similar apps.
+- * Access has to be given to non-kernel-ram areas as well, these contain the PCI
+- * mmio resources as well as potential bios/acpi data regions.
++ * On x86, access has to be given to the first megabyte of RAM because that
++ * area traditionally contains BIOS code and data regions used by X, dosemu,
++ * and similar apps. Since they map the entire memory range, the whole range
++ * must be allowed (for mapping), but any areas that would otherwise be
++ * disallowed are flagged as being "zero filled" instead of rejected.
++ * Access has to be given to non-kernel-ram areas as well, these contain the
++ * PCI mmio resources as well as potential bios/acpi data regions.
+  */
+ int devmem_is_allowed(unsigned long pagenr)
+ {
+-      if (pagenr < 256)
+-              return 1;
+-      if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
++      if (page_is_ram(pagenr)) {
++              /*
++               * For disallowed memory regions in the low 1MB range,
++               * request that the page be shown as all zeros.
++               */
++              if (pagenr < 256)
++                      return 2;
++
++              return 0;
++      }
++
++      /*
++       * This must follow RAM test, since System RAM is considered a
++       * restricted resource under CONFIG_STRICT_IOMEM.
++       */
++      if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) {
++              /* Low 1MB bypasses iomem restrictions. */
++              if (pagenr < 256)
++                      return 1;
++
+               return 0;
+-      if (!page_is_ram(pagenr))
+-              return 1;
+-      return 0;
++      }
++
++      return 1;
+ }
+ void free_init_pages(char *what, unsigned long begin, unsigned long end)
+--- a/drivers/char/mem.c
++++ b/drivers/char/mem.c
+@@ -60,6 +60,10 @@ static inline int valid_mmap_phys_addr_r
+ #endif
+ #ifdef CONFIG_STRICT_DEVMEM
++static inline int page_is_allowed(unsigned long pfn)
++{
++      return devmem_is_allowed(pfn);
++}
+ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
+ {
+       u64 from = ((u64)pfn) << PAGE_SHIFT;
+@@ -75,6 +79,10 @@ static inline int range_is_allowed(unsig
+       return 1;
+ }
+ #else
++static inline int page_is_allowed(unsigned long pfn)
++{
++      return 1;
++}
+ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
+ {
+       return 1;
+@@ -122,23 +130,31 @@ static ssize_t read_mem(struct file *fil
+       while (count > 0) {
+               unsigned long remaining;
++              int allowed;
+               sz = size_inside_page(p, count);
+-              if (!range_is_allowed(p >> PAGE_SHIFT, count))
++              allowed = page_is_allowed(p >> PAGE_SHIFT);
++              if (!allowed)
+                       return -EPERM;
++              if (allowed == 2) {
++                      /* Show zeros for restricted memory. */
++                      remaining = clear_user(buf, sz);
++              } else {
++                      /*
++                       * On ia64 if a page has been mapped somewhere as
++                       * uncached, then it must also be accessed uncached
++                       * by the kernel or data corruption may occur.
++                       */
++                      ptr = xlate_dev_mem_ptr(p);
++                      if (!ptr)
++                              return -EFAULT;
+-              /*
+-               * On ia64 if a page has been mapped somewhere as uncached, then
+-               * it must also be accessed uncached by the kernel or data
+-               * corruption may occur.
+-               */
+-              ptr = xlate_dev_mem_ptr(p);
+-              if (!ptr)
+-                      return -EFAULT;
++                      remaining = copy_to_user(buf, ptr, sz);
++
++                      unxlate_dev_mem_ptr(p, ptr);
++              }
+-              remaining = copy_to_user(buf, ptr, sz);
+-              unxlate_dev_mem_ptr(p, ptr);
+               if (remaining)
+                       return -EFAULT;
+@@ -181,30 +197,36 @@ static ssize_t write_mem(struct file *fi
+ #endif
+       while (count > 0) {
++              int allowed;
++
+               sz = size_inside_page(p, count);
+-              if (!range_is_allowed(p >> PAGE_SHIFT, sz))
++              allowed = page_is_allowed(p >> PAGE_SHIFT);
++              if (!allowed)
+                       return -EPERM;
+-              /*
+-               * On ia64 if a page has been mapped somewhere as uncached, then
+-               * it must also be accessed uncached by the kernel or data
+-               * corruption may occur.
+-               */
+-              ptr = xlate_dev_mem_ptr(p);
+-              if (!ptr) {
+-                      if (written)
+-                              break;
+-                      return -EFAULT;
+-              }
++              /* Skip actual writing when a page is marked as restricted. */
++              if (allowed == 1) {
++                      /*
++                       * On ia64 if a page has been mapped somewhere as
++                       * uncached, then it must also be accessed uncached
++                       * by the kernel or data corruption may occur.
++                       */
++                      ptr = xlate_dev_mem_ptr(p);
++                      if (!ptr) {
++                              if (written)
++                                      break;
++                              return -EFAULT;
++                      }
+-              copied = copy_from_user(ptr, buf, sz);
+-              unxlate_dev_mem_ptr(p, ptr);
+-              if (copied) {
+-                      written += sz - copied;
+-                      if (written)
+-                              break;
+-                      return -EFAULT;
++                      copied = copy_from_user(ptr, buf, sz);
++                      unxlate_dev_mem_ptr(p, ptr);
++                      if (copied) {
++                              written += sz - copied;
++                              if (written)
++                                      break;
++                              return -EFAULT;
++                      }
+               }
+               buf += sz;
diff --git a/queue-4.9/nbd-fix-64-bit-division.patch b/queue-4.9/nbd-fix-64-bit-division.patch
new file mode 100644 (file)
index 0000000..5a270d0
--- /dev/null
@@ -0,0 +1,38 @@
+From e88f72cb9f54f6d244e55f629fe5e2f34ca6f9ed Mon Sep 17 00:00:00 2001
+From: Jens Axboe <axboe@fb.com>
+Date: Sat, 3 Dec 2016 12:08:03 -0700
+Subject: nbd: fix 64-bit division
+
+From: Jens Axboe <axboe@fb.com>
+
+commit e88f72cb9f54f6d244e55f629fe5e2f34ca6f9ed upstream.
+
+We have this:
+
+ERROR: "__aeabi_ldivmod" [drivers/block/nbd.ko] undefined!
+ERROR: "__divdi3" [drivers/block/nbd.ko] undefined!
+nbd.c:(.text+0x247c72): undefined reference to `__divdi3'
+
+due to a recent commit, that did 64-bit division. Use the proper
+divider function so that 32-bit compiles don't break.
+
+Fixes: ef77b515243b ("nbd: use loff_t for blocksize and nbd_set_size args")
+Signed-off-by: Jens Axboe <axboe@fb.com>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/nbd.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -648,7 +648,7 @@ static int __nbd_ioctl(struct block_devi
+       case NBD_SET_SIZE:
+               return nbd_size_set(nbd, bdev, nbd->blksize,
+-                                  arg / nbd->blksize);
++                                      div_s64(arg, nbd->blksize));
+       case NBD_SET_SIZE_BLOCKS:
+               return nbd_size_set(nbd, bdev, nbd->blksize, arg);
diff --git a/queue-4.9/nbd-use-loff_t-for-blocksize-and-nbd_set_size-args.patch b/queue-4.9/nbd-use-loff_t-for-blocksize-and-nbd_set_size-args.patch
new file mode 100644 (file)
index 0000000..ac2aeb0
--- /dev/null
@@ -0,0 +1,61 @@
+From ef77b515243b3499d62cf446eda6ca7e0a0b079c Mon Sep 17 00:00:00 2001
+From: Josef Bacik <jbacik@fb.com>
+Date: Fri, 2 Dec 2016 16:19:12 -0500
+Subject: nbd: use loff_t for blocksize and nbd_set_size args
+
+From: Josef Bacik <jbacik@fb.com>
+
+commit ef77b515243b3499d62cf446eda6ca7e0a0b079c upstream.
+
+If we have large devices (say like the 40t drive I was trying to test with) we
+will end up overflowing the int arguments to nbd_set_size and not get the right
+size for our device.  Fix this by using loff_t everywhere so I don't have to
+think about this again.  Thanks,
+
+Signed-off-by: Josef Bacik <jbacik@fb.com>
+Signed-off-by: Jens Axboe <axboe@fb.com>
+[bwh: Backported to 4.9: adjust context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/block/nbd.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -54,7 +54,7 @@ struct nbd_device {
+       struct mutex tx_lock;
+       struct gendisk *disk;
+-      int blksize;
++      loff_t blksize;
+       loff_t bytesize;
+       /* protects initialization and shutdown of the socket */
+@@ -126,7 +126,7 @@ static void nbd_size_update(struct nbd_d
+ }
+ static int nbd_size_set(struct nbd_device *nbd, struct block_device *bdev,
+-                      int blocksize, int nr_blocks)
++                      loff_t blocksize, loff_t nr_blocks)
+ {
+       int ret;
+@@ -135,7 +135,7 @@ static int nbd_size_set(struct nbd_devic
+               return ret;
+       nbd->blksize = blocksize;
+-      nbd->bytesize = (loff_t)blocksize * (loff_t)nr_blocks;
++      nbd->bytesize = blocksize * nr_blocks;
+       nbd_size_update(nbd, bdev);
+@@ -817,7 +817,7 @@ static int nbd_dev_dbg_init(struct nbd_d
+       debugfs_create_file("tasks", 0444, dir, nbd, &nbd_dbg_tasks_ops);
+       debugfs_create_u64("size_bytes", 0444, dir, &nbd->bytesize);
+       debugfs_create_u32("timeout", 0444, dir, &nbd->tag_set.timeout);
+-      debugfs_create_u32("blocksize", 0444, dir, &nbd->blksize);
++      debugfs_create_u64("blocksize", 0444, dir, &nbd->blksize);
+       debugfs_create_file("flags", 0444, dir, nbd, &nbd_dbg_flags_ops);
+       return 0;
diff --git a/queue-4.9/parisc-fix-get_user-for-64-bit-value-on-32-bit-kernel.patch b/queue-4.9/parisc-fix-get_user-for-64-bit-value-on-32-bit-kernel.patch
new file mode 100644 (file)
index 0000000..3130467
--- /dev/null
@@ -0,0 +1,153 @@
+From 3f795cef0ecdf9bc980dd058d49bdab4b19af1d3 Mon Sep 17 00:00:00 2001
+From: Helge Deller <deller@gmx.de>
+Date: Sun, 16 Apr 2017 10:00:14 +0200
+Subject: parisc: Fix get_user() for 64-bit value on 32-bit kernel
+
+From: Helge Deller <deller@gmx.de>
+
+commit 3f795cef0ecdf9bc980dd058d49bdab4b19af1d3 upstream.
+
+This fixes a bug in which the upper 32-bits of a 64-bit value which is
+read by get_user() was lost on a 32-bit kernel.
+While touching this code, split out pre-loading of %sr2 space register
+and clean up code indent.
+
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/parisc/include/asm/uaccess.h |   86 ++++++++++++++++++++++++--------------
+ 1 file changed, 55 insertions(+), 31 deletions(-)
+
+--- a/arch/parisc/include/asm/uaccess.h
++++ b/arch/parisc/include/asm/uaccess.h
+@@ -42,10 +42,10 @@ static inline long access_ok(int type, c
+ #define get_user __get_user
+ #if !defined(CONFIG_64BIT)
+-#define LDD_USER(ptr)         __get_user_asm64(ptr)
++#define LDD_USER(val, ptr)    __get_user_asm64(val, ptr)
+ #define STD_USER(x, ptr)      __put_user_asm64(x, ptr)
+ #else
+-#define LDD_USER(ptr)         __get_user_asm("ldd", ptr)
++#define LDD_USER(val, ptr)    __get_user_asm(val, "ldd", ptr)
+ #define STD_USER(x, ptr)      __put_user_asm("std", x, ptr)
+ #endif
+@@ -100,63 +100,87 @@ struct exception_data {
+               " mtsp %0,%%sr2\n\t"            \
+               : : "r"(get_fs()) : )
+-#define __get_user(x, ptr)                               \
+-({                                                       \
+-      register long __gu_err __asm__ ("r8") = 0;       \
+-      register long __gu_val;                          \
+-                                                       \
+-      load_sr2();                                      \
+-      switch (sizeof(*(ptr))) {                        \
+-          case 1: __get_user_asm("ldb", ptr); break;   \
+-          case 2: __get_user_asm("ldh", ptr); break;   \
+-          case 4: __get_user_asm("ldw", ptr); break;   \
+-          case 8: LDD_USER(ptr);  break;               \
+-          default: BUILD_BUG(); break;                 \
+-      }                                                \
+-                                                       \
+-      (x) = (__force __typeof__(*(ptr))) __gu_val;     \
+-      __gu_err;                                        \
++#define __get_user_internal(val, ptr)                 \
++({                                                    \
++      register long __gu_err __asm__ ("r8") = 0;      \
++                                                      \
++      switch (sizeof(*(ptr))) {                       \
++      case 1: __get_user_asm(val, "ldb", ptr); break; \
++      case 2: __get_user_asm(val, "ldh", ptr); break; \
++      case 4: __get_user_asm(val, "ldw", ptr); break; \
++      case 8: LDD_USER(val, ptr); break;              \
++      default: BUILD_BUG();                           \
++      }                                               \
++                                                      \
++      __gu_err;                                       \
+ })
+-#define __get_user_asm(ldx, ptr)                        \
++#define __get_user(val, ptr)                          \
++({                                                    \
++      load_sr2();                                     \
++      __get_user_internal(val, ptr);                  \
++})
++
++#define __get_user_asm(val, ldx, ptr)                 \
++{                                                     \
++      register long __gu_val;                         \
++                                                      \
+       __asm__("1: " ldx " 0(%%sr2,%2),%0\n"           \
+               "9:\n"                                  \
+               ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
+               : "=r"(__gu_val), "=r"(__gu_err)        \
+-              : "r"(ptr), "1"(__gu_err));
++              : "r"(ptr), "1"(__gu_err));             \
++                                                      \
++      (val) = (__force __typeof__(*(ptr))) __gu_val;  \
++}
+ #if !defined(CONFIG_64BIT)
+-#define __get_user_asm64(ptr)                                 \
++#define __get_user_asm64(val, ptr)                    \
++{                                                     \
++      union {                                         \
++              unsigned long long      l;              \
++              __typeof__(*(ptr))      t;              \
++      } __gu_tmp;                                     \
++                                                      \
+       __asm__("   copy %%r0,%R0\n"                    \
+               "1: ldw 0(%%sr2,%2),%0\n"               \
+               "2: ldw 4(%%sr2,%2),%R0\n"              \
+               "9:\n"                                  \
+               ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
+               ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \
+-              : "=r"(__gu_val), "=r"(__gu_err)        \
+-              : "r"(ptr), "1"(__gu_err));
++              : "=&r"(__gu_tmp.l), "=r"(__gu_err)     \
++              : "r"(ptr), "1"(__gu_err));             \
++                                                      \
++      (val) = __gu_tmp.t;                             \
++}
+ #endif /* !defined(CONFIG_64BIT) */
+-#define __put_user(x, ptr)                                      \
++#define __put_user_internal(x, ptr)                           \
+ ({                                                            \
+       register long __pu_err __asm__ ("r8") = 0;              \
+         __typeof__(*(ptr)) __x = (__typeof__(*(ptr)))(x);     \
+                                                               \
+-      load_sr2();                                             \
+       switch (sizeof(*(ptr))) {                               \
+-          case 1: __put_user_asm("stb", __x, ptr); break;     \
+-          case 2: __put_user_asm("sth", __x, ptr); break;     \
+-          case 4: __put_user_asm("stw", __x, ptr); break;     \
+-          case 8: STD_USER(__x, ptr); break;                  \
+-          default: BUILD_BUG(); break;                        \
+-      }                                                       \
++      case 1: __put_user_asm("stb", __x, ptr); break;         \
++      case 2: __put_user_asm("sth", __x, ptr); break;         \
++      case 4: __put_user_asm("stw", __x, ptr); break;         \
++      case 8: STD_USER(__x, ptr); break;                      \
++      default: BUILD_BUG();                                   \
++      }                                                       \
+                                                               \
+       __pu_err;                                               \
+ })
++#define __put_user(x, ptr)                                    \
++({                                                            \
++      load_sr2();                                             \
++      __put_user_internal(x, ptr);                            \
++})
++
++
+ /*
+  * The "__put_user/kernel_asm()" macros tell gcc they read from memory
+  * instead of writing. This is because they do not write to any memory
diff --git a/queue-4.9/platform-x86-acer-wmi-setup-accelerometer-when-machine-has-appropriate-notify-event.patch b/queue-4.9/platform-x86-acer-wmi-setup-accelerometer-when-machine-has-appropriate-notify-event.patch
new file mode 100644 (file)
index 0000000..7e97131
--- /dev/null
@@ -0,0 +1,84 @@
+From 98d610c3739ac354319a6590b915f4624d9151e6 Mon Sep 17 00:00:00 2001
+From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com>
+Date: Thu, 3 Nov 2016 08:18:52 +0800
+Subject: platform/x86: acer-wmi: setup accelerometer when machine has appropriate notify event
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lee, Chun-Yi <joeyli.kernel@gmail.com>
+
+commit 98d610c3739ac354319a6590b915f4624d9151e6 upstream.
+
+The accelerometer event relies on the ACERWMID_EVENT_GUID notify.
+So, this patch changes the codes to setup accelerometer input device
+when detected ACERWMID_EVENT_GUID. It avoids that the accel input
+device created on every Acer machines.
+
+In addition, patch adds a clearly parsing logic of accelerometer hid
+to acer_wmi_get_handle_cb callback function. It is positive matching
+the "SENR" name with "BST0001" device to avoid non-supported hardware.
+
+Reported-by: Bjørn Mork <bjorn@mork.no>
+Cc: Darren Hart <dvhart@infradead.org>
+Signed-off-by: Lee, Chun-Yi <jlee@suse.com>
+[andy: slightly massage commit message]
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/platform/x86/acer-wmi.c |   22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+--- a/drivers/platform/x86/acer-wmi.c
++++ b/drivers/platform/x86/acer-wmi.c
+@@ -1846,11 +1846,24 @@ static int __init acer_wmi_enable_lm(voi
+       return status;
+ }
++#define ACER_WMID_ACCEL_HID   "BST0001"
++
+ static acpi_status __init acer_wmi_get_handle_cb(acpi_handle ah, u32 level,
+                                               void *ctx, void **retval)
+ {
++      struct acpi_device *dev;
++
++      if (!strcmp(ctx, "SENR")) {
++              if (acpi_bus_get_device(ah, &dev))
++                      return AE_OK;
++              if (!strcmp(ACER_WMID_ACCEL_HID, acpi_device_hid(dev)))
++                      return AE_OK;
++      } else
++              return AE_OK;
++
+       *(acpi_handle *)retval = ah;
+-      return AE_OK;
++
++      return AE_CTRL_TERMINATE;
+ }
+ static int __init acer_wmi_get_handle(const char *name, const char *prop,
+@@ -1877,7 +1890,7 @@ static int __init acer_wmi_accel_setup(v
+ {
+       int err;
+-      err = acer_wmi_get_handle("SENR", "BST0001", &gsensor_handle);
++      err = acer_wmi_get_handle("SENR", ACER_WMID_ACCEL_HID, &gsensor_handle);
+       if (err)
+               return err;
+@@ -2233,10 +2246,11 @@ static int __init acer_wmi_init(void)
+               err = acer_wmi_input_setup();
+               if (err)
+                       return err;
++              err = acer_wmi_accel_setup();
++              if (err)
++                      return err;
+       }
+-      acer_wmi_accel_setup();
+-
+       err = platform_driver_register(&acer_platform_driver);
+       if (err) {
+               pr_err("Unable to register platform driver\n");
diff --git a/queue-4.9/rtc-tegra-implement-clock-handling.patch b/queue-4.9/rtc-tegra-implement-clock-handling.patch
new file mode 100644 (file)
index 0000000..7d76055
--- /dev/null
@@ -0,0 +1,125 @@
+From 5fa4086987506b2ab8c92f8f99f2295db9918856 Mon Sep 17 00:00:00 2001
+From: Thierry Reding <treding@nvidia.com>
+Date: Thu, 12 Jan 2017 17:07:43 +0100
+Subject: rtc: tegra: Implement clock handling
+
+From: Thierry Reding <treding@nvidia.com>
+
+commit 5fa4086987506b2ab8c92f8f99f2295db9918856 upstream.
+
+Accessing the registers of the RTC block on Tegra requires the module
+clock to be enabled. This only works because the RTC module clock will
+be enabled by default during early boot. However, because the clock is
+unused, the CCF will disable it at late_init time. This causes the RTC
+to become unusable afterwards. This can easily be reproduced by trying
+to use the RTC:
+
+       $ hwclock --rtc /dev/rtc1
+
+This will hang the system. I ran into this by following up on a report
+by Martin Michlmayr that reboot wasn't working on Tegra210 systems. It
+turns out that the rtc-tegra driver's ->shutdown() implementation will
+hang the CPU, because of the disabled clock, before the system can be
+rebooted.
+
+What confused me for a while is that the same driver is used on prior
+Tegra generations where the hang can not be observed. However, as Peter
+De Schrijver pointed out, this is because on 32-bit Tegra chips the RTC
+clock is enabled by the tegra20_timer.c clocksource driver, which uses
+the RTC to provide a persistent clock. This code is never enabled on
+64-bit Tegra because the persistent clock infrastructure does not exist
+on 64-bit ARM.
+
+The proper fix for this is to add proper clock handling to the RTC
+driver in order to ensure that the clock is enabled when the driver
+requires it. All device trees contain the clock already, therefore
+no additional changes are required.
+
+Reported-by: Martin Michlmayr <tbm@cyrius.com>
+Acked-By Peter De Schrijver <pdeschrijver@nvidia.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+[bwh: Backported to 4.9: adjust context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/rtc/rtc-tegra.c |   28 ++++++++++++++++++++++++++--
+ 1 file changed, 26 insertions(+), 2 deletions(-)
+
+--- a/drivers/rtc/rtc-tegra.c
++++ b/drivers/rtc/rtc-tegra.c
+@@ -18,6 +18,7 @@
+  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+  */
+ #include <linux/kernel.h>
++#include <linux/clk.h>
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
+@@ -59,6 +60,7 @@ struct tegra_rtc_info {
+       struct platform_device  *pdev;
+       struct rtc_device       *rtc_dev;
+       void __iomem            *rtc_base; /* NULL if not initialized. */
++      struct clk              *clk;
+       int                     tegra_rtc_irq; /* alarm and periodic irq */
+       spinlock_t              tegra_rtc_lock;
+ };
+@@ -326,6 +328,14 @@ static int __init tegra_rtc_probe(struct
+       if (info->tegra_rtc_irq <= 0)
+               return -EBUSY;
++      info->clk = devm_clk_get(&pdev->dev, NULL);
++      if (IS_ERR(info->clk))
++              return PTR_ERR(info->clk);
++
++      ret = clk_prepare_enable(info->clk);
++      if (ret < 0)
++              return ret;
++
+       /* set context info. */
+       info->pdev = pdev;
+       spin_lock_init(&info->tegra_rtc_lock);
+@@ -346,7 +356,7 @@ static int __init tegra_rtc_probe(struct
+               ret = PTR_ERR(info->rtc_dev);
+               dev_err(&pdev->dev, "Unable to register device (err=%d).\n",
+                       ret);
+-              return ret;
++              goto disable_clk;
+       }
+       ret = devm_request_irq(&pdev->dev, info->tegra_rtc_irq,
+@@ -356,12 +366,25 @@ static int __init tegra_rtc_probe(struct
+               dev_err(&pdev->dev,
+                       "Unable to request interrupt for device (err=%d).\n",
+                       ret);
+-              return ret;
++              goto disable_clk;
+       }
+       dev_notice(&pdev->dev, "Tegra internal Real Time Clock\n");
+       return 0;
++
++disable_clk:
++      clk_disable_unprepare(info->clk);
++      return ret;
++}
++
++static int tegra_rtc_remove(struct platform_device *pdev)
++{
++      struct tegra_rtc_info *info = platform_get_drvdata(pdev);
++
++      clk_disable_unprepare(info->clk);
++
++      return 0;
+ }
+ #ifdef CONFIG_PM_SLEEP
+@@ -413,6 +436,7 @@ static void tegra_rtc_shutdown(struct pl
+ MODULE_ALIAS("platform:tegra_rtc");
+ static struct platform_driver tegra_rtc_driver = {
++      .remove         = tegra_rtc_remove,
+       .shutdown       = tegra_rtc_shutdown,
+       .driver         = {
+               .name   = "tegra_rtc",
index 8bf622bc949d0411bbc7dc13f97aed5e7afba5e3..56cd50699c0eec5adff52021c6b3b436a9487339 100644 (file)
@@ -44,3 +44,24 @@ char-lack-of-bool-string-made-config_devport-always-on.patch
 revert-mips-lantiq-fix-cascaded-irq-setup.patch
 kvm-fix-page-struct-leak-in-handle_vmon.patch
 zram-do-not-use-copy_page-with-non-page-aligned-address.patch
+ftrace-fix-function-pid-filter-on-instances.patch
+crypto-algif_aead-fix-bogus-request-dereference-in-completion-function.patch
+crypto-ahash-fix-einprogress-notification-callback.patch
+parisc-fix-get_user-for-64-bit-value-on-32-bit-kernel.patch
+ath9k-fix-null-pointer-dereference.patch
+dvb-usb-v2-avoid-use-after-free.patch
+ext4-fix-inode-checksum-calculation-problem-if-i_extra_size-is-small.patch
+mm-memcontrol-use-special-workqueue-for-creating-per-memcg-caches.patch
+drm-nouveau-disp-mcp7x-disable-dptmds-workaround.patch
+nbd-use-loff_t-for-blocksize-and-nbd_set_size-args.patch
+nbd-fix-64-bit-division.patch
+asoc-intel-select-dw_dmac_core-since-it-s-mandatory.patch
+platform-x86-acer-wmi-setup-accelerometer-when-machine-has-appropriate-notify-event.patch
+x86-xen-fix-apic-id-mismatch-warning-on-intel.patch
+acpi-ec-use-busy-polling-mode-when-gpe-is-not-enabled.patch
+rtc-tegra-implement-clock-handling.patch
+mm-tighten-x86-dev-mem-with-zeroing-reads.patch
+dvb-usb-don-t-use-stack-for-firmware-load.patch
+dvb-usb-firmware-don-t-do-dma-on-stack.patch
+cxusb-use-a-dma-capable-buffer-also-for-reading.patch
+virtio-console-avoid-dma-from-stack.patch
diff --git a/queue-4.9/virtio-console-avoid-dma-from-stack.patch b/queue-4.9/virtio-console-avoid-dma-from-stack.patch
new file mode 100644 (file)
index 0000000..9e1cda8
--- /dev/null
@@ -0,0 +1,52 @@
+From c4baad50297d84bde1a7ad45e50c73adae4a2192 Mon Sep 17 00:00:00 2001
+From: Omar Sandoval <osandov@fb.com>
+Date: Wed, 1 Feb 2017 00:02:27 -0800
+Subject: virtio-console: avoid DMA from stack
+
+From: Omar Sandoval <osandov@fb.com>
+
+commit c4baad50297d84bde1a7ad45e50c73adae4a2192 upstream.
+
+put_chars() stuffs the buffer it gets into an sg, but that buffer may be
+on the stack. This breaks with CONFIG_VMAP_STACK=y (for me, it
+manifested as printks getting turned into NUL bytes).
+
+Signed-off-by: Omar Sandoval <osandov@fb.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Amit Shah <amit.shah@redhat.com>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Cc: Brad Spengler <spender@grsecurity.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/virtio_console.c |   12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/virtio_console.c
++++ b/drivers/char/virtio_console.c
+@@ -1136,6 +1136,8 @@ static int put_chars(u32 vtermno, const
+ {
+       struct port *port;
+       struct scatterlist sg[1];
++      void *data;
++      int ret;
+       if (unlikely(early_put_chars))
+               return early_put_chars(vtermno, buf, count);
+@@ -1144,8 +1146,14 @@ static int put_chars(u32 vtermno, const
+       if (!port)
+               return -EPIPE;
+-      sg_init_one(sg, buf, count);
+-      return __send_to_port(port, sg, 1, count, (void *)buf, false);
++      data = kmemdup(buf, count, GFP_ATOMIC);
++      if (!data)
++              return -ENOMEM;
++
++      sg_init_one(sg, data, count);
++      ret = __send_to_port(port, sg, 1, count, data, false);
++      kfree(data);
++      return ret;
+ }
+ /*
diff --git a/queue-4.9/x86-xen-fix-apic-id-mismatch-warning-on-intel.patch b/queue-4.9/x86-xen-fix-apic-id-mismatch-warning-on-intel.patch
new file mode 100644 (file)
index 0000000..3882e15
--- /dev/null
@@ -0,0 +1,61 @@
+From cc272163ea554a97dac180fa8dd6cd54c2810bd1 Mon Sep 17 00:00:00 2001
+From: Mohit Gambhir <mohit.gambhir@oracle.com>
+Date: Thu, 26 Jan 2017 13:12:27 -0500
+Subject: x86/xen: Fix APIC id mismatch warning on Intel
+
+From: Mohit Gambhir <mohit.gambhir@oracle.com>
+
+commit cc272163ea554a97dac180fa8dd6cd54c2810bd1 upstream.
+
+This patch fixes the following warning message seen when booting the
+kernel as Dom0 with Xen on Intel machines.
+
+[0.003000] [Firmware Bug]: CPU1: APIC id mismatch. Firmware: 0 APIC: 1]
+
+The code generating the warning in validate_apic_and_package_id() matches
+cpu_data(cpu).apicid (initialized in init_intel()->
+detect_extended_topology() using cpuid) against the apicid returned from
+xen_apic_read(). Now, xen_apic_read() makes a hypercall to retrieve apicid
+for the boot  cpu but returns 0 otherwise. Hence the warning gets thrown
+for all but the boot cpu.
+
+The idea behind xen_apic_read() returning 0 for apicid is that the
+guests (even Dom0) should not need to know what physical processor their
+vcpus are running on. This is because we currently  do not have topology
+information in Xen and also because xen allows more vcpus than physical
+processors. However, boot cpu's apicid is required for loading
+xen-acpi-processor driver on AMD machines. Look at following patch for
+details:
+
+commit 558daa289a40 ("xen/apic: Return the APIC ID (and version) for CPU
+0.")
+
+So to get rid of the warning, this patch modifies
+xen_cpu_present_to_apicid() to return cpu_data(cpu).apicid instead of
+calling xen_apic_read().
+
+The warning is not seen on AMD machines because init_amd() populates
+cpu_data(cpu).apicid by calling hard_smp_processor_id()->xen_apic_read()
+as opposed to using apicid from cpuid as is done on Intel machines.
+
+Signed-off-by: Mohit Gambhir <mohit.gambhir@oracle.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/xen/apic.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/x86/xen/apic.c
++++ b/arch/x86/xen/apic.c
+@@ -145,7 +145,7 @@ static void xen_silent_inquire(int apici
+ static int xen_cpu_present_to_apicid(int cpu)
+ {
+       if (cpu_present(cpu))
+-              return xen_get_apic_id(xen_apic_read(APIC_ID));
++              return cpu_data(cpu).apicid;
+       else
+               return BAD_APICID;
+ }