]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 3 Apr 2017 12:40:10 +0000 (14:40 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 3 Apr 2017 12:40:10 +0000 (14:40 +0200)
added patches:
acpi-do-not-create-a-platform_device-for-ioapic-ioxapic.patch
acpi-fix-incompatibility-with-mcount-based-function-graph-tracing.patch
alsa-hda-fix-a-problem-for-lineout-on-a-dell-aio-machine.patch
alsa-seq-fix-race-during-fifo-resize.patch
arcv2-slc-make-sure-busy-bit-is-set-properly-on-slc-flushing.patch
asoc-atmel-classd-fix-audio-clock-rate.patch
asoc-intel-skylake-fix-invalid-memory-access-due-to-wrong-reference-of-pointer.patch
asoc-rt5665-fix-getting-wrong-work-handler-container.patch
crypto-ccp-make-some-ccp-dma-channels-private.patch
crypto-xts-lrw-fix-out-of-bounds-write-after-kmalloc-failure.patch
dt-bindings-rng-clocks-property-on-omap_rng-not-always-mandatory.patch
hid-wacom-don-t-add-ghost-interface-as-shared-data.patch
mmc-sdhci-disable-runtime-pm-when-the-sdio_irq-is-enabled.patch
mmc-sdhci-of-at91-fix-mmc_ddr_52-timing-selection.patch
nfsd-map-the-enokey-to-nfserr_perm-for-avoiding-warning.patch
nfsv4.1-fix-infinite-loop-on-io-bad_stateid-error.patch
parisc-avoid-stalled-cpu-warnings-after-system-shutdown.patch
parisc-clean-up-fixup-routines-for-get_user-put_user.patch
parisc-fix-access-fault-handling-in-pa_memcpy.patch
pci-iproc-save-host-bridge-window-resource-in-struct-iproc_pcie.patch
pci-thunder-pem-add-legacy-firmware-support-for-cavium-thunderx-host-controller.patch
pci-thunder-pem-use-cavium-assigned-hardware-id-for-thunderx-host-controller.patch
scsi-libsas-fix-ata-xfer-length.patch
scsi-scsi_dh_alua-check-scsi_device_get-return-value.patch
scsi-scsi_dh_alua-ensure-that-alua_activate-calls-the-completion-function.patch
scsi-sg-check-length-passed-to-sg_next_cmd_len.patch
serial-mxs-auart-fix-baudrate-calculation.patch
tty-serial-atmel-fix-race-condition-tx-dma.patch
tty-serial-atmel-fix-tx-path-in-atmel_console_write.patch
usb-fix-linked-list-corruption-in-rh_call_control.patch
xhci-set-urb-actual-length-for-stopped-control-transfers.patch

32 files changed:
queue-4.10/acpi-do-not-create-a-platform_device-for-ioapic-ioxapic.patch [new file with mode: 0644]
queue-4.10/acpi-fix-incompatibility-with-mcount-based-function-graph-tracing.patch [new file with mode: 0644]
queue-4.10/alsa-hda-fix-a-problem-for-lineout-on-a-dell-aio-machine.patch [new file with mode: 0644]
queue-4.10/alsa-seq-fix-race-during-fifo-resize.patch [new file with mode: 0644]
queue-4.10/arcv2-slc-make-sure-busy-bit-is-set-properly-on-slc-flushing.patch [new file with mode: 0644]
queue-4.10/asoc-atmel-classd-fix-audio-clock-rate.patch [new file with mode: 0644]
queue-4.10/asoc-intel-skylake-fix-invalid-memory-access-due-to-wrong-reference-of-pointer.patch [new file with mode: 0644]
queue-4.10/asoc-rt5665-fix-getting-wrong-work-handler-container.patch [new file with mode: 0644]
queue-4.10/crypto-ccp-make-some-ccp-dma-channels-private.patch [new file with mode: 0644]
queue-4.10/crypto-xts-lrw-fix-out-of-bounds-write-after-kmalloc-failure.patch [new file with mode: 0644]
queue-4.10/dt-bindings-rng-clocks-property-on-omap_rng-not-always-mandatory.patch [new file with mode: 0644]
queue-4.10/hid-wacom-don-t-add-ghost-interface-as-shared-data.patch [new file with mode: 0644]
queue-4.10/mmc-sdhci-disable-runtime-pm-when-the-sdio_irq-is-enabled.patch [new file with mode: 0644]
queue-4.10/mmc-sdhci-of-at91-fix-mmc_ddr_52-timing-selection.patch [new file with mode: 0644]
queue-4.10/nfsd-map-the-enokey-to-nfserr_perm-for-avoiding-warning.patch [new file with mode: 0644]
queue-4.10/nfsv4.1-fix-infinite-loop-on-io-bad_stateid-error.patch [new file with mode: 0644]
queue-4.10/parisc-avoid-stalled-cpu-warnings-after-system-shutdown.patch [new file with mode: 0644]
queue-4.10/parisc-clean-up-fixup-routines-for-get_user-put_user.patch [new file with mode: 0644]
queue-4.10/parisc-fix-access-fault-handling-in-pa_memcpy.patch [new file with mode: 0644]
queue-4.10/pci-iproc-save-host-bridge-window-resource-in-struct-iproc_pcie.patch [new file with mode: 0644]
queue-4.10/pci-thunder-pem-add-legacy-firmware-support-for-cavium-thunderx-host-controller.patch [new file with mode: 0644]
queue-4.10/pci-thunder-pem-use-cavium-assigned-hardware-id-for-thunderx-host-controller.patch [new file with mode: 0644]
queue-4.10/scsi-libsas-fix-ata-xfer-length.patch [new file with mode: 0644]
queue-4.10/scsi-scsi_dh_alua-check-scsi_device_get-return-value.patch [new file with mode: 0644]
queue-4.10/scsi-scsi_dh_alua-ensure-that-alua_activate-calls-the-completion-function.patch [new file with mode: 0644]
queue-4.10/scsi-sg-check-length-passed-to-sg_next_cmd_len.patch [new file with mode: 0644]
queue-4.10/serial-mxs-auart-fix-baudrate-calculation.patch [new file with mode: 0644]
queue-4.10/series
queue-4.10/tty-serial-atmel-fix-race-condition-tx-dma.patch [new file with mode: 0644]
queue-4.10/tty-serial-atmel-fix-tx-path-in-atmel_console_write.patch [new file with mode: 0644]
queue-4.10/usb-fix-linked-list-corruption-in-rh_call_control.patch [new file with mode: 0644]
queue-4.10/xhci-set-urb-actual-length-for-stopped-control-transfers.patch [new file with mode: 0644]

diff --git a/queue-4.10/acpi-do-not-create-a-platform_device-for-ioapic-ioxapic.patch b/queue-4.10/acpi-do-not-create-a-platform_device-for-ioapic-ioxapic.patch
new file mode 100644 (file)
index 0000000..69dbb77
--- /dev/null
@@ -0,0 +1,40 @@
+From 08f63d97749185fab942a3a47ed80f5bd89b8b7d Mon Sep 17 00:00:00 2001
+From: Joerg Roedel <jroedel@suse.de>
+Date: Wed, 22 Mar 2017 18:33:25 +0100
+Subject: ACPI: Do not create a platform_device for IOAPIC/IOxAPIC
+
+From: Joerg Roedel <jroedel@suse.de>
+
+commit 08f63d97749185fab942a3a47ed80f5bd89b8b7d upstream.
+
+No platform-device is required for IO(x)APICs, so don't even
+create them.
+
+[ rjw: This fixes a problem with leaking platform device objects
+  after IOAPIC/IOxAPIC hot-removal events.]
+
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/acpi_platform.c |    8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/acpi/acpi_platform.c
++++ b/drivers/acpi/acpi_platform.c
+@@ -25,9 +25,11 @@
+ ACPI_MODULE_NAME("platform");
+ static const struct acpi_device_id forbidden_id_list[] = {
+-      {"PNP0000", 0}, /* PIC */
+-      {"PNP0100", 0}, /* Timer */
+-      {"PNP0200", 0}, /* AT DMA Controller */
++      {"PNP0000",  0},        /* PIC */
++      {"PNP0100",  0},        /* Timer */
++      {"PNP0200",  0},        /* AT DMA Controller */
++      {"ACPI0009", 0},        /* IOxAPIC */
++      {"ACPI000A", 0},        /* IOAPIC */
+       {"", 0},
+ };
diff --git a/queue-4.10/acpi-fix-incompatibility-with-mcount-based-function-graph-tracing.patch b/queue-4.10/acpi-fix-incompatibility-with-mcount-based-function-graph-tracing.patch
new file mode 100644 (file)
index 0000000..69a6661
--- /dev/null
@@ -0,0 +1,55 @@
+From 61b79e16c68d703dde58c25d3935d67210b7d71b Mon Sep 17 00:00:00 2001
+From: Josh Poimboeuf <jpoimboe@redhat.com>
+Date: Thu, 16 Mar 2017 08:56:28 -0500
+Subject: ACPI: Fix incompatibility with mcount-based function graph tracing
+
+From: Josh Poimboeuf <jpoimboe@redhat.com>
+
+commit 61b79e16c68d703dde58c25d3935d67210b7d71b upstream.
+
+Paul Menzel reported a warning:
+
+  WARNING: CPU: 0 PID: 774 at /build/linux-ROBWaj/linux-4.9.13/kernel/trace/trace_functions_graph.c:233 ftrace_return_to_handler+0x1aa/0x1e0
+  Bad frame pointer: expected f6919d98, received f6919db0
+    from func acpi_pm_device_sleep_wake return to c43b6f9d
+
+The warning means that function graph tracing is broken for the
+acpi_pm_device_sleep_wake() function.  That's because the ACPI Makefile
+unconditionally sets the '-Os' gcc flag to optimize for size.  That's an
+issue because mcount-based function graph tracing is incompatible with
+'-Os' on x86, thanks to the following gcc bug:
+
+  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42109
+
+I have another patch pending which will ensure that mcount-based
+function graph tracing is never used with CONFIG_CC_OPTIMIZE_FOR_SIZE on
+x86.
+
+But this patch is needed in addition to that one because the ACPI
+Makefile overrides that config option for no apparent reason.  It has
+had this flag since the beginning of git history, and there's no related
+comment, so I don't know why it's there.  As far as I can tell, there's
+no reason for it to be there.  The appropriate behavior is for it to
+honor CONFIG_CC_OPTIMIZE_FOR_{SIZE,PERFORMANCE} like the rest of the
+kernel.
+
+Reported-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
+Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/Makefile |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/acpi/Makefile
++++ b/drivers/acpi/Makefile
+@@ -2,7 +2,6 @@
+ # Makefile for the Linux ACPI interpreter
+ #
+-ccflags-y                     := -Os
+ ccflags-$(CONFIG_ACPI_DEBUG)  += -DACPI_DEBUG_OUTPUT
+ #
diff --git a/queue-4.10/alsa-hda-fix-a-problem-for-lineout-on-a-dell-aio-machine.patch b/queue-4.10/alsa-hda-fix-a-problem-for-lineout-on-a-dell-aio-machine.patch
new file mode 100644 (file)
index 0000000..a3545bf
--- /dev/null
@@ -0,0 +1,68 @@
+From 2f726aec19a9d2c63bec9a8a53a3910ffdcd09f8 Mon Sep 17 00:00:00 2001
+From: Hui Wang <hui.wang@canonical.com>
+Date: Fri, 31 Mar 2017 10:31:40 +0800
+Subject: ALSA: hda - fix a problem for lineout on a Dell AIO machine
+
+From: Hui Wang <hui.wang@canonical.com>
+
+commit 2f726aec19a9d2c63bec9a8a53a3910ffdcd09f8 upstream.
+
+On this Dell AIO machine, the lineout jack does not work.
+
+We found the pin 0x1a is assigned to lineout on this machine, and in
+the past, we applied ALC298_FIXUP_DELL1_MIC_NO_PRESENCE to fix the
+heaset-set mic problem for this machine, this fixup will redefine
+the pin 0x1a to headphone-mic, as a result the lineout doesn't
+work anymore.
+
+After consulting with Dell, they told us this machine doesn't support
+microphone via headset jack, so we add a new fixup which only defines
+the pin 0x18 as the headset-mic.
+
+[rearranged the fixup insertion position by tiwai in order to make the
+ merge with other branches easier -- tiwai]
+
+Fixes: 59ec4b57bcae ("ALSA: hda - Fix headset mic detection problem for two dell machines")
+Signed-off-by: Hui Wang <hui.wang@canonical.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c |   12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -4846,6 +4846,7 @@ enum {
+       ALC292_FIXUP_DISABLE_AAMIX,
+       ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
+       ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
++      ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
+       ALC275_FIXUP_DELL_XPS,
+       ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
+       ALC293_FIXUP_LENOVO_SPK_NOISE,
+@@ -5446,6 +5447,15 @@ static const struct hda_fixup alc269_fix
+               .chained = true,
+               .chain_id = ALC269_FIXUP_HEADSET_MODE
+       },
++      [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
++              .type = HDA_FIXUP_PINS,
++              .v.pins = (const struct hda_pintbl[]) {
++                      { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
++                      { }
++              },
++              .chained = true,
++              .chain_id = ALC269_FIXUP_HEADSET_MODE
++      },
+       [ALC275_FIXUP_DELL_XPS] = {
+               .type = HDA_FIXUP_VERBS,
+               .v.verbs = (const struct hda_verb[]) {
+@@ -5518,7 +5528,7 @@ static const struct hda_fixup alc269_fix
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc298_fixup_speaker_volume,
+               .chained = true,
+-              .chain_id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
++              .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
+       },
+       [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
+               .type = HDA_FIXUP_PINS,
diff --git a/queue-4.10/alsa-seq-fix-race-during-fifo-resize.patch b/queue-4.10/alsa-seq-fix-race-during-fifo-resize.patch
new file mode 100644 (file)
index 0000000..aded867
--- /dev/null
@@ -0,0 +1,38 @@
+From 2d7d54002e396c180db0c800c1046f0a3c471597 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Fri, 24 Mar 2017 17:07:57 +0100
+Subject: ALSA: seq: Fix race during FIFO resize
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 2d7d54002e396c180db0c800c1046f0a3c471597 upstream.
+
+When a new event is queued while processing to resize the FIFO in
+snd_seq_fifo_clear(), it may lead to a use-after-free, as the old pool
+that is being queued gets removed.  For avoiding this race, we need to
+close the pool to be deleted and sync its usage before actually
+deleting it.
+
+The issue was spotted by syzkaller.
+
+Reported-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/seq/seq_fifo.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/sound/core/seq/seq_fifo.c
++++ b/sound/core/seq/seq_fifo.c
+@@ -265,6 +265,10 @@ int snd_seq_fifo_resize(struct snd_seq_f
+       /* NOTE: overflow flag is not cleared */
+       spin_unlock_irqrestore(&f->lock, flags);
++      /* close the old pool and wait until all users are gone */
++      snd_seq_pool_mark_closing(oldpool);
++      snd_use_lock_sync(&f->use_lock);
++
+       /* release cells in old pool */
+       for (cell = oldhead; cell; cell = next) {
+               next = cell->next;
diff --git a/queue-4.10/arcv2-slc-make-sure-busy-bit-is-set-properly-on-slc-flushing.patch b/queue-4.10/arcv2-slc-make-sure-busy-bit-is-set-properly-on-slc-flushing.patch
new file mode 100644 (file)
index 0000000..34b9d90
--- /dev/null
@@ -0,0 +1,39 @@
+From c70c473396cbdec1168a6eff60e13029c0916854 Mon Sep 17 00:00:00 2001
+From: Alexey Brodkin <abrodkin@synopsys.com>
+Date: Wed, 29 Mar 2017 17:15:11 +0300
+Subject: ARCv2: SLC: Make sure busy bit is set properly on SLC flushing
+
+From: Alexey Brodkin <abrodkin@synopsys.com>
+
+commit c70c473396cbdec1168a6eff60e13029c0916854 upstream.
+
+As reported in STAR 9001165532, an SLC control reg read (for checking
+busy state) right after SLC invalidate command may incorrectly return
+NOT busy causing software to NOT spin-wait while operation is underway.
+(and for some reason this only happens if L1 cache is also disabled - as
+required by IOC programming model)
+
+Suggested workaround is to do an additional Control Reg read, which
+ensures the 2nd read gets the right status.
+
+Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
+[vgupta: reworte changelog a bit]
+Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arc/mm/cache.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/arc/mm/cache.c
++++ b/arch/arc/mm/cache.c
+@@ -633,6 +633,9 @@ noinline static void slc_entire_op(const
+       write_aux_reg(ARC_REG_SLC_INVALIDATE, 1);
++      /* Make sure "busy" bit reports correct stataus, see STAR 9001165532 */
++      read_aux_reg(r);
++
+       /* Important to wait for flush to complete */
+       while (read_aux_reg(r) & SLC_CTRL_BUSY);
+ }
diff --git a/queue-4.10/asoc-atmel-classd-fix-audio-clock-rate.patch b/queue-4.10/asoc-atmel-classd-fix-audio-clock-rate.patch
new file mode 100644 (file)
index 0000000..c25f66a
--- /dev/null
@@ -0,0 +1,32 @@
+From cd3ac9affc43b44f49d7af70d275f0bd426ba643 Mon Sep 17 00:00:00 2001
+From: Songjun Wu <songjun.wu@microchip.com>
+Date: Fri, 24 Feb 2017 15:10:43 +0800
+Subject: ASoC: atmel-classd: fix audio clock rate
+
+From: Songjun Wu <songjun.wu@microchip.com>
+
+commit cd3ac9affc43b44f49d7af70d275f0bd426ba643 upstream.
+
+Fix the audio clock rate according to the datasheet.
+
+Reported-by: Dushara Jayasinghe <dushara@successful.com.au>
+Signed-off-by: Songjun Wu <songjun.wu@microchip.com>
+Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/atmel/atmel-classd.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/soc/atmel/atmel-classd.c
++++ b/sound/soc/atmel/atmel-classd.c
+@@ -349,7 +349,7 @@ static int atmel_classd_codec_dai_digita
+ }
+ #define CLASSD_ACLK_RATE_11M2896_MPY_8 (112896 * 100 * 8)
+-#define CLASSD_ACLK_RATE_12M288_MPY_8  (12228 * 1000 * 8)
++#define CLASSD_ACLK_RATE_12M288_MPY_8  (12288 * 1000 * 8)
+ static struct {
+       int rate;
diff --git a/queue-4.10/asoc-intel-skylake-fix-invalid-memory-access-due-to-wrong-reference-of-pointer.patch b/queue-4.10/asoc-intel-skylake-fix-invalid-memory-access-due-to-wrong-reference-of-pointer.patch
new file mode 100644 (file)
index 0000000..10cbab1
--- /dev/null
@@ -0,0 +1,48 @@
+From d1a6fe41d3c4ff0d26f0b186d774493555ca5282 Mon Sep 17 00:00:00 2001
+From: Takashi Sakamoto <takashi.sakamoto@miraclelinux.com>
+Date: Fri, 24 Feb 2017 11:48:41 +0900
+Subject: ASoC: Intel: Skylake: fix invalid memory access due to wrong reference of pointer
+
+From: Takashi Sakamoto <takashi.sakamoto@miraclelinux.com>
+
+commit d1a6fe41d3c4ff0d26f0b186d774493555ca5282 upstream.
+
+In 'skl_tplg_set_module_init_data()', a pointer to 'params' member of
+'struct skl_algo_data' is calculated, then casted to (u32 *) and assigned
+to a member of configuration data. The configuration data is passed to the
+other functions and used to process intel IPC. In this processing, the
+value of member is used to get message data, however this can bring invalid
+memory access in 'skl_set_module_params()' as a result of calculation of
+a pointer for actual message data.
+
+(sound/soc/intel/skylake/skl-topology.c)
+skl_tplg_init_pipe_modules()
+->skl_tplg_set_module_init_data() (has this bug)
+->skl_tplg_set_module_params()
+  (sound/soc/intel/skylake/skl-messages.c)
+  ->skl_set_module_params()
+    ((char *)param) + data_offset
+
+This commit fixes the bug.
+
+Fixes: abb740033b56 ("ASoC: Intel: Skylake: Add support to configure module params")
+Signed-off-by: Takashi Sakamoto <takashi.sakamoto@miraclelinux.com>
+Acked-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/intel/skylake/skl-topology.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/soc/intel/skylake/skl-topology.c
++++ b/sound/soc/intel/skylake/skl-topology.c
+@@ -486,7 +486,7 @@ static int skl_tplg_set_module_init_data
+                       if (bc->set_params != SKL_PARAM_INIT)
+                               continue;
+-                      mconfig->formats_config.caps = (u32 *)&bc->params;
++                      mconfig->formats_config.caps = (u32 *)bc->params;
+                       mconfig->formats_config.caps_size = bc->size;
+                       break;
diff --git a/queue-4.10/asoc-rt5665-fix-getting-wrong-work-handler-container.patch b/queue-4.10/asoc-rt5665-fix-getting-wrong-work-handler-container.patch
new file mode 100644 (file)
index 0000000..673b4e4
--- /dev/null
@@ -0,0 +1,31 @@
+From f1994a9c0930de4b2244816e62120cad08283cdc Mon Sep 17 00:00:00 2001
+From: Bard Liao <bardliao@realtek.com>
+Date: Wed, 8 Mar 2017 19:03:10 +0800
+Subject: ASoC: rt5665: fix getting wrong work handler container
+
+From: Bard Liao <bardliao@realtek.com>
+
+commit f1994a9c0930de4b2244816e62120cad08283cdc upstream.
+
+We got rt5665 private data from wrong work. It will result in kernel
+panic.
+
+Signed-off-by: Bard Liao <bardliao@realtek.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/codecs/rt5665.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/soc/codecs/rt5665.c
++++ b/sound/soc/codecs/rt5665.c
+@@ -1241,7 +1241,7 @@ static irqreturn_t rt5665_irq(int irq, v
+ static void rt5665_jd_check_handler(struct work_struct *work)
+ {
+       struct rt5665_priv *rt5665 = container_of(work, struct rt5665_priv,
+-              calibrate_work.work);
++              jd_check_work.work);
+       if (snd_soc_read(rt5665->codec, RT5665_AJD1_CTRL) & 0x0010) {
+               /* jack out */
diff --git a/queue-4.10/crypto-ccp-make-some-ccp-dma-channels-private.patch b/queue-4.10/crypto-ccp-make-some-ccp-dma-channels-private.patch
new file mode 100644 (file)
index 0000000..7736079
--- /dev/null
@@ -0,0 +1,125 @@
+From efc989fce8703914bac091dcc4b8ff7a72ccf987 Mon Sep 17 00:00:00 2001
+From: Gary R Hook <gary.hook@amd.com>
+Date: Thu, 23 Mar 2017 12:53:30 -0500
+Subject: crypto: ccp - Make some CCP DMA channels private
+
+From: Gary R Hook <gary.hook@amd.com>
+
+commit efc989fce8703914bac091dcc4b8ff7a72ccf987 upstream.
+
+The CCP registers its queues as channels capable of handling
+general DMA operations. The NTB driver will use DMA if
+directed, but as public channels can be reserved for use in
+asynchronous operations some channels should be held back
+as private. Since the public/private determination is
+handled at a device level, reserve the "other" (secondary)
+CCP channels as private.
+
+Add a module parameter that allows for override, to be
+applied to all channels on all devices.
+
+Signed-off-by: Gary R Hook <gary.hook@amd.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/crypto/ccp/ccp-dev-v5.c    |    1 
+ drivers/crypto/ccp/ccp-dev.h       |    5 ++++
+ drivers/crypto/ccp/ccp-dmaengine.c |   41 +++++++++++++++++++++++++++++++++++++
+ 3 files changed, 47 insertions(+)
+
+--- a/drivers/crypto/ccp/ccp-dev-v5.c
++++ b/drivers/crypto/ccp/ccp-dev-v5.c
+@@ -1014,6 +1014,7 @@ const struct ccp_vdata ccpv5a = {
+ const struct ccp_vdata ccpv5b = {
+       .version = CCP_VERSION(5, 0),
++      .dma_chan_attr = DMA_PRIVATE,
+       .setup = ccp5other_config,
+       .perform = &ccp5_actions,
+       .bar = 2,
+--- a/drivers/crypto/ccp/ccp-dev.h
++++ b/drivers/crypto/ccp/ccp-dev.h
+@@ -179,6 +179,10 @@
+ /* ------------------------ General CCP Defines ------------------------ */
++#define       CCP_DMA_DFLT                    0x0
++#define       CCP_DMA_PRIV                    0x1
++#define       CCP_DMA_PUB                     0x2
++
+ #define CCP_DMAPOOL_MAX_SIZE          64
+ #define CCP_DMAPOOL_ALIGN             BIT(5)
+@@ -635,6 +639,7 @@ struct ccp_actions {
+ /* Structure to hold CCP version-specific values */
+ struct ccp_vdata {
+       const unsigned int version;
++      const unsigned int dma_chan_attr;
+       void (*setup)(struct ccp_device *);
+       const struct ccp_actions *perform;
+       const unsigned int bar;
+--- a/drivers/crypto/ccp/ccp-dmaengine.c
++++ b/drivers/crypto/ccp/ccp-dmaengine.c
+@@ -10,6 +10,7 @@
+  * published by the Free Software Foundation.
+  */
++#include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/dmaengine.h>
+ #include <linux/spinlock.h>
+@@ -25,6 +26,37 @@
+       (mask == 0) ? 64 : fls64(mask); \
+ })
++/* The CCP as a DMA provider can be configured for public or private
++ * channels. Default is specified in the vdata for the device (PCI ID).
++ * This module parameter will override for all channels on all devices:
++ *   dma_chan_attr = 0x2 to force all channels public
++ *                 = 0x1 to force all channels private
++ *                 = 0x0 to defer to the vdata setting
++ *                 = any other value: warning, revert to 0x0
++ */
++static unsigned int dma_chan_attr = CCP_DMA_DFLT;
++module_param(dma_chan_attr, uint, 0444);
++MODULE_PARM_DESC(dma_chan_attr, "Set DMA channel visibility: 0 (default) = device defaults, 1 = make private, 2 = make public");
++
++unsigned int ccp_get_dma_chan_attr(struct ccp_device *ccp)
++{
++      switch (dma_chan_attr) {
++      case CCP_DMA_DFLT:
++              return ccp->vdata->dma_chan_attr;
++
++      case CCP_DMA_PRIV:
++              return DMA_PRIVATE;
++
++      case CCP_DMA_PUB:
++              return 0;
++
++      default:
++              dev_info_once(ccp->dev, "Invalid value for dma_chan_attr: %d\n",
++                            dma_chan_attr);
++              return ccp->vdata->dma_chan_attr;
++      }
++}
++
+ static void ccp_free_cmd_resources(struct ccp_device *ccp,
+                                  struct list_head *list)
+ {
+@@ -675,6 +707,15 @@ int ccp_dmaengine_register(struct ccp_de
+       dma_cap_set(DMA_SG, dma_dev->cap_mask);
+       dma_cap_set(DMA_INTERRUPT, dma_dev->cap_mask);
++      /* The DMA channels for this device can be set to public or private,
++       * and overridden by the module parameter dma_chan_attr.
++       * Default: according to the value in vdata (dma_chan_attr=0)
++       * dma_chan_attr=0x1: all channels private (override vdata)
++       * dma_chan_attr=0x2: all channels public (override vdata)
++       */
++      if (ccp_get_dma_chan_attr(ccp) == DMA_PRIVATE)
++              dma_cap_set(DMA_PRIVATE, dma_dev->cap_mask);
++
+       INIT_LIST_HEAD(&dma_dev->channels);
+       for (i = 0; i < ccp->cmd_q_count; i++) {
+               chan = ccp->ccp_dma_chan + i;
diff --git a/queue-4.10/crypto-xts-lrw-fix-out-of-bounds-write-after-kmalloc-failure.patch b/queue-4.10/crypto-xts-lrw-fix-out-of-bounds-write-after-kmalloc-failure.patch
new file mode 100644 (file)
index 0000000..08cc047
--- /dev/null
@@ -0,0 +1,64 @@
+From 9df0eb180c2074451f25556eb566d89c7057c2ac Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Thu, 23 Mar 2017 13:39:46 -0700
+Subject: crypto: xts,lrw - fix out-of-bounds write after kmalloc failure
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit 9df0eb180c2074451f25556eb566d89c7057c2ac upstream.
+
+In the generic XTS and LRW algorithms, for input data > 128 bytes, a
+temporary buffer is allocated to hold the values to be XOR'ed with the
+data before and after encryption or decryption.  If the allocation
+fails, the fixed-size buffer embedded in the request buffer is meant to
+be used as a fallback --- resulting in more calls to the ECB algorithm,
+but still producing the correct result.  However, we weren't correctly
+limiting subreq->cryptlen in this case, resulting in pre_crypt()
+overrunning the embedded buffer.  Fix this by setting subreq->cryptlen
+correctly.
+
+Fixes: f1c131b45410 ("crypto: xts - Convert to skcipher")
+Fixes: 700cb3f5fe75 ("crypto: lrw - Convert to skcipher")
+Reported-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Acked-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/lrw.c |    7 +++++--
+ crypto/xts.c |    7 +++++--
+ 2 files changed, 10 insertions(+), 4 deletions(-)
+
+--- a/crypto/lrw.c
++++ b/crypto/lrw.c
+@@ -286,8 +286,11 @@ static int init_crypt(struct skcipher_re
+       subreq->cryptlen = LRW_BUFFER_SIZE;
+       if (req->cryptlen > LRW_BUFFER_SIZE) {
+-              subreq->cryptlen = min(req->cryptlen, (unsigned)PAGE_SIZE);
+-              rctx->ext = kmalloc(subreq->cryptlen, gfp);
++              unsigned int n = min(req->cryptlen, (unsigned int)PAGE_SIZE);
++
++              rctx->ext = kmalloc(n, gfp);
++              if (rctx->ext)
++                      subreq->cryptlen = n;
+       }
+       rctx->src = req->src;
+--- a/crypto/xts.c
++++ b/crypto/xts.c
+@@ -230,8 +230,11 @@ static int init_crypt(struct skcipher_re
+       subreq->cryptlen = XTS_BUFFER_SIZE;
+       if (req->cryptlen > XTS_BUFFER_SIZE) {
+-              subreq->cryptlen = min(req->cryptlen, (unsigned)PAGE_SIZE);
+-              rctx->ext = kmalloc(subreq->cryptlen, gfp);
++              unsigned int n = min(req->cryptlen, (unsigned int)PAGE_SIZE);
++
++              rctx->ext = kmalloc(n, gfp);
++              if (rctx->ext)
++                      subreq->cryptlen = n;
+       }
+       rctx->src = req->src;
diff --git a/queue-4.10/dt-bindings-rng-clocks-property-on-omap_rng-not-always-mandatory.patch b/queue-4.10/dt-bindings-rng-clocks-property-on-omap_rng-not-always-mandatory.patch
new file mode 100644 (file)
index 0000000..b3c9790
--- /dev/null
@@ -0,0 +1,40 @@
+From 74d1cf4897f919837efc4e34d800b996936eb38e Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Date: Fri, 17 Mar 2017 13:58:39 +0100
+Subject: dt-bindings: rng: clocks property on omap_rng not always mandatory
+
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+
+commit 74d1cf4897f919837efc4e34d800b996936eb38e upstream.
+
+Commit 52060836f79 ("dt-bindings: omap-rng: Document SafeXcel IP-76
+device variant") update the omap_rng Device Tree binding to add support
+for the IP-76 variation of the IP. As part of this change, a "clocks"
+property was added, but is indicated as "Required", without indicated
+it's actually only required for some compatible strings.
+
+This commit fixes that, by explicitly stating that the clocks property
+is only required with the inside-secure,safexcel-eip76 compatible
+string.
+
+Fixes: 52060836f79 ("dt-bindings: omap-rng: Document SafeXcel IP-76 device variant")
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ Documentation/devicetree/bindings/rng/omap_rng.txt |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/Documentation/devicetree/bindings/rng/omap_rng.txt
++++ b/Documentation/devicetree/bindings/rng/omap_rng.txt
+@@ -12,7 +12,8 @@ Required properties:
+ - reg : Offset and length of the register set for the module
+ - interrupts : the interrupt number for the RNG module.
+               Used for "ti,omap4-rng" and "inside-secure,safexcel-eip76"
+-- clocks: the trng clock source
++- clocks: the trng clock source. Only mandatory for the
++  "inside-secure,safexcel-eip76" compatible.
+ Example:
+ /* AM335x */
diff --git a/queue-4.10/hid-wacom-don-t-add-ghost-interface-as-shared-data.patch b/queue-4.10/hid-wacom-don-t-add-ghost-interface-as-shared-data.patch
new file mode 100644 (file)
index 0000000..ea833e8
--- /dev/null
@@ -0,0 +1,57 @@
+From 8b4073596997f2ccbf68d8e72e07b827388a4536 Mon Sep 17 00:00:00 2001
+From: Aaron Armstrong Skomra <skomra@gmail.com>
+Date: Wed, 29 Mar 2017 10:35:39 -0700
+Subject: HID: wacom: Don't add ghost interface as shared data
+
+From: Aaron Armstrong Skomra <skomra@gmail.com>
+
+commit 8b4073596997f2ccbf68d8e72e07b827388a4536 upstream.
+
+A previous commit (below) adds a check for already probed interfaces to
+Wacom's matching heuristic. Unfortunately this causes the Bamboo Pen
+(CTL-460) to match itself to its 'ghost' touch interface. After
+subsequent changes to the driver this match to the ghost causes the
+kernel to crash. This patch avoids calling wacom_add_shared_data()
+for the BAMBOO_PEN's ghost touch interface.
+
+Fixes: 41372d5d40e7 ("HID: wacom: Augment 'oVid' and 'oPid' with heuristics for HID_GENERIC")
+Signed-off-by: Aaron Armstrong Skomra <aaron.skomra@wacom.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/wacom_sys.c |   16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/hid/wacom_sys.c
++++ b/drivers/hid/wacom_sys.c
+@@ -2081,6 +2081,14 @@ static int wacom_parse_and_register(stru
+       wacom_update_name(wacom, wireless ? " (WL)" : "");
++      /* pen only Bamboo neither support touch nor pad */
++      if ((features->type == BAMBOO_PEN) &&
++          ((features->device_type & WACOM_DEVICETYPE_TOUCH) ||
++          (features->device_type & WACOM_DEVICETYPE_PAD))) {
++              error = -ENODEV;
++              goto fail;
++      }
++
+       error = wacom_add_shared_data(hdev);
+       if (error)
+               goto fail;
+@@ -2127,14 +2135,6 @@ static int wacom_parse_and_register(stru
+               error = -ENODEV;
+               goto fail_quirks;
+       }
+-
+-      /* pen only Bamboo neither support touch nor pad */
+-      if ((features->type == BAMBOO_PEN) &&
+-          ((features->device_type & WACOM_DEVICETYPE_TOUCH) ||
+-          (features->device_type & WACOM_DEVICETYPE_PAD))) {
+-              error = -ENODEV;
+-              goto fail_quirks;
+-      }
+       if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR)
+               error = hid_hw_open(hdev);
diff --git a/queue-4.10/mmc-sdhci-disable-runtime-pm-when-the-sdio_irq-is-enabled.patch b/queue-4.10/mmc-sdhci-disable-runtime-pm-when-the-sdio_irq-is-enabled.patch
new file mode 100644 (file)
index 0000000..f4ae761
--- /dev/null
@@ -0,0 +1,74 @@
+From 923713b357455cfb9aca2cd3429cb0806a724ed2 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Sun, 26 Mar 2017 13:14:45 +0200
+Subject: mmc: sdhci: Disable runtime pm when the sdio_irq is enabled
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit 923713b357455cfb9aca2cd3429cb0806a724ed2 upstream.
+
+SDIO cards may need clock to send the card interrupt to the host.
+
+On a cherrytrail tablet with a RTL8723BS wifi chip, without this patch
+pinging the tablet results in:
+
+PING 192.168.1.14 (192.168.1.14) 56(84) bytes of data.
+64 bytes from 192.168.1.14: icmp_seq=1 ttl=64 time=78.6 ms
+64 bytes from 192.168.1.14: icmp_seq=2 ttl=64 time=1760 ms
+64 bytes from 192.168.1.14: icmp_seq=3 ttl=64 time=753 ms
+64 bytes from 192.168.1.14: icmp_seq=4 ttl=64 time=3.88 ms
+64 bytes from 192.168.1.14: icmp_seq=5 ttl=64 time=795 ms
+64 bytes from 192.168.1.14: icmp_seq=6 ttl=64 time=1841 ms
+64 bytes from 192.168.1.14: icmp_seq=7 ttl=64 time=810 ms
+64 bytes from 192.168.1.14: icmp_seq=8 ttl=64 time=1860 ms
+64 bytes from 192.168.1.14: icmp_seq=9 ttl=64 time=812 ms
+64 bytes from 192.168.1.14: icmp_seq=10 ttl=64 time=48.6 ms
+
+Where as with this patch I get:
+
+PING 192.168.1.14 (192.168.1.14) 56(84) bytes of data.
+64 bytes from 192.168.1.14: icmp_seq=1 ttl=64 time=3.96 ms
+64 bytes from 192.168.1.14: icmp_seq=2 ttl=64 time=1.97 ms
+64 bytes from 192.168.1.14: icmp_seq=3 ttl=64 time=17.2 ms
+64 bytes from 192.168.1.14: icmp_seq=4 ttl=64 time=2.46 ms
+64 bytes from 192.168.1.14: icmp_seq=5 ttl=64 time=2.83 ms
+64 bytes from 192.168.1.14: icmp_seq=6 ttl=64 time=1.40 ms
+64 bytes from 192.168.1.14: icmp_seq=7 ttl=64 time=2.10 ms
+64 bytes from 192.168.1.14: icmp_seq=8 ttl=64 time=1.40 ms
+64 bytes from 192.168.1.14: icmp_seq=9 ttl=64 time=2.04 ms
+64 bytes from 192.168.1.14: icmp_seq=10 ttl=64 time=1.40 ms
+
+Cc: Dong Aisheng <b29396@freescale.com>
+Cc: Ian W MORRISON <ianwmorrison@gmail.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Acked-by: Dong Aisheng <aisheng.dong@nxp.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/sdhci.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -1830,6 +1830,9 @@ static void sdhci_enable_sdio_irq(struct
+       struct sdhci_host *host = mmc_priv(mmc);
+       unsigned long flags;
++      if (enable)
++              pm_runtime_get_noresume(host->mmc->parent);
++
+       spin_lock_irqsave(&host->lock, flags);
+       if (enable)
+               host->flags |= SDHCI_SDIO_IRQ_ENABLED;
+@@ -1838,6 +1841,9 @@ static void sdhci_enable_sdio_irq(struct
+       sdhci_enable_sdio_irq_nolock(host, enable);
+       spin_unlock_irqrestore(&host->lock, flags);
++
++      if (!enable)
++              pm_runtime_put_noidle(host->mmc->parent);
+ }
+ static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
diff --git a/queue-4.10/mmc-sdhci-of-at91-fix-mmc_ddr_52-timing-selection.patch b/queue-4.10/mmc-sdhci-of-at91-fix-mmc_ddr_52-timing-selection.patch
new file mode 100644 (file)
index 0000000..de23117
--- /dev/null
@@ -0,0 +1,54 @@
+From d0918764c17b94c30bbb2619929b1719ff52707a Mon Sep 17 00:00:00 2001
+From: Ludovic Desroches <ludovic.desroches@microchip.com>
+Date: Tue, 28 Mar 2017 11:00:45 +0200
+Subject: mmc: sdhci-of-at91: fix MMC_DDR_52 timing selection
+
+From: Ludovic Desroches <ludovic.desroches@microchip.com>
+
+commit d0918764c17b94c30bbb2619929b1719ff52707a upstream.
+
+The controller has different timings for MMC_TIMING_UHS_DDR50 and
+MMC_TIMING_MMC_DDR52. Configuring the controller with SDHCI_CTRL_UHS_DDR50,
+when MMC_TIMING_MMC_DDR52 timings are requested, is not correct and can
+lead to unexpected behavior.
+
+Signed-off-by: Ludovic Desroches <ludovic.desroches@microchip.com>
+Fixes: bb5f8ea4d514 ("mmc: sdhci-of-at91: introduce driver for the Atmel SDMMC")
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/sdhci-of-at91.c |   11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/drivers/mmc/host/sdhci-of-at91.c
++++ b/drivers/mmc/host/sdhci-of-at91.c
+@@ -29,6 +29,8 @@
+ #include "sdhci-pltfm.h"
++#define SDMMC_MC1R    0x204
++#define               SDMMC_MC1R_DDR          BIT(3)
+ #define SDMMC_CACR    0x230
+ #define               SDMMC_CACR_CAPWREN      BIT(0)
+ #define               SDMMC_CACR_KEY          (0x46 << 8)
+@@ -103,11 +105,18 @@ static void sdhci_at91_set_power(struct
+       sdhci_set_power_noreg(host, mode, vdd);
+ }
++void sdhci_at91_set_uhs_signaling(struct sdhci_host *host, unsigned int timing)
++{
++      if (timing == MMC_TIMING_MMC_DDR52)
++              sdhci_writeb(host, SDMMC_MC1R_DDR, SDMMC_MC1R);
++      sdhci_set_uhs_signaling(host, timing);
++}
++
+ static const struct sdhci_ops sdhci_at91_sama5d2_ops = {
+       .set_clock              = sdhci_at91_set_clock,
+       .set_bus_width          = sdhci_set_bus_width,
+       .reset                  = sdhci_reset,
+-      .set_uhs_signaling      = sdhci_set_uhs_signaling,
++      .set_uhs_signaling      = sdhci_at91_set_uhs_signaling,
+       .set_power              = sdhci_at91_set_power,
+ };
diff --git a/queue-4.10/nfsd-map-the-enokey-to-nfserr_perm-for-avoiding-warning.patch b/queue-4.10/nfsd-map-the-enokey-to-nfserr_perm-for-avoiding-warning.patch
new file mode 100644 (file)
index 0000000..c23c2ae
--- /dev/null
@@ -0,0 +1,61 @@
+From c952cd4e949ab3d07287efc2e80246e03727d15d Mon Sep 17 00:00:00 2001
+From: Kinglong Mee <kinglongmee@gmail.com>
+Date: Fri, 10 Mar 2017 09:52:20 +0800
+Subject: nfsd: map the ENOKEY to nfserr_perm for avoiding warning
+
+From: Kinglong Mee <kinglongmee@gmail.com>
+
+commit c952cd4e949ab3d07287efc2e80246e03727d15d upstream.
+
+Now that Ext4 and f2fs filesystems support encrypted directories and
+files, attempts to access those files may return ENOKEY, resulting in
+the following WARNING.
+
+Map ENOKEY to nfserr_perm instead of nfserr_io.
+
+[ 1295.411759] ------------[ cut here ]------------
+[ 1295.411787] WARNING: CPU: 0 PID: 12786 at fs/nfsd/nfsproc.c:796 nfserrno+0x74/0x80 [nfsd]
+[ 1295.411806] nfsd: non-standard errno: -126
+[ 1295.411816] Modules linked in: nfsd nfs_acl auth_rpcgss nfsv4 nfs lockd fscache tun bridge stp llc fuse ip_set nfnetlink vmw_vsock_vmci_transport vsock snd_seq_midi snd_seq_midi_event coretemp crct10dif_pclmul crc32_generic crc32_pclmul snd_ens1371 gameport ghash_clmulni_intel snd_ac97_codec f2fs intel_rapl_perf ac97_bus snd_seq ppdev snd_pcm snd_rawmidi snd_timer vmw_balloon snd_seq_device snd joydev soundcore parport_pc parport nfit acpi_cpufreq tpm_tis vmw_vmci tpm_tis_core tpm shpchp i2c_piix4 grace sunrpc xfs libcrc32c vmwgfx drm_kms_helper ttm drm crc32c_intel e1000 mptspi scsi_transport_spi serio_raw mptscsih mptbase ata_generic pata_acpi fjes [last unloaded: nfs_acl]
+[ 1295.412522] CPU: 0 PID: 12786 Comm: nfsd Tainted: G        W       4.11.0-rc1+ #521
+[ 1295.412959] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/02/2015
+[ 1295.413814] Call Trace:
+[ 1295.414252]  dump_stack+0x63/0x86
+[ 1295.414666]  __warn+0xcb/0xf0
+[ 1295.415087]  warn_slowpath_fmt+0x5f/0x80
+[ 1295.415502]  ? put_filp+0x42/0x50
+[ 1295.415927]  nfserrno+0x74/0x80 [nfsd]
+[ 1295.416339]  nfsd_open+0xd7/0x180 [nfsd]
+[ 1295.416746]  nfs4_get_vfs_file+0x367/0x3c0 [nfsd]
+[ 1295.417182]  ? security_inode_permission+0x41/0x60
+[ 1295.417591]  nfsd4_process_open2+0x9b2/0x1200 [nfsd]
+[ 1295.418007]  nfsd4_open+0x481/0x790 [nfsd]
+[ 1295.418409]  nfsd4_proc_compound+0x395/0x680 [nfsd]
+[ 1295.418812]  nfsd_dispatch+0xb8/0x1f0 [nfsd]
+[ 1295.419233]  svc_process_common+0x4d9/0x830 [sunrpc]
+[ 1295.419631]  svc_process+0xfe/0x1b0 [sunrpc]
+[ 1295.420033]  nfsd+0xe9/0x150 [nfsd]
+[ 1295.420420]  kthread+0x101/0x140
+[ 1295.420802]  ? nfsd_destroy+0x60/0x60 [nfsd]
+[ 1295.421199]  ? kthread_park+0x90/0x90
+[ 1295.421598]  ret_from_fork+0x2c/0x40
+[ 1295.421996] ---[ end trace 0d5a969cd7852e1f ]---
+
+Signed-off-by: Kinglong Mee <kinglongmee@gmail.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfsd/nfsproc.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/nfsd/nfsproc.c
++++ b/fs/nfsd/nfsproc.c
+@@ -790,6 +790,7 @@ nfserrno (int errno)
+               { nfserr_serverfault, -ESERVERFAULT },
+               { nfserr_serverfault, -ENFILE },
+               { nfserr_io, -EUCLEAN },
++              { nfserr_perm, -ENOKEY },
+       };
+       int     i;
diff --git a/queue-4.10/nfsv4.1-fix-infinite-loop-on-io-bad_stateid-error.patch b/queue-4.10/nfsv4.1-fix-infinite-loop-on-io-bad_stateid-error.patch
new file mode 100644 (file)
index 0000000..3986610
--- /dev/null
@@ -0,0 +1,47 @@
+From 0e3d3e5df07dcf8a50d96e0ecd6ab9a888f55dfc Mon Sep 17 00:00:00 2001
+From: Olga Kornievskaia <kolga@netapp.com>
+Date: Thu, 30 Mar 2017 13:49:03 -0400
+Subject: NFSv4.1 fix infinite loop on IO BAD_STATEID error
+
+From: Olga Kornievskaia <kolga@netapp.com>
+
+commit 0e3d3e5df07dcf8a50d96e0ecd6ab9a888f55dfc upstream.
+
+Commit 63d63cbf5e03 "NFSv4.1: Don't recheck delegations that
+have already been checked" introduced a regression where when a
+client received BAD_STATEID error it would not send any TEST_STATEID
+and instead go into an infinite loop of resending the IO that caused
+the BAD_STATEID.
+
+Fixes: 63d63cbf5e03 ("NFSv4.1: Don't recheck delegations that have already been checked")
+Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/nfs4proc.c |    9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -2550,17 +2550,14 @@ static void nfs41_check_delegation_state
+       }
+       nfs4_stateid_copy(&stateid, &delegation->stateid);
+-      if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
++      if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) ||
++              !test_and_clear_bit(NFS_DELEGATION_TEST_EXPIRED,
++                      &delegation->flags)) {
+               rcu_read_unlock();
+               nfs_finish_clear_delegation_stateid(state, &stateid);
+               return;
+       }
+-      if (!test_and_clear_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags)) {
+-              rcu_read_unlock();
+-              return;
+-      }
+-
+       cred = get_rpccred(delegation->cred);
+       rcu_read_unlock();
+       status = nfs41_test_and_free_expired_stateid(server, &stateid, cred);
diff --git a/queue-4.10/parisc-avoid-stalled-cpu-warnings-after-system-shutdown.patch b/queue-4.10/parisc-avoid-stalled-cpu-warnings-after-system-shutdown.patch
new file mode 100644 (file)
index 0000000..6f14271
--- /dev/null
@@ -0,0 +1,33 @@
+From 476e75a44b56038bee9207242d4bc718f6b4de06 Mon Sep 17 00:00:00 2001
+From: Helge Deller <deller@gmx.de>
+Date: Wed, 29 Mar 2017 08:25:30 +0200
+Subject: parisc: Avoid stalled CPU warnings after system shutdown
+
+From: Helge Deller <deller@gmx.de>
+
+commit 476e75a44b56038bee9207242d4bc718f6b4de06 upstream.
+
+Commit 73580dac7618 ("parisc: Fix system shutdown halt") introduced an endless
+loop for systems which don't provide a software power off function.  But the
+soft lockup detector will detect this and report stalled CPUs after some time.
+Avoid those unwanted warnings by disabling the soft lockup detector.
+
+Fixes: 73580dac7618 ("parisc: Fix system shutdown halt")
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/parisc/kernel/process.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/parisc/kernel/process.c
++++ b/arch/parisc/kernel/process.c
+@@ -140,6 +140,8 @@ void machine_power_off(void)
+       printk(KERN_EMERG "System shut down completed.\n"
+              "Please power this system off now.");
++      /* prevent soft lockup/stalled CPU messages for endless loop. */
++      rcu_sysrq_start();
+       for (;;);
+ }
diff --git a/queue-4.10/parisc-clean-up-fixup-routines-for-get_user-put_user.patch b/queue-4.10/parisc-clean-up-fixup-routines-for-get_user-put_user.patch
new file mode 100644 (file)
index 0000000..4448e15
--- /dev/null
@@ -0,0 +1,303 @@
+From d19f5e41b344a057bb2450024a807476f30978d2 Mon Sep 17 00:00:00 2001
+From: Helge Deller <deller@gmx.de>
+Date: Sat, 25 Mar 2017 11:59:15 +0100
+Subject: parisc: Clean up fixup routines for get_user()/put_user()
+
+From: Helge Deller <deller@gmx.de>
+
+commit d19f5e41b344a057bb2450024a807476f30978d2 upstream.
+
+Al Viro noticed that userspace accesses via get_user()/put_user() can be
+simplified a lot with regard to usage of the exception handling.
+
+This patch implements a fixup routine for get_user() and put_user() in such
+that the exception handler will automatically load -EFAULT into the register
+%r8 (the error value) in case on a fault on userspace.  Additionally the fixup
+routine will zero the target register on fault in case of a get_user() call.
+The target register is extracted out of the faulting assembly instruction.
+
+This patch brings a few benefits over the old implementation:
+1. Exception handling gets much cleaner, easier and smaller in size.
+2. Helper functions like fixup_get_user_skip_1 (all of fixup.S) can be dropped.
+3. No need to hardcode %r9 as target register for get_user() any longer. This
+   helps the compiler register allocator and thus creates less assembler
+   statements.
+4. No dependency on the exception_data contents any longer.
+5. Nested faults will be handled cleanly.
+
+Reported-by: Al Viro <viro@ZenIV.linux.org.uk>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/parisc/include/asm/uaccess.h |   59 +++++++++++++---------
+ arch/parisc/kernel/parisc_ksyms.c |   10 ---
+ arch/parisc/lib/Makefile          |    2 
+ arch/parisc/lib/fixup.S           |   98 --------------------------------------
+ arch/parisc/mm/fault.c            |   17 ++++++
+ 5 files changed, 52 insertions(+), 134 deletions(-)
+
+--- a/arch/parisc/include/asm/uaccess.h
++++ b/arch/parisc/include/asm/uaccess.h
+@@ -68,6 +68,15 @@ struct exception_table_entry {
+       ".previous\n"
+ /*
++ * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() creates a special exception table entry
++ * (with lowest bit set) for which the fault handler in fixup_exception() will
++ * load -EFAULT into %r8 for a read or write fault, and zeroes the target
++ * register in case of a read fault in get_user().
++ */
++#define ASM_EXCEPTIONTABLE_ENTRY_EFAULT( fault_addr, except_addr )\
++      ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr + 1)
++
++/*
+  * The page fault handler stores, in a per-cpu area, the following information
+  * if a fixup routine is available.
+  */
+@@ -94,7 +103,7 @@ struct exception_data {
+ #define __get_user(x, ptr)                               \
+ ({                                                       \
+       register long __gu_err __asm__ ("r8") = 0;       \
+-      register long __gu_val __asm__ ("r9") = 0;       \
++      register long __gu_val;                          \
+                                                        \
+       load_sr2();                                      \
+       switch (sizeof(*(ptr))) {                        \
+@@ -110,22 +119,23 @@ struct exception_data {
+ })
+ #define __get_user_asm(ldx, ptr)                        \
+-      __asm__("\n1:\t" ldx "\t0(%%sr2,%2),%0\n\t"     \
+-              ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_get_user_skip_1)\
++      __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)               \
+-              : "r1");
++              : "r"(ptr), "1"(__gu_err));
+ #if !defined(CONFIG_64BIT)
+ #define __get_user_asm64(ptr)                                 \
+-      __asm__("\n1:\tldw 0(%%sr2,%2),%0"              \
+-              "\n2:\tldw 4(%%sr2,%2),%R0\n\t"         \
+-              ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_get_user_skip_2)\
+-              ASM_EXCEPTIONTABLE_ENTRY(2b, fixup_get_user_skip_1)\
++      __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)               \
+-              : "r1");
++              : "r"(ptr), "1"(__gu_err));
+ #endif /* !defined(CONFIG_64BIT) */
+@@ -151,32 +161,31 @@ struct exception_data {
+  * 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
+  * gcc knows about, so there are no aliasing issues. These macros must
+- * also be aware that "fixup_put_user_skip_[12]" are executed in the
+- * context of the fault, and any registers used there must be listed
+- * as clobbers. In this case only "r1" is used by the current routines.
+- * r8/r9 are already listed as err/val.
++ * also be aware that fixups are executed in the context of the fault,
++ * and any registers used there must be listed as clobbers.
++ * r8 is already listed as err.
+  */
+ #define __put_user_asm(stx, x, ptr)                         \
+       __asm__ __volatile__ (                              \
+-              "\n1:\t" stx "\t%2,0(%%sr2,%1)\n\t"         \
+-              ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_put_user_skip_1)\
++              "1: " stx " %2,0(%%sr2,%1)\n"               \
++              "9:\n"                                      \
++              ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b)     \
+               : "=r"(__pu_err)                            \
+-              : "r"(ptr), "r"(x), "0"(__pu_err)           \
+-              : "r1")
++              : "r"(ptr), "r"(x), "0"(__pu_err))
+ #if !defined(CONFIG_64BIT)
+ #define __put_user_asm64(__val, ptr) do {                 \
+       __asm__ __volatile__ (                              \
+-              "\n1:\tstw %2,0(%%sr2,%1)"                  \
+-              "\n2:\tstw %R2,4(%%sr2,%1)\n\t"             \
+-              ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_put_user_skip_2)\
+-              ASM_EXCEPTIONTABLE_ENTRY(2b, fixup_put_user_skip_1)\
++              "1: stw %2,0(%%sr2,%1)\n"                   \
++              "2: stw %R2,4(%%sr2,%1)\n"                  \
++              "9:\n"                                      \
++              ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b)     \
++              ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b)     \
+               : "=r"(__pu_err)                            \
+-              : "r"(ptr), "r"(__val), "0"(__pu_err) \
+-              : "r1");                                    \
++              : "r"(ptr), "r"(__val), "0"(__pu_err));     \
+ } while (0)
+ #endif /* !defined(CONFIG_64BIT) */
+--- a/arch/parisc/kernel/parisc_ksyms.c
++++ b/arch/parisc/kernel/parisc_ksyms.c
+@@ -47,16 +47,6 @@ EXPORT_SYMBOL(__cmpxchg_u64);
+ EXPORT_SYMBOL(lclear_user);
+ EXPORT_SYMBOL(lstrnlen_user);
+-/* Global fixups - defined as int to avoid creation of function pointers */
+-extern int fixup_get_user_skip_1;
+-extern int fixup_get_user_skip_2;
+-extern int fixup_put_user_skip_1;
+-extern int fixup_put_user_skip_2;
+-EXPORT_SYMBOL(fixup_get_user_skip_1);
+-EXPORT_SYMBOL(fixup_get_user_skip_2);
+-EXPORT_SYMBOL(fixup_put_user_skip_1);
+-EXPORT_SYMBOL(fixup_put_user_skip_2);
+-
+ #ifndef CONFIG_64BIT
+ /* Needed so insmod can set dp value */
+ extern int $global$;
+--- a/arch/parisc/lib/Makefile
++++ b/arch/parisc/lib/Makefile
+@@ -2,7 +2,7 @@
+ # Makefile for parisc-specific library files
+ #
+-lib-y := lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o \
++lib-y := lusercopy.o bitops.o checksum.o io.o memset.o memcpy.o \
+          ucmpdi2.o delay.o
+ obj-y := iomap.o
+--- a/arch/parisc/lib/fixup.S
++++ /dev/null
+@@ -1,98 +0,0 @@
+-/*
+- * Linux/PA-RISC Project (http://www.parisc-linux.org/)
+- *
+- *  Copyright (C) 2004  Randolph Chung <tausq@debian.org>
+- *
+- *    This program is free software; you can redistribute it and/or modify
+- *    it under the terms of the GNU General Public License as published by
+- *    the Free Software Foundation; either version 2, or (at your option)
+- *    any later version.
+- *
+- *    This program is distributed in the hope that it will be useful,
+- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- *    GNU General Public License for more details.
+- *
+- *    You should have received a copy of the GNU General Public License
+- *    along with this program; if not, write to the Free Software
+- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+- * 
+- * Fixup routines for kernel exception handling.
+- */
+-#include <asm/asm-offsets.h>
+-#include <asm/assembly.h>
+-#include <asm/errno.h>
+-#include <linux/linkage.h>
+-
+-#ifdef CONFIG_SMP
+-      .macro  get_fault_ip t1 t2
+-      loadgp
+-      addil LT%__per_cpu_offset,%r27
+-      LDREG RT%__per_cpu_offset(%r1),\t1
+-      /* t2 = smp_processor_id() */
+-      mfctl 30,\t2
+-      ldw TI_CPU(\t2),\t2
+-#ifdef CONFIG_64BIT
+-      extrd,u \t2,63,32,\t2
+-#endif
+-      /* t2 = &__per_cpu_offset[smp_processor_id()]; */
+-      LDREGX \t2(\t1),\t2 
+-      addil LT%exception_data,%r27
+-      LDREG RT%exception_data(%r1),\t1
+-      /* t1 = this_cpu_ptr(&exception_data) */
+-      add,l \t1,\t2,\t1
+-      /* %r27 = t1->fault_gp - restore gp */
+-      LDREG EXCDATA_GP(\t1), %r27
+-      /* t1 = t1->fault_ip */
+-      LDREG EXCDATA_IP(\t1), \t1
+-      .endm
+-#else
+-      .macro  get_fault_ip t1 t2
+-      loadgp
+-      /* t1 = this_cpu_ptr(&exception_data) */
+-      addil LT%exception_data,%r27
+-      LDREG RT%exception_data(%r1),\t2
+-      /* %r27 = t2->fault_gp - restore gp */
+-      LDREG EXCDATA_GP(\t2), %r27
+-      /* t1 = t2->fault_ip */
+-      LDREG EXCDATA_IP(\t2), \t1
+-      .endm
+-#endif
+-
+-      .level LEVEL
+-
+-      .text
+-      .section .fixup, "ax"
+-
+-      /* get_user() fixups, store -EFAULT in r8, and 0 in r9 */
+-ENTRY_CFI(fixup_get_user_skip_1)
+-      get_fault_ip %r1,%r8
+-      ldo 4(%r1), %r1
+-      ldi -EFAULT, %r8
+-      bv %r0(%r1)
+-      copy %r0, %r9
+-ENDPROC_CFI(fixup_get_user_skip_1)
+-
+-ENTRY_CFI(fixup_get_user_skip_2)
+-      get_fault_ip %r1,%r8
+-      ldo 8(%r1), %r1
+-      ldi -EFAULT, %r8
+-      bv %r0(%r1)
+-      copy %r0, %r9
+-ENDPROC_CFI(fixup_get_user_skip_2)
+-
+-      /* put_user() fixups, store -EFAULT in r8 */
+-ENTRY_CFI(fixup_put_user_skip_1)
+-      get_fault_ip %r1,%r8
+-      ldo 4(%r1), %r1
+-      bv %r0(%r1)
+-      ldi -EFAULT, %r8
+-ENDPROC_CFI(fixup_put_user_skip_1)
+-
+-ENTRY_CFI(fixup_put_user_skip_2)
+-      get_fault_ip %r1,%r8
+-      ldo 8(%r1), %r1
+-      bv %r0(%r1)
+-      ldi -EFAULT, %r8
+-ENDPROC_CFI(fixup_put_user_skip_2)
+-
+--- a/arch/parisc/mm/fault.c
++++ b/arch/parisc/mm/fault.c
+@@ -149,6 +149,23 @@ int fixup_exception(struct pt_regs *regs
+               d->fault_space = regs->isr;
+               d->fault_addr = regs->ior;
++              /*
++               * Fix up get_user() and put_user().
++               * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() sets the least-significant
++               * bit in the relative address of the fixup routine to indicate
++               * that %r8 should be loaded with -EFAULT to report a userspace
++               * access error.
++               */
++              if (fix->fixup & 1) {
++                      regs->gr[8] = -EFAULT;
++
++                      /* zero target register for get_user() */
++                      if (parisc_acctyp(0, regs->iir) == VM_READ) {
++                              int treg = regs->iir & 0x1f;
++                              regs->gr[treg] = 0;
++                      }
++              }
++
+               regs->iaoq[0] = (unsigned long)&fix->fixup + fix->fixup;
+               regs->iaoq[0] &= ~3;
+               /*
diff --git a/queue-4.10/parisc-fix-access-fault-handling-in-pa_memcpy.patch b/queue-4.10/parisc-fix-access-fault-handling-in-pa_memcpy.patch
new file mode 100644 (file)
index 0000000..cb781d7
--- /dev/null
@@ -0,0 +1,862 @@
+From 554bfeceb8a22d448cd986fc9efce25e833278a1 Mon Sep 17 00:00:00 2001
+From: Helge Deller <deller@gmx.de>
+Date: Wed, 29 Mar 2017 21:41:05 +0200
+Subject: parisc: Fix access fault handling in pa_memcpy()
+
+From: Helge Deller <deller@gmx.de>
+
+commit 554bfeceb8a22d448cd986fc9efce25e833278a1 upstream.
+
+pa_memcpy() is the major memcpy implementation in the parisc kernel which is
+used to do any kind of userspace/kernel memory copies.
+
+Al Viro noticed various bugs in the implementation of pa_mempcy(), most notably
+that in case of faults it may report back to have copied more bytes than it
+actually did.
+
+Fixing those bugs is quite hard in the C-implementation, because the compiler
+is messing around with the registers and we are not guaranteed that specific
+variables are always in the same processor registers. This makes proper fault
+handling complicated.
+
+This patch implements pa_memcpy() in assembler. That way we have correct fault
+handling and adding a 64-bit copy routine was quite easy.
+
+Runtime tested with 32- and 64bit kernels.
+
+Reported-by: Al Viro <viro@ZenIV.linux.org.uk>
+Signed-off-by: John David Anglin <dave.anglin@bell.net>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/parisc/lib/lusercopy.S |  318 ++++++++++++++++++++++++++++++
+ arch/parisc/lib/memcpy.c    |  461 --------------------------------------------
+ 2 files changed, 321 insertions(+), 458 deletions(-)
+
+--- a/arch/parisc/lib/lusercopy.S
++++ b/arch/parisc/lib/lusercopy.S
+@@ -5,6 +5,8 @@
+  *    Copyright (C) 2000 Richard Hirst <rhirst with parisc-linux.org>
+  *    Copyright (C) 2001 Matthieu Delahaye <delahaym at esiee.fr>
+  *    Copyright (C) 2003 Randolph Chung <tausq with parisc-linux.org>
++ *    Copyright (C) 2017 Helge Deller <deller@gmx.de>
++ *    Copyright (C) 2017 John David Anglin <dave.anglin@bell.net>
+  *
+  *
+  *    This program is free software; you can redistribute it and/or modify
+@@ -132,4 +134,320 @@ ENDPROC_CFI(lstrnlen_user)
+       .procend
++
++
++/*
++ * unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len)
++ *
++ * Inputs:
++ * - sr1 already contains space of source region
++ * - sr2 already contains space of destination region
++ *
++ * Returns:
++ * - number of bytes that could not be copied.
++ *   On success, this will be zero.
++ *
++ * This code is based on a C-implementation of a copy routine written by
++ * Randolph Chung, which in turn was derived from the glibc.
++ *
++ * Several strategies are tried to try to get the best performance for various
++ * conditions. In the optimal case, we copy by loops that copy 32- or 16-bytes
++ * at a time using general registers.  Unaligned copies are handled either by
++ * aligning the destination and then using shift-and-write method, or in a few
++ * cases by falling back to a byte-at-a-time copy.
++ *
++ * Testing with various alignments and buffer sizes shows that this code is
++ * often >10x faster than a simple byte-at-a-time copy, even for strangely
++ * aligned operands. It is interesting to note that the glibc version of memcpy
++ * (written in C) is actually quite fast already. This routine is able to beat
++ * it by 30-40% for aligned copies because of the loop unrolling, but in some
++ * cases the glibc version is still slightly faster. This lends more
++ * credibility that gcc can generate very good code as long as we are careful.
++ *
++ * Possible optimizations:
++ * - add cache prefetching
++ * - try not to use the post-increment address modifiers; they may create
++ *   additional interlocks. Assumption is that those were only efficient on old
++ *   machines (pre PA8000 processors)
++ */
++
++      dst = arg0
++      src = arg1
++      len = arg2
++      end = arg3
++      t1  = r19
++      t2  = r20
++      t3  = r21
++      t4  = r22
++      srcspc = sr1
++      dstspc = sr2
++
++      t0 = r1
++      a1 = t1
++      a2 = t2
++      a3 = t3
++      a0 = t4
++
++      save_src = ret0
++      save_dst = ret1
++      save_len = r31
++
++ENTRY_CFI(pa_memcpy)
++      .proc
++      .callinfo NO_CALLS
++      .entry
++
++      /* Last destination address */
++      add     dst,len,end
++
++      /* short copy with less than 16 bytes? */
++      cmpib,>>=,n 15,len,.Lbyte_loop
++
++      /* same alignment? */
++      xor     src,dst,t0
++      extru   t0,31,2,t1
++      cmpib,<>,n  0,t1,.Lunaligned_copy
++
++#ifdef CONFIG_64BIT
++      /* only do 64-bit copies if we can get aligned. */
++      extru   t0,31,3,t1
++      cmpib,<>,n  0,t1,.Lalign_loop32
++
++      /* loop until we are 64-bit aligned */
++.Lalign_loop64:
++      extru   dst,31,3,t1
++      cmpib,=,n       0,t1,.Lcopy_loop_16
++20:   ldb,ma  1(srcspc,src),t1
++21:   stb,ma  t1,1(dstspc,dst)
++      b       .Lalign_loop64
++      ldo     -1(len),len
++
++      ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done)
++      ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done)
++
++      ldi     31,t0
++.Lcopy_loop_16:
++      cmpb,COND(>>=),n t0,len,.Lword_loop
++
++10:   ldd     0(srcspc,src),t1
++11:   ldd     8(srcspc,src),t2
++      ldo     16(src),src
++12:   std,ma  t1,8(dstspc,dst)
++13:   std,ma  t2,8(dstspc,dst)
++14:   ldd     0(srcspc,src),t1
++15:   ldd     8(srcspc,src),t2
++      ldo     16(src),src
++16:   std,ma  t1,8(dstspc,dst)
++17:   std,ma  t2,8(dstspc,dst)
++
++      ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done)
++      ASM_EXCEPTIONTABLE_ENTRY(11b,.Lcopy16_fault)
++      ASM_EXCEPTIONTABLE_ENTRY(12b,.Lcopy_done)
++      ASM_EXCEPTIONTABLE_ENTRY(13b,.Lcopy_done)
++      ASM_EXCEPTIONTABLE_ENTRY(14b,.Lcopy_done)
++      ASM_EXCEPTIONTABLE_ENTRY(15b,.Lcopy16_fault)
++      ASM_EXCEPTIONTABLE_ENTRY(16b,.Lcopy_done)
++      ASM_EXCEPTIONTABLE_ENTRY(17b,.Lcopy_done)
++
++      b       .Lcopy_loop_16
++      ldo     -32(len),len
++
++.Lword_loop:
++      cmpib,COND(>>=),n 3,len,.Lbyte_loop
++20:   ldw,ma  4(srcspc,src),t1
++21:   stw,ma  t1,4(dstspc,dst)
++      b       .Lword_loop
++      ldo     -4(len),len
++
++      ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done)
++      ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done)
++
++#endif /* CONFIG_64BIT */
++
++      /* loop until we are 32-bit aligned */
++.Lalign_loop32:
++      extru   dst,31,2,t1
++      cmpib,=,n       0,t1,.Lcopy_loop_4
++20:   ldb,ma  1(srcspc,src),t1
++21:   stb,ma  t1,1(dstspc,dst)
++      b       .Lalign_loop32
++      ldo     -1(len),len
++
++      ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done)
++      ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done)
++
++
++.Lcopy_loop_4:
++      cmpib,COND(>>=),n 15,len,.Lbyte_loop
++
++10:   ldw     0(srcspc,src),t1
++11:   ldw     4(srcspc,src),t2
++12:   stw,ma  t1,4(dstspc,dst)
++13:   stw,ma  t2,4(dstspc,dst)
++14:   ldw     8(srcspc,src),t1
++15:   ldw     12(srcspc,src),t2
++      ldo     16(src),src
++16:   stw,ma  t1,4(dstspc,dst)
++17:   stw,ma  t2,4(dstspc,dst)
++
++      ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done)
++      ASM_EXCEPTIONTABLE_ENTRY(11b,.Lcopy8_fault)
++      ASM_EXCEPTIONTABLE_ENTRY(12b,.Lcopy_done)
++      ASM_EXCEPTIONTABLE_ENTRY(13b,.Lcopy_done)
++      ASM_EXCEPTIONTABLE_ENTRY(14b,.Lcopy_done)
++      ASM_EXCEPTIONTABLE_ENTRY(15b,.Lcopy8_fault)
++      ASM_EXCEPTIONTABLE_ENTRY(16b,.Lcopy_done)
++      ASM_EXCEPTIONTABLE_ENTRY(17b,.Lcopy_done)
++
++      b       .Lcopy_loop_4
++      ldo     -16(len),len
++
++.Lbyte_loop:
++      cmpclr,COND(<>) len,%r0,%r0
++      b,n     .Lcopy_done
++20:   ldb     0(srcspc,src),t1
++      ldo     1(src),src
++21:   stb,ma  t1,1(dstspc,dst)
++      b       .Lbyte_loop
++      ldo     -1(len),len
++
++      ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done)
++      ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done)
++
++.Lcopy_done:
++      bv      %r0(%r2)
++      sub     end,dst,ret0
++
++
++      /* src and dst are not aligned the same way. */
++      /* need to go the hard way */
++.Lunaligned_copy:
++      /* align until dst is 32bit-word-aligned */
++      extru   dst,31,2,t1
++      cmpib,COND(=),n 0,t1,.Lcopy_dstaligned
++20:   ldb     0(srcspc,src),t1
++      ldo     1(src),src
++21:   stb,ma  t1,1(dstspc,dst)
++      b       .Lunaligned_copy
++      ldo     -1(len),len
++
++      ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done)
++      ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done)
++
++.Lcopy_dstaligned:
++
++      /* store src, dst and len in safe place */
++      copy    src,save_src
++      copy    dst,save_dst
++      copy    len,save_len
++
++      /* len now needs give number of words to copy */
++      SHRREG  len,2,len
++
++      /*
++       * Copy from a not-aligned src to an aligned dst using shifts.
++       * Handles 4 words per loop.
++       */
++
++      depw,z src,28,2,t0
++      subi 32,t0,t0
++      mtsar t0
++      extru len,31,2,t0
++      cmpib,= 2,t0,.Lcase2
++      /* Make src aligned by rounding it down.  */
++      depi 0,31,2,src
++
++      cmpiclr,<> 3,t0,%r0
++      b,n .Lcase3
++      cmpiclr,<> 1,t0,%r0
++      b,n .Lcase1
++.Lcase0:
++      cmpb,= %r0,len,.Lcda_finish
++      nop
++
++1:    ldw,ma 4(srcspc,src), a3
++      ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
++1:    ldw,ma 4(srcspc,src), a0
++      ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
++      b,n .Ldo3
++.Lcase1:
++1:    ldw,ma 4(srcspc,src), a2
++      ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
++1:    ldw,ma 4(srcspc,src), a3
++      ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
++      ldo -1(len),len
++      cmpb,=,n %r0,len,.Ldo0
++.Ldo4:
++1:    ldw,ma 4(srcspc,src), a0
++      ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
++      shrpw a2, a3, %sar, t0
++1:    stw,ma t0, 4(dstspc,dst)
++      ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done)
++.Ldo3:
++1:    ldw,ma 4(srcspc,src), a1
++      ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
++      shrpw a3, a0, %sar, t0
++1:    stw,ma t0, 4(dstspc,dst)
++      ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done)
++.Ldo2:
++1:    ldw,ma 4(srcspc,src), a2
++      ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
++      shrpw a0, a1, %sar, t0
++1:    stw,ma t0, 4(dstspc,dst)
++      ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done)
++.Ldo1:
++1:    ldw,ma 4(srcspc,src), a3
++      ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
++      shrpw a1, a2, %sar, t0
++1:    stw,ma t0, 4(dstspc,dst)
++      ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done)
++      ldo -4(len),len
++      cmpb,<> %r0,len,.Ldo4
++      nop
++.Ldo0:
++      shrpw a2, a3, %sar, t0
++1:    stw,ma t0, 4(dstspc,dst)
++      ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done)
++
++.Lcda_rdfault:
++.Lcda_finish:
++      /* calculate new src, dst and len and jump to byte-copy loop */
++      sub     dst,save_dst,t0
++      add     save_src,t0,src
++      b       .Lbyte_loop
++      sub     save_len,t0,len
++
++.Lcase3:
++1:    ldw,ma 4(srcspc,src), a0
++      ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
++1:    ldw,ma 4(srcspc,src), a1
++      ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
++      b .Ldo2
++      ldo 1(len),len
++.Lcase2:
++1:    ldw,ma 4(srcspc,src), a1
++      ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
++1:    ldw,ma 4(srcspc,src), a2
++      ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
++      b .Ldo1
++      ldo 2(len),len
++
++
++      /* fault exception fixup handlers: */
++#ifdef CONFIG_64BIT
++.Lcopy16_fault:
++10:   b       .Lcopy_done
++      std,ma  t1,8(dstspc,dst)
++      ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done)
++#endif
++
++.Lcopy8_fault:
++10:   b       .Lcopy_done
++      stw,ma  t1,4(dstspc,dst)
++      ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done)
++
++      .exit
++ENDPROC_CFI(pa_memcpy)
++      .procend
++
+       .end
+--- a/arch/parisc/lib/memcpy.c
++++ b/arch/parisc/lib/memcpy.c
+@@ -2,7 +2,7 @@
+  *    Optimized memory copy routines.
+  *
+  *    Copyright (C) 2004 Randolph Chung <tausq@debian.org>
+- *    Copyright (C) 2013 Helge Deller <deller@gmx.de>
++ *    Copyright (C) 2013-2017 Helge Deller <deller@gmx.de>
+  *
+  *    This program is free software; you can redistribute it and/or modify
+  *    it under the terms of the GNU General Public License as published by
+@@ -21,474 +21,21 @@
+  *    Portions derived from the GNU C Library
+  *    Copyright (C) 1991, 1997, 2003 Free Software Foundation, Inc.
+  *
+- * Several strategies are tried to try to get the best performance for various
+- * conditions. In the optimal case, we copy 64-bytes in an unrolled loop using 
+- * fp regs. This is followed by loops that copy 32- or 16-bytes at a time using
+- * general registers.  Unaligned copies are handled either by aligning the 
+- * destination and then using shift-and-write method, or in a few cases by 
+- * falling back to a byte-at-a-time copy.
+- *
+- * I chose to implement this in C because it is easier to maintain and debug,
+- * and in my experiments it appears that the C code generated by gcc (3.3/3.4
+- * at the time of writing) is fairly optimal. Unfortunately some of the 
+- * semantics of the copy routine (exception handling) is difficult to express
+- * in C, so we have to play some tricks to get it to work.
+- *
+- * All the loads and stores are done via explicit asm() code in order to use
+- * the right space registers. 
+- * 
+- * Testing with various alignments and buffer sizes shows that this code is 
+- * often >10x faster than a simple byte-at-a-time copy, even for strangely
+- * aligned operands. It is interesting to note that the glibc version
+- * of memcpy (written in C) is actually quite fast already. This routine is 
+- * able to beat it by 30-40% for aligned copies because of the loop unrolling, 
+- * but in some cases the glibc version is still slightly faster. This lends 
+- * more credibility that gcc can generate very good code as long as we are 
+- * careful.
+- *
+- * TODO:
+- * - cache prefetching needs more experimentation to get optimal settings
+- * - try not to use the post-increment address modifiers; they create additional
+- *   interlocks
+- * - replace byte-copy loops with stybs sequences
+  */
+-#ifdef __KERNEL__
+ #include <linux/module.h>
+ #include <linux/compiler.h>
+ #include <linux/uaccess.h>
+-#define s_space "%%sr1"
+-#define d_space "%%sr2"
+-#else
+-#include "memcpy.h"
+-#define s_space "%%sr0"
+-#define d_space "%%sr0"
+-#define pa_memcpy new2_copy
+-#endif
+ DECLARE_PER_CPU(struct exception_data, exception_data);
+-#define preserve_branch(label)        do {                                    \
+-      volatile int dummy = 0;                                         \
+-      /* The following branch is never taken, it's just here to  */   \
+-      /* prevent gcc from optimizing away our exception code. */      \
+-      if (unlikely(dummy != dummy))                                   \
+-              goto label;                                             \
+-} while (0)
+-
+ #define get_user_space() (segment_eq(get_fs(), KERNEL_DS) ? 0 : mfsp(3))
+ #define get_kernel_space() (0)
+-#define MERGE(w0, sh_1, w1, sh_2)  ({                                 \
+-      unsigned int _r;                                                \
+-      asm volatile (                                                  \
+-      "mtsar %3\n"                                                    \
+-      "shrpw %1, %2, %%sar, %0\n"                                     \
+-      : "=r"(_r)                                                      \
+-      : "r"(w0), "r"(w1), "r"(sh_2)                                   \
+-      );                                                              \
+-      _r;                                                             \
+-})
+-#define THRESHOLD     16
+-
+-#ifdef DEBUG_MEMCPY
+-#define DPRINTF(fmt, args...) do { printk(KERN_DEBUG "%s:%d:%s ", __FILE__, __LINE__, __func__ ); printk(KERN_DEBUG fmt, ##args ); } while (0)
+-#else
+-#define DPRINTF(fmt, args...)
+-#endif
+-
+-#define def_load_ai_insn(_insn,_sz,_tt,_s,_a,_t,_e)   \
+-      __asm__ __volatile__ (                          \
+-      "1:\t" #_insn ",ma " #_sz "(" _s ",%1), %0\n\t" \
+-      ASM_EXCEPTIONTABLE_ENTRY(1b,_e)                 \
+-      : _tt(_t), "+r"(_a)                             \
+-      :                                               \
+-      : "r8")
+-
+-#define def_store_ai_insn(_insn,_sz,_tt,_s,_a,_t,_e)  \
+-      __asm__ __volatile__ (                          \
+-      "1:\t" #_insn ",ma %1, " #_sz "(" _s ",%0)\n\t" \
+-      ASM_EXCEPTIONTABLE_ENTRY(1b,_e)                 \
+-      : "+r"(_a)                                      \
+-      : _tt(_t)                                       \
+-      : "r8")
+-
+-#define ldbma(_s, _a, _t, _e) def_load_ai_insn(ldbs,1,"=r",_s,_a,_t,_e)
+-#define stbma(_s, _t, _a, _e) def_store_ai_insn(stbs,1,"r",_s,_a,_t,_e)
+-#define ldwma(_s, _a, _t, _e) def_load_ai_insn(ldw,4,"=r",_s,_a,_t,_e)
+-#define stwma(_s, _t, _a, _e) def_store_ai_insn(stw,4,"r",_s,_a,_t,_e)
+-#define flddma(_s, _a, _t, _e) def_load_ai_insn(fldd,8,"=f",_s,_a,_t,_e)
+-#define fstdma(_s, _t, _a, _e) def_store_ai_insn(fstd,8,"f",_s,_a,_t,_e)
+-
+-#define def_load_insn(_insn,_tt,_s,_o,_a,_t,_e)       \
+-      __asm__ __volatile__ (                          \
+-      "1:\t" #_insn " " #_o "(" _s ",%1), %0\n\t"     \
+-      ASM_EXCEPTIONTABLE_ENTRY(1b,_e)                 \
+-      : _tt(_t)                                       \
+-      : "r"(_a)                                       \
+-      : "r8")
+-
+-#define def_store_insn(_insn,_tt,_s,_t,_o,_a,_e)      \
+-      __asm__ __volatile__ (                          \
+-      "1:\t" #_insn " %0, " #_o "(" _s ",%1)\n\t"     \
+-      ASM_EXCEPTIONTABLE_ENTRY(1b,_e)                 \
+-      :                                               \
+-      : _tt(_t), "r"(_a)                              \
+-      : "r8")
+-
+-#define ldw(_s,_o,_a,_t,_e)   def_load_insn(ldw,"=r",_s,_o,_a,_t,_e)
+-#define stw(_s,_t,_o,_a,_e)   def_store_insn(stw,"r",_s,_t,_o,_a,_e)
+-
+-#ifdef  CONFIG_PREFETCH
+-static inline void prefetch_src(const void *addr)
+-{
+-      __asm__("ldw 0(" s_space ",%0), %%r0" : : "r" (addr));
+-}
+-
+-static inline void prefetch_dst(const void *addr)
+-{
+-      __asm__("ldd 0(" d_space ",%0), %%r0" : : "r" (addr));
+-}
+-#else
+-#define prefetch_src(addr) do { } while(0)
+-#define prefetch_dst(addr) do { } while(0)
+-#endif
+-
+-#define PA_MEMCPY_OK          0
+-#define PA_MEMCPY_LOAD_ERROR  1
+-#define PA_MEMCPY_STORE_ERROR 2
+-
+-/* Copy from a not-aligned src to an aligned dst, using shifts. Handles 4 words
+- * per loop.  This code is derived from glibc. 
+- */
+-static noinline unsigned long copy_dstaligned(unsigned long dst,
+-                                      unsigned long src, unsigned long len)
+-{
+-      /* gcc complains that a2 and a3 may be uninitialized, but actually
+-       * they cannot be.  Initialize a2/a3 to shut gcc up.
+-       */
+-      register unsigned int a0, a1, a2 = 0, a3 = 0;
+-      int sh_1, sh_2;
+-
+-      /* prefetch_src((const void *)src); */
+-
+-      /* Calculate how to shift a word read at the memory operation
+-         aligned srcp to make it aligned for copy.  */
+-      sh_1 = 8 * (src % sizeof(unsigned int));
+-      sh_2 = 8 * sizeof(unsigned int) - sh_1;
+-
+-      /* Make src aligned by rounding it down.  */
+-      src &= -sizeof(unsigned int);
+-
+-      switch (len % 4)
+-      {
+-              case 2:
+-                      /* a1 = ((unsigned int *) src)[0];
+-                         a2 = ((unsigned int *) src)[1]; */
+-                      ldw(s_space, 0, src, a1, cda_ldw_exc);
+-                      ldw(s_space, 4, src, a2, cda_ldw_exc);
+-                      src -= 1 * sizeof(unsigned int);
+-                      dst -= 3 * sizeof(unsigned int);
+-                      len += 2;
+-                      goto do1;
+-              case 3:
+-                      /* a0 = ((unsigned int *) src)[0];
+-                         a1 = ((unsigned int *) src)[1]; */
+-                      ldw(s_space, 0, src, a0, cda_ldw_exc);
+-                      ldw(s_space, 4, src, a1, cda_ldw_exc);
+-                      src -= 0 * sizeof(unsigned int);
+-                      dst -= 2 * sizeof(unsigned int);
+-                      len += 1;
+-                      goto do2;
+-              case 0:
+-                      if (len == 0)
+-                              return PA_MEMCPY_OK;
+-                      /* a3 = ((unsigned int *) src)[0];
+-                         a0 = ((unsigned int *) src)[1]; */
+-                      ldw(s_space, 0, src, a3, cda_ldw_exc);
+-                      ldw(s_space, 4, src, a0, cda_ldw_exc);
+-                      src -=-1 * sizeof(unsigned int);
+-                      dst -= 1 * sizeof(unsigned int);
+-                      len += 0;
+-                      goto do3;
+-              case 1:
+-                      /* a2 = ((unsigned int *) src)[0];
+-                         a3 = ((unsigned int *) src)[1]; */
+-                      ldw(s_space, 0, src, a2, cda_ldw_exc);
+-                      ldw(s_space, 4, src, a3, cda_ldw_exc);
+-                      src -=-2 * sizeof(unsigned int);
+-                      dst -= 0 * sizeof(unsigned int);
+-                      len -= 1;
+-                      if (len == 0)
+-                              goto do0;
+-                      goto do4;                       /* No-op.  */
+-      }
+-
+-      do
+-      {
+-              /* prefetch_src((const void *)(src + 4 * sizeof(unsigned int))); */
+-do4:
+-              /* a0 = ((unsigned int *) src)[0]; */
+-              ldw(s_space, 0, src, a0, cda_ldw_exc);
+-              /* ((unsigned int *) dst)[0] = MERGE (a2, sh_1, a3, sh_2); */
+-              stw(d_space, MERGE (a2, sh_1, a3, sh_2), 0, dst, cda_stw_exc);
+-do3:
+-              /* a1 = ((unsigned int *) src)[1]; */
+-              ldw(s_space, 4, src, a1, cda_ldw_exc);
+-              /* ((unsigned int *) dst)[1] = MERGE (a3, sh_1, a0, sh_2); */
+-              stw(d_space, MERGE (a3, sh_1, a0, sh_2), 4, dst, cda_stw_exc);
+-do2:
+-              /* a2 = ((unsigned int *) src)[2]; */
+-              ldw(s_space, 8, src, a2, cda_ldw_exc);
+-              /* ((unsigned int *) dst)[2] = MERGE (a0, sh_1, a1, sh_2); */
+-              stw(d_space, MERGE (a0, sh_1, a1, sh_2), 8, dst, cda_stw_exc);
+-do1:
+-              /* a3 = ((unsigned int *) src)[3]; */
+-              ldw(s_space, 12, src, a3, cda_ldw_exc);
+-              /* ((unsigned int *) dst)[3] = MERGE (a1, sh_1, a2, sh_2); */
+-              stw(d_space, MERGE (a1, sh_1, a2, sh_2), 12, dst, cda_stw_exc);
+-
+-              src += 4 * sizeof(unsigned int);
+-              dst += 4 * sizeof(unsigned int);
+-              len -= 4;
+-      }
+-      while (len != 0);
+-
+-do0:
+-      /* ((unsigned int *) dst)[0] = MERGE (a2, sh_1, a3, sh_2); */
+-      stw(d_space, MERGE (a2, sh_1, a3, sh_2), 0, dst, cda_stw_exc);
+-
+-      preserve_branch(handle_load_error);
+-      preserve_branch(handle_store_error);
+-
+-      return PA_MEMCPY_OK;
+-
+-handle_load_error:
+-      __asm__ __volatile__ ("cda_ldw_exc:\n");
+-      return PA_MEMCPY_LOAD_ERROR;
+-
+-handle_store_error:
+-      __asm__ __volatile__ ("cda_stw_exc:\n");
+-      return PA_MEMCPY_STORE_ERROR;
+-}
+-
+-
+-/* Returns PA_MEMCPY_OK, PA_MEMCPY_LOAD_ERROR or PA_MEMCPY_STORE_ERROR.
+- * In case of an access fault the faulty address can be read from the per_cpu
+- * exception data struct. */
+-static noinline unsigned long pa_memcpy_internal(void *dstp, const void *srcp,
+-                                      unsigned long len)
+-{
+-      register unsigned long src, dst, t1, t2, t3;
+-      register unsigned char *pcs, *pcd;
+-      register unsigned int *pws, *pwd;
+-      register double *pds, *pdd;
+-      unsigned long ret;
+-
+-      src = (unsigned long)srcp;
+-      dst = (unsigned long)dstp;
+-      pcs = (unsigned char *)srcp;
+-      pcd = (unsigned char *)dstp;
+-
+-      /* prefetch_src((const void *)srcp); */
+-
+-      if (len < THRESHOLD)
+-              goto byte_copy;
+-
+-      /* Check alignment */
+-      t1 = (src ^ dst);
+-      if (unlikely(t1 & (sizeof(double)-1)))
+-              goto unaligned_copy;
+-
+-      /* src and dst have same alignment. */
+-
+-      /* Copy bytes till we are double-aligned. */
+-      t2 = src & (sizeof(double) - 1);
+-      if (unlikely(t2 != 0)) {
+-              t2 = sizeof(double) - t2;
+-              while (t2 && len) {
+-                      /* *pcd++ = *pcs++; */
+-                      ldbma(s_space, pcs, t3, pmc_load_exc);
+-                      len--;
+-                      stbma(d_space, t3, pcd, pmc_store_exc);
+-                      t2--;
+-              }
+-      }
+-
+-      pds = (double *)pcs;
+-      pdd = (double *)pcd;
+-
+-#if 0
+-      /* Copy 8 doubles at a time */
+-      while (len >= 8*sizeof(double)) {
+-              register double r1, r2, r3, r4, r5, r6, r7, r8;
+-              /* prefetch_src((char *)pds + L1_CACHE_BYTES); */
+-              flddma(s_space, pds, r1, pmc_load_exc);
+-              flddma(s_space, pds, r2, pmc_load_exc);
+-              flddma(s_space, pds, r3, pmc_load_exc);
+-              flddma(s_space, pds, r4, pmc_load_exc);
+-              fstdma(d_space, r1, pdd, pmc_store_exc);
+-              fstdma(d_space, r2, pdd, pmc_store_exc);
+-              fstdma(d_space, r3, pdd, pmc_store_exc);
+-              fstdma(d_space, r4, pdd, pmc_store_exc);
+-
+-#if 0
+-              if (L1_CACHE_BYTES <= 32)
+-                      prefetch_src((char *)pds + L1_CACHE_BYTES);
+-#endif
+-              flddma(s_space, pds, r5, pmc_load_exc);
+-              flddma(s_space, pds, r6, pmc_load_exc);
+-              flddma(s_space, pds, r7, pmc_load_exc);
+-              flddma(s_space, pds, r8, pmc_load_exc);
+-              fstdma(d_space, r5, pdd, pmc_store_exc);
+-              fstdma(d_space, r6, pdd, pmc_store_exc);
+-              fstdma(d_space, r7, pdd, pmc_store_exc);
+-              fstdma(d_space, r8, pdd, pmc_store_exc);
+-              len -= 8*sizeof(double);
+-      }
+-#endif
+-
+-      pws = (unsigned int *)pds;
+-      pwd = (unsigned int *)pdd;
+-
+-word_copy:
+-      while (len >= 8*sizeof(unsigned int)) {
+-              register unsigned int r1,r2,r3,r4,r5,r6,r7,r8;
+-              /* prefetch_src((char *)pws + L1_CACHE_BYTES); */
+-              ldwma(s_space, pws, r1, pmc_load_exc);
+-              ldwma(s_space, pws, r2, pmc_load_exc);
+-              ldwma(s_space, pws, r3, pmc_load_exc);
+-              ldwma(s_space, pws, r4, pmc_load_exc);
+-              stwma(d_space, r1, pwd, pmc_store_exc);
+-              stwma(d_space, r2, pwd, pmc_store_exc);
+-              stwma(d_space, r3, pwd, pmc_store_exc);
+-              stwma(d_space, r4, pwd, pmc_store_exc);
+-
+-              ldwma(s_space, pws, r5, pmc_load_exc);
+-              ldwma(s_space, pws, r6, pmc_load_exc);
+-              ldwma(s_space, pws, r7, pmc_load_exc);
+-              ldwma(s_space, pws, r8, pmc_load_exc);
+-              stwma(d_space, r5, pwd, pmc_store_exc);
+-              stwma(d_space, r6, pwd, pmc_store_exc);
+-              stwma(d_space, r7, pwd, pmc_store_exc);
+-              stwma(d_space, r8, pwd, pmc_store_exc);
+-              len -= 8*sizeof(unsigned int);
+-      }
+-
+-      while (len >= 4*sizeof(unsigned int)) {
+-              register unsigned int r1,r2,r3,r4;
+-              ldwma(s_space, pws, r1, pmc_load_exc);
+-              ldwma(s_space, pws, r2, pmc_load_exc);
+-              ldwma(s_space, pws, r3, pmc_load_exc);
+-              ldwma(s_space, pws, r4, pmc_load_exc);
+-              stwma(d_space, r1, pwd, pmc_store_exc);
+-              stwma(d_space, r2, pwd, pmc_store_exc);
+-              stwma(d_space, r3, pwd, pmc_store_exc);
+-              stwma(d_space, r4, pwd, pmc_store_exc);
+-              len -= 4*sizeof(unsigned int);
+-      }
+-
+-      pcs = (unsigned char *)pws;
+-      pcd = (unsigned char *)pwd;
+-
+-byte_copy:
+-      while (len) {
+-              /* *pcd++ = *pcs++; */
+-              ldbma(s_space, pcs, t3, pmc_load_exc);
+-              stbma(d_space, t3, pcd, pmc_store_exc);
+-              len--;
+-      }
+-
+-      return PA_MEMCPY_OK;
+-
+-unaligned_copy:
+-      /* possibly we are aligned on a word, but not on a double... */
+-      if (likely((t1 & (sizeof(unsigned int)-1)) == 0)) {
+-              t2 = src & (sizeof(unsigned int) - 1);
+-
+-              if (unlikely(t2 != 0)) {
+-                      t2 = sizeof(unsigned int) - t2;
+-                      while (t2) {
+-                              /* *pcd++ = *pcs++; */
+-                              ldbma(s_space, pcs, t3, pmc_load_exc);
+-                              stbma(d_space, t3, pcd, pmc_store_exc);
+-                              len--;
+-                              t2--;
+-                      }
+-              }
+-
+-              pws = (unsigned int *)pcs;
+-              pwd = (unsigned int *)pcd;
+-              goto word_copy;
+-      }
+-
+-      /* Align the destination.  */
+-      if (unlikely((dst & (sizeof(unsigned int) - 1)) != 0)) {
+-              t2 = sizeof(unsigned int) - (dst & (sizeof(unsigned int) - 1));
+-              while (t2) {
+-                      /* *pcd++ = *pcs++; */
+-                      ldbma(s_space, pcs, t3, pmc_load_exc);
+-                      stbma(d_space, t3, pcd, pmc_store_exc);
+-                      len--;
+-                      t2--;
+-              }
+-              dst = (unsigned long)pcd;
+-              src = (unsigned long)pcs;
+-      }
+-
+-      ret = copy_dstaligned(dst, src, len / sizeof(unsigned int));
+-      if (ret)
+-              return ret;
+-
+-      pcs += (len & -sizeof(unsigned int));
+-      pcd += (len & -sizeof(unsigned int));
+-      len %= sizeof(unsigned int);
+-
+-      preserve_branch(handle_load_error);
+-      preserve_branch(handle_store_error);
+-
+-      goto byte_copy;
+-
+-handle_load_error:
+-      __asm__ __volatile__ ("pmc_load_exc:\n");
+-      return PA_MEMCPY_LOAD_ERROR;
+-
+-handle_store_error:
+-      __asm__ __volatile__ ("pmc_store_exc:\n");
+-      return PA_MEMCPY_STORE_ERROR;
+-}
+-
+-
+ /* Returns 0 for success, otherwise, returns number of bytes not transferred. */
+-static unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len)
+-{
+-      unsigned long ret, fault_addr, reference;
+-      struct exception_data *d;
++extern unsigned long pa_memcpy(void *dst, const void *src,
++                              unsigned long len);
+-      ret = pa_memcpy_internal(dstp, srcp, len);
+-      if (likely(ret == PA_MEMCPY_OK))
+-              return 0;
+-
+-      /* if a load or store fault occured we can get the faulty addr */
+-      d = this_cpu_ptr(&exception_data);
+-      fault_addr = d->fault_addr;
+-
+-      /* error in load or store? */
+-      if (ret == PA_MEMCPY_LOAD_ERROR)
+-              reference = (unsigned long) srcp;
+-      else
+-              reference = (unsigned long) dstp;
+-
+-      DPRINTF("pa_memcpy: fault type = %lu, len=%lu fault_addr=%lu ref=%lu\n",
+-              ret, len, fault_addr, reference);
+-
+-      if (fault_addr >= reference)
+-              return len - (fault_addr - reference);
+-      else
+-              return len;
+-}
+-
+-#ifdef __KERNEL__
+ unsigned long __copy_to_user(void __user *dst, const void *src,
+                            unsigned long len)
+ {
+@@ -537,5 +84,3 @@ long probe_kernel_read(void *dst, const
+       return __probe_kernel_read(dst, src, size);
+ }
+-
+-#endif
diff --git a/queue-4.10/pci-iproc-save-host-bridge-window-resource-in-struct-iproc_pcie.patch b/queue-4.10/pci-iproc-save-host-bridge-window-resource-in-struct-iproc_pcie.patch
new file mode 100644 (file)
index 0000000..7ae3b70
--- /dev/null
@@ -0,0 +1,137 @@
+From 6e347b5e05ea2ac4ac467a5a1cfaebb2c7f06f80 Mon Sep 17 00:00:00 2001
+From: Bjorn Helgaas <bhelgaas@google.com>
+Date: Thu, 9 Mar 2017 11:27:07 -0600
+Subject: PCI: iproc: Save host bridge window resource in struct iproc_pcie
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Bjorn Helgaas <bhelgaas@google.com>
+
+commit 6e347b5e05ea2ac4ac467a5a1cfaebb2c7f06f80 upstream.
+
+The host bridge memory window resource is inserted into the iomem_resource
+tree and cannot be deallocated until the host bridge itself is removed.
+
+Previously, the window was on the stack, which meant the iomem_resource
+entry pointed into the stack and was corrupted as soon as the probe
+function returned, which caused memory corruption and errors like this:
+
+  pcie_iproc_bcma bcma0:8: resource collision: [mem 0x40000000-0x47ffffff] conflicts with PCIe MEM space [mem 0x40000000-0x47ffffff]
+
+Move the memory window resource from the stack into struct iproc_pcie so
+its lifetime matches that of the host bridge.
+
+Fixes: c3245a566400 ("PCI: iproc: Request host bridge window resources")
+Reported-and-tested-by: Rafał Miłecki <zajec5@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/host/pcie-iproc-bcma.c     |   24 ++++++++++++------------
+ drivers/pci/host/pcie-iproc-platform.c |   19 ++++++++++---------
+ drivers/pci/host/pcie-iproc.h          |    1 +
+ 3 files changed, 23 insertions(+), 21 deletions(-)
+
+--- a/drivers/pci/host/pcie-iproc-bcma.c
++++ b/drivers/pci/host/pcie-iproc-bcma.c
+@@ -44,8 +44,7 @@ static int iproc_pcie_bcma_probe(struct
+ {
+       struct device *dev = &bdev->dev;
+       struct iproc_pcie *pcie;
+-      LIST_HEAD(res);
+-      struct resource res_mem;
++      LIST_HEAD(resources);
+       int ret;
+       pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+@@ -63,22 +62,23 @@ static int iproc_pcie_bcma_probe(struct
+       pcie->base_addr = bdev->addr;
+-      res_mem.start = bdev->addr_s[0];
+-      res_mem.end = bdev->addr_s[0] + SZ_128M - 1;
+-      res_mem.name = "PCIe MEM space";
+-      res_mem.flags = IORESOURCE_MEM;
+-      pci_add_resource(&res, &res_mem);
++      pcie->mem.start = bdev->addr_s[0];
++      pcie->mem.end = bdev->addr_s[0] + SZ_128M - 1;
++      pcie->mem.name = "PCIe MEM space";
++      pcie->mem.flags = IORESOURCE_MEM;
++      pci_add_resource(&resources, &pcie->mem);
+       pcie->map_irq = iproc_pcie_bcma_map_irq;
+-      ret = iproc_pcie_setup(pcie, &res);
+-      if (ret)
++      ret = iproc_pcie_setup(pcie, &resources);
++      if (ret) {
+               dev_err(dev, "PCIe controller setup failed\n");
+-
+-      pci_free_resource_list(&res);
++              pci_free_resource_list(&resources);
++              return ret;
++      }
+       bcma_set_drvdata(bdev, pcie);
+-      return ret;
++      return 0;
+ }
+ static void iproc_pcie_bcma_remove(struct bcma_device *bdev)
+--- a/drivers/pci/host/pcie-iproc-platform.c
++++ b/drivers/pci/host/pcie-iproc-platform.c
+@@ -52,7 +52,7 @@ static int iproc_pcie_pltfm_probe(struct
+       struct device_node *np = dev->of_node;
+       struct resource reg;
+       resource_size_t iobase = 0;
+-      LIST_HEAD(res);
++      LIST_HEAD(resources);
+       int ret;
+       of_id = of_match_device(iproc_pcie_of_match_table, dev);
+@@ -101,10 +101,10 @@ static int iproc_pcie_pltfm_probe(struct
+               pcie->phy = NULL;
+       }
+-      ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &iobase);
++      ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &resources,
++                                             &iobase);
+       if (ret) {
+-              dev_err(dev,
+-                      "unable to get PCI host bridge resources\n");
++              dev_err(dev, "unable to get PCI host bridge resources\n");
+               return ret;
+       }
+@@ -117,14 +117,15 @@ static int iproc_pcie_pltfm_probe(struct
+               pcie->map_irq = of_irq_parse_and_map_pci;
+       }
+-      ret = iproc_pcie_setup(pcie, &res);
+-      if (ret)
++      ret = iproc_pcie_setup(pcie, &resources);
++      if (ret) {
+               dev_err(dev, "PCIe controller setup failed\n");
+-
+-      pci_free_resource_list(&res);
++              pci_free_resource_list(&resources);
++              return ret;
++      }
+       platform_set_drvdata(pdev, pcie);
+-      return ret;
++      return 0;
+ }
+ static int iproc_pcie_pltfm_remove(struct platform_device *pdev)
+--- a/drivers/pci/host/pcie-iproc.h
++++ b/drivers/pci/host/pcie-iproc.h
+@@ -90,6 +90,7 @@ struct iproc_pcie {
+ #ifdef CONFIG_ARM
+       struct pci_sys_data sysdata;
+ #endif
++      struct resource mem;
+       struct pci_bus *root_bus;
+       struct phy *phy;
+       int (*map_irq)(const struct pci_dev *, u8, u8);
diff --git a/queue-4.10/pci-thunder-pem-add-legacy-firmware-support-for-cavium-thunderx-host-controller.patch b/queue-4.10/pci-thunder-pem-add-legacy-firmware-support-for-cavium-thunderx-host-controller.patch
new file mode 100644 (file)
index 0000000..af73fe0
--- /dev/null
@@ -0,0 +1,109 @@
+From 9abb27c7594a62bbf6385e20b7f5a90b4eceae2f Mon Sep 17 00:00:00 2001
+From: Tomasz Nowicki <tn@semihalf.com>
+Date: Thu, 23 Mar 2017 17:10:16 -0500
+Subject: PCI: thunder-pem: Add legacy firmware support for Cavium ThunderX host controller
+
+From: Tomasz Nowicki <tn@semihalf.com>
+
+commit 9abb27c7594a62bbf6385e20b7f5a90b4eceae2f upstream.
+
+During early days of PCI quirks support, ThunderX firmware did not provide
+PNP0c02 node with PCI configuration space and PEM-specific register ranges.
+This means that for legacy FW we are not reserving these resources and
+cannot gather PEM-specific resources for further PEM initialization.
+
+To support already deployed legacy FW, calculate PEM-specific ranges and
+provide resources reservation as fallback scenario into PEM driver when we
+could not gather PEM reg base from ACPI tables.
+
+Tested-by: Robert Richter <rrichter@cavium.com>
+Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
+Signed-off-by: Vadim Lomovtsev <Vadim.Lomovtsev@caviumnetworks.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Robert Richter <rrichter@cavium.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/host/pci-thunder-pem.c |   56 +++++++++++++++++++++++++++++++++++--
+ 1 file changed, 54 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/host/pci-thunder-pem.c
++++ b/drivers/pci/host/pci-thunder-pem.c
+@@ -14,6 +14,7 @@
+  * Copyright (C) 2015 - 2016 Cavium, Inc.
+  */
++#include <linux/bitfield.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/of_address.h>
+@@ -319,6 +320,50 @@ static int thunder_pem_init(struct devic
+ #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
++#define PEM_RES_BASE          0x87e0c0000000UL
++#define PEM_NODE_MASK         GENMASK(45, 44)
++#define PEM_INDX_MASK         GENMASK(26, 24)
++#define PEM_MIN_DOM_IN_NODE   4
++#define PEM_MAX_DOM_IN_NODE   10
++
++static void thunder_pem_reserve_range(struct device *dev, int seg,
++                                    struct resource *r)
++{
++      resource_size_t start = r->start, end = r->end;
++      struct resource *res;
++      const char *regionid;
++
++      regionid = kasprintf(GFP_KERNEL, "PEM RC:%d", seg);
++      if (!regionid)
++              return;
++
++      res = request_mem_region(start, end - start + 1, regionid);
++      if (res)
++              res->flags &= ~IORESOURCE_BUSY;
++      else
++              kfree(regionid);
++
++      dev_info(dev, "%pR %s reserved\n", r,
++               res ? "has been" : "could not be");
++}
++
++static void thunder_pem_legacy_fw(struct acpi_pci_root *root,
++                               struct resource *res_pem)
++{
++      int node = acpi_get_node(root->device->handle);
++      int index;
++
++      if (node == NUMA_NO_NODE)
++              node = 0;
++
++      index = root->segment - PEM_MIN_DOM_IN_NODE;
++      index -= node * PEM_MAX_DOM_IN_NODE;
++      res_pem->start = PEM_RES_BASE | FIELD_PREP(PEM_NODE_MASK, node) |
++                                      FIELD_PREP(PEM_INDX_MASK, index);
++      res_pem->end = res_pem->start + SZ_16M - 1;
++      res_pem->flags = IORESOURCE_MEM;
++}
++
+ static int thunder_pem_acpi_init(struct pci_config_window *cfg)
+ {
+       struct device *dev = cfg->parent;
+@@ -332,9 +377,16 @@ static int thunder_pem_acpi_init(struct
+               return -ENOMEM;
+       ret = acpi_get_rc_resources(dev, "CAVA02B", root->segment, res_pem);
++
++      /*
++       * If we fail to gather resources it means that we run with old
++       * FW where we need to calculate PEM-specific resources manually.
++       */
+       if (ret) {
+-              dev_err(dev, "can't get rc base address\n");
+-              return ret;
++              thunder_pem_legacy_fw(root, res_pem);
++              /* Reserve PEM-specific resources and PCI configuration space */
++              thunder_pem_reserve_range(dev, root->segment, res_pem);
++              thunder_pem_reserve_range(dev, root->segment, &cfg->res);
+       }
+       return thunder_pem_init(dev, cfg, res_pem);
diff --git a/queue-4.10/pci-thunder-pem-use-cavium-assigned-hardware-id-for-thunderx-host-controller.patch b/queue-4.10/pci-thunder-pem-use-cavium-assigned-hardware-id-for-thunderx-host-controller.patch
new file mode 100644 (file)
index 0000000..9acd6e9
--- /dev/null
@@ -0,0 +1,34 @@
+From 81caa91b72fd6a0b8dfc5eb10942c34f7efd2bc5 Mon Sep 17 00:00:00 2001
+From: Tomasz Nowicki <tn@semihalf.com>
+Date: Thu, 23 Mar 2017 17:10:10 -0500
+Subject: PCI: thunder-pem: Use Cavium assigned hardware ID for ThunderX host controller
+
+From: Tomasz Nowicki <tn@semihalf.com>
+
+commit 81caa91b72fd6a0b8dfc5eb10942c34f7efd2bc5 upstream.
+
+"CAV" is the only PNP/ACPI hardware ID vendor prefix assigned to Cavium so
+fix this as it should be from day one.
+
+Fixes: 44f22bd91e88 ("PCI: Add MCFG quirks for Cavium ThunderX pass2.x host controller")
+Tested-by: Robert Richter <rrichter@cavium.com>
+Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Robert Richter <rrichter@cavium.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/host/pci-thunder-pem.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pci/host/pci-thunder-pem.c
++++ b/drivers/pci/host/pci-thunder-pem.c
+@@ -331,7 +331,7 @@ static int thunder_pem_acpi_init(struct
+       if (!res_pem)
+               return -ENOMEM;
+-      ret = acpi_get_rc_resources(dev, "THRX0002", root->segment, res_pem);
++      ret = acpi_get_rc_resources(dev, "CAVA02B", root->segment, res_pem);
+       if (ret) {
+               dev_err(dev, "can't get rc base address\n");
+               return ret;
diff --git a/queue-4.10/scsi-libsas-fix-ata-xfer-length.patch b/queue-4.10/scsi-libsas-fix-ata-xfer-length.patch
new file mode 100644 (file)
index 0000000..53c56cf
--- /dev/null
@@ -0,0 +1,40 @@
+From 9702c67c6066f583b629cf037d2056245bb7a8e6 Mon Sep 17 00:00:00 2001
+From: John Garry <john.garry@huawei.com>
+Date: Thu, 16 Mar 2017 23:07:28 +0800
+Subject: scsi: libsas: fix ata xfer length
+
+From: John Garry <john.garry@huawei.com>
+
+commit 9702c67c6066f583b629cf037d2056245bb7a8e6 upstream.
+
+The total ata xfer length may not be calculated properly, in that we do
+not use the proper method to get an sg element dma length.
+
+According to the code comment, sg_dma_len() should be used after
+dma_map_sg() is called.
+
+This issue was found by turning on the SMMUv3 in front of the hisi_sas
+controller in hip07. Multiple sg elements were being combined into a
+single element, but the original first element length was being use as
+the total xfer length.
+
+Fixes: ff2aeb1eb64c8a4770a6 ("libata: convert to chained sg")
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/libsas/sas_ata.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/scsi/libsas/sas_ata.c
++++ b/drivers/scsi/libsas/sas_ata.c
+@@ -221,7 +221,7 @@ static unsigned int sas_ata_qc_issue(str
+               task->num_scatter = qc->n_elem;
+       } else {
+               for_each_sg(qc->sg, sg, qc->n_elem, si)
+-                      xfer += sg->length;
++                      xfer += sg_dma_len(sg);
+               task->total_xfer_len = xfer;
+               task->num_scatter = si;
diff --git a/queue-4.10/scsi-scsi_dh_alua-check-scsi_device_get-return-value.patch b/queue-4.10/scsi-scsi_dh_alua-check-scsi_device_get-return-value.patch
new file mode 100644 (file)
index 0000000..d011889
--- /dev/null
@@ -0,0 +1,92 @@
+From 625fe857e4fac6518716f3c0ff5e5deb8ec6d238 Mon Sep 17 00:00:00 2001
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+Date: Fri, 17 Mar 2017 17:02:01 -0700
+Subject: scsi: scsi_dh_alua: Check scsi_device_get() return value
+
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+
+commit 625fe857e4fac6518716f3c0ff5e5deb8ec6d238 upstream.
+
+Do not queue ALUA work nor call scsi_device_put() if the
+scsi_device_get() call fails. This patch fixes the following crash:
+
+general protection fault: 0000 [#1] SMP
+RIP: 0010:scsi_device_put+0xb/0x30
+Call Trace:
+ scsi_disk_put+0x2d/0x40
+ sd_release+0x3d/0xb0
+ __blkdev_put+0x29e/0x360
+ blkdev_put+0x49/0x170
+ dm_put_table_device+0x58/0xc0 [dm_mod]
+ dm_put_device+0x70/0xc0 [dm_mod]
+ free_priority_group+0x92/0xc0 [dm_multipath]
+ free_multipath+0x70/0xc0 [dm_multipath]
+ multipath_dtr+0x19/0x20 [dm_multipath]
+ dm_table_destroy+0x67/0x120 [dm_mod]
+ dev_suspend+0xde/0x240 [dm_mod]
+ ctl_ioctl+0x1f5/0x520 [dm_mod]
+ dm_ctl_ioctl+0xe/0x20 [dm_mod]
+ do_vfs_ioctl+0x8f/0x700
+ SyS_ioctl+0x3c/0x70
+ entry_SYSCALL_64_fastpath+0x18/0xad
+
+Fixes: commit 03197b61c5ec ("scsi_dh_alua: Use workqueue for RTPG")
+Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Cc: Hannes Reinecke <hare@suse.de>
+Cc: Tang Junhui <tang.junhui@zte.com.cn>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/device_handler/scsi_dh_alua.c |   18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- a/drivers/scsi/device_handler/scsi_dh_alua.c
++++ b/drivers/scsi/device_handler/scsi_dh_alua.c
+@@ -874,7 +874,7 @@ static void alua_rtpg_queue(struct alua_
+       unsigned long flags;
+       struct workqueue_struct *alua_wq = kaluad_wq;
+-      if (!pg)
++      if (!pg || scsi_device_get(sdev))
+               return;
+       spin_lock_irqsave(&pg->lock, flags);
+@@ -888,14 +888,12 @@ static void alua_rtpg_queue(struct alua_
+               pg->flags |= ALUA_PG_RUN_RTPG;
+               kref_get(&pg->kref);
+               pg->rtpg_sdev = sdev;
+-              scsi_device_get(sdev);
+               start_queue = 1;
+       } else if (!(pg->flags & ALUA_PG_RUN_RTPG) && force) {
+               pg->flags |= ALUA_PG_RUN_RTPG;
+               /* Do not queue if the worker is already running */
+               if (!(pg->flags & ALUA_PG_RUNNING)) {
+                       kref_get(&pg->kref);
+-                      sdev = NULL;
+                       start_queue = 1;
+               }
+       }
+@@ -904,13 +902,15 @@ static void alua_rtpg_queue(struct alua_
+               alua_wq = kaluad_sync_wq;
+       spin_unlock_irqrestore(&pg->lock, flags);
+-      if (start_queue &&
+-          !queue_delayed_work(alua_wq, &pg->rtpg_work,
+-                              msecs_to_jiffies(ALUA_RTPG_DELAY_MSECS))) {
+-              if (sdev)
+-                      scsi_device_put(sdev);
+-              kref_put(&pg->kref, release_port_group);
++      if (start_queue) {
++              if (queue_delayed_work(alua_wq, &pg->rtpg_work,
++                              msecs_to_jiffies(ALUA_RTPG_DELAY_MSECS)))
++                      sdev = NULL;
++              else
++                      kref_put(&pg->kref, release_port_group);
+       }
++      if (sdev)
++              scsi_device_put(sdev);
+ }
+ /*
diff --git a/queue-4.10/scsi-scsi_dh_alua-ensure-that-alua_activate-calls-the-completion-function.patch b/queue-4.10/scsi-scsi_dh_alua-ensure-that-alua_activate-calls-the-completion-function.patch
new file mode 100644 (file)
index 0000000..a4699f2
--- /dev/null
@@ -0,0 +1,85 @@
+From 7cb689fe42927281b8d98606ae5450173fcc66a9 Mon Sep 17 00:00:00 2001
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+Date: Fri, 17 Mar 2017 17:02:02 -0700
+Subject: scsi: scsi_dh_alua: Ensure that alua_activate() calls the completion function
+
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+
+commit 7cb689fe42927281b8d98606ae5450173fcc66a9 upstream.
+
+Callers of scsi_dh_activate(), e.g. dm-mpath, assume that this function
+either returns an error code or calls the completion function. Make
+alua_activate() call the completion function even if scsi_device_get()
+fails.
+
+Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Cc: Hannes Reinecke <hare@suse.de>
+Cc: Tang Junhui <tang.junhui@zte.com.cn>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/device_handler/scsi_dh_alua.c |   20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+--- a/drivers/scsi/device_handler/scsi_dh_alua.c
++++ b/drivers/scsi/device_handler/scsi_dh_alua.c
+@@ -113,7 +113,7 @@ struct alua_queue_data {
+ #define ALUA_POLICY_SWITCH_ALL                1
+ static void alua_rtpg_work(struct work_struct *work);
+-static void alua_rtpg_queue(struct alua_port_group *pg,
++static bool alua_rtpg_queue(struct alua_port_group *pg,
+                           struct scsi_device *sdev,
+                           struct alua_queue_data *qdata, bool force);
+ static void alua_check(struct scsi_device *sdev, bool force);
+@@ -866,7 +866,13 @@ static void alua_rtpg_work(struct work_s
+       kref_put(&pg->kref, release_port_group);
+ }
+-static void alua_rtpg_queue(struct alua_port_group *pg,
++/**
++ * alua_rtpg_queue() - cause RTPG to be submitted asynchronously
++ *
++ * Returns true if and only if alua_rtpg_work() will be called asynchronously.
++ * That function is responsible for calling @qdata->fn().
++ */
++static bool alua_rtpg_queue(struct alua_port_group *pg,
+                           struct scsi_device *sdev,
+                           struct alua_queue_data *qdata, bool force)
+ {
+@@ -875,7 +881,7 @@ static void alua_rtpg_queue(struct alua_
+       struct workqueue_struct *alua_wq = kaluad_wq;
+       if (!pg || scsi_device_get(sdev))
+-              return;
++              return false;
+       spin_lock_irqsave(&pg->lock, flags);
+       if (qdata) {
+@@ -911,6 +917,8 @@ static void alua_rtpg_queue(struct alua_
+       }
+       if (sdev)
+               scsi_device_put(sdev);
++
++      return true;
+ }
+ /*
+@@ -1011,11 +1019,13 @@ static int alua_activate(struct scsi_dev
+               mutex_unlock(&h->init_mutex);
+               goto out;
+       }
+-      fn = NULL;
+       rcu_read_unlock();
+       mutex_unlock(&h->init_mutex);
+-      alua_rtpg_queue(pg, sdev, qdata, true);
++      if (alua_rtpg_queue(pg, sdev, qdata, true))
++              fn = NULL;
++      else
++              err = SCSI_DH_DEV_OFFLINED;
+       kref_put(&pg->kref, release_port_group);
+ out:
+       if (fn)
diff --git a/queue-4.10/scsi-sg-check-length-passed-to-sg_next_cmd_len.patch b/queue-4.10/scsi-sg-check-length-passed-to-sg_next_cmd_len.patch
new file mode 100644 (file)
index 0000000..8a91ac6
--- /dev/null
@@ -0,0 +1,33 @@
+From bf33f87dd04c371ea33feb821b60d63d754e3124 Mon Sep 17 00:00:00 2001
+From: peter chang <dpf@google.com>
+Date: Wed, 15 Feb 2017 14:11:54 -0800
+Subject: scsi: sg: check length passed to SG_NEXT_CMD_LEN
+
+From: peter chang <dpf@google.com>
+
+commit bf33f87dd04c371ea33feb821b60d63d754e3124 upstream.
+
+The user can control the size of the next command passed along, but the
+value passed to the ioctl isn't checked against the usable max command
+size.
+
+Signed-off-by: Peter Chang <dpf@google.com>
+Acked-by: Douglas Gilbert <dgilbert@interlog.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/sg.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -998,6 +998,8 @@ sg_ioctl(struct file *filp, unsigned int
+               result = get_user(val, ip);
+               if (result)
+                       return result;
++              if (val > SG_MAX_CDB_SIZE)
++                      return -ENOMEM;
+               sfp->next_cmd_len = (val > 0) ? val : 0;
+               return 0;
+       case SG_GET_VERSION_NUM:
diff --git a/queue-4.10/serial-mxs-auart-fix-baudrate-calculation.patch b/queue-4.10/serial-mxs-auart-fix-baudrate-calculation.patch
new file mode 100644 (file)
index 0000000..238e1d5
--- /dev/null
@@ -0,0 +1,40 @@
+From a6040bc610554c66088fda3608ae5d6307c548e4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Mon, 20 Mar 2017 10:05:38 +0100
+Subject: serial: mxs-auart: Fix baudrate calculation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+commit a6040bc610554c66088fda3608ae5d6307c548e4 upstream.
+
+The reference manual for the i.MX28 recommends to calculate the divisor
+as
+
+       divisor = (UARTCLK * 32) / baud rate, rounded to the nearest integer
+
+, so let's do this. For a typical setup of UARTCLK = 24 MHz and baud
+rate = 115200 this changes the divisor from 6666 to 6667 and so the
+actual baud rate improves from 115211.521 Bd (error ≅ 0.01 %) to
+115194.240 Bd (error ≅ 0.005 %).
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/mxs-auart.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/mxs-auart.c
++++ b/drivers/tty/serial/mxs-auart.c
+@@ -1085,7 +1085,7 @@ static void mxs_auart_settermios(struct
+                                       AUART_LINECTRL_BAUD_DIV_MAX);
+               baud_max = u->uartclk * 32 / AUART_LINECTRL_BAUD_DIV_MIN;
+               baud = uart_get_baud_rate(u, termios, old, baud_min, baud_max);
+-              div = u->uartclk * 32 / baud;
++              div = DIV_ROUND_CLOSEST(u->uartclk * 32, baud);
+       }
+       ctrl |= AUART_LINECTRL_BAUD_DIVFRAC(div & 0x3F);
index f620f80a411c5c6addb448784524959356857e6b..f927d9e67f85d95e8ee8468034c50e345a5d6b40 100644 (file)
@@ -26,3 +26,34 @@ xfs-fix-and-streamline-error-handling-in-xfs_end_io.patch
 xfs-use-xfs_icluster_size_fsb-to-calculate-inode-alignment-mask.patch
 xfs-use-iomap-new-flag-for-newly-allocated-delalloc-blocks.patch
 xfs-try-any-ag-when-allocating-the-first-btree-block-when-reflinking.patch
+scsi-sg-check-length-passed-to-sg_next_cmd_len.patch
+scsi-libsas-fix-ata-xfer-length.patch
+scsi-scsi_dh_alua-check-scsi_device_get-return-value.patch
+scsi-scsi_dh_alua-ensure-that-alua_activate-calls-the-completion-function.patch
+pci-iproc-save-host-bridge-window-resource-in-struct-iproc_pcie.patch
+pci-thunder-pem-use-cavium-assigned-hardware-id-for-thunderx-host-controller.patch
+pci-thunder-pem-add-legacy-firmware-support-for-cavium-thunderx-host-controller.patch
+alsa-seq-fix-race-during-fifo-resize.patch
+alsa-hda-fix-a-problem-for-lineout-on-a-dell-aio-machine.patch
+asoc-atmel-classd-fix-audio-clock-rate.patch
+asoc-intel-skylake-fix-invalid-memory-access-due-to-wrong-reference-of-pointer.patch
+asoc-rt5665-fix-getting-wrong-work-handler-container.patch
+hid-wacom-don-t-add-ghost-interface-as-shared-data.patch
+mmc-sdhci-disable-runtime-pm-when-the-sdio_irq-is-enabled.patch
+mmc-sdhci-of-at91-fix-mmc_ddr_52-timing-selection.patch
+crypto-ccp-make-some-ccp-dma-channels-private.patch
+crypto-xts-lrw-fix-out-of-bounds-write-after-kmalloc-failure.patch
+arcv2-slc-make-sure-busy-bit-is-set-properly-on-slc-flushing.patch
+nfsv4.1-fix-infinite-loop-on-io-bad_stateid-error.patch
+nfsd-map-the-enokey-to-nfserr_perm-for-avoiding-warning.patch
+dt-bindings-rng-clocks-property-on-omap_rng-not-always-mandatory.patch
+parisc-clean-up-fixup-routines-for-get_user-put_user.patch
+parisc-avoid-stalled-cpu-warnings-after-system-shutdown.patch
+parisc-fix-access-fault-handling-in-pa_memcpy.patch
+acpi-fix-incompatibility-with-mcount-based-function-graph-tracing.patch
+acpi-do-not-create-a-platform_device-for-ioapic-ioxapic.patch
+tty-serial-atmel-fix-race-condition-tx-dma.patch
+tty-serial-atmel-fix-tx-path-in-atmel_console_write.patch
+xhci-set-urb-actual-length-for-stopped-control-transfers.patch
+usb-fix-linked-list-corruption-in-rh_call_control.patch
+serial-mxs-auart-fix-baudrate-calculation.patch
diff --git a/queue-4.10/tty-serial-atmel-fix-race-condition-tx-dma.patch b/queue-4.10/tty-serial-atmel-fix-race-condition-tx-dma.patch
new file mode 100644 (file)
index 0000000..119b83a
--- /dev/null
@@ -0,0 +1,37 @@
+From 31ca2c63fdc0aee725cbd4f207c1256f5deaabde Mon Sep 17 00:00:00 2001
+From: Richard Genoud <richard.genoud@gmail.com>
+Date: Mon, 20 Mar 2017 11:52:41 +0100
+Subject: tty/serial: atmel: fix race condition (TX+DMA)
+
+From: Richard Genoud <richard.genoud@gmail.com>
+
+commit 31ca2c63fdc0aee725cbd4f207c1256f5deaabde upstream.
+
+If uart_flush_buffer() is called between atmel_tx_dma() and
+atmel_complete_tx_dma(), the circular buffer has been cleared, but not
+atmel_port->tx_len.
+That leads to a circular buffer overflow (dumping (UART_XMIT_SIZE -
+atmel_port->tx_len) bytes).
+
+Tested-by: Nicolas Ferre <nicolas.ferre@microchip.com>
+Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/atmel_serial.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/tty/serial/atmel_serial.c
++++ b/drivers/tty/serial/atmel_serial.c
+@@ -1938,6 +1938,11 @@ static void atmel_flush_buffer(struct ua
+               atmel_uart_writel(port, ATMEL_PDC_TCR, 0);
+               atmel_port->pdc_tx.ofs = 0;
+       }
++      /*
++       * in uart_flush_buffer(), the xmit circular buffer has just
++       * been cleared, so we have to reset tx_len accordingly.
++       */
++      atmel_port->tx_len = 0;
+ }
+ /*
diff --git a/queue-4.10/tty-serial-atmel-fix-tx-path-in-atmel_console_write.patch b/queue-4.10/tty-serial-atmel-fix-tx-path-in-atmel_console_write.patch
new file mode 100644 (file)
index 0000000..6ec2933
--- /dev/null
@@ -0,0 +1,35 @@
+From 497e1e16f45c70574dc9922c7f75c642c2162119 Mon Sep 17 00:00:00 2001
+From: Nicolas Ferre <nicolas.ferre@microchip.com>
+Date: Mon, 20 Mar 2017 16:38:57 +0100
+Subject: tty/serial: atmel: fix TX path in atmel_console_write()
+
+From: Nicolas Ferre <nicolas.ferre@microchip.com>
+
+commit 497e1e16f45c70574dc9922c7f75c642c2162119 upstream.
+
+A side effect of 89d8232411a8 ("tty/serial: atmel_serial: BUG: stop DMA
+from transmitting in stop_tx") is that the console can be called with
+TX path disabled. Then the system would hang trying to push charecters
+out in atmel_console_putchar().
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
+Fixes: 89d8232411a8 ("tty/serial: atmel_serial: BUG: stop DMA from transmitting in stop_tx")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/atmel_serial.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/tty/serial/atmel_serial.c
++++ b/drivers/tty/serial/atmel_serial.c
+@@ -2476,6 +2476,9 @@ static void atmel_console_write(struct c
+       pdc_tx = atmel_uart_readl(port, ATMEL_PDC_PTSR) & ATMEL_PDC_TXTEN;
+       atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS);
++      /* Make sure that tx path is actually able to send characters */
++      atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN);
++
+       uart_console_write(port, s, count, atmel_console_putchar);
+       /*
diff --git a/queue-4.10/usb-fix-linked-list-corruption-in-rh_call_control.patch b/queue-4.10/usb-fix-linked-list-corruption-in-rh_call_control.patch
new file mode 100644 (file)
index 0000000..35c77f5
--- /dev/null
@@ -0,0 +1,48 @@
+From 1633682053a7ee8058e10c76722b9b28e97fb73f Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Fri, 24 Mar 2017 13:38:28 -0400
+Subject: USB: fix linked-list corruption in rh_call_control()
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 1633682053a7ee8058e10c76722b9b28e97fb73f upstream.
+
+Using KASAN, Dmitry found a bug in the rh_call_control() routine: If
+buffer allocation fails, the routine returns immediately without
+unlinking its URB from the control endpoint, eventually leading to
+linked-list corruption.
+
+This patch fixes the problem by jumping to the end of the routine
+(where the URB is unlinked) when an allocation failure occurs.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-and-tested-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hcd.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -520,8 +520,10 @@ static int rh_call_control (struct usb_h
+        */
+       tbuf_size =  max_t(u16, sizeof(struct usb_hub_descriptor), wLength);
+       tbuf = kzalloc(tbuf_size, GFP_KERNEL);
+-      if (!tbuf)
+-              return -ENOMEM;
++      if (!tbuf) {
++              status = -ENOMEM;
++              goto err_alloc;
++      }
+       bufp = tbuf;
+@@ -734,6 +736,7 @@ error:
+       }
+       kfree(tbuf);
++ err_alloc:
+       /* any errors get returned through the urb completion */
+       spin_lock_irq(&hcd_root_hub_lock);
diff --git a/queue-4.10/xhci-set-urb-actual-length-for-stopped-control-transfers.patch b/queue-4.10/xhci-set-urb-actual-length-for-stopped-control-transfers.patch
new file mode 100644 (file)
index 0000000..322450c
--- /dev/null
@@ -0,0 +1,38 @@
+From 0ab2881a406b9fd46224a3e8253bbc0141b4f844 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Tue, 28 Mar 2017 15:55:29 +0300
+Subject: xhci: Set URB actual length for stopped control transfers
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 0ab2881a406b9fd46224a3e8253bbc0141b4f844 upstream.
+
+A control transfer that stopped at the status stage incorrectly
+warned about a "unexpected TRB Type 4", and did not set the
+transferred actual_length for the URB.
+
+The URB actual_length for control transfers should contain the
+bytes transferred in the data stage.
+
+Bytes of a partially sent setup stage and missing bytes from
+status stage should be left out.
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -2000,6 +2000,9 @@ static int process_ctrl_td(struct xhci_h
+               case TRB_NORMAL:
+                       td->urb->actual_length = requested - remaining;
+                       goto finish_td;
++              case TRB_STATUS:
++                      td->urb->actual_length = requested;
++                      goto finish_td;
+               default:
+                       xhci_warn(xhci, "WARN: unexpected TRB Type %d\n",
+                                 trb_type);