From: Greg Kroah-Hartman Date: Mon, 10 Aug 2015 21:35:12 +0000 (-0700) Subject: 4.1-stable patches X-Git-Tag: v3.10.87~43 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a3852365984ff1554ad42950a4ef6b6a3d769b9c;p=thirdparty%2Fkernel%2Fstable-queue.git 4.1-stable patches added patches: bluetooth-fix-null-pointer-dereference-in-smp_conn_security.patch dmaengine-pl330-fix-overflow-when-reporting-residue-in-memcpy.patch dmaengine-pl330-really-fix-choppy-sound-because-of-wrong-residue-calculation.patch drivers-usb-delete-xhci-command-timer-if-necessary.patch drm-dp-mst-remove-debug-warn_on.patch drm-i915-declare-the-swizzling-unknown-for-l-shaped-configurations.patch drm-i915-replace-warn-inside-i915_read64_2x32-with-retry-loop.patch drm-radeon-combios-add-some-validation-of-lvds-values.patch drm-radeon-rework-audio-detect-v4.patch fsnotify-fix-oops-in-fsnotify_clear_marks_by_group_flags.patch ipr-fix-incorrect-trace-indexing.patch ipr-fix-invalid-array-indexing-for-hrrq.patch ipr-fix-locking-for-unit-attention-handling.patch mips-do_mcheck-fix-kernel-code-dump-with-eva.patch mips-export-get_c0_perfcount_int.patch mips-fix-sched_getaffinity-with-mt-fpaff-enabled.patch mips-flush-rps-on-kernel-entry-with-eva.patch mips-make-set_pte-smp-safe.patch mips-malta-don-t-reinitialise-rtc.patch mips-show_stack-fix-stack-trace-with-eva.patch phy-twl4030-usb-make-runtime-pm-more-reliable.patch revert-mips-bcm63xx-provide-a-plat_post_dma_flush-hook.patch usb-chipidea-ehci_init_driver-is-intended-to-call-one-time.patch usb-sierra-add-1199-68ab-device-id.patch usb-udc-core-add-device_del-call-to-error-pathway.patch xhci-fix-off-by-one-error-in-trb-dma-address-boundary-check.patch --- diff --git a/queue-4.1/bluetooth-fix-null-pointer-dereference-in-smp_conn_security.patch b/queue-4.1/bluetooth-fix-null-pointer-dereference-in-smp_conn_security.patch new file mode 100644 index 00000000000..bd4f7f22eae --- /dev/null +++ b/queue-4.1/bluetooth-fix-null-pointer-dereference-in-smp_conn_security.patch @@ -0,0 +1,36 @@ +From 25ba265390c09b0a2b2f3fd9ba82e37248b7a371 Mon Sep 17 00:00:00 2001 +From: Johan Hedberg +Date: Mon, 20 Jul 2015 20:31:25 +0300 +Subject: Bluetooth: Fix NULL pointer dereference in smp_conn_security + +From: Johan Hedberg + +commit 25ba265390c09b0a2b2f3fd9ba82e37248b7a371 upstream. + +The l2cap_conn->smp pointer may be NULL for various valid reasons where SMP has +failed to initialize properly. One such scenario is when crypto support is +missing, another when the adapter has been powered on through a legacy method. +The smp_conn_security() function should have the appropriate check for this +situation to avoid NULL pointer dereferences. + +Signed-off-by: Johan Hedberg +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman + +--- + net/bluetooth/smp.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/bluetooth/smp.c ++++ b/net/bluetooth/smp.c +@@ -2295,6 +2295,10 @@ int smp_conn_security(struct hci_conn *h + return 1; + + chan = conn->smp; ++ if (!chan) { ++ BT_ERR("SMP security requested but not available"); ++ return 1; ++ } + + if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED)) + return 1; diff --git a/queue-4.1/dmaengine-pl330-fix-overflow-when-reporting-residue-in-memcpy.patch b/queue-4.1/dmaengine-pl330-fix-overflow-when-reporting-residue-in-memcpy.patch new file mode 100644 index 00000000000..ee521cb6d7a --- /dev/null +++ b/queue-4.1/dmaengine-pl330-fix-overflow-when-reporting-residue-in-memcpy.patch @@ -0,0 +1,36 @@ +From ae128293d97404f491dc76f1843c7adacfec3441 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Mon, 15 Jun 2015 17:25:16 +0900 +Subject: dmaengine: pl330: Fix overflow when reporting residue in memcpy + +From: Krzysztof Kozlowski + +commit ae128293d97404f491dc76f1843c7adacfec3441 upstream. + +During memcpy operations the residue was always set to an u32 overflowed +value. + +In pl330_tx_status() function number of currently transferred bytes was +subtracted from internal "bytes_requested" field. However this +"bytes_requested" was not initialized at start to length of memcpy +buffer so transferred bytes were subtracted from 0 causing overflow. + +Signed-off-by: Krzysztof Kozlowski +Fixes: aee4d1fac887 ("dmaengine: pl330: improve pl330_tx_status() function") +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/pl330.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -2621,6 +2621,7 @@ pl330_prep_dma_memcpy(struct dma_chan *c + desc->rqcfg.brst_len = 1; + + desc->rqcfg.brst_len = get_burst_len(desc, len); ++ desc->bytes_requested = len; + + desc->txd.flags = flags; + diff --git a/queue-4.1/dmaengine-pl330-really-fix-choppy-sound-because-of-wrong-residue-calculation.patch b/queue-4.1/dmaengine-pl330-really-fix-choppy-sound-because-of-wrong-residue-calculation.patch new file mode 100644 index 00000000000..6cd98b3f958 --- /dev/null +++ b/queue-4.1/dmaengine-pl330-really-fix-choppy-sound-because-of-wrong-residue-calculation.patch @@ -0,0 +1,52 @@ +From 5dd90e5b91e0f5c925b12b132c7cd27538870256 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Mon, 15 Jun 2015 23:00:09 +0900 +Subject: dmaengine: pl330: Really fix choppy sound because of wrong residue calculation + +From: Krzysztof Kozlowski + +commit 5dd90e5b91e0f5c925b12b132c7cd27538870256 upstream. + +When pl330 driver was used during sound playback, after some time or +after a number of plays the sound became choppy or totally noisy. For +example on Odroid XU3 board the first four executions of aplay with +small WAVE worked fine, but fifth was unrecognizable with errors: + $ aplay /usr/share/sounds/alsa/Front_Right.wava + underrun!!! (at least 0.095 ms long) + +Issue was caused by wrong residue reported by pl330 driver to +pcm_dmaengine for its cyclic dma transfers. + +The pl330_tx_status(), residue reporting function, used a "last" flag in +a descriptor to indicate that there is no more data to send. + +The pl330_tx_submit() iterated over descriptors trying to remove this +flag from them and then mark last descriptor as "last". However when +iterating it actually removed the flag not from descriptors but always +from last of it (and then reset it). Thus effectively once some +descriptor was marked as last, then it stayed like this forever causing +residue to be reported too low. + +Signed-off-by: Krzysztof Kozlowski +Fixes: aee4d1fac887 ("dmaengine: pl330: improve pl330_tx_status() function") +Reported-by: gabriel@unseen.is +Suggested-by: Marek Szyprowski +Tested-by: Lars-Peter Clausen +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/pl330.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/dma/pl330.c ++++ b/drivers/dma/pl330.c +@@ -2328,7 +2328,7 @@ static dma_cookie_t pl330_tx_submit(stru + desc->txd.callback = last->txd.callback; + desc->txd.callback_param = last->txd.callback_param; + } +- last->last = false; ++ desc->last = false; + + dma_cookie_assign(&desc->txd); + diff --git a/queue-4.1/drivers-usb-delete-xhci-command-timer-if-necessary.patch b/queue-4.1/drivers-usb-delete-xhci-command-timer-if-necessary.patch new file mode 100644 index 00000000000..893b451ed9a --- /dev/null +++ b/queue-4.1/drivers-usb-delete-xhci-command-timer-if-necessary.patch @@ -0,0 +1,60 @@ +From ffe5adcb7661d94e952d6b5ed7f493cb4ef0c7bc Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Mon, 3 Aug 2015 16:07:49 +0300 +Subject: drivers/usb: Delete XHCI command timer if necessary + +From: Gavin Shan + +commit ffe5adcb7661d94e952d6b5ed7f493cb4ef0c7bc upstream. + +When xhci_mem_cleanup() is called, it's possible that the command +timer isn't initialized and scheduled. For those cases, to delete +the command timer causes soft-lockup as below stack dump shows. + +The patch avoids deleting the command timer if it's not scheduled +with the help of timer_pending(). + +NMI watchdog: BUG: soft lockup - CPU#40 stuck for 23s! [kworker/40:1:8140] + : +NIP [c000000000150b30] lock_timer_base.isra.34+0x90/0xa0 +LR [c000000000150c24] try_to_del_timer_sync+0x34/0xa0 +Call Trace: +[c000000f67c975e0] [c0000000015b84f8] mon_ops+0x0/0x8 (unreliable) +[c000000f67c97620] [c000000000150c24] try_to_del_timer_sync+0x34/0xa0 +[c000000f67c97660] [c000000000150cf0] del_timer_sync+0x60/0x80 +[c000000f67c97690] [c00000000070ac0c] xhci_mem_cleanup+0x5c/0x5e0 +[c000000f67c97740] [c00000000070c2e8] xhci_mem_init+0x1158/0x13b0 +[c000000f67c97860] [c000000000700978] xhci_init+0x88/0x110 +[c000000f67c978e0] [c000000000701644] xhci_gen_setup+0x2b4/0x590 +[c000000f67c97970] [c0000000006d4410] xhci_pci_setup+0x40/0x190 +[c000000f67c979f0] [c0000000006b1af8] usb_add_hcd+0x418/0xba0 +[c000000f67c97ab0] [c0000000006cb15c] usb_hcd_pci_probe+0x1dc/0x5c0 +[c000000f67c97b50] [c0000000006d3ba4] xhci_pci_probe+0x64/0x1f0 +[c000000f67c97ba0] [c0000000004fe9ac] local_pci_probe+0x6c/0x130 +[c000000f67c97c30] [c0000000000e5ce8] work_for_cpu_fn+0x38/0x60 +[c000000f67c97c60] [c0000000000eacb8] process_one_work+0x198/0x470 +[c000000f67c97cf0] [c0000000000eb6ac] worker_thread+0x37c/0x5a0 +[c000000f67c97d80] [c0000000000f2730] kthread+0x110/0x130 +[c000000f67c97e30] [c000000000009660] ret_from_kernel_thread+0x5c/0x7c + +Reported-by: Priya M. A +Signed-off-by: Gavin Shan +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-mem.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -1792,7 +1792,8 @@ void xhci_mem_cleanup(struct xhci_hcd *x + int size; + int i, j, num_ports; + +- del_timer_sync(&xhci->cmd_timer); ++ if (timer_pending(&xhci->cmd_timer)) ++ del_timer_sync(&xhci->cmd_timer); + + /* Free the Event Ring Segment Table and the actual Event Ring */ + size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); diff --git a/queue-4.1/drm-dp-mst-remove-debug-warn_on.patch b/queue-4.1/drm-dp-mst-remove-debug-warn_on.patch new file mode 100644 index 00000000000..30a1510c286 --- /dev/null +++ b/queue-4.1/drm-dp-mst-remove-debug-warn_on.patch @@ -0,0 +1,34 @@ +From 42639ba554655c280ae6cb72df0522b1201f2961 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 3 Aug 2015 17:24:10 +0200 +Subject: drm/dp-mst: Remove debug WARN_ON + +From: Daniel Vetter + +commit 42639ba554655c280ae6cb72df0522b1201f2961 upstream. + +Apparently been in there since forever and fairly easy to hit when +hotplugging really fast. I can do that since my mst hub has a manual +button to flick the hpd line for reprobing. The resulting WARNING spam +isn't pretty. + +Cc: Dave Airlie +Reviewed-by: Thierry Reding +Reviewed-by: Ander Conselvan de Oliveira +Signed-off-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/drm_dp_mst_topology.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/gpu/drm/drm_dp_mst_topology.c ++++ b/drivers/gpu/drm/drm_dp_mst_topology.c +@@ -1294,7 +1294,6 @@ retry: + goto retry; + } + DRM_DEBUG_KMS("failed to dpcd write %d %d\n", tosend, ret); +- WARN(1, "fail\n"); + + return -EIO; + } diff --git a/queue-4.1/drm-i915-declare-the-swizzling-unknown-for-l-shaped-configurations.patch b/queue-4.1/drm-i915-declare-the-swizzling-unknown-for-l-shaped-configurations.patch new file mode 100644 index 00000000000..812134c0c20 --- /dev/null +++ b/queue-4.1/drm-i915-declare-the-swizzling-unknown-for-l-shaped-configurations.patch @@ -0,0 +1,56 @@ +From 5eb3e5a5e11d14f9deb2a4b83555443b69ab9940 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Sun, 28 Jun 2015 09:19:26 +0100 +Subject: drm/i915: Declare the swizzling unknown for L-shaped configurations + +From: Chris Wilson + +commit 5eb3e5a5e11d14f9deb2a4b83555443b69ab9940 upstream. + +The old style of memory interleaving swizzled upto the end of the +first even bank of memory, and then used the remainder as unswizzled on +the unpaired bank - i.e. swizzling is not constant for all memory. This +causes problems when we try to migrate memory and so the kernel prevents +migration at all when we detect L-shaped inconsistent swizzling. +However, this issue also extends to userspace who try to manually detile +into memory as the swizzling for an individual page is unknown (it +depends on its physical address only known to the kernel), userspace +cannot correctly swizzle. + +Note that this is a new attempt for the previously merged one, +reverted in + +commit d82c0ba6e306f079407f07003e53c262d683397b +Author: Daniel Vetter +Date: Tue Jul 14 12:29:27 2015 +0200 + + Revert "drm/i915: Declare the swizzling unknown for L-shaped configurations" + +This is cc: stable since we need it to fix up troubles with wc cpu +mmaps that userspace recently started to use widely. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91105 +Signed-off-by: Chris Wilson +Cc: Daniel Vetter +[danvet: Add note about previous (failed attempt).] +Signed-off-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_gem_tiling.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/i915/i915_gem_tiling.c ++++ b/drivers/gpu/drm/i915/i915_gem_tiling.c +@@ -464,7 +464,10 @@ i915_gem_get_tiling(struct drm_device *d + } + + /* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */ +- args->phys_swizzle_mode = args->swizzle_mode; ++ if (dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) ++ args->phys_swizzle_mode = I915_BIT_6_SWIZZLE_UNKNOWN; ++ else ++ args->phys_swizzle_mode = args->swizzle_mode; + if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17) + args->swizzle_mode = I915_BIT_6_SWIZZLE_9; + if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17) diff --git a/queue-4.1/drm-i915-replace-warn-inside-i915_read64_2x32-with-retry-loop.patch b/queue-4.1/drm-i915-replace-warn-inside-i915_read64_2x32-with-retry-loop.patch new file mode 100644 index 00000000000..f63fa4a4a03 --- /dev/null +++ b/queue-4.1/drm-i915-replace-warn-inside-i915_read64_2x32-with-retry-loop.patch @@ -0,0 +1,51 @@ +From ee0a227b7ac6e75f28e10269f81c7ec6eb600952 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Wed, 15 Jul 2015 09:50:42 +0100 +Subject: drm/i915: Replace WARN inside I915_READ64_2x32 with retry loop +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Chris Wilson + +commit ee0a227b7ac6e75f28e10269f81c7ec6eb600952 upstream. + +Since we may conceivably encounter situations where the upper part of the +64bit register changes between reads, for example when a timestamp +counter overflows, change the WARN into a retry loop. + +Signed-off-by: Chris Wilson +Cc: Michał Winiarski +Signed-off-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_drv.h | 17 ++++++++--------- + 1 file changed, 8 insertions(+), 9 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -3190,15 +3190,14 @@ int intel_freq_opcode(struct drm_i915_pr + #define I915_READ64(reg) dev_priv->uncore.funcs.mmio_readq(dev_priv, (reg), true) + + #define I915_READ64_2x32(lower_reg, upper_reg) ({ \ +- u32 upper = I915_READ(upper_reg); \ +- u32 lower = I915_READ(lower_reg); \ +- u32 tmp = I915_READ(upper_reg); \ +- if (upper != tmp) { \ +- upper = tmp; \ +- lower = I915_READ(lower_reg); \ +- WARN_ON(I915_READ(upper_reg) != upper); \ +- } \ +- (u64)upper << 32 | lower; }) ++ u32 upper, lower, tmp; \ ++ tmp = I915_READ(upper_reg); \ ++ do { \ ++ upper = tmp; \ ++ lower = I915_READ(lower_reg); \ ++ tmp = I915_READ(upper_reg); \ ++ } while (upper != tmp); \ ++ (u64)upper << 32 | lower; }) + + #define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg) + #define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg) diff --git a/queue-4.1/drm-radeon-combios-add-some-validation-of-lvds-values.patch b/queue-4.1/drm-radeon-combios-add-some-validation-of-lvds-values.patch new file mode 100644 index 00000000000..e5277523beb --- /dev/null +++ b/queue-4.1/drm-radeon-combios-add-some-validation-of-lvds-values.patch @@ -0,0 +1,45 @@ +From 0a90a0cff9f429f886f423967ae053150dce9259 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Mon, 27 Jul 2015 19:24:31 -0400 +Subject: drm/radeon/combios: add some validation of lvds values + +From: Alex Deucher + +commit 0a90a0cff9f429f886f423967ae053150dce9259 upstream. + +Fixes a broken hsync start value uncovered by: +abc0b1447d4974963548777a5ba4a4457c82c426 +(drm: Perform basic sanity checks on probed modes) + +The driver handled the bad hsync start elsewhere, but +the above commit prevented it from getting added. + +bug: +https://bugs.freedesktop.org/show_bug.cgi?id=91401 + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_combios.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/radeon/radeon_combios.c ++++ b/drivers/gpu/drm/radeon/radeon_combios.c +@@ -1255,10 +1255,15 @@ struct radeon_encoder_lvds *radeon_combi + + if ((RBIOS16(tmp) == lvds->native_mode.hdisplay) && + (RBIOS16(tmp + 2) == lvds->native_mode.vdisplay)) { ++ u32 hss = (RBIOS16(tmp + 21) - RBIOS16(tmp + 19) - 1) * 8; ++ ++ if (hss > lvds->native_mode.hdisplay) ++ hss = (10 - 1) * 8; ++ + lvds->native_mode.htotal = lvds->native_mode.hdisplay + + (RBIOS16(tmp + 17) - RBIOS16(tmp + 19)) * 8; + lvds->native_mode.hsync_start = lvds->native_mode.hdisplay + +- (RBIOS16(tmp + 21) - RBIOS16(tmp + 19) - 1) * 8; ++ hss; + lvds->native_mode.hsync_end = lvds->native_mode.hsync_start + + (RBIOS8(tmp + 23) * 8); + diff --git a/queue-4.1/drm-radeon-rework-audio-detect-v4.patch b/queue-4.1/drm-radeon-rework-audio-detect-v4.patch new file mode 100644 index 00000000000..b428309dfc9 --- /dev/null +++ b/queue-4.1/drm-radeon-rework-audio-detect-v4.patch @@ -0,0 +1,528 @@ +From d0ea397e22f9ad0113c1dbdaab14eded050472eb Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Thu, 23 Jul 2015 10:01:09 -0400 +Subject: drm/radeon: rework audio detect (v4) + +From: Alex Deucher + +commit d0ea397e22f9ad0113c1dbdaab14eded050472eb upstream. + +1. Always assign audio function pointers even if the display does +not support audio. We need to properly disable the audio stream +when when using a non-audio capable monitor. Fixes purple line +on some hdmi monitors. + +2. Check if a pin is in use by another encoder before disabling +it. + +v2: make sure we've fetched the edid before checking audio and + look up the encoder before calling audio_detect since + connector->encoder may not be assigned yet. Separate + pin and afmt. They are allocated at different times and + have no dependency on eachother. +v3: fix connector fetching in encoder functions +v4: fix missed dig->pin check in dce6_afmt_write_latency_fields + +bugs: +https://bugzilla.kernel.org/show_bug.cgi?id=93701 +https://bugzilla.redhat.com/show_bug.cgi?id=1236337 +https://bugs.freedesktop.org/show_bug.cgi?id=91041 + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/dce6_afmt.c | 62 +++++------- + drivers/gpu/drm/radeon/radeon_audio.c | 143 ++++++++++++----------------- + drivers/gpu/drm/radeon/radeon_audio.h | 3 + drivers/gpu/drm/radeon/radeon_connectors.c | 18 ++- + drivers/gpu/drm/radeon/radeon_mode.h | 2 + 5 files changed, 105 insertions(+), 123 deletions(-) + +--- a/drivers/gpu/drm/radeon/dce6_afmt.c ++++ b/drivers/gpu/drm/radeon/dce6_afmt.c +@@ -93,30 +93,26 @@ void dce6_afmt_select_pin(struct drm_enc + struct radeon_device *rdev = encoder->dev->dev_private; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; +- u32 offset; + +- if (!dig || !dig->afmt || !dig->afmt->pin) ++ if (!dig || !dig->afmt || !dig->pin) + return; + +- offset = dig->afmt->offset; +- +- WREG32(AFMT_AUDIO_SRC_CONTROL + offset, +- AFMT_AUDIO_SRC_SELECT(dig->afmt->pin->id)); ++ WREG32(AFMT_AUDIO_SRC_CONTROL + dig->afmt->offset, ++ AFMT_AUDIO_SRC_SELECT(dig->pin->id)); + } + + void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, +- struct drm_connector *connector, struct drm_display_mode *mode) ++ struct drm_connector *connector, ++ struct drm_display_mode *mode) + { + struct radeon_device *rdev = encoder->dev->dev_private; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; +- u32 tmp = 0, offset; ++ u32 tmp = 0; + +- if (!dig || !dig->afmt || !dig->afmt->pin) ++ if (!dig || !dig->afmt || !dig->pin) + return; + +- offset = dig->afmt->pin->offset; +- + if (mode->flags & DRM_MODE_FLAG_INTERLACE) { + if (connector->latency_present[1]) + tmp = VIDEO_LIPSYNC(connector->video_latency[1]) | +@@ -130,24 +126,24 @@ void dce6_afmt_write_latency_fields(stru + else + tmp = VIDEO_LIPSYNC(0) | AUDIO_LIPSYNC(0); + } +- WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp); ++ WREG32_ENDPOINT(dig->pin->offset, ++ AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp); + } + + void dce6_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, +- u8 *sadb, int sad_count) ++ u8 *sadb, int sad_count) + { + struct radeon_device *rdev = encoder->dev->dev_private; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; +- u32 offset, tmp; ++ u32 tmp; + +- if (!dig || !dig->afmt || !dig->afmt->pin) ++ if (!dig || !dig->afmt || !dig->pin) + return; + +- offset = dig->afmt->pin->offset; +- + /* program the speaker allocation */ +- tmp = RREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER); ++ tmp = RREG32_ENDPOINT(dig->pin->offset, ++ AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER); + tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); + /* set HDMI mode */ + tmp |= HDMI_CONNECTION; +@@ -155,24 +151,24 @@ void dce6_afmt_hdmi_write_speaker_alloca + tmp |= SPEAKER_ALLOCATION(sadb[0]); + else + tmp |= SPEAKER_ALLOCATION(5); /* stereo */ +- WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp); ++ WREG32_ENDPOINT(dig->pin->offset, ++ AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp); + } + + void dce6_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, +- u8 *sadb, int sad_count) ++ u8 *sadb, int sad_count) + { + struct radeon_device *rdev = encoder->dev->dev_private; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; +- u32 offset, tmp; ++ u32 tmp; + +- if (!dig || !dig->afmt || !dig->afmt->pin) ++ if (!dig || !dig->afmt || !dig->pin) + return; + +- offset = dig->afmt->pin->offset; +- + /* program the speaker allocation */ +- tmp = RREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER); ++ tmp = RREG32_ENDPOINT(dig->pin->offset, ++ AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER); + tmp &= ~(HDMI_CONNECTION | SPEAKER_ALLOCATION_MASK); + /* set DP mode */ + tmp |= DP_CONNECTION; +@@ -180,13 +176,13 @@ void dce6_afmt_dp_write_speaker_allocati + tmp |= SPEAKER_ALLOCATION(sadb[0]); + else + tmp |= SPEAKER_ALLOCATION(5); /* stereo */ +- WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp); ++ WREG32_ENDPOINT(dig->pin->offset, ++ AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp); + } + + void dce6_afmt_write_sad_regs(struct drm_encoder *encoder, +- struct cea_sad *sads, int sad_count) ++ struct cea_sad *sads, int sad_count) + { +- u32 offset; + int i; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; +@@ -206,11 +202,9 @@ void dce6_afmt_write_sad_regs(struct drm + { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO }, + }; + +- if (!dig || !dig->afmt || !dig->afmt->pin) ++ if (!dig || !dig->afmt || !dig->pin) + return; + +- offset = dig->afmt->pin->offset; +- + for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { + u32 value = 0; + u8 stereo_freqs = 0; +@@ -237,7 +231,7 @@ void dce6_afmt_write_sad_regs(struct drm + + value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); + +- WREG32_ENDPOINT(offset, eld_reg_to_type[i][0], value); ++ WREG32_ENDPOINT(dig->pin->offset, eld_reg_to_type[i][0], value); + } + } + +@@ -253,7 +247,7 @@ void dce6_audio_enable(struct radeon_dev + } + + void dce6_hdmi_audio_set_dto(struct radeon_device *rdev, +- struct radeon_crtc *crtc, unsigned int clock) ++ struct radeon_crtc *crtc, unsigned int clock) + { + /* Two dtos; generally use dto0 for HDMI */ + u32 value = 0; +@@ -272,7 +266,7 @@ void dce6_hdmi_audio_set_dto(struct rade + } + + void dce6_dp_audio_set_dto(struct radeon_device *rdev, +- struct radeon_crtc *crtc, unsigned int clock) ++ struct radeon_crtc *crtc, unsigned int clock) + { + /* Two dtos; generally use dto1 for DP */ + u32 value = 0; +--- a/drivers/gpu/drm/radeon/radeon_audio.c ++++ b/drivers/gpu/drm/radeon/radeon_audio.c +@@ -245,6 +245,28 @@ static struct radeon_audio_funcs dce6_dp + static void radeon_audio_enable(struct radeon_device *rdev, + struct r600_audio_pin *pin, u8 enable_mask) + { ++ struct drm_encoder *encoder; ++ struct radeon_encoder *radeon_encoder; ++ struct radeon_encoder_atom_dig *dig; ++ int pin_count = 0; ++ ++ if (!pin) ++ return; ++ ++ if (rdev->mode_info.mode_config_initialized) { ++ list_for_each_entry(encoder, &rdev->ddev->mode_config.encoder_list, head) { ++ if (radeon_encoder_is_digital(encoder)) { ++ radeon_encoder = to_radeon_encoder(encoder); ++ dig = radeon_encoder->enc_priv; ++ if (dig->pin == pin) ++ pin_count++; ++ } ++ } ++ ++ if ((pin_count > 1) && (enable_mask == 0)) ++ return; ++ } ++ + if (rdev->audio.funcs->enable) + rdev->audio.funcs->enable(rdev, pin, enable_mask); + } +@@ -336,24 +358,13 @@ void radeon_audio_endpoint_wreg(struct r + + static void radeon_audio_write_sad_regs(struct drm_encoder *encoder) + { +- struct radeon_encoder *radeon_encoder; +- struct drm_connector *connector; +- struct radeon_connector *radeon_connector = NULL; ++ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct cea_sad *sads; + int sad_count; + +- list_for_each_entry(connector, +- &encoder->dev->mode_config.connector_list, head) { +- if (connector->encoder == encoder) { +- radeon_connector = to_radeon_connector(connector); +- break; +- } +- } +- +- if (!radeon_connector) { +- DRM_ERROR("Couldn't find encoder's connector\n"); ++ if (!connector) + return; +- } + + sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads); + if (sad_count <= 0) { +@@ -362,8 +373,6 @@ static void radeon_audio_write_sad_regs( + } + BUG_ON(!sads); + +- radeon_encoder = to_radeon_encoder(encoder); +- + if (radeon_encoder->audio && radeon_encoder->audio->write_sad_regs) + radeon_encoder->audio->write_sad_regs(encoder, sads, sad_count); + +@@ -372,27 +381,16 @@ static void radeon_audio_write_sad_regs( + + static void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder) + { ++ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); +- struct drm_connector *connector; +- struct radeon_connector *radeon_connector = NULL; + u8 *sadb = NULL; + int sad_count; + +- list_for_each_entry(connector, +- &encoder->dev->mode_config.connector_list, head) { +- if (connector->encoder == encoder) { +- radeon_connector = to_radeon_connector(connector); +- break; +- } +- } +- +- if (!radeon_connector) { +- DRM_ERROR("Couldn't find encoder's connector\n"); ++ if (!connector) + return; +- } + +- sad_count = drm_edid_to_speaker_allocation( +- radeon_connector_edid(connector), &sadb); ++ sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), ++ &sadb); + if (sad_count < 0) { + DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", + sad_count); +@@ -406,26 +404,13 @@ static void radeon_audio_write_speaker_a + } + + static void radeon_audio_write_latency_fields(struct drm_encoder *encoder, +- struct drm_display_mode *mode) ++ struct drm_display_mode *mode) + { +- struct radeon_encoder *radeon_encoder; +- struct drm_connector *connector; +- struct radeon_connector *radeon_connector = 0; +- +- list_for_each_entry(connector, +- &encoder->dev->mode_config.connector_list, head) { +- if (connector->encoder == encoder) { +- radeon_connector = to_radeon_connector(connector); +- break; +- } +- } ++ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + +- if (!radeon_connector) { +- DRM_ERROR("Couldn't find encoder's connector\n"); ++ if (!connector) + return; +- } +- +- radeon_encoder = to_radeon_encoder(encoder); + + if (radeon_encoder->audio && radeon_encoder->audio->write_latency_fields) + radeon_encoder->audio->write_latency_fields(encoder, connector, mode); +@@ -451,29 +436,23 @@ static void radeon_audio_select_pin(stru + } + + void radeon_audio_detect(struct drm_connector *connector, ++ struct drm_encoder *encoder, + enum drm_connector_status status) + { +- struct radeon_device *rdev; +- struct radeon_encoder *radeon_encoder; ++ struct drm_device *dev = connector->dev; ++ struct radeon_device *rdev = dev->dev_private; ++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig; + +- if (!connector || !connector->encoder) ++ if (!radeon_audio_chipset_supported(rdev)) + return; + +- rdev = connector->encoder->dev->dev_private; +- +- if (!radeon_audio_chipset_supported(rdev)) ++ if (!radeon_encoder_is_digital(encoder)) + return; + +- radeon_encoder = to_radeon_encoder(connector->encoder); + dig = radeon_encoder->enc_priv; + + if (status == connector_status_connected) { +- if (!drm_detect_monitor_audio(radeon_connector_edid(connector))) { +- radeon_encoder->audio = NULL; +- return; +- } +- + if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + +@@ -486,11 +465,17 @@ void radeon_audio_detect(struct drm_conn + radeon_encoder->audio = rdev->audio.hdmi_funcs; + } + +- dig->afmt->pin = radeon_audio_get_pin(connector->encoder); +- radeon_audio_enable(rdev, dig->afmt->pin, 0xf); ++ if (drm_detect_monitor_audio(radeon_connector_edid(connector))) { ++ if (!dig->pin) ++ dig->pin = radeon_audio_get_pin(encoder); ++ radeon_audio_enable(rdev, dig->pin, 0xf); ++ } else { ++ radeon_audio_enable(rdev, dig->pin, 0); ++ dig->pin = NULL; ++ } + } else { +- radeon_audio_enable(rdev, dig->afmt->pin, 0); +- dig->afmt->pin = NULL; ++ radeon_audio_enable(rdev, dig->pin, 0); ++ dig->pin = NULL; + } + } + +@@ -518,29 +503,18 @@ static void radeon_audio_set_dto(struct + } + + static int radeon_audio_set_avi_packet(struct drm_encoder *encoder, +- struct drm_display_mode *mode) ++ struct drm_display_mode *mode) + { + struct radeon_device *rdev = encoder->dev->dev_private; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; +- struct drm_connector *connector; +- struct radeon_connector *radeon_connector = NULL; ++ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); + u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; + struct hdmi_avi_infoframe frame; + int err; + +- list_for_each_entry(connector, +- &encoder->dev->mode_config.connector_list, head) { +- if (connector->encoder == encoder) { +- radeon_connector = to_radeon_connector(connector); +- break; +- } +- } +- +- if (!radeon_connector) { +- DRM_ERROR("Couldn't find encoder's connector\n"); +- return -ENOENT; +- } ++ if (!connector) ++ return -EINVAL; + + err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); + if (err < 0) { +@@ -563,8 +537,8 @@ static int radeon_audio_set_avi_packet(s + return err; + } + +- if (dig && dig->afmt && +- radeon_encoder->audio && radeon_encoder->audio->set_avi_packet) ++ if (dig && dig->afmt && radeon_encoder->audio && ++ radeon_encoder->audio->set_avi_packet) + radeon_encoder->audio->set_avi_packet(rdev, dig->afmt->offset, + buffer, sizeof(buffer)); + +@@ -745,7 +719,7 @@ static void radeon_audio_hdmi_mode_set(s + } + + static void radeon_audio_dp_mode_set(struct drm_encoder *encoder, +- struct drm_display_mode *mode) ++ struct drm_display_mode *mode) + { + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; +@@ -756,6 +730,9 @@ static void radeon_audio_dp_mode_set(str + struct radeon_connector_atom_dig *dig_connector = + radeon_connector->con_priv; + ++ if (!connector) ++ return; ++ + if (!dig || !dig->afmt) + return; + +@@ -774,7 +751,7 @@ static void radeon_audio_dp_mode_set(str + } + + void radeon_audio_mode_set(struct drm_encoder *encoder, +- struct drm_display_mode *mode) ++ struct drm_display_mode *mode) + { + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + +--- a/drivers/gpu/drm/radeon/radeon_audio.h ++++ b/drivers/gpu/drm/radeon/radeon_audio.h +@@ -68,7 +68,8 @@ struct radeon_audio_funcs + + int radeon_audio_init(struct radeon_device *rdev); + void radeon_audio_detect(struct drm_connector *connector, +- enum drm_connector_status status); ++ struct drm_encoder *encoder, ++ enum drm_connector_status status); + u32 radeon_audio_endpoint_rreg(struct radeon_device *rdev, + u32 offset, u32 reg); + void radeon_audio_endpoint_wreg(struct radeon_device *rdev, +--- a/drivers/gpu/drm/radeon/radeon_connectors.c ++++ b/drivers/gpu/drm/radeon/radeon_connectors.c +@@ -1379,8 +1379,16 @@ out: + /* updated in get modes as well since we need to know if it's analog or digital */ + radeon_connector_update_scratch_regs(connector, ret); + +- if (radeon_audio != 0) +- radeon_audio_detect(connector, ret); ++ if ((radeon_audio != 0) && radeon_connector->use_digital) { ++ const struct drm_connector_helper_funcs *connector_funcs = ++ connector->helper_private; ++ ++ encoder = connector_funcs->best_encoder(connector); ++ if (encoder && (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)) { ++ radeon_connector_get_edid(connector); ++ radeon_audio_detect(connector, encoder, ret); ++ } ++ } + + exit: + pm_runtime_mark_last_busy(connector->dev->dev); +@@ -1717,8 +1725,10 @@ radeon_dp_detect(struct drm_connector *c + + radeon_connector_update_scratch_regs(connector, ret); + +- if (radeon_audio != 0) +- radeon_audio_detect(connector, ret); ++ if ((radeon_audio != 0) && encoder) { ++ radeon_connector_get_edid(connector); ++ radeon_audio_detect(connector, encoder, ret); ++ } + + out: + pm_runtime_mark_last_busy(connector->dev->dev); +--- a/drivers/gpu/drm/radeon/radeon_mode.h ++++ b/drivers/gpu/drm/radeon/radeon_mode.h +@@ -237,7 +237,6 @@ struct radeon_afmt { + int offset; + bool last_buffer_filled_status; + int id; +- struct r600_audio_pin *pin; + }; + + struct radeon_mode_info { +@@ -439,6 +438,7 @@ struct radeon_encoder_atom_dig { + uint8_t backlight_level; + int panel_mode; + struct radeon_afmt *afmt; ++ struct r600_audio_pin *pin; + int active_mst_links; + }; + diff --git a/queue-4.1/fsnotify-fix-oops-in-fsnotify_clear_marks_by_group_flags.patch b/queue-4.1/fsnotify-fix-oops-in-fsnotify_clear_marks_by_group_flags.patch new file mode 100644 index 00000000000..b97818543ca --- /dev/null +++ b/queue-4.1/fsnotify-fix-oops-in-fsnotify_clear_marks_by_group_flags.patch @@ -0,0 +1,77 @@ +From 8f2f3eb59dff4ec538de55f2e0592fec85966aab Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 6 Aug 2015 15:46:42 -0700 +Subject: fsnotify: fix oops in fsnotify_clear_marks_by_group_flags() + +From: Jan Kara + +commit 8f2f3eb59dff4ec538de55f2e0592fec85966aab upstream. + +fsnotify_clear_marks_by_group_flags() can race with +fsnotify_destroy_marks() so that when fsnotify_destroy_mark_locked() +drops mark_mutex, a mark from the list iterated by +fsnotify_clear_marks_by_group_flags() can be freed and thus the next +entry pointer we have cached may become stale and we dereference free +memory. + +Fix the problem by first moving marks to free to a special private list +and then always free the first entry in the special list. This method +is safe even when entries from the list can disappear once we drop the +lock. + +Signed-off-by: Jan Kara +Reported-by: Ashish Sangwan +Reviewed-by: Ashish Sangwan +Cc: Lino Sanfilippo +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/notify/mark.c | 30 +++++++++++++++++++++++++----- + 1 file changed, 25 insertions(+), 5 deletions(-) + +--- a/fs/notify/mark.c ++++ b/fs/notify/mark.c +@@ -412,16 +412,36 @@ void fsnotify_clear_marks_by_group_flags + unsigned int flags) + { + struct fsnotify_mark *lmark, *mark; ++ LIST_HEAD(to_free); + ++ /* ++ * We have to be really careful here. Anytime we drop mark_mutex, e.g. ++ * fsnotify_clear_marks_by_inode() can come and free marks. Even in our ++ * to_free list so we have to use mark_mutex even when accessing that ++ * list. And freeing mark requires us to drop mark_mutex. So we can ++ * reliably free only the first mark in the list. That's why we first ++ * move marks to free to to_free list in one go and then free marks in ++ * to_free list one by one. ++ */ + mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING); + list_for_each_entry_safe(mark, lmark, &group->marks_list, g_list) { +- if (mark->flags & flags) { +- fsnotify_get_mark(mark); +- fsnotify_destroy_mark_locked(mark, group); +- fsnotify_put_mark(mark); +- } ++ if (mark->flags & flags) ++ list_move(&mark->g_list, &to_free); + } + mutex_unlock(&group->mark_mutex); ++ ++ while (1) { ++ mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING); ++ if (list_empty(&to_free)) { ++ mutex_unlock(&group->mark_mutex); ++ break; ++ } ++ mark = list_first_entry(&to_free, struct fsnotify_mark, g_list); ++ fsnotify_get_mark(mark); ++ fsnotify_destroy_mark_locked(mark, group); ++ mutex_unlock(&group->mark_mutex); ++ fsnotify_put_mark(mark); ++ } + } + + /* diff --git a/queue-4.1/ipr-fix-incorrect-trace-indexing.patch b/queue-4.1/ipr-fix-incorrect-trace-indexing.patch new file mode 100644 index 00000000000..ad574777b2f --- /dev/null +++ b/queue-4.1/ipr-fix-incorrect-trace-indexing.patch @@ -0,0 +1,52 @@ +From bb7c54339e6a10ecce5c4961adf5e75b3cf0af30 Mon Sep 17 00:00:00 2001 +From: Brian King +Date: Tue, 14 Jul 2015 11:41:31 -0500 +Subject: ipr: Fix incorrect trace indexing + +From: Brian King + +commit bb7c54339e6a10ecce5c4961adf5e75b3cf0af30 upstream. + +When ipr's internal driver trace was changed to an atomic, a signed/unsigned +bug slipped in which results in us indexing backwards in our memory buffer +writing on memory that does not belong to us. This patch fixes this by removing +the modulo and instead just mask off the low bits. + +Tested-by: Wen Xiong +Reviewed-by: Wen Xiong +Reviewed-by: Gabriel Krisman Bertazi +Signed-off-by: Brian King +Reviewed-by: Martin K. Petersen +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/ipr.c | 5 +++-- + drivers/scsi/ipr.h | 1 + + 2 files changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/ipr.c ++++ b/drivers/scsi/ipr.c +@@ -599,9 +599,10 @@ static void ipr_trc_hook(struct ipr_cmnd + { + struct ipr_trace_entry *trace_entry; + struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; ++ unsigned int trace_index; + +- trace_entry = &ioa_cfg->trace[atomic_add_return +- (1, &ioa_cfg->trace_index)%IPR_NUM_TRACE_ENTRIES]; ++ trace_index = atomic_add_return(1, &ioa_cfg->trace_index) & IPR_TRACE_INDEX_MASK; ++ trace_entry = &ioa_cfg->trace[trace_index]; + trace_entry->time = jiffies; + trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0]; + trace_entry->type = type; +--- a/drivers/scsi/ipr.h ++++ b/drivers/scsi/ipr.h +@@ -1486,6 +1486,7 @@ struct ipr_ioa_cfg { + + #define IPR_NUM_TRACE_INDEX_BITS 8 + #define IPR_NUM_TRACE_ENTRIES (1 << IPR_NUM_TRACE_INDEX_BITS) ++#define IPR_TRACE_INDEX_MASK (IPR_NUM_TRACE_ENTRIES - 1) + #define IPR_TRACE_SIZE (sizeof(struct ipr_trace_entry) * IPR_NUM_TRACE_ENTRIES) + char trace_start[8]; + #define IPR_TRACE_START_LABEL "trace" diff --git a/queue-4.1/ipr-fix-invalid-array-indexing-for-hrrq.patch b/queue-4.1/ipr-fix-invalid-array-indexing-for-hrrq.patch new file mode 100644 index 00000000000..5343f94741f --- /dev/null +++ b/queue-4.1/ipr-fix-invalid-array-indexing-for-hrrq.patch @@ -0,0 +1,67 @@ +From 3f1c0581310d5d94bd72740231507e763a6252a4 Mon Sep 17 00:00:00 2001 +From: Brian King +Date: Tue, 14 Jul 2015 11:41:33 -0500 +Subject: ipr: Fix invalid array indexing for HRRQ + +From: Brian King + +commit 3f1c0581310d5d94bd72740231507e763a6252a4 upstream. + +Fixes another signed / unsigned array indexing bug in the ipr driver. +Currently, when hrrq_index wraps, it becomes a negative number. We +do the modulo, but still have a negative number, so we end up indexing +backwards in the array. Given where the hrrq array is located in memory, +we probably won't actually reference memory we don't own, but nonetheless +ipr is still looking at data within struct ipr_ioa_cfg and interpreting it as +struct ipr_hrr_queue data, so bad things could certainly happen. + +Each ipr adapter has anywhere from 1 to 16 HRRQs. By default, we use 2 on new +adapters. Let's take an example: + +Assume ioa_cfg->hrrq_index=0x7fffffffe and ioa_cfg->hrrq_num=4: + +The atomic_add_return will then return -1. We mod this with 3 and get -2, add +one and get -1 for an array index. + +On adapters which support more than a single HRRQ, we dedicate HRRQ to adapter +initialization and error interrupts so that we can optimize the other queues +for fast path I/O. So all normal I/O uses HRRQ 1-15. So we want to spread the +I/O requests across those HRRQs. + +With the default module parameter settings, this bug won't hit, only when +someone sets the ipr.number_of_msix parameter to a value larger than 3 is when +bad things start to happen. + +Tested-by: Wen Xiong +Reviewed-by: Wen Xiong +Reviewed-by: Gabriel Krisman Bertazi +Signed-off-by: Brian King +Reviewed-by: Martin K. Petersen +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/ipr.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/drivers/scsi/ipr.c ++++ b/drivers/scsi/ipr.c +@@ -1052,10 +1052,15 @@ static void ipr_send_blocking_cmd(struct + + static int ipr_get_hrrq_index(struct ipr_ioa_cfg *ioa_cfg) + { ++ unsigned int hrrq; ++ + if (ioa_cfg->hrrq_num == 1) +- return 0; +- else +- return (atomic_add_return(1, &ioa_cfg->hrrq_index) % (ioa_cfg->hrrq_num - 1)) + 1; ++ hrrq = 0; ++ else { ++ hrrq = atomic_add_return(1, &ioa_cfg->hrrq_index); ++ hrrq = (hrrq % (ioa_cfg->hrrq_num - 1)) + 1; ++ } ++ return hrrq; + } + + /** diff --git a/queue-4.1/ipr-fix-locking-for-unit-attention-handling.patch b/queue-4.1/ipr-fix-locking-for-unit-attention-handling.patch new file mode 100644 index 00000000000..4b592a3b4a4 --- /dev/null +++ b/queue-4.1/ipr-fix-locking-for-unit-attention-handling.patch @@ -0,0 +1,55 @@ +From 36b8e180e1e929e00b351c3b72aab3147fc14116 Mon Sep 17 00:00:00 2001 +From: Brian King +Date: Tue, 14 Jul 2015 11:41:29 -0500 +Subject: ipr: Fix locking for unit attention handling + +From: Brian King + +commit 36b8e180e1e929e00b351c3b72aab3147fc14116 upstream. + +Make sure we have the host lock held when calling scsi_report_bus_reset. Fixes +a crash seen as the __devices list in the scsi host was changing as we were +iterating through it. + +Reviewed-by: Wen Xiong +Reviewed-by: Gabriel Krisman Bertazi +Signed-off-by: Brian King +Reviewed-by: Martin K. Petersen +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/ipr.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/scsi/ipr.c ++++ b/drivers/scsi/ipr.c +@@ -6263,21 +6263,23 @@ static void ipr_scsi_done(struct ipr_cmn + struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; + struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; + u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); +- unsigned long hrrq_flags; ++ unsigned long lock_flags; + + scsi_set_resid(scsi_cmd, be32_to_cpu(ipr_cmd->s.ioasa.hdr.residual_data_len)); + + if (likely(IPR_IOASC_SENSE_KEY(ioasc) == 0)) { + scsi_dma_unmap(scsi_cmd); + +- spin_lock_irqsave(ipr_cmd->hrrq->lock, hrrq_flags); ++ spin_lock_irqsave(ipr_cmd->hrrq->lock, lock_flags); + list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); + scsi_cmd->scsi_done(scsi_cmd); +- spin_unlock_irqrestore(ipr_cmd->hrrq->lock, hrrq_flags); ++ spin_unlock_irqrestore(ipr_cmd->hrrq->lock, lock_flags); + } else { +- spin_lock_irqsave(ipr_cmd->hrrq->lock, hrrq_flags); ++ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); ++ spin_lock(&ipr_cmd->hrrq->_lock); + ipr_erp_start(ioa_cfg, ipr_cmd); +- spin_unlock_irqrestore(ipr_cmd->hrrq->lock, hrrq_flags); ++ spin_unlock(&ipr_cmd->hrrq->_lock); ++ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + } + } + diff --git a/queue-4.1/mips-do_mcheck-fix-kernel-code-dump-with-eva.patch b/queue-4.1/mips-do_mcheck-fix-kernel-code-dump-with-eva.patch new file mode 100644 index 00000000000..27e437246e0 --- /dev/null +++ b/queue-4.1/mips-do_mcheck-fix-kernel-code-dump-with-eva.patch @@ -0,0 +1,58 @@ +From 55c723e181ccec30fb5c672397fe69ec35967d97 Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Mon, 27 Jul 2015 13:50:21 +0100 +Subject: MIPS: do_mcheck: Fix kernel code dump with EVA + +From: James Hogan + +commit 55c723e181ccec30fb5c672397fe69ec35967d97 upstream. + +If a machine check exception is raised in kernel mode, user context, +with EVA enabled, then the do_mcheck handler will attempt to read the +code around the EPC using EVA load instructions, i.e. as if the reads +were from user mode. This will either read random user data if the +process has anything mapped at the same address, or it will cause an +exception which is handled by __get_user, resulting in this output: + + Code: (Bad address in epc) + +Fix by setting the current user access mode to kernel if the saved +register context indicates the exception was taken in kernel mode. This +causes __get_user to use normal loads to read the kernel code. + +Signed-off-by: James Hogan +Cc: Markos Chandras +Cc: Leonid Yegoshin +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/10777/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kernel/traps.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/arch/mips/kernel/traps.c ++++ b/arch/mips/kernel/traps.c +@@ -1518,6 +1518,7 @@ asmlinkage void do_mcheck(struct pt_regs + const int field = 2 * sizeof(unsigned long); + int multi_match = regs->cp0_status & ST0_TS; + enum ctx_state prev_state; ++ mm_segment_t old_fs = get_fs(); + + prev_state = exception_enter(); + show_regs(regs); +@@ -1539,8 +1540,13 @@ asmlinkage void do_mcheck(struct pt_regs + dump_tlb_all(); + } + ++ if (!user_mode(regs)) ++ set_fs(KERNEL_DS); ++ + show_code((unsigned int __user *) regs->cp0_epc); + ++ set_fs(old_fs); ++ + /* + * Some chips may have other causes of machine check (e.g. SB1 + * graduation timer) diff --git a/queue-4.1/mips-export-get_c0_perfcount_int.patch b/queue-4.1/mips-export-get_c0_perfcount_int.patch new file mode 100644 index 00000000000..1db3cd422f5 --- /dev/null +++ b/queue-4.1/mips-export-get_c0_perfcount_int.patch @@ -0,0 +1,90 @@ +From 0cb0985f57783c2f3c6c8ffe7e7665e80c56bd92 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Thu, 23 Jul 2015 18:59:52 +0200 +Subject: MIPS: Export get_c0_perfcount_int() + +From: Felix Fietkau + +commit 0cb0985f57783c2f3c6c8ffe7e7665e80c56bd92 upstream. + +get_c0_perfcount_int is tested from oprofile code. If oprofile is +compiled as module, get_c0_perfcount_int needs to be exported, otherwise +it cannot be resolved. + +Fixes: a669efc4a3b4 ("MIPS: Add hook to get C0 performance counter interrupt") +Signed-off-by: Felix Fietkau +Cc: linux-mips@linux-mips.org +Cc: abrestic@chromium.org +Patchwork: https://patchwork.linux-mips.org/patch/10763/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/ath79/setup.c | 1 + + arch/mips/lantiq/irq.c | 1 + + arch/mips/mti-malta/malta-time.c | 1 + + arch/mips/mti-sead3/sead3-time.c | 1 + + arch/mips/pistachio/time.c | 1 + + arch/mips/ralink/irq.c | 1 + + 6 files changed, 6 insertions(+) + +--- a/arch/mips/ath79/setup.c ++++ b/arch/mips/ath79/setup.c +@@ -186,6 +186,7 @@ int get_c0_perfcount_int(void) + { + return ATH79_MISC_IRQ(5); + } ++EXPORT_SYMBOL_GPL(get_c0_perfcount_int); + + unsigned int get_c0_compare_int(void) + { +--- a/arch/mips/lantiq/irq.c ++++ b/arch/mips/lantiq/irq.c +@@ -466,6 +466,7 @@ int get_c0_perfcount_int(void) + { + return ltq_perfcount_irq; + } ++EXPORT_SYMBOL_GPL(get_c0_perfcount_int); + + unsigned int get_c0_compare_int(void) + { +--- a/arch/mips/mti-malta/malta-time.c ++++ b/arch/mips/mti-malta/malta-time.c +@@ -148,6 +148,7 @@ int get_c0_perfcount_int(void) + + return mips_cpu_perf_irq; + } ++EXPORT_SYMBOL_GPL(get_c0_perfcount_int); + + unsigned int get_c0_compare_int(void) + { +--- a/arch/mips/mti-sead3/sead3-time.c ++++ b/arch/mips/mti-sead3/sead3-time.c +@@ -77,6 +77,7 @@ int get_c0_perfcount_int(void) + return MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; + return -1; + } ++EXPORT_SYMBOL_GPL(get_c0_perfcount_int); + + unsigned int get_c0_compare_int(void) + { +--- a/arch/mips/pistachio/time.c ++++ b/arch/mips/pistachio/time.c +@@ -26,6 +26,7 @@ int get_c0_perfcount_int(void) + { + return gic_get_c0_perfcount_int(); + } ++EXPORT_SYMBOL_GPL(get_c0_perfcount_int); + + void __init plat_time_init(void) + { +--- a/arch/mips/ralink/irq.c ++++ b/arch/mips/ralink/irq.c +@@ -89,6 +89,7 @@ int get_c0_perfcount_int(void) + { + return rt_perfcount_irq; + } ++EXPORT_SYMBOL_GPL(get_c0_perfcount_int); + + unsigned int get_c0_compare_int(void) + { diff --git a/queue-4.1/mips-fix-sched_getaffinity-with-mt-fpaff-enabled.patch b/queue-4.1/mips-fix-sched_getaffinity-with-mt-fpaff-enabled.patch new file mode 100644 index 00000000000..6611ef1e67a --- /dev/null +++ b/queue-4.1/mips-fix-sched_getaffinity-with-mt-fpaff-enabled.patch @@ -0,0 +1,46 @@ +From 1d62d737555e1378eb62a8bba26644f7d97139d2 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Sun, 19 Jul 2015 00:38:41 +0200 +Subject: MIPS: Fix sched_getaffinity with MT FPAFF enabled + +From: Felix Fietkau + +commit 1d62d737555e1378eb62a8bba26644f7d97139d2 upstream. + +p->thread.user_cpus_allowed is zero-initialized and is only filled on +the first sched_setaffinity call. + +To avoid adding overhead in the task initialization codepath, simply OR +the returned mask in sched_getaffinity with p->cpus_allowed. + +Signed-off-by: Felix Fietkau +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/10740/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kernel/mips-mt-fpaff.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/arch/mips/kernel/mips-mt-fpaff.c ++++ b/arch/mips/kernel/mips-mt-fpaff.c +@@ -154,7 +154,7 @@ asmlinkage long mipsmt_sys_sched_getaffi + unsigned long __user *user_mask_ptr) + { + unsigned int real_len; +- cpumask_t mask; ++ cpumask_t allowed, mask; + int retval; + struct task_struct *p; + +@@ -173,7 +173,8 @@ asmlinkage long mipsmt_sys_sched_getaffi + if (retval) + goto out_unlock; + +- cpumask_and(&mask, &p->thread.user_cpus_allowed, cpu_possible_mask); ++ cpumask_or(&allowed, &p->thread.user_cpus_allowed, &p->cpus_allowed); ++ cpumask_and(&mask, &allowed, cpu_active_mask); + + out_unlock: + read_unlock(&tasklist_lock); diff --git a/queue-4.1/mips-flush-rps-on-kernel-entry-with-eva.patch b/queue-4.1/mips-flush-rps-on-kernel-entry-with-eva.patch new file mode 100644 index 00000000000..8754f60fd92 --- /dev/null +++ b/queue-4.1/mips-flush-rps-on-kernel-entry-with-eva.patch @@ -0,0 +1,64 @@ +From 3aff47c062b944a5e1f9af56a37a23f5295628fc Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Fri, 31 Jul 2015 16:29:38 +0100 +Subject: MIPS: Flush RPS on kernel entry with EVA + +From: James Hogan + +commit 3aff47c062b944a5e1f9af56a37a23f5295628fc upstream. + +When EVA is enabled, flush the Return Prediction Stack (RPS) present on +some MIPS cores on entry to the kernel from user mode. + +This is important specifically for interAptiv with EVA enabled, +otherwise kernel mode RPS mispredicts may trigger speculative fetches of +user return addresses, which may be sensitive in the kernel address +space due to EVA's overlapping user/kernel address spaces. + +Signed-off-by: James Hogan +Cc: Ralf Baechle +Cc: Markos Chandras +Cc: Leonid Yegoshin +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/10812/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/include/asm/stackframe.h | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +--- a/arch/mips/include/asm/stackframe.h ++++ b/arch/mips/include/asm/stackframe.h +@@ -152,6 +152,31 @@ + .set noreorder + bltz k0, 8f + move k1, sp ++#ifdef CONFIG_EVA ++ /* ++ * Flush interAptiv's Return Prediction Stack (RPS) by writing ++ * EntryHi. Toggling Config7.RPS is slower and less portable. ++ * ++ * The RPS isn't automatically flushed when exceptions are ++ * taken, which can result in kernel mode speculative accesses ++ * to user addresses if the RPS mispredicts. That's harmless ++ * when user and kernel share the same address space, but with ++ * EVA the same user segments may be unmapped to kernel mode, ++ * even containing sensitive MMIO regions or invalid memory. ++ * ++ * This can happen when the kernel sets the return address to ++ * ret_from_* and jr's to the exception handler, which looks ++ * more like a tail call than a function call. If nested calls ++ * don't evict the last user address in the RPS, it will ++ * mispredict the return and fetch from a user controlled ++ * address into the icache. ++ * ++ * More recent EVA-capable cores with MAAR to restrict ++ * speculative accesses aren't affected. ++ */ ++ MFC0 k0, CP0_ENTRYHI ++ MTC0 k0, CP0_ENTRYHI ++#endif + .set reorder + /* Called from user mode, new stack. */ + get_saved_sp diff --git a/queue-4.1/mips-make-set_pte-smp-safe.patch b/queue-4.1/mips-make-set_pte-smp-safe.patch new file mode 100644 index 00000000000..895a175a655 --- /dev/null +++ b/queue-4.1/mips-make-set_pte-smp-safe.patch @@ -0,0 +1,77 @@ +From 46011e6ea39235e4aca656673c500eac81a07a17 Mon Sep 17 00:00:00 2001 +From: David Daney +Date: Mon, 3 Aug 2015 17:48:43 -0700 +Subject: MIPS: Make set_pte() SMP safe. + +From: David Daney + +commit 46011e6ea39235e4aca656673c500eac81a07a17 upstream. + +On MIPS the GLOBAL bit of the PTE must have the same value in any +aligned pair of PTEs. These pairs of PTEs are referred to as +"buddies". In a SMP system is is possible for two CPUs to be calling +set_pte() on adjacent PTEs at the same time. There is a race between +setting the PTE and a different CPU setting the GLOBAL bit in its +buddy PTE. + +This race can be observed when multiple CPUs are executing +vmap()/vfree() at the same time. + +Make setting the buddy PTE's GLOBAL bit an atomic operation to close +the race condition. + +The case of CONFIG_64BIT_PHYS_ADDR && CONFIG_CPU_MIPS32 is *not* +handled. + +Signed-off-by: David Daney +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/10835/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/include/asm/pgtable.h | 31 +++++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +--- a/arch/mips/include/asm/pgtable.h ++++ b/arch/mips/include/asm/pgtable.h +@@ -182,8 +182,39 @@ static inline void set_pte(pte_t *ptep, + * Make sure the buddy is global too (if it's !none, + * it better already be global) + */ ++#ifdef CONFIG_SMP ++ /* ++ * For SMP, multiple CPUs can race, so we need to do ++ * this atomically. ++ */ ++#ifdef CONFIG_64BIT ++#define LL_INSN "lld" ++#define SC_INSN "scd" ++#else /* CONFIG_32BIT */ ++#define LL_INSN "ll" ++#define SC_INSN "sc" ++#endif ++ unsigned long page_global = _PAGE_GLOBAL; ++ unsigned long tmp; ++ ++ __asm__ __volatile__ ( ++ " .set push\n" ++ " .set noreorder\n" ++ "1: " LL_INSN " %[tmp], %[buddy]\n" ++ " bnez %[tmp], 2f\n" ++ " or %[tmp], %[tmp], %[global]\n" ++ " " SC_INSN " %[tmp], %[buddy]\n" ++ " beqz %[tmp], 1b\n" ++ " nop\n" ++ "2:\n" ++ " .set pop" ++ : [buddy] "+m" (buddy->pte), ++ [tmp] "=&r" (tmp) ++ : [global] "r" (page_global)); ++#else /* !CONFIG_SMP */ + if (pte_none(*buddy)) + pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL; ++#endif /* CONFIG_SMP */ + } + #endif + } diff --git a/queue-4.1/mips-malta-don-t-reinitialise-rtc.patch b/queue-4.1/mips-malta-don-t-reinitialise-rtc.patch new file mode 100644 index 00000000000..e96e3fb3ae1 --- /dev/null +++ b/queue-4.1/mips-malta-don-t-reinitialise-rtc.patch @@ -0,0 +1,69 @@ +From 106eccb4d20f35ebc58ff2286c170d9e79c5ff68 Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Fri, 17 Jul 2015 15:54:41 +0100 +Subject: MIPS: Malta: Don't reinitialise RTC + +From: James Hogan + +commit 106eccb4d20f35ebc58ff2286c170d9e79c5ff68 upstream. + +On Malta, since commit a87ea88d8f6c ("MIPS: Malta: initialise the RTC at +boot"), the RTC is reinitialised and forced into binary coded decimal +(BCD) mode during init, even if the bootloader has already initialised +it, and may even have already put it into binary mode (as YAMON does). +This corrupts the current time, can result in the RTC seconds being an +invalid BCD (e.g. 0x1a..0x1f) for up to 6 seconds, as well as confusing +YAMON for a while after reset, enough for it to report timeouts when +attempting to load from TFTP (it actually uses the RTC in that code). + +Therefore only initialise the RTC to the extent that is necessary so +that Linux avoids interfering with the bootloader setup, while also +allowing it to estimate the CPU frequency without hanging, without a +bootloader necessarily having done anything with the RTC (for example +when the kernel is loaded via EJTAG). + +The divider control is configured for a 32KHZ reference clock if +necessary, and the SET bit of the RTC_CONTROL register is cleared if +necessary without changing any other bits (this bit will be set when +coming out of reset if the battery has been disconnected). + +Fixes: a87ea88d8f6c ("MIPS: Malta: initialise the RTC at boot") +Signed-off-by: James Hogan +Reviewed-by: Paul Burton +Cc: Ralf Baechle +Cc: Maciej W. Rozycki +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/10739/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/mti-malta/malta-time.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +--- a/arch/mips/mti-malta/malta-time.c ++++ b/arch/mips/mti-malta/malta-time.c +@@ -165,14 +165,17 @@ unsigned int get_c0_compare_int(void) + + static void __init init_rtc(void) + { +- /* stop the clock whilst setting it up */ +- CMOS_WRITE(RTC_SET | RTC_24H, RTC_CONTROL); ++ unsigned char freq, ctrl; + +- /* 32KHz time base */ +- CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_FREQ_SELECT); ++ /* Set 32KHz time base if not already set */ ++ freq = CMOS_READ(RTC_FREQ_SELECT); ++ if ((freq & RTC_DIV_CTL) != RTC_REF_CLCK_32KHZ) ++ CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_FREQ_SELECT); + +- /* start the clock */ +- CMOS_WRITE(RTC_24H, RTC_CONTROL); ++ /* Ensure SET bit is clear so RTC can run */ ++ ctrl = CMOS_READ(RTC_CONTROL); ++ if (ctrl & RTC_SET) ++ CMOS_WRITE(ctrl & ~RTC_SET, RTC_CONTROL); + } + + void __init plat_time_init(void) diff --git a/queue-4.1/mips-show_stack-fix-stack-trace-with-eva.patch b/queue-4.1/mips-show_stack-fix-stack-trace-with-eva.patch new file mode 100644 index 00000000000..9fe0f760b0f --- /dev/null +++ b/queue-4.1/mips-show_stack-fix-stack-trace-with-eva.patch @@ -0,0 +1,69 @@ +From 1e77863a51698c4319587df34171bd823691a66a Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Mon, 27 Jul 2015 13:50:22 +0100 +Subject: MIPS: show_stack: Fix stack trace with EVA + +From: James Hogan + +commit 1e77863a51698c4319587df34171bd823691a66a upstream. + +The show_stack() function deals exclusively with kernel contexts, but if +it gets called in user context with EVA enabled, show_stacktrace() will +attempt to access the stack using EVA accesses, which will either read +other user mapped data, or more likely cause an exception which will be +handled by __get_user(). + +This is easily reproduced using SysRq t to show all task states, which +results in the following stack dump output: + + Stack : (Bad stack address) + +Fix by setting the current user access mode to kernel around the call to +show_stacktrace(). This causes __get_user() to use normal loads to read +the kernel stack. + +Now we get the correct output, like this: + + Stack : 00000000 80168960 00000000 004a0000 00000000 00000000 8060016c 1f3abd0c + 1f172cd8 8056f09c 7ff1e450 8014fc3c 00000001 806dd0b0 0000001d 00000002 + 1f17c6a0 1f17c804 1f17c6a0 8066f6e0 00000000 0000000a 00000000 00000000 + 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 + 00000000 00000000 00000000 00000000 00000000 0110e800 1f3abd6c 1f17c6a0 + ... + +Signed-off-by: James Hogan +Cc: Markos Chandras +Cc: Leonid Yegoshin +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/10778/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kernel/traps.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/arch/mips/kernel/traps.c ++++ b/arch/mips/kernel/traps.c +@@ -192,6 +192,7 @@ static void show_stacktrace(struct task_ + void show_stack(struct task_struct *task, unsigned long *sp) + { + struct pt_regs regs; ++ mm_segment_t old_fs = get_fs(); + if (sp) { + regs.regs[29] = (unsigned long)sp; + regs.regs[31] = 0; +@@ -210,7 +211,13 @@ void show_stack(struct task_struct *task + prepare_frametrace(®s); + } + } ++ /* ++ * show_stack() deals exclusively with kernel mode, so be sure to access ++ * the stack in the kernel (not user) address space. ++ */ ++ set_fs(KERNEL_DS); + show_stacktrace(task, ®s); ++ set_fs(old_fs); + } + + static void show_code(unsigned int __user *pc) diff --git a/queue-4.1/phy-twl4030-usb-make-runtime-pm-more-reliable.patch b/queue-4.1/phy-twl4030-usb-make-runtime-pm-more-reliable.patch new file mode 100644 index 00000000000..164fe7e24a4 --- /dev/null +++ b/queue-4.1/phy-twl4030-usb-make-runtime-pm-more-reliable.patch @@ -0,0 +1,102 @@ +From 56301df6bcaaed31e77b8c500ca1b437f46a3158 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Thu, 16 Apr 2015 18:03:04 +1000 +Subject: phy: twl4030-usb: make runtime pm more reliable. + +From: NeilBrown + +commit 56301df6bcaaed31e77b8c500ca1b437f46a3158 upstream. + +A construct like: + + if (pm_runtime_suspended(twl->dev)) + pm_runtime_get_sync(twl->dev); + +is against the spirit of the runtime_pm interface as it +makes the internal refcounting useless. + +In this case it is also racy, particularly as 'put_autosuspend' +is used to drop a reference. +When that happens a timer is started and the device is +runtime-suspended after the timeout. +If the above code runs in this window, the device will not be +found to be suspended so no pm_runtime reference is taken. +When the timer expires the device will be suspended, which is +against the intention of the code. + +So be more direct is taking and dropping references. +If twl->linkstat is VBUS_VALID or ID_GROUND, then hold a +pm_runtime reference, otherwise don't. +Define "cable_present()" to test for this condition. + +Tested-by: Tony Lindgren +Signed-off-by: NeilBrown +Signed-off-by: Kishon Vijay Abraham I +Cc: Alexander Holler +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/phy/phy-twl4030-usb.c | 29 ++++++++++++++++++++--------- + 1 file changed, 20 insertions(+), 9 deletions(-) + +--- a/drivers/phy/phy-twl4030-usb.c ++++ b/drivers/phy/phy-twl4030-usb.c +@@ -144,6 +144,16 @@ + #define PMBR1 0x0D + #define GPIO_USB_4PIN_ULPI_2430C (3 << 0) + ++/* ++ * If VBUS is valid or ID is ground, then we know a ++ * cable is present and we need to be runtime-enabled ++ */ ++static inline bool cable_present(enum omap_musb_vbus_id_status stat) ++{ ++ return stat == OMAP_MUSB_VBUS_VALID || ++ stat == OMAP_MUSB_ID_GROUND; ++} ++ + struct twl4030_usb { + struct usb_phy phy; + struct device *dev; +@@ -536,8 +546,10 @@ static irqreturn_t twl4030_usb_irq(int i + + mutex_lock(&twl->lock); + if (status >= 0 && status != twl->linkstat) { ++ status_changed = ++ cable_present(twl->linkstat) != ++ cable_present(status); + twl->linkstat = status; +- status_changed = true; + } + mutex_unlock(&twl->lock); + +@@ -553,15 +565,11 @@ static irqreturn_t twl4030_usb_irq(int i + * USB_LINK_VBUS state. musb_hdrc won't care until it + * starts to handle softconnect right. + */ +- if ((status == OMAP_MUSB_VBUS_VALID) || +- (status == OMAP_MUSB_ID_GROUND)) { +- if (pm_runtime_suspended(twl->dev)) +- pm_runtime_get_sync(twl->dev); ++ if (cable_present(status)) { ++ pm_runtime_get_sync(twl->dev); + } else { +- if (pm_runtime_active(twl->dev)) { +- pm_runtime_mark_last_busy(twl->dev); +- pm_runtime_put_autosuspend(twl->dev); +- } ++ pm_runtime_mark_last_busy(twl->dev); ++ pm_runtime_put_autosuspend(twl->dev); + } + omap_musb_mailbox(status); + } +@@ -766,6 +774,9 @@ static int twl4030_usb_remove(struct pla + + /* disable complete OTG block */ + twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); ++ ++ if (cable_present(twl->linkstat)) ++ pm_runtime_put_noidle(twl->dev); + pm_runtime_mark_last_busy(twl->dev); + pm_runtime_put(twl->dev); + diff --git a/queue-4.1/revert-mips-bcm63xx-provide-a-plat_post_dma_flush-hook.patch b/queue-4.1/revert-mips-bcm63xx-provide-a-plat_post_dma_flush-hook.patch new file mode 100644 index 00000000000..9e839d6d6f3 --- /dev/null +++ b/queue-4.1/revert-mips-bcm63xx-provide-a-plat_post_dma_flush-hook.patch @@ -0,0 +1,54 @@ +From 247bfb65d731350093f5d1a0a8b3d65e49c17baa Mon Sep 17 00:00:00 2001 +From: Florian Fainelli +Date: Tue, 28 Jul 2015 19:24:24 -0700 +Subject: Revert "MIPS: BCM63xx: Provide a plat_post_dma_flush hook" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Florian Fainelli + +commit 247bfb65d731350093f5d1a0a8b3d65e49c17baa upstream. + +This reverts commit 3cf29543413207d3ab1c3f62a88c09bb46f2264e ("MIPS: +BCM63xx: Provide a plat_post_dma_flush hook") since this commit was +found to prevent BCM6358 (early BMIPS4350 cores) and some BCM6368 +(BMIPS4380 cores) from booting reliably. + +Alvaro was able to track this down to an issue specifically located to +devices that use the second thread (TP1) when booting. Since BCM63xx did +not have a need for plat_post_dma_flush() hook before, let's just keep +things the way they were. + +Reported-by: Álvaro Fernández Rojas +Reported-by: Jonas Gorski +Signed-off-by: Florian Fainelli +Cc: Kevin Cernekee +Cc: Nicolas Schichan +Cc: linux-mips@linux-mips.org +Cc: blogic@openwrt.org +Cc: noltari@gmail.com +Cc: jogo@openwrt.org +Cc: Florian Fainelli +Cc: stable@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/10804/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/include/asm/mach-bcm63xx/dma-coherence.h | 10 ---------- + 1 file changed, 10 deletions(-) + +--- a/arch/mips/include/asm/mach-bcm63xx/dma-coherence.h ++++ /dev/null +@@ -1,10 +0,0 @@ +-#ifndef __ASM_MACH_BCM63XX_DMA_COHERENCE_H +-#define __ASM_MACH_BCM63XX_DMA_COHERENCE_H +- +-#include +- +-#define plat_post_dma_flush bmips_post_dma_flush +- +-#include +- +-#endif /* __ASM_MACH_BCM63XX_DMA_COHERENCE_H */ diff --git a/queue-4.1/series b/queue-4.1/series index 947288b5a96..26042d2847e 100644 --- a/queue-4.1/series +++ b/queue-4.1/series @@ -1,2 +1,28 @@ mips-unaligned-fix-build-error-on-big-endian-r6-kernels.patch mips-replace-add-and-sub-instructions-in-relocate_kernel.s-with-addiu.patch +mips-malta-don-t-reinitialise-rtc.patch +mips-fix-sched_getaffinity-with-mt-fpaff-enabled.patch +mips-export-get_c0_perfcount_int.patch +mips-do_mcheck-fix-kernel-code-dump-with-eva.patch +mips-show_stack-fix-stack-trace-with-eva.patch +revert-mips-bcm63xx-provide-a-plat_post_dma_flush-hook.patch +mips-flush-rps-on-kernel-entry-with-eva.patch +mips-make-set_pte-smp-safe.patch +fsnotify-fix-oops-in-fsnotify_clear_marks_by_group_flags.patch +drm-i915-declare-the-swizzling-unknown-for-l-shaped-configurations.patch +drm-i915-replace-warn-inside-i915_read64_2x32-with-retry-loop.patch +drm-radeon-rework-audio-detect-v4.patch +drm-radeon-combios-add-some-validation-of-lvds-values.patch +drm-dp-mst-remove-debug-warn_on.patch +ipr-fix-locking-for-unit-attention-handling.patch +ipr-fix-incorrect-trace-indexing.patch +ipr-fix-invalid-array-indexing-for-hrrq.patch +bluetooth-fix-null-pointer-dereference-in-smp_conn_security.patch +dmaengine-pl330-fix-overflow-when-reporting-residue-in-memcpy.patch +dmaengine-pl330-really-fix-choppy-sound-because-of-wrong-residue-calculation.patch +xhci-fix-off-by-one-error-in-trb-dma-address-boundary-check.patch +drivers-usb-delete-xhci-command-timer-if-necessary.patch +usb-sierra-add-1199-68ab-device-id.patch +usb-udc-core-add-device_del-call-to-error-pathway.patch +usb-chipidea-ehci_init_driver-is-intended-to-call-one-time.patch +phy-twl4030-usb-make-runtime-pm-more-reliable.patch diff --git a/queue-4.1/usb-chipidea-ehci_init_driver-is-intended-to-call-one-time.patch b/queue-4.1/usb-chipidea-ehci_init_driver-is-intended-to-call-one-time.patch new file mode 100644 index 00000000000..260ac54be3b --- /dev/null +++ b/queue-4.1/usb-chipidea-ehci_init_driver-is-intended-to-call-one-time.patch @@ -0,0 +1,199 @@ +From 2f01a33bd26545c16fea7592697f7f15c416402b Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Tue, 21 Jul 2015 09:51:29 +0800 +Subject: usb: chipidea: ehci_init_driver is intended to call one time + +From: Peter Chen + +commit 2f01a33bd26545c16fea7592697f7f15c416402b upstream. + +The ehci_init_driver is used to initialize hcd APIs for each +ehci controller driver, it is designed to be called only one time +and before driver register is called. The current design will +cause ehci_init_driver is called multiple times at probe process, +it will cause hc_driver's initialization affect current running hcd. + +We run out NULL pointer dereference problem when one hcd is started +by module_init, and the other is started by otg thread at SMP platform. +The reason for this problem is ehci_init_driver will do memory copy +for current uniform hc_driver, and this memory copy will do memset (as 0) +first, so when the first hcd is running usb_add_hcd, and the second +hcd may clear the uniform hc_driver's space (at ehci_init_driver), +then the first hcd will meet NULL pointer at the same time. + +See below two logs: + +LOG_1: +ci_hdrc ci_hdrc.0: EHCI Host Controller +ci_hdrc ci_hdrc.0: new USB bus registered, assigned bus number 1 +ci_hdrc ci_hdrc.1: doesn't support gadget +Unable to handle kernel NULL pointer dereference at virtual address 00000014 +pgd = 80004000 +[00000014] *pgd=00000000 +Internal error: Oops: 805 [#1] PREEMPT SMP ARM +Modules linked in: +CPU: 0 PID: 108 Comm: kworker/u8:2 Not tainted 3.14.38-222193-g24b2734-dirty #25 +Workqueue: ci_otg ci_otg_work +task: d839ec00 ti: d8400000 task.ti: d8400000 +PC is at ehci_run+0x4c/0x284 +LR is at _raw_spin_unlock_irqrestore+0x28/0x54 +pc : [<8041f9a0>] lr : [<8070ea84>] psr: 60000113 +sp : d8401e30 ip : 00000000 fp : d8004400 +r10: 00000001 r9 : 00000001 r8 : 00000000 +r7 : 00000000 r6 : d8419940 r5 : 80dd24c0 r4 : d8419800 +r3 : 8001d060 r2 : 00000000 r1 : 00000001 r0 : 00000000 +Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel +Control: 10c53c7d Table: 1000404a DAC: 00000015 +Process kworker/u8:2 (pid: 108, stack limit = 0xd8400238) +Stack: (0xd8401e30 to 0xd8402000) +1e20: d87523c0 d8401e48 66667562 d8419800 +1e40: 00000000 00000000 d8419800 00000000 00000000 00000000 d84198b0 8040fcdc +1e60: 00000000 80dd320c d8477610 d8419c00 d803d010 d8419800 00000000 00000000 +1e80: d8004400 00000000 d8400008 80431494 80431374 d803d100 d803d010 d803d1ac +1ea0: 00000000 80432428 804323d4 d803d100 00000001 80435eb8 80e0d0bc d803d100 +1ec0: 00000006 80436458 00000000 d803d100 80e92ec8 80436f44 d803d010 d803d100 +1ee0: d83fde00 8043292c d8752710 d803d1f4 d803d010 8042ddfc 8042ddb8 d83f3b00 +1f00: d803d1f4 80042b60 00000000 00000003 00000001 00000001 80054598 d83f3b00 +1f20: d8004400 d83f3b18 d8004414 d8400000 80e3957b 00000089 d8004400 80043814 +1f40: d839ec00 00000000 d83fcd80 d83f3b00 800436e4 00000000 00000000 00000000 +1f60: 00000000 80048f34 00000000 00000000 00000000 d83f3b00 00000000 00000000 +1f80: d8401f80 d8401f80 00000000 00000000 d8401f90 d8401f90 d8401fac d83fcd80 +1fa0: 80048e68 00000000 00000000 8000e538 00000000 00000000 00000000 00000000 +1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +1fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000 +[<8041f9a0>] (ehci_run) from [<8040fcdc>] (usb_add_hcd+0x248/0x6e8) +[<8040fcdc>] (usb_add_hcd) from [<80431494>] (host_start+0x120/0x2e4) +[<80431494>] (host_start) from [<80432428>] (ci_otg_start_host+0x54/0xbc) +[<80432428>] (ci_otg_start_host) from [<80435eb8>] (otg_set_protocol+0xa4/0xd0) +[<80435eb8>] (otg_set_protocol) from [<80436458>] (otg_set_state+0x574/0xc58) +[<80436458>] (otg_set_state) from [<80436f44>] (otg_statemachine+0x408/0x46c) +[<80436f44>] (otg_statemachine) from [<8043292c>] (ci_otg_fsm_work+0x3c/0x190) +[<8043292c>] (ci_otg_fsm_work) from [<8042ddfc>] (ci_otg_work+0x44/0x1c4) +[<8042ddfc>] (ci_otg_work) from [<80042b60>] (process_one_work+0xf4/0x35c) +[<80042b60>] (process_one_work) from [<80043814>] (worker_thread+0x130/0x3bc) +[<80043814>] (worker_thread) from [<80048f34>] (kthread+0xcc/0xe4) +[<80048f34>] (kthread) from [<8000e538>] (ret_from_fork+0x14/0x3c) +Code: e5953018 e3530000 0a000000 e12fff33 (e5878014) + +LOG_2: +ci_hdrc ci_hdrc.0: EHCI Host Controller +ci_hdrc ci_hdrc.0: new USB bus registered, assigned bus number 1 +ci_hdrc ci_hdrc.1: doesn't support gadget +Unable to handle kernel NULL pointer dereference at virtual address 00000000 +pgd = 80004000 +[00000000] *pgd=00000000 +In Online 00:00ternal e Offline rror: Oops: 80000005 [#1] PREEMPT SMP ARM +Modules linked in: +CPU: 0 PID: 108 Comm: kworker/u8:2 Not tainted 3.14.38-02007-g24b2734-dirty #127 +Workque Online 00:00ue: ci_o Offline tg ci_otg_work +Online 00:00task: d8 Offline 39ec00 ti: d83ea000 task.ti: d83ea000 +PC is at 0x0 +LR is at usb_add_hcd+0x248/0x6e8 +pc : [<00000000>] lr : [<8040f644>] psr: 60000113 +sp : d83ebe60 ip : 00000000 fp : d8004400 +r10: 00000001 r9 : 00000001 r8 : d85fd4b0 +r7 : 00000000 r6 : 00000000 r5 : 00000000 r4 : d85fd400 +r3 : 00000000 r2 : d85fd4f4 r1 : 80410178 r0 : d85fd400 +Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel +Control: 10c53c7d Table: 1000404a DAC: 00000015 +Process kworker/u8:2 (pid: 108, stack limit = 0xd83ea238) +Stack: (0xd83ebe60 to 0xd83ec000) +be60: 00000000 80dd920c d8654e10 d85fd800 d803e010 d85fd400 00000000 00000000 +be80: d8004400 00000000 d83ea008 80430e34 80430d14 d803e100 d803e010 d803e1ac +bea0: 00000000 80431dc8 80431d74 d803e100 00000001 80435858 80e130bc d803e100 +bec0: 00000006 80435df8 00000000 d803e100 80e98ec8 804368e4 d803e010 d803e100 +bee0: d86e8100 804322cc d86cf050 d803e1f4 d803e010 8042d79c 8042d758 d83cf900 +bf00: d803e1f4 80042b78 00000000 00000003 00000001 00000001 800545e8 d83cf900 +bf20: d8004400 d83cf918 d8004414 d83ea000 80e3f57b 00000089 d8004400 8004382c +bf40: d839ec00 00000000 d8393780 d83cf900 800436fc 00000000 00000000 00000000 +bf60: 00000000 80048f50 80e019f4 00000000 0000264c d83cf900 00000000 00000000 +bf80: d83ebf80 d83ebf80 00000000 00000000 d83ebf90 d83ebf90 d83ebfac d8393780 +bfa0: 80048e84 00000000 00000000 8000e538 00000000 00000000 00000000 00000000 +bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 ee66e85d 133ebd03 +[<804 Online 00:000f644>] Offline (usb_add_hcd) from [<80430e34>] (host_start+0x120/0x2e4) +[<80430e34>] (host_start) from [<80431dc8>] (ci_otg_start_host+0x54/0xbc) +[<80431dc8>] (ci_otg_start_host) from [<80435858>] (otg_set_protocol+0xa4/0xd0) +[<80435858>] (otg_set_protocol) from [<80435df8>] (otg_set_state+0x574/0xc58) +[<80435df8>] (otg_set_state) from [<804368e4>] (otg_statemachine+0x408/0x46c) +[<804368e4>] (otg_statemachine) from [<804322cc>] (ci_otg_fsm_work+0x3c/0x190) +[<804322cc>] (ci_otg_fsm_work) from [<8042d79c>] (ci_otg_work+0x44/0x1c4) +[<8042d79c>] (ci_otg_work) from [<80042b78>] (process_one_work+0xf4/0x35c) +[<80042b78>] (process_one_work) from [<8004382c>] (worker_thread+0x130/0x3bc) +[<8004382c>] (worker_thread) from [<80048f50>] (kthread+0xcc/0xe4) +[<80048f50>] (kthread) from [<8000e538>] (ret_from_fork+0x14/0x3c) +Code: bad PC value + +Cc: Jun Li +Cc: Alan Stern +Acked-by: Alan Stern +Signed-off-by: Peter Chen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/chipidea/core.c | 13 ++++++++++++- + drivers/usb/chipidea/host.c | 7 +++++-- + drivers/usb/chipidea/host.h | 6 ++++++ + 3 files changed, 23 insertions(+), 3 deletions(-) + +--- a/drivers/usb/chipidea/core.c ++++ b/drivers/usb/chipidea/core.c +@@ -1024,7 +1024,18 @@ static struct platform_driver ci_hdrc_dr + }, + }; + +-module_platform_driver(ci_hdrc_driver); ++static int __init ci_hdrc_platform_register(void) ++{ ++ ci_hdrc_host_driver_init(); ++ return platform_driver_register(&ci_hdrc_driver); ++} ++module_init(ci_hdrc_platform_register); ++ ++static void __exit ci_hdrc_platform_unregister(void) ++{ ++ platform_driver_unregister(&ci_hdrc_driver); ++} ++module_exit(ci_hdrc_platform_unregister); + + MODULE_ALIAS("platform:ci_hdrc"); + MODULE_LICENSE("GPL v2"); +--- a/drivers/usb/chipidea/host.c ++++ b/drivers/usb/chipidea/host.c +@@ -237,9 +237,12 @@ int ci_hdrc_host_init(struct ci_hdrc *ci + rdrv->name = "host"; + ci->roles[CI_ROLE_HOST] = rdrv; + ++ return 0; ++} ++ ++void ci_hdrc_host_driver_init(void) ++{ + ehci_init_driver(&ci_ehci_hc_driver, &ehci_ci_overrides); + orig_bus_suspend = ci_ehci_hc_driver.bus_suspend; + ci_ehci_hc_driver.bus_suspend = ci_ehci_bus_suspend; +- +- return 0; + } +--- a/drivers/usb/chipidea/host.h ++++ b/drivers/usb/chipidea/host.h +@@ -5,6 +5,7 @@ + + int ci_hdrc_host_init(struct ci_hdrc *ci); + void ci_hdrc_host_destroy(struct ci_hdrc *ci); ++void ci_hdrc_host_driver_init(void); + + #else + +@@ -17,6 +18,11 @@ static inline void ci_hdrc_host_destroy( + { + + } ++ ++static void ci_hdrc_host_driver_init(void) ++{ ++ ++} + + #endif + diff --git a/queue-4.1/usb-sierra-add-1199-68ab-device-id.patch b/queue-4.1/usb-sierra-add-1199-68ab-device-id.patch new file mode 100644 index 00000000000..e266b5fe701 --- /dev/null +++ b/queue-4.1/usb-sierra-add-1199-68ab-device-id.patch @@ -0,0 +1,330 @@ +From 74472233233f577eaa0ca6d6e17d9017b6e53150 Mon Sep 17 00:00:00 2001 +From: Dirk Behme +Date: Mon, 27 Jul 2015 08:56:05 +0200 +Subject: USB: sierra: add 1199:68AB device ID + +From: Dirk Behme + +commit 74472233233f577eaa0ca6d6e17d9017b6e53150 upstream. + +Add support for the Sierra Wireless AR8550 device with +USB descriptor 0x1199, 0x68AB. + +It is common with MC879x modules 1199:683c/683d which +also are composite devices with 7 interfaces (0..6) +and also MDM62xx based as the AR8550. + +The major difference are only the interface attributes +02/02/01 on interfaces 3 and 4 on the AR8550. They are +vendor specific ff/ff/ff on MC879x modules. + +lsusb reports: + +Bus 001 Device 004: ID 1199:68ab Sierra Wireless, Inc. +Device Descriptor: + bLength 18 + bDescriptorType 1 + bcdUSB 2.00 + bDeviceClass 0 (Defined at Interface level) + bDeviceSubClass 0 + bDeviceProtocol 0 + bMaxPacketSize0 64 + idVendor 0x1199 Sierra Wireless, Inc. + idProduct 0x68ab + bcdDevice 0.06 + iManufacturer 3 Sierra Wireless, Incorporated + iProduct 2 AR8550 + iSerial 0 + bNumConfigurations 1 + Configuration Descriptor: + bLength 9 + bDescriptorType 2 + wTotalLength 198 + bNumInterfaces 7 + bConfigurationValue 1 + iConfiguration 1 Sierra Configuration + bmAttributes 0xe0 + Self Powered + Remote Wakeup + MaxPower 0mA + Interface Descriptor: + bLength 9 + bDescriptorType 4 + bInterfaceNumber 0 + bAlternateSetting 0 + bNumEndpoints 2 + bInterfaceClass 255 Vendor Specific Class + bInterfaceSubClass 255 Vendor Specific Subclass + bInterfaceProtocol 255 Vendor Specific Protocol + iInterface 0 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x81 EP 1 IN + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0200 1x 512 bytes + bInterval 32 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x01 EP 1 OUT + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0200 1x 512 bytes + bInterval 32 + Interface Descriptor: + bLength 9 + bDescriptorType 4 + bInterfaceNumber 1 + bAlternateSetting 0 + bNumEndpoints 2 + bInterfaceClass 255 Vendor Specific Class + bInterfaceSubClass 255 Vendor Specific Subclass + bInterfaceProtocol 255 Vendor Specific Protocol + iInterface 0 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x82 EP 2 IN + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0200 1x 512 bytes + bInterval 32 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x02 EP 2 OUT + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0200 1x 512 bytes + bInterval 32 + Interface Descriptor: + bLength 9 + bDescriptorType 4 + bInterfaceNumber 2 + bAlternateSetting 0 + bNumEndpoints 2 + bInterfaceClass 255 Vendor Specific Class + bInterfaceSubClass 255 Vendor Specific Subclass + bInterfaceProtocol 255 Vendor Specific Protocol + iInterface 0 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x83 EP 3 IN + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0200 1x 512 bytes + bInterval 32 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x03 EP 3 OUT + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0200 1x 512 bytes + bInterval 32 + Interface Descriptor: + bLength 9 + bDescriptorType 4 + bInterfaceNumber 3 + bAlternateSetting 0 + bNumEndpoints 3 + bInterfaceClass 2 Communications + bInterfaceSubClass 2 Abstract (modem) + bInterfaceProtocol 1 AT-commands (v.25ter) + iInterface 0 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x84 EP 4 IN + bmAttributes 3 + Transfer Type Interrupt + Synch Type None + Usage Type Data + wMaxPacketSize 0x0040 1x 64 bytes + bInterval 5 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x85 EP 5 IN + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0200 1x 512 bytes + bInterval 32 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x04 EP 4 OUT + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0200 1x 512 bytes + bInterval 32 + Interface Descriptor: + bLength 9 + bDescriptorType 4 + bInterfaceNumber 4 + bAlternateSetting 0 + bNumEndpoints 3 + bInterfaceClass 2 Communications + bInterfaceSubClass 2 Abstract (modem) + bInterfaceProtocol 1 AT-commands (v.25ter) + iInterface 0 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x86 EP 6 IN + bmAttributes 3 + Transfer Type Interrupt + Synch Type None + Usage Type Data + wMaxPacketSize 0x0040 1x 64 bytes + bInterval 5 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x87 EP 7 IN + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0200 1x 512 bytes + bInterval 32 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x05 EP 5 OUT + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0200 1x 512 bytes + bInterval 32 + Interface Descriptor: + bLength 9 + bDescriptorType 4 + bInterfaceNumber 5 + bAlternateSetting 0 + bNumEndpoints 3 + bInterfaceClass 255 Vendor Specific Class + bInterfaceSubClass 255 Vendor Specific Subclass + bInterfaceProtocol 255 Vendor Specific Protocol + iInterface 0 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x88 EP 8 IN + bmAttributes 3 + Transfer Type Interrupt + Synch Type None + Usage Type Data + wMaxPacketSize 0x0040 1x 64 bytes + bInterval 5 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x89 EP 9 IN + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0200 1x 512 bytes + bInterval 32 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x06 EP 6 OUT + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0200 1x 512 bytes + bInterval 32 + Interface Descriptor: + bLength 9 + bDescriptorType 4 + bInterfaceNumber 6 + bAlternateSetting 0 + bNumEndpoints 3 + bInterfaceClass 255 Vendor Specific Class + bInterfaceSubClass 255 Vendor Specific Subclass + bInterfaceProtocol 255 Vendor Specific Protocol + iInterface 0 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x8a EP 10 IN + bmAttributes 3 + Transfer Type Interrupt + Synch Type None + Usage Type Data + wMaxPacketSize 0x0040 1x 64 bytes + bInterval 5 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x8b EP 11 IN + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0200 1x 512 bytes + bInterval 32 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x07 EP 7 OUT + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0200 1x 512 bytes + bInterval 32 +Device Qualifier (for other device speed): + bLength 10 + bDescriptorType 6 + bcdUSB 2.00 + bDeviceClass 0 (Defined at Interface level) + bDeviceSubClass 0 + bDeviceProtocol 0 + bMaxPacketSize0 64 + bNumConfigurations 1 +Device Status: 0x0001 + Self Powered + +Signed-off-by: Dirk Behme +Cc: Lars Melin +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/sierra.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/serial/sierra.c ++++ b/drivers/usb/serial/sierra.c +@@ -289,6 +289,7 @@ static const struct usb_device_id id_tab + { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x68AA, 0xFF, 0xFF, 0xFF), + .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist + }, ++ { USB_DEVICE(0x1199, 0x68AB) }, /* Sierra Wireless AR8550 */ + /* AT&T Direct IP LTE modems */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0F3D, 0x68AA, 0xFF, 0xFF, 0xFF), + .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist diff --git a/queue-4.1/usb-udc-core-add-device_del-call-to-error-pathway.patch b/queue-4.1/usb-udc-core-add-device_del-call-to-error-pathway.patch new file mode 100644 index 00000000000..0ef6492f2c7 --- /dev/null +++ b/queue-4.1/usb-udc-core-add-device_del-call-to-error-pathway.patch @@ -0,0 +1,33 @@ +From c93e64e91248becd0edb8f01723dff9da890e2ab Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 16 Jan 2015 11:32:51 -0500 +Subject: usb: udc: core: add device_del() call to error pathway + +From: Alan Stern + +commit c93e64e91248becd0edb8f01723dff9da890e2ab upstream. + +This patch fixes a bug in the error pathway of +usb_add_gadget_udc_release() in udc-core.c. If the udc registration +fails, the gadget registration is not fully undone; there's a +put_device(&gadget->dev) call but no device_del(). + +Acked-by: Peter Chen +Signed-off-by: Alan Stern +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/udc/udc-core.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/gadget/udc/udc-core.c ++++ b/drivers/usb/gadget/udc/udc-core.c +@@ -321,6 +321,7 @@ err4: + + err3: + put_device(&udc->dev); ++ device_del(&gadget->dev); + + err2: + put_device(&gadget->dev); diff --git a/queue-4.1/xhci-fix-off-by-one-error-in-trb-dma-address-boundary-check.patch b/queue-4.1/xhci-fix-off-by-one-error-in-trb-dma-address-boundary-check.patch new file mode 100644 index 00000000000..12ca9a38b55 --- /dev/null +++ b/queue-4.1/xhci-fix-off-by-one-error-in-trb-dma-address-boundary-check.patch @@ -0,0 +1,50 @@ +From 7895086afde2a05fa24a0e410d8e6b75ca7c8fdd Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Mon, 3 Aug 2015 16:07:48 +0300 +Subject: xhci: fix off by one error in TRB DMA address boundary check +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mathias Nyman + +commit 7895086afde2a05fa24a0e410d8e6b75ca7c8fdd upstream. + +We need to check that a TRB is part of the current segment +before calculating its DMA address. + +Previously a ring segment didn't use a full memory page, and every +new ring segment got a new memory page, so the off by one +error in checking the upper bound was never seen. + +Now that we use a full memory page, 256 TRBs (4096 bytes), the off by one +didn't catch the case when a TRB was the first element of the next segment. + +This is triggered if the virtual memory pages for a ring segment are +next to each in increasing order where the ring buffer wraps around and +causes errors like: + +[ 106.398223] xhci_hcd 0000:00:14.0: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 0 comp_code 1 +[ 106.398230] xhci_hcd 0000:00:14.0: Looking for event-dma fffd3000 trb-start fffd4fd0 trb-end fffd5000 seg-start fffd4000 seg-end fffd4ff0 + +The trb-end address is one outside the end-seg address. + +Tested-by: Arkadiusz Miśkiewicz +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -82,7 +82,7 @@ dma_addr_t xhci_trb_virt_to_dma(struct x + return 0; + /* offset in TRBs */ + segment_offset = trb - seg->trbs; +- if (segment_offset > TRBS_PER_SEGMENT) ++ if (segment_offset >= TRBS_PER_SEGMENT) + return 0; + return seg->dma + (segment_offset * sizeof(*trb)); + }