From: Greg Kroah-Hartman Date: Mon, 9 Jan 2017 09:33:27 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.4.42~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0acaaf7e76a051af6b2790fb60ac899df29373d4;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: asm-prototypes-clear-any-cpp-defines-before-declaring-the-functions.patch drm-i915-fix-oops-in-overlay-due-to-frontbuffer-tracking.patch drm-i915-fix-oopses-in-the-overlay-code-due-to-i915_gem_active-stuff.patch drm-i915-force-vdd-off-on-the-new-power-seqeuencer-before-starting-to-use-it.patch drm-i915-initialize-overlay-last_flip-properly.patch gcc-plugins-update-gcc-common.h-for-gcc-7.patch kvm-mips-don-t-clobber-cp0_status.ux.patch kvm-mips-flush-kvm-entry-code-from-icache-globally.patch kvm-x86-reset-mmu-on-kvm_set_vcpu_events.patch mac80211-initialize-fast-xmit-info-later.patch pinctrl-amd-set-the-level-based-on-acpi-tables.patch usb-dummy-hcd-fix-bug-in-stop_activity-handle-ep0.patch usb-dwc3-core-avoid-overflow-events.patch usb-fix-problems-with-duplicate-endpoint-addresses.patch usb-gadget-composite-test-get_alt-presence-instead-of-set_alt.patch usb-gadgetfs-fix-checks-of-wtotallength-in-config-descriptors.patch usb-gadgetfs-fix-unbounded-memory-allocation-bug.patch usb-gadgetfs-fix-use-after-free-bug.patch usb-gadgetfs-restrict-upper-bound-on-device-configuration-size.patch usb-musb-core-add-clear_ep_rxintr-to-musb_platform_ops.patch usb-musb-dsps-implement-clear_ep_rxintr-callback.patch usb-storage-unusual_uas-add-jmicron-jms56x-to-unusual-device.patch usb-xhci-fix-possible-wild-pointer.patch --- diff --git a/queue-4.9/asm-prototypes-clear-any-cpp-defines-before-declaring-the-functions.patch b/queue-4.9/asm-prototypes-clear-any-cpp-defines-before-declaring-the-functions.patch new file mode 100644 index 00000000000..09738724b81 --- /dev/null +++ b/queue-4.9/asm-prototypes-clear-any-cpp-defines-before-declaring-the-functions.patch @@ -0,0 +1,78 @@ +From c7858bf16c0b2cc62f475f31e6df28c3a68da1d6 Mon Sep 17 00:00:00 2001 +From: Michal Marek +Date: Tue, 3 Jan 2017 13:49:42 +0100 +Subject: asm-prototypes: Clear any CPP defines before declaring the functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michal Marek + +commit c7858bf16c0b2cc62f475f31e6df28c3a68da1d6 upstream. + +The asm-prototypes.h file is used to provide dummy function declarations +for genksyms, when processing asm files with EXPORT_SYMBOL. Make sure +that any architecture defines get out of our way. x86 currently has an +issue with memcpy on 64bit with CONFIG_KMEMCHECK=y and with +memset/__memset on 32bit: + + $ cat init/test.c + #include + $ make -s init/test.o + In file included from ./arch/x86/include/asm/string.h:4:0, + from ./include/linux/string.h:18, + from ./include/linux/bitmap.h:8, + from ./include/linux/cpumask.h:11, + from ./arch/x86/include/asm/cpumask.h:4, + from ./arch/x86/include/asm/msr.h:10, + from ./arch/x86/include/asm/processor.h:20, + from ./arch/x86/include/asm/cpufeature.h:4, + from ./arch/x86/include/asm/thread_info.h:52, + from ./include/linux/thread_info.h:25, + from ./arch/x86/include/asm/preempt.h:6, + from ./include/linux/preempt.h:59, + from ./include/linux/spinlock.h:50, + from ./include/linux/seqlock.h:35, + from ./include/linux/time.h:5, + from ./include/uapi/linux/timex.h:56, + from ./include/linux/timex.h:56, + from ./include/linux/sched.h:19, + from ./include/linux/uaccess.h:4, + from ./arch/x86/include/asm/asm-prototypes.h:2, + from init/test.c:1: + ./arch/x86/include/asm/string_64.h:52:47: error: expected declaration specifiers or ‘...’ before ‘(’ token + #define memcpy(dst, src, len) __inline_memcpy((dst), (src), (len)) + ./include/asm-generic/asm-prototypes.h:6:14: note: in expansion of macro ‘memcpy’ + extern void *memcpy(void *, const void *, __kernel_size_t); + + ^ + ... + +During real build, this manifests itself by genksyms segfaulting. + +Fixes: 334bb7738764 ("x86/kbuild: enable modversions for symbols exported from asm") +Reported-and-tested-by: Borislav Petkov +Cc: Adam Borowski +Signed-off-by: Michal Marek +Signed-off-by: Greg Kroah-Hartman + +--- + include/asm-generic/asm-prototypes.h | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/include/asm-generic/asm-prototypes.h ++++ b/include/asm-generic/asm-prototypes.h +@@ -1,7 +1,13 @@ + #include ++#undef __memset + extern void *__memset(void *, int, __kernel_size_t); ++#undef __memcpy + extern void *__memcpy(void *, const void *, __kernel_size_t); ++#undef __memmove + extern void *__memmove(void *, const void *, __kernel_size_t); ++#undef memset + extern void *memset(void *, int, __kernel_size_t); ++#undef memcpy + extern void *memcpy(void *, const void *, __kernel_size_t); ++#undef memmove + extern void *memmove(void *, const void *, __kernel_size_t); diff --git a/queue-4.9/drm-i915-fix-oops-in-overlay-due-to-frontbuffer-tracking.patch b/queue-4.9/drm-i915-fix-oops-in-overlay-due-to-frontbuffer-tracking.patch new file mode 100644 index 00000000000..8a0414605f2 --- /dev/null +++ b/queue-4.9/drm-i915-fix-oops-in-overlay-due-to-frontbuffer-tracking.patch @@ -0,0 +1,42 @@ +From 9169757ae67bc927750ae907624e65cc15b4fe5a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 7 Dec 2016 19:28:03 +0200 +Subject: drm/i915: Fix oops in overlay due to frontbuffer tracking +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ville Syrjälä + +commit 9169757ae67bc927750ae907624e65cc15b4fe5a upstream. + +The vma will be NULL if the overlay was previously off, so +dereferencing it will oops. Check for NULL before doing that. + +Cc: Chris Wilson +Cc: Joonas Lahtinen +Fixes: 9b3b7841b86d ("drm/i915/overlay: Use VMA as the primary tracker for images") +Signed-off-by: Ville Syrjälä +Link: http://patchwork.freedesktop.org/patch/msgid/1481131693-27993-2-git-send-email-ville.syrjala@linux.intel.com +Reviewed-by: Chris Wilson +(cherry picked from commit 4a15cdbbc55463e55a7cdcf33f84ccc742ca9c29) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_overlay.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_overlay.c ++++ b/drivers/gpu/drm/i915/intel_overlay.c +@@ -840,8 +840,8 @@ static int intel_overlay_do_put_image(st + if (ret) + goto out_unpin; + +- i915_gem_track_fb(overlay->vma->obj, new_bo, +- INTEL_FRONTBUFFER_OVERLAY(pipe)); ++ i915_gem_track_fb(overlay->vma ? overlay->vma->obj : NULL, ++ vma->obj, INTEL_FRONTBUFFER_OVERLAY(pipe)); + + overlay->old_vma = overlay->vma; + overlay->vma = vma; diff --git a/queue-4.9/drm-i915-fix-oopses-in-the-overlay-code-due-to-i915_gem_active-stuff.patch b/queue-4.9/drm-i915-fix-oopses-in-the-overlay-code-due-to-i915_gem_active-stuff.patch new file mode 100644 index 00000000000..2fdef05b612 --- /dev/null +++ b/queue-4.9/drm-i915-fix-oopses-in-the-overlay-code-due-to-i915_gem_active-stuff.patch @@ -0,0 +1,73 @@ +From b72eb5ffa6d8601d9ba72619d75fb5b27723743a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 7 Dec 2016 17:56:47 +0000 +Subject: drm/i915: Fix oopses in the overlay code due to i915_gem_active stuff +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ville Syrjälä + +commit b72eb5ffa6d8601d9ba72619d75fb5b27723743a upstream. + +The i915_gem_active stuff doesn't like a NULL ->retire hook, but +the overlay code can set it to NULL. That obviously ends up oopsing. +Fix it by introducing a new helper to assign the retirement callback +that will switch out the NULL function pointer with +i915_gem_retire_noop. + +Cc: Chris Wilson +Cc: Joonas Lahtinen +Fixes: 0d9bdd886f29 ("drm/i915: Convert intel_overlay to request tracking") +Signed-off-by: Ville Syrjälä +Signed-off-by: Chris Wilson +Link: http://patchwork.freedesktop.org/patch/msgid/20161207175647.10018-1-chris@chris-wilson.co.uk +(cherry picked from commit ecd9caa0522db5a6b03ac8858c42067ef9d8323b) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_gem_request.h | 19 +++++++++++++++++++ + drivers/gpu/drm/i915/intel_overlay.c | 3 ++- + 2 files changed, 21 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/i915/i915_gem_request.h ++++ b/drivers/gpu/drm/i915/i915_gem_request.h +@@ -344,6 +344,25 @@ i915_gem_active_set(struct i915_gem_acti + rcu_assign_pointer(active->request, request); + } + ++/** ++ * i915_gem_active_set_retire_fn - updates the retirement callback ++ * @active - the active tracker ++ * @fn - the routine called when the request is retired ++ * @mutex - struct_mutex used to guard retirements ++ * ++ * i915_gem_active_set_retire_fn() updates the function pointer that ++ * is called when the final request associated with the @active tracker ++ * is retired. ++ */ ++static inline void ++i915_gem_active_set_retire_fn(struct i915_gem_active *active, ++ i915_gem_retire_fn fn, ++ struct mutex *mutex) ++{ ++ lockdep_assert_held(mutex); ++ active->retire = fn ?: i915_gem_retire_noop; ++} ++ + static inline struct drm_i915_gem_request * + __i915_gem_active_peek(const struct i915_gem_active *active) + { +--- a/drivers/gpu/drm/i915/intel_overlay.c ++++ b/drivers/gpu/drm/i915/intel_overlay.c +@@ -216,7 +216,8 @@ static void intel_overlay_submit_request + { + GEM_BUG_ON(i915_gem_active_peek(&overlay->last_flip, + &overlay->i915->drm.struct_mutex)); +- overlay->last_flip.retire = retire; ++ i915_gem_active_set_retire_fn(&overlay->last_flip, retire, ++ &overlay->i915->drm.struct_mutex); + i915_gem_active_set(&overlay->last_flip, req); + i915_add_request(req); + } diff --git a/queue-4.9/drm-i915-force-vdd-off-on-the-new-power-seqeuencer-before-starting-to-use-it.patch b/queue-4.9/drm-i915-force-vdd-off-on-the-new-power-seqeuencer-before-starting-to-use-it.patch new file mode 100644 index 00000000000..845ef8e1f12 --- /dev/null +++ b/queue-4.9/drm-i915-force-vdd-off-on-the-new-power-seqeuencer-before-starting-to-use-it.patch @@ -0,0 +1,146 @@ +From 8581f1b5ee0837e55197f036406bc99746ac94b2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 20 Dec 2016 18:51:17 +0200 +Subject: drm/i915: Force VDD off on the new power seqeuencer before starting to use it +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ville Syrjälä + +commit 8581f1b5ee0837e55197f036406bc99746ac94b2 upstream. + +Apparently some VLV BIOSen like to leave the VDD force bit enabled +even for power seqeuncers that aren't properly hooked up to any +port. That will result in a imbalance in the AUX power domain +refcount when we stat to use said power sequencer as edp_panel_vdd_on() +will not grab the power domain reference if it sees that the VDD is +already on. + +To fix this let's make sure we turn off the VDD force bit when we +initialize the power sequencer registers. That is, unless it's +being done from the init path since there we are actually +initializing the registers for the current power sequencer and +we don't want to turn VDD off needlessly as that would require +waiting for the power cycle delay before we turn it back on. + +This fixes the following kind of warnings: +WARNING: CPU: 0 PID: 123 at ../drivers/gpu/drm/i915/intel_runtime_pm.c:1455 intel_display_power_put+0x13a/0x170 [i915]() +WARN_ON(!power_domains->domain_use_count[domain]) +... + +v2: Fix typos in comment (David) + +Cc: Matwey V. Kornilov +Tested-by: Matwey V. Kornilov +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98695 +Signed-off-by: Ville Syrjälä +Link: http://patchwork.freedesktop.org/patch/msgid/20161220165117.24801-1-ville.syrjala@linux.intel.com +Reviewed-by: David Weinehall +(cherry picked from commit 5d5ab2d26f32bdaa5872b938658e0bf8d341bc4c) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_dp.c | 41 +++++++++++++++++++++++++++++++++------- + 1 file changed, 34 insertions(+), 7 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -280,7 +280,8 @@ intel_dp_init_panel_power_sequencer(stru + struct intel_dp *intel_dp); + static void + intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, +- struct intel_dp *intel_dp); ++ struct intel_dp *intel_dp, ++ bool force_disable_vdd); + static void + intel_dp_pps_init(struct drm_device *dev, struct intel_dp *intel_dp); + +@@ -442,7 +443,7 @@ vlv_power_sequencer_pipe(struct intel_dp + + /* init power sequencer on this pipe and port */ + intel_dp_init_panel_power_sequencer(dev, intel_dp); +- intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); ++ intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, true); + + /* + * Even vdd force doesn't work until we've made +@@ -479,7 +480,7 @@ bxt_power_sequencer_idx(struct intel_dp + * Only the HW needs to be reprogrammed, the SW state is fixed and + * has been setup during connector init. + */ +- intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); ++ intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, false); + + return 0; + } +@@ -562,7 +563,7 @@ vlv_initial_power_sequencer_setup(struct + port_name(port), pipe_name(intel_dp->pps_pipe)); + + intel_dp_init_panel_power_sequencer(dev, intel_dp); +- intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); ++ intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, false); + } + + void intel_power_sequencer_reset(struct drm_i915_private *dev_priv) +@@ -2924,7 +2925,7 @@ static void vlv_init_panel_power_sequenc + + /* init power sequencer on this pipe and port */ + intel_dp_init_panel_power_sequencer(dev, intel_dp); +- intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); ++ intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, true); + } + + static void vlv_pre_enable_dp(struct intel_encoder *encoder, +@@ -5054,7 +5055,8 @@ intel_dp_init_panel_power_sequencer(stru + + static void + intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, +- struct intel_dp *intel_dp) ++ struct intel_dp *intel_dp, ++ bool force_disable_vdd) + { + struct drm_i915_private *dev_priv = to_i915(dev); + u32 pp_on, pp_off, pp_div, port_sel = 0; +@@ -5067,6 +5069,31 @@ intel_dp_init_panel_power_sequencer_regi + + intel_pps_get_registers(dev_priv, intel_dp, ®s); + ++ /* ++ * On some VLV machines the BIOS can leave the VDD ++ * enabled even on power seqeuencers which aren't ++ * hooked up to any port. This would mess up the ++ * power domain tracking the first time we pick ++ * one of these power sequencers for use since ++ * edp_panel_vdd_on() would notice that the VDD was ++ * already on and therefore wouldn't grab the power ++ * domain reference. Disable VDD first to avoid this. ++ * This also avoids spuriously turning the VDD on as ++ * soon as the new power seqeuencer gets initialized. ++ */ ++ if (force_disable_vdd) { ++ u32 pp = ironlake_get_pp_control(intel_dp); ++ ++ WARN(pp & PANEL_POWER_ON, "Panel power already on\n"); ++ ++ if (pp & EDP_FORCE_VDD) ++ DRM_DEBUG_KMS("VDD already on, disabling first\n"); ++ ++ pp &= ~EDP_FORCE_VDD; ++ ++ I915_WRITE(regs.pp_ctrl, pp); ++ } ++ + pp_on = (seq->t1_t3 << PANEL_POWER_UP_DELAY_SHIFT) | + (seq->t8 << PANEL_LIGHT_ON_DELAY_SHIFT); + pp_off = (seq->t9 << PANEL_LIGHT_OFF_DELAY_SHIFT) | +@@ -5119,7 +5146,7 @@ static void intel_dp_pps_init(struct drm + vlv_initial_power_sequencer_setup(intel_dp); + } else { + intel_dp_init_panel_power_sequencer(dev, intel_dp); +- intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); ++ intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, false); + } + } + diff --git a/queue-4.9/drm-i915-initialize-overlay-last_flip-properly.patch b/queue-4.9/drm-i915-initialize-overlay-last_flip-properly.patch new file mode 100644 index 00000000000..f5120797449 --- /dev/null +++ b/queue-4.9/drm-i915-initialize-overlay-last_flip-properly.patch @@ -0,0 +1,38 @@ +From a6d3e7d35d088b2aabad1688b740e17bfdf566c5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 21 Dec 2016 16:45:47 +0200 +Subject: drm/i915: Initialize overlay->last_flip properly +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ville Syrjälä + +commit a6d3e7d35d088b2aabad1688b740e17bfdf566c5 upstream. + +Initialize overlay->last_flip properly instead of leaving it zeroed. + +Cc: Chris Wilson +Fixes: 0d9bdd886f29 ("drm/i915: Convert intel_overlay to request tracking") +Reviewed-by: Chris Wilson +Signed-off-by: Ville Syrjälä +Link: http://patchwork.freedesktop.org/patch/msgid/20161221144547.27319-1-ville.syrjala@linux.intel.com +(cherry picked from commit 330afdb1df0f3fb48583105493a8f4f8d9e3af36) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_overlay.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/gpu/drm/i915/intel_overlay.c ++++ b/drivers/gpu/drm/i915/intel_overlay.c +@@ -1431,6 +1431,8 @@ void intel_setup_overlay(struct drm_i915 + overlay->contrast = 75; + overlay->saturation = 146; + ++ init_request_active(&overlay->last_flip, NULL); ++ + regs = intel_overlay_map_regs(overlay); + if (!regs) + goto out_unpin_bo; diff --git a/queue-4.9/gcc-plugins-update-gcc-common.h-for-gcc-7.patch b/queue-4.9/gcc-plugins-update-gcc-common.h-for-gcc-7.patch new file mode 100644 index 00000000000..a620cfeca29 --- /dev/null +++ b/queue-4.9/gcc-plugins-update-gcc-common.h-for-gcc-7.patch @@ -0,0 +1,202 @@ +From 81d873a87114b05dbb74d1fbf0c4322ba4bfdee4 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Fri, 16 Dec 2016 11:36:06 -0800 +Subject: gcc-plugins: update gcc-common.h for gcc-7 + +From: Kees Cook + +commit 81d873a87114b05dbb74d1fbf0c4322ba4bfdee4 upstream. + +This updates gcc-common.h from Emese Revfy for gcc 7. This fixes issues seen +by Kugan and Arnd. Build tested with gcc 5.4 and 7 snapshot. + +Signed-off-by: Kees Cook +Signed-off-by: Greg Kroah-Hartman + +--- + scripts/gcc-plugins/gcc-common.h | 85 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 85 insertions(+) + +--- a/scripts/gcc-plugins/gcc-common.h ++++ b/scripts/gcc-plugins/gcc-common.h +@@ -39,6 +39,9 @@ + #include "hash-map.h" + #endif + ++#if BUILDING_GCC_VERSION >= 7000 ++#include "memmodel.h" ++#endif + #include "emit-rtl.h" + #include "debug.h" + #include "target.h" +@@ -91,6 +94,9 @@ + #include "tree-ssa-alias.h" + #include "tree-ssa.h" + #include "stringpool.h" ++#if BUILDING_GCC_VERSION >= 7000 ++#include "tree-vrp.h" ++#endif + #include "tree-ssanames.h" + #include "print-tree.h" + #include "tree-eh.h" +@@ -287,6 +293,22 @@ static inline struct cgraph_node *cgraph + return NULL; + } + ++static inline bool cgraph_for_node_and_aliases(cgraph_node_ptr node, bool (*callback)(cgraph_node_ptr, void *), void *data, bool include_overwritable) ++{ ++ cgraph_node_ptr alias; ++ ++ if (callback(node, data)) ++ return true; ++ ++ for (alias = node->same_body; alias; alias = alias->next) { ++ if (include_overwritable || cgraph_function_body_availability(alias) > AVAIL_OVERWRITABLE) ++ if (cgraph_for_node_and_aliases(alias, callback, data, include_overwritable)) ++ return true; ++ } ++ ++ return false; ++} ++ + #define FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node) \ + for ((node) = cgraph_first_function_with_gimple_body(); (node); \ + (node) = cgraph_next_function_with_gimple_body(node)) +@@ -399,6 +421,7 @@ typedef union gimple_statement_d gassign + typedef union gimple_statement_d gcall; + typedef union gimple_statement_d gcond; + typedef union gimple_statement_d gdebug; ++typedef union gimple_statement_d ggoto; + typedef union gimple_statement_d gphi; + typedef union gimple_statement_d greturn; + +@@ -452,6 +475,16 @@ static inline const gdebug *as_a_const_g + return stmt; + } + ++static inline ggoto *as_a_ggoto(gimple stmt) ++{ ++ return stmt; ++} ++ ++static inline const ggoto *as_a_const_ggoto(const_gimple stmt) ++{ ++ return stmt; ++} ++ + static inline gphi *as_a_gphi(gimple stmt) + { + return stmt; +@@ -496,6 +529,14 @@ static inline const greturn *as_a_const_ + + typedef struct rtx_def rtx_insn; + ++static inline const char *get_decl_section_name(const_tree decl) ++{ ++ if (DECL_SECTION_NAME(decl) == NULL_TREE) ++ return NULL; ++ ++ return TREE_STRING_POINTER(DECL_SECTION_NAME(decl)); ++} ++ + static inline void set_decl_section_name(tree node, const char *value) + { + if (value) +@@ -511,6 +552,7 @@ typedef struct gimple_statement_base gas + typedef struct gimple_statement_call gcall; + typedef struct gimple_statement_base gcond; + typedef struct gimple_statement_base gdebug; ++typedef struct gimple_statement_base ggoto; + typedef struct gimple_statement_phi gphi; + typedef struct gimple_statement_base greturn; + +@@ -564,6 +606,16 @@ static inline const gdebug *as_a_const_g + return stmt; + } + ++static inline ggoto *as_a_ggoto(gimple stmt) ++{ ++ return stmt; ++} ++ ++static inline const ggoto *as_a_const_ggoto(const_gimple stmt) ++{ ++ return stmt; ++} ++ + static inline gphi *as_a_gphi(gimple stmt) + { + return as_a(stmt); +@@ -611,6 +663,11 @@ inline bool is_a_helper + + #define INSN_DELETED_P(insn) (insn)->deleted() + ++static inline const char *get_decl_section_name(const_tree decl) ++{ ++ return DECL_SECTION_NAME(decl); ++} ++ + /* symtab/cgraph related */ + #define debug_cgraph_node(node) (node)->debug() + #define cgraph_get_node(decl) cgraph_node::get(decl) +@@ -619,6 +676,7 @@ inline bool is_a_helper + #define cgraph_n_nodes symtab->cgraph_count + #define cgraph_max_uid symtab->cgraph_max_uid + #define varpool_get_node(decl) varpool_node::get(decl) ++#define dump_varpool_node(file, node) (node)->dump(file) + + #define cgraph_create_edge(caller, callee, call_stmt, count, freq, nest) \ + (caller)->create_edge((callee), (call_stmt), (count), (freq)) +@@ -674,6 +732,11 @@ static inline cgraph_node_ptr cgraph_ali + return node->get_alias_target(); + } + ++static inline bool cgraph_for_node_and_aliases(cgraph_node_ptr node, bool (*callback)(cgraph_node_ptr, void *), void *data, bool include_overwritable) ++{ ++ return node->call_for_symbol_thunks_and_aliases(callback, data, include_overwritable); ++} ++ + static inline struct cgraph_node_hook_list *cgraph_add_function_insertion_hook(cgraph_node_hook hook, void *data) + { + return symtab->add_cgraph_insertion_hook(hook, data); +@@ -731,6 +794,13 @@ static inline gimple gimple_build_assign + + template <> + template <> ++inline bool is_a_helper::test(const_gimple gs) ++{ ++ return gs->code == GIMPLE_GOTO; ++} ++ ++template <> ++template <> + inline bool is_a_helper::test(const_gimple gs) + { + return gs->code == GIMPLE_RETURN; +@@ -766,6 +836,16 @@ static inline const gcall *as_a_const_gc + return as_a(stmt); + } + ++static inline ggoto *as_a_ggoto(gimple stmt) ++{ ++ return as_a(stmt); ++} ++ ++static inline const ggoto *as_a_const_ggoto(const_gimple stmt) ++{ ++ return as_a(stmt); ++} ++ + static inline gphi *as_a_gphi(gimple stmt) + { + return as_a(stmt); +@@ -828,4 +908,9 @@ static inline void debug_gimple_stmt(con + #define debug_gimple_stmt(s) debug_gimple_stmt(CONST_CAST_GIMPLE(s)) + #endif + ++#if BUILDING_GCC_VERSION >= 7000 ++#define get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep, keep_aligning) \ ++ get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep) ++#endif ++ + #endif diff --git a/queue-4.9/kvm-mips-don-t-clobber-cp0_status.ux.patch b/queue-4.9/kvm-mips-don-t-clobber-cp0_status.ux.patch new file mode 100644 index 00000000000..90b683b5660 --- /dev/null +++ b/queue-4.9/kvm-mips-don-t-clobber-cp0_status.ux.patch @@ -0,0 +1,64 @@ +From 4c881451d3017033597ea186cf79ae41a73e1ef8 Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Tue, 3 Jan 2017 17:43:00 +0000 +Subject: KVM: MIPS: Don't clobber CP0_Status.UX +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: James Hogan + +commit 4c881451d3017033597ea186cf79ae41a73e1ef8 upstream. + +On 64-bit kernels, MIPS KVM will clear CP0_Status.UX to prevent the +guest (running in user mode) from accessing the 64-bit memory segments. +However the previous value of CP0_Status.UX is never restored when +exiting from the guest. + +If the user process uses 64-bit addressing (the n64 ABI) this can result +in address error exceptions from the kernel if it needs to deliver a +signal before returning to user mode, as the kernel will need to write a +sigframe to high user addresses on the user stack which are disallowed +by CP0_Status.UX=0. + +This is fixed by explicitly setting SX and UX again when exiting from +the guest, and explicitly clearing those bits when returning to the +guest. Having the SX and UX bits set when handling guest exits (rather +than only when exiting to userland) will be helpful when we support VZ, +since we shouldn't need to directly read or write guest memory, so it +will be valid for cache management IPIs to access host user addresses. + +Signed-off-by: James Hogan +Cc: Paolo Bonzini +Cc: "Radim Krčmář" +Cc: Ralf Baechle +Cc: linux-mips@linux-mips.org +Cc: kvm@vger.kernel.org +Signed-off-by: Radim Krčmář +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kvm/entry.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/arch/mips/kvm/entry.c ++++ b/arch/mips/kvm/entry.c +@@ -521,6 +521,9 @@ void *kvm_mips_build_exit(void *addr) + uasm_i_and(&p, V0, V0, AT); + uasm_i_lui(&p, AT, ST0_CU0 >> 16); + uasm_i_or(&p, V0, V0, AT); ++#ifdef CONFIG_64BIT ++ uasm_i_ori(&p, V0, V0, ST0_SX | ST0_UX); ++#endif + uasm_i_mtc0(&p, V0, C0_STATUS); + uasm_i_ehb(&p); + +@@ -643,7 +646,7 @@ static void *kvm_mips_build_ret_to_guest + + /* Setup status register for running guest in UM */ + uasm_i_ori(&p, V1, V1, ST0_EXL | KSU_USER | ST0_IE); +- UASM_i_LA(&p, AT, ~(ST0_CU0 | ST0_MX)); ++ UASM_i_LA(&p, AT, ~(ST0_CU0 | ST0_MX | ST0_SX | ST0_UX)); + uasm_i_and(&p, V1, V1, AT); + uasm_i_mtc0(&p, V1, C0_STATUS); + uasm_i_ehb(&p); diff --git a/queue-4.9/kvm-mips-flush-kvm-entry-code-from-icache-globally.patch b/queue-4.9/kvm-mips-flush-kvm-entry-code-from-icache-globally.patch new file mode 100644 index 00000000000..9d0ebe7cdeb --- /dev/null +++ b/queue-4.9/kvm-mips-flush-kvm-entry-code-from-icache-globally.patch @@ -0,0 +1,41 @@ +From 32eb12a6c11034867401d56b012e3c15d5f8141e Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Tue, 3 Jan 2017 17:43:01 +0000 +Subject: KVM: MIPS: Flush KVM entry code from icache globally +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: James Hogan + +commit 32eb12a6c11034867401d56b012e3c15d5f8141e upstream. + +Flush the KVM entry code from the icache on all CPUs, not just the one +that built the entry code. + +Signed-off-by: James Hogan +Cc: Paolo Bonzini +Cc: "Radim Krčmář" +Cc: Ralf Baechle +Cc: linux-mips@linux-mips.org +Cc: kvm@vger.kernel.org +Signed-off-by: Radim Krčmář +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kvm/mips.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/mips/kvm/mips.c ++++ b/arch/mips/kvm/mips.c +@@ -360,8 +360,8 @@ struct kvm_vcpu *kvm_arch_vcpu_create(st + dump_handler("kvm_exit", gebase + 0x2000, vcpu->arch.vcpu_run); + + /* Invalidate the icache for these ranges */ +- local_flush_icache_range((unsigned long)gebase, +- (unsigned long)gebase + ALIGN(size, PAGE_SIZE)); ++ flush_icache_range((unsigned long)gebase, ++ (unsigned long)gebase + ALIGN(size, PAGE_SIZE)); + + /* + * Allocate comm page for guest kernel, a TLB will be reserved for diff --git a/queue-4.9/kvm-x86-reset-mmu-on-kvm_set_vcpu_events.patch b/queue-4.9/kvm-x86-reset-mmu-on-kvm_set_vcpu_events.patch new file mode 100644 index 00000000000..0619936f903 --- /dev/null +++ b/queue-4.9/kvm-x86-reset-mmu-on-kvm_set_vcpu_events.patch @@ -0,0 +1,47 @@ +From 6ef4e07ecd2db21025c446327ecf34414366498b Mon Sep 17 00:00:00 2001 +From: Xiao Guangrong +Date: Sat, 24 Dec 2016 10:00:42 +0100 +Subject: KVM: x86: reset MMU on KVM_SET_VCPU_EVENTS + +From: Xiao Guangrong + +commit 6ef4e07ecd2db21025c446327ecf34414366498b upstream. + +Otherwise, mismatch between the smm bit in hflags and the MMU role +can cause a NULL pointer dereference. + +Signed-off-by: Xiao Guangrong +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/x86.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -3036,6 +3036,8 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_ + memset(&events->reserved, 0, sizeof(events->reserved)); + } + ++static void kvm_set_hflags(struct kvm_vcpu *vcpu, unsigned emul_flags); ++ + static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, + struct kvm_vcpu_events *events) + { +@@ -3072,10 +3074,13 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_e + vcpu->arch.apic->sipi_vector = events->sipi_vector; + + if (events->flags & KVM_VCPUEVENT_VALID_SMM) { ++ u32 hflags = vcpu->arch.hflags; + if (events->smi.smm) +- vcpu->arch.hflags |= HF_SMM_MASK; ++ hflags |= HF_SMM_MASK; + else +- vcpu->arch.hflags &= ~HF_SMM_MASK; ++ hflags &= ~HF_SMM_MASK; ++ kvm_set_hflags(vcpu, hflags); ++ + vcpu->arch.smi_pending = events->smi.pending; + if (events->smi.smm_inside_nmi) + vcpu->arch.hflags |= HF_SMM_INSIDE_NMI_MASK; diff --git a/queue-4.9/mac80211-initialize-fast-xmit-info-later.patch b/queue-4.9/mac80211-initialize-fast-xmit-info-later.patch new file mode 100644 index 00000000000..1176ec96b94 --- /dev/null +++ b/queue-4.9/mac80211-initialize-fast-xmit-info-later.patch @@ -0,0 +1,46 @@ +From 35f432a03e41d3bf08c51ede917f94e2288fbe8c Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Mon, 2 Jan 2017 11:19:29 +0100 +Subject: mac80211: initialize fast-xmit 'info' later + +From: Johannes Berg + +commit 35f432a03e41d3bf08c51ede917f94e2288fbe8c upstream. + +In ieee80211_xmit_fast(), 'info' is initialized to point to the skb +that's passed in, but that skb may later be replaced by a clone (if +it was shared), leading to an invalid pointer. + +This can lead to use-after-free and also later crashes since the +real SKB's info->hw_queue doesn't get initialized properly. + +Fix this by assigning info only later, when it's needed, after the +skb replacement (may have) happened. + +Reported-by: Ben Greear +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/tx.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -3262,7 +3262,7 @@ static bool ieee80211_xmit_fast(struct i + int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); + int hw_headroom = sdata->local->hw.extra_tx_headroom; + struct ethhdr eth; +- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ++ struct ieee80211_tx_info *info; + struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; + struct ieee80211_tx_data tx; + ieee80211_tx_result r; +@@ -3326,6 +3326,7 @@ static bool ieee80211_xmit_fast(struct i + memcpy(skb->data + fast_tx->da_offs, eth.h_dest, ETH_ALEN); + memcpy(skb->data + fast_tx->sa_offs, eth.h_source, ETH_ALEN); + ++ info = IEEE80211_SKB_CB(skb); + memset(info, 0, sizeof(*info)); + info->band = fast_tx->band; + info->control.vif = &sdata->vif; diff --git a/queue-4.9/pinctrl-amd-set-the-level-based-on-acpi-tables.patch b/queue-4.9/pinctrl-amd-set-the-level-based-on-acpi-tables.patch new file mode 100644 index 00000000000..73e7cf150e8 --- /dev/null +++ b/queue-4.9/pinctrl-amd-set-the-level-based-on-acpi-tables.patch @@ -0,0 +1,60 @@ +From 2983f296f2327bc517e3b29344fce82271160197 Mon Sep 17 00:00:00 2001 +From: Shyam Sundar S K +Date: Thu, 8 Dec 2016 17:31:14 +0530 +Subject: pinctrl/amd: Set the level based on ACPI tables + +From: Shyam Sundar S K + +commit 2983f296f2327bc517e3b29344fce82271160197 upstream. + +In the function amd_gpio_irq_set_type, read the values from +the ACPI table to set the level and drop the settings passed +by the client. + +Reviewed-by: Pankaj Sen +Reviewed-by: Nitesh Kumar Agrawal +Reviewed-by: Shah, Nehal-bakulchandra +Signed-off-by: Shyam-sundar S-k +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pinctrl/pinctrl-amd.c | 19 +++++++------------ + 1 file changed, 7 insertions(+), 12 deletions(-) + +--- a/drivers/pinctrl/pinctrl-amd.c ++++ b/drivers/pinctrl/pinctrl-amd.c +@@ -382,26 +382,21 @@ static int amd_gpio_irq_set_type(struct + { + int ret = 0; + u32 pin_reg; +- unsigned long flags; +- bool level_trig; +- u32 active_level; ++ unsigned long flags, irq_flags; + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct amd_gpio *gpio_dev = gpiochip_get_data(gc); + + spin_lock_irqsave(&gpio_dev->lock, flags); + pin_reg = readl(gpio_dev->base + (d->hwirq)*4); + +- /* +- * When level_trig is set EDGE and active_level is set HIGH in BIOS +- * default settings, ignore incoming settings from client and use +- * BIOS settings to configure GPIO register. ++ /* Ignore the settings coming from the client and ++ * read the values from the ACPI tables ++ * while setting the trigger type + */ +- level_trig = !(pin_reg & (LEVEL_TRIGGER << LEVEL_TRIG_OFF)); +- active_level = pin_reg & (ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF); + +- if(level_trig && +- ((active_level >> ACTIVE_LEVEL_OFF) == ACTIVE_HIGH)) +- type = IRQ_TYPE_EDGE_FALLING; ++ irq_flags = irq_get_trigger_type(d->irq); ++ if (irq_flags != IRQ_TYPE_NONE) ++ type = irq_flags; + + switch (type & IRQ_TYPE_SENSE_MASK) { + case IRQ_TYPE_EDGE_RISING: diff --git a/queue-4.9/series b/queue-4.9/series index 43d73b9431c..ddc8b5e1702 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -10,3 +10,26 @@ parisc-add-line-break-when-printing-segfault-info.patch parisc-mark-cr16-clocksource-unstable-on-smp-systems.patch hid-sensor-hub-move-the-memset-to-sensor_hub_get_feature.patch arm-davinci-da850-don-t-add-emac-clock-to-lookup-table-twice.patch +pinctrl-amd-set-the-level-based-on-acpi-tables.patch +mac80211-initialize-fast-xmit-info-later.patch +asm-prototypes-clear-any-cpp-defines-before-declaring-the-functions.patch +gcc-plugins-update-gcc-common.h-for-gcc-7.patch +drm-i915-fix-oopses-in-the-overlay-code-due-to-i915_gem_active-stuff.patch +drm-i915-fix-oops-in-overlay-due-to-frontbuffer-tracking.patch +drm-i915-force-vdd-off-on-the-new-power-seqeuencer-before-starting-to-use-it.patch +drm-i915-initialize-overlay-last_flip-properly.patch +kvm-x86-reset-mmu-on-kvm_set_vcpu_events.patch +kvm-mips-don-t-clobber-cp0_status.ux.patch +kvm-mips-flush-kvm-entry-code-from-icache-globally.patch +usb-musb-core-add-clear_ep_rxintr-to-musb_platform_ops.patch +usb-musb-dsps-implement-clear_ep_rxintr-callback.patch +usb-storage-unusual_uas-add-jmicron-jms56x-to-unusual-device.patch +usb-gadgetfs-restrict-upper-bound-on-device-configuration-size.patch +usb-gadgetfs-fix-unbounded-memory-allocation-bug.patch +usb-gadgetfs-fix-use-after-free-bug.patch +usb-gadgetfs-fix-checks-of-wtotallength-in-config-descriptors.patch +usb-fix-problems-with-duplicate-endpoint-addresses.patch +usb-dummy-hcd-fix-bug-in-stop_activity-handle-ep0.patch +usb-gadget-composite-test-get_alt-presence-instead-of-set_alt.patch +usb-dwc3-core-avoid-overflow-events.patch +usb-xhci-fix-possible-wild-pointer.patch diff --git a/queue-4.9/usb-dummy-hcd-fix-bug-in-stop_activity-handle-ep0.patch b/queue-4.9/usb-dummy-hcd-fix-bug-in-stop_activity-handle-ep0.patch new file mode 100644 index 00000000000..555903ddfa6 --- /dev/null +++ b/queue-4.9/usb-dummy-hcd-fix-bug-in-stop_activity-handle-ep0.patch @@ -0,0 +1,67 @@ +From bcdbeb844773333d2d1c08004f3b3e25921040e5 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Wed, 14 Dec 2016 14:55:56 -0500 +Subject: USB: dummy-hcd: fix bug in stop_activity (handle ep0) + +From: Alan Stern + +commit bcdbeb844773333d2d1c08004f3b3e25921040e5 upstream. + +The stop_activity() routine in dummy-hcd is supposed to unlink all +active requests for every endpoint, among other things. But it +doesn't handle ep0. As a result, fuzz testing can generate a WARNING +like the following: + +WARNING: CPU: 0 PID: 4410 at drivers/usb/gadget/udc/dummy_hcd.c:672 dummy_free_request+0x153/0x170 +Modules linked in: +CPU: 0 PID: 4410 Comm: syz-executor Not tainted 4.9.0-rc7+ #32 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 + ffff88006a64ed10 ffffffff81f96b8a ffffffff41b58ab3 1ffff1000d4c9d35 + ffffed000d4c9d2d ffff880065f8ac00 0000000041b58ab3 ffffffff8598b510 + ffffffff81f968f8 0000000041b58ab3 ffffffff859410e0 ffffffff813f0590 +Call Trace: + [< inline >] __dump_stack lib/dump_stack.c:15 + [] dump_stack+0x292/0x398 lib/dump_stack.c:51 + [] __warn+0x19f/0x1e0 kernel/panic.c:550 + [] warn_slowpath_null+0x2c/0x40 kernel/panic.c:585 + [] dummy_free_request+0x153/0x170 drivers/usb/gadget/udc/dummy_hcd.c:672 + [] usb_ep_free_request+0xc0/0x420 drivers/usb/gadget/udc/core.c:195 + [] gadgetfs_unbind+0x131/0x190 drivers/usb/gadget/legacy/inode.c:1612 + [] usb_gadget_remove_driver+0x10f/0x2b0 drivers/usb/gadget/udc/core.c:1228 + [] usb_gadget_unregister_driver+0x154/0x240 drivers/usb/gadget/udc/core.c:1357 + +This patch fixes the problem by iterating over all the endpoints in +the driver's ep array instead of iterating over the gadget's ep_list, +which explicitly leaves out ep0. + +Signed-off-by: Alan Stern +Reported-by: Andrey Konovalov +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/udc/dummy_hcd.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -330,7 +330,7 @@ static void nuke(struct dummy *dum, stru + /* caller must hold lock */ + static void stop_activity(struct dummy *dum) + { +- struct dummy_ep *ep; ++ int i; + + /* prevent any more requests */ + dum->address = 0; +@@ -338,8 +338,8 @@ static void stop_activity(struct dummy * + /* The timer is left running so that outstanding URBs can fail */ + + /* nuke any pending requests first, so driver i/o is quiesced */ +- list_for_each_entry(ep, &dum->gadget.ep_list, ep.ep_list) +- nuke(dum, ep); ++ for (i = 0; i < DUMMY_ENDPOINTS; ++i) ++ nuke(dum, &dum->ep[i]); + + /* driver now does any non-usb quiescing necessary */ + } diff --git a/queue-4.9/usb-dwc3-core-avoid-overflow-events.patch b/queue-4.9/usb-dwc3-core-avoid-overflow-events.patch new file mode 100644 index 00000000000..8bebd4bcfdb --- /dev/null +++ b/queue-4.9/usb-dwc3-core-avoid-overflow-events.patch @@ -0,0 +1,37 @@ +From e71d363d9c611c99fb78f53bfee99616e7fe352c Mon Sep 17 00:00:00 2001 +From: Felipe Balbi +Date: Fri, 23 Dec 2016 14:40:40 +0200 +Subject: usb: dwc3: core: avoid Overflow events + +From: Felipe Balbi + +commit e71d363d9c611c99fb78f53bfee99616e7fe352c upstream. + +Now that we're handling so many transfers at a time +and for some dwc3 revisions LPM events *must* be +enabled, we can fall into a situation where too many +events fire and we start receiving Overflow events. + +Let's do what XHCI does and allocate a full page for +the Event Ring, this will avoid any future issues. + +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/core.h | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -43,9 +43,7 @@ + #define DWC3_XHCI_RESOURCES_NUM 2 + + #define DWC3_SCRATCHBUF_SIZE 4096 /* each buffer is assumed to be 4KiB */ +-#define DWC3_EVENT_SIZE 4 /* bytes */ +-#define DWC3_EVENT_MAX_NUM 64 /* 2 events/endpoint */ +-#define DWC3_EVENT_BUFFERS_SIZE (DWC3_EVENT_SIZE * DWC3_EVENT_MAX_NUM) ++#define DWC3_EVENT_BUFFERS_SIZE 4096 + #define DWC3_EVENT_TYPE_MASK 0xfe + + #define DWC3_EVENT_TYPE_DEV 0 diff --git a/queue-4.9/usb-fix-problems-with-duplicate-endpoint-addresses.patch b/queue-4.9/usb-fix-problems-with-duplicate-endpoint-addresses.patch new file mode 100644 index 00000000000..7f1b54a31ce --- /dev/null +++ b/queue-4.9/usb-fix-problems-with-duplicate-endpoint-addresses.patch @@ -0,0 +1,76 @@ +From 0a8fd1346254974c3a852338508e4a4cddbb35f1 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Mon, 19 Dec 2016 12:03:41 -0500 +Subject: USB: fix problems with duplicate endpoint addresses + +From: Alan Stern + +commit 0a8fd1346254974c3a852338508e4a4cddbb35f1 upstream. + +When checking a new device's descriptors, the USB core does not check +for duplicate endpoint addresses. This can cause a problem when the +sysfs files for those endpoints are created; trying to create multiple +files with the same name will provoke a WARNING: + +WARNING: CPU: 2 PID: 865 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x8a/0xa0 +sysfs: cannot create duplicate filename +'/devices/platform/dummy_hcd.0/usb2/2-1/2-1:64.0/ep_05' +Kernel panic - not syncing: panic_on_warn set ... + +CPU: 2 PID: 865 Comm: kworker/2:1 Not tainted 4.9.0-rc7+ #34 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 +Workqueue: usb_hub_wq hub_event + ffff88006bee64c8 ffffffff81f96b8a ffffffff00000001 1ffff1000d7dcc2c + ffffed000d7dcc24 0000000000000001 0000000041b58ab3 ffffffff8598b510 + ffffffff81f968f8 ffffffff850fee20 ffffffff85cff020 dffffc0000000000 +Call Trace: + [< inline >] __dump_stack lib/dump_stack.c:15 + [] dump_stack+0x292/0x398 lib/dump_stack.c:51 + [] panic+0x1cb/0x3a9 kernel/panic.c:179 + [] __warn+0x1c4/0x1e0 kernel/panic.c:542 + [] warn_slowpath_fmt+0xc5/0x110 kernel/panic.c:565 + [] sysfs_warn_dup+0x8a/0xa0 fs/sysfs/dir.c:30 + [] sysfs_create_dir_ns+0x178/0x1d0 fs/sysfs/dir.c:59 + [< inline >] create_dir lib/kobject.c:71 + [] kobject_add_internal+0x227/0xa60 lib/kobject.c:229 + [< inline >] kobject_add_varg lib/kobject.c:366 + [] kobject_add+0x139/0x220 lib/kobject.c:411 + [] device_add+0x353/0x1660 drivers/base/core.c:1088 + [] device_register+0x1d/0x20 drivers/base/core.c:1206 + [] usb_create_ep_devs+0x163/0x260 drivers/usb/core/endpoint.c:195 + [] create_intf_ep_devs+0x13b/0x200 drivers/usb/core/message.c:1030 + [] usb_set_configuration+0x1083/0x18d0 drivers/usb/core/message.c:1937 + [] generic_probe+0x6e/0xe0 drivers/usb/core/generic.c:172 + [] usb_probe_device+0xaa/0xe0 drivers/usb/core/driver.c:263 + +This patch prevents the problem by checking for duplicate endpoint +addresses during enumeration and skipping any duplicates. + +Signed-off-by: Alan Stern +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/config.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -234,6 +234,16 @@ static int usb_parse_endpoint(struct dev + if (ifp->desc.bNumEndpoints >= num_ep) + goto skip_to_next_endpoint_or_interface_descriptor; + ++ /* Check for duplicate endpoint addresses */ ++ for (i = 0; i < ifp->desc.bNumEndpoints; ++i) { ++ if (ifp->endpoint[i].desc.bEndpointAddress == ++ d->bEndpointAddress) { ++ dev_warn(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n", ++ cfgno, inum, asnum, d->bEndpointAddress); ++ goto skip_to_next_endpoint_or_interface_descriptor; ++ } ++ } ++ + endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints]; + ++ifp->desc.bNumEndpoints; + diff --git a/queue-4.9/usb-gadget-composite-test-get_alt-presence-instead-of-set_alt.patch b/queue-4.9/usb-gadget-composite-test-get_alt-presence-instead-of-set_alt.patch new file mode 100644 index 00000000000..104321dca63 --- /dev/null +++ b/queue-4.9/usb-gadget-composite-test-get_alt-presence-instead-of-set_alt.patch @@ -0,0 +1,61 @@ +From 7e4da3fcf7c9fe042f2f7cb7bf23861a899b4a8f Mon Sep 17 00:00:00 2001 +From: Krzysztof Opasiak +Date: Tue, 20 Dec 2016 19:52:16 +0100 +Subject: usb: gadget: composite: Test get_alt() presence instead of set_alt() + +From: Krzysztof Opasiak + +commit 7e4da3fcf7c9fe042f2f7cb7bf23861a899b4a8f upstream. + +By convention (according to doc) if function does not provide +get_alt() callback composite framework should assume that it has only +altsetting 0 and should respond with error if host tries to set +other one. + +After commit dd4dff8b035f ("USB: composite: Fix bug: should test +set_alt function pointer before use it") +we started checking set_alt() callback instead of get_alt(). +This check is useless as we check if set_alt() is set inside +usb_add_function() and fail if it's NULL. + +Let's fix this check and move comment about why we check the get +method instead of set a little bit closer to prevent future false +fixes. + +Fixes: dd4dff8b035f ("USB: composite: Fix bug: should test set_alt function pointer before use it") +Signed-off-by: Krzysztof Opasiak +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/composite.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/drivers/usb/gadget/composite.c ++++ b/drivers/usb/gadget/composite.c +@@ -1694,9 +1694,7 @@ composite_setup(struct usb_gadget *gadge + value = min(w_length, (u16) 1); + break; + +- /* function drivers must handle get/set altsetting; if there's +- * no get() method, we know only altsetting zero works. +- */ ++ /* function drivers must handle get/set altsetting */ + case USB_REQ_SET_INTERFACE: + if (ctrl->bRequestType != USB_RECIP_INTERFACE) + goto unknown; +@@ -1705,7 +1703,13 @@ composite_setup(struct usb_gadget *gadge + f = cdev->config->interface[intf]; + if (!f) + break; +- if (w_value && !f->set_alt) ++ ++ /* ++ * If there's no get_alt() method, we know only altsetting zero ++ * works. There is no need to check if set_alt() is not NULL ++ * as we check this in usb_add_function(). ++ */ ++ if (w_value && !f->get_alt) + break; + value = f->set_alt(f, w_index, w_value); + if (value == USB_GADGET_DELAYED_STATUS) { diff --git a/queue-4.9/usb-gadgetfs-fix-checks-of-wtotallength-in-config-descriptors.patch b/queue-4.9/usb-gadgetfs-fix-checks-of-wtotallength-in-config-descriptors.patch new file mode 100644 index 00000000000..74d4871a437 --- /dev/null +++ b/queue-4.9/usb-gadgetfs-fix-checks-of-wtotallength-in-config-descriptors.patch @@ -0,0 +1,67 @@ +From 1c069b057dcf64fada952eaa868d35f02bb0cfc2 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 9 Dec 2016 15:24:24 -0500 +Subject: USB: gadgetfs: fix checks of wTotalLength in config descriptors + +From: Alan Stern + +commit 1c069b057dcf64fada952eaa868d35f02bb0cfc2 upstream. + +Andrey Konovalov's fuzz testing of gadgetfs showed that we should +improve the driver's checks for valid configuration descriptors passed +in by the user. In particular, the driver needs to verify that the +wTotalLength value in the descriptor is not too short (smaller +than USB_DT_CONFIG_SIZE). And the check for whether wTotalLength is +too large has to be changed, because the driver assumes there is +always enough room remaining in the buffer to hold a device descriptor +(at least USB_DT_DEVICE_SIZE bytes). + +This patch adds the additional check and fixes the existing check. It +may do a little more than strictly necessary, but one extra check +won't hurt. + +Signed-off-by: Alan Stern +CC: Andrey Konovalov +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/legacy/inode.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/drivers/usb/gadget/legacy/inode.c ++++ b/drivers/usb/gadget/legacy/inode.c +@@ -1734,10 +1734,12 @@ static struct usb_gadget_driver gadgetfs + * such as configuration notifications. + */ + +-static int is_valid_config (struct usb_config_descriptor *config) ++static int is_valid_config(struct usb_config_descriptor *config, ++ unsigned int total) + { + return config->bDescriptorType == USB_DT_CONFIG + && config->bLength == USB_DT_CONFIG_SIZE ++ && total >= USB_DT_CONFIG_SIZE + && config->bConfigurationValue != 0 + && (config->bmAttributes & USB_CONFIG_ATT_ONE) != 0 + && (config->bmAttributes & USB_CONFIG_ATT_WAKEUP) == 0; +@@ -1787,7 +1789,8 @@ dev_config (struct file *fd, const char + /* full or low speed config */ + dev->config = (void *) kbuf; + total = le16_to_cpu(dev->config->wTotalLength); +- if (!is_valid_config (dev->config) || total >= length) ++ if (!is_valid_config(dev->config, total) || ++ total > length - USB_DT_DEVICE_SIZE) + goto fail; + kbuf += total; + length -= total; +@@ -1796,7 +1799,8 @@ dev_config (struct file *fd, const char + if (kbuf [1] == USB_DT_CONFIG) { + dev->hs_config = (void *) kbuf; + total = le16_to_cpu(dev->hs_config->wTotalLength); +- if (!is_valid_config (dev->hs_config) || total >= length) ++ if (!is_valid_config(dev->hs_config, total) || ++ total > length - USB_DT_DEVICE_SIZE) + goto fail; + kbuf += total; + length -= total; diff --git a/queue-4.9/usb-gadgetfs-fix-unbounded-memory-allocation-bug.patch b/queue-4.9/usb-gadgetfs-fix-unbounded-memory-allocation-bug.patch new file mode 100644 index 00000000000..0e4b8621273 --- /dev/null +++ b/queue-4.9/usb-gadgetfs-fix-unbounded-memory-allocation-bug.patch @@ -0,0 +1,67 @@ +From faab50984fe6636e616c7cc3d30308ba391d36fd Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 9 Dec 2016 15:17:46 -0500 +Subject: USB: gadgetfs: fix unbounded memory allocation bug + +From: Alan Stern + +commit faab50984fe6636e616c7cc3d30308ba391d36fd upstream. + +Andrey Konovalov reports that fuzz testing with syzkaller causes a +KASAN warning in gadgetfs: + +BUG: KASAN: slab-out-of-bounds in dev_config+0x86f/0x1190 at addr ffff88003c47e160 +Write of size 65537 by task syz-executor0/6356 +CPU: 3 PID: 6356 Comm: syz-executor0 Not tainted 4.9.0-rc7+ #19 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 + ffff88003c107ad8 ffffffff81f96aba ffffffff3dc11ef0 1ffff10007820eee + ffffed0007820ee6 ffff88003dc11f00 0000000041b58ab3 ffffffff8598b4c8 + ffffffff81f96828 ffffffff813fb4a0 ffff88003b6eadc0 ffff88003c107738 +Call Trace: + [< inline >] __dump_stack lib/dump_stack.c:15 + [] dump_stack+0x292/0x398 lib/dump_stack.c:51 + [] kasan_object_err+0x1c/0x70 mm/kasan/report.c:159 + [< inline >] print_address_description mm/kasan/report.c:197 + [] kasan_report_error+0x1f0/0x4e0 mm/kasan/report.c:286 + [] kasan_report+0x35/0x40 mm/kasan/report.c:306 + [< inline >] check_memory_region_inline mm/kasan/kasan.c:308 + [] check_memory_region+0x139/0x190 mm/kasan/kasan.c:315 + [] kasan_check_write+0x14/0x20 mm/kasan/kasan.c:326 + [< inline >] copy_from_user arch/x86/include/asm/uaccess.h:689 + [< inline >] ep0_write drivers/usb/gadget/legacy/inode.c:1135 + [] dev_config+0x86f/0x1190 drivers/usb/gadget/legacy/inode.c:1759 + [] __vfs_write+0x5d5/0x760 fs/read_write.c:510 + [] vfs_write+0x170/0x4e0 fs/read_write.c:560 + [< inline >] SYSC_write fs/read_write.c:607 + [] SyS_write+0xfb/0x230 fs/read_write.c:599 + [] entry_SYSCALL_64_fastpath+0x1f/0xc2 + +Indeed, there is a comment saying that the value of len is restricted +to a 16-bit integer, but the code doesn't actually do this. + +This patch fixes the warning. It replaces the comment with a +computation that forces the amount of data copied from the user in +ep0_write() to be no larger than the wLength size for the control +transfer, which is a 16-bit quantity. + +Signed-off-by: Alan Stern +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/legacy/inode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/legacy/inode.c ++++ b/drivers/usb/gadget/legacy/inode.c +@@ -1126,7 +1126,7 @@ ep0_write (struct file *fd, const char _ + /* data and/or status stage for control request */ + } else if (dev->state == STATE_DEV_SETUP) { + +- /* IN DATA+STATUS caller makes len <= wLength */ ++ len = min_t(size_t, len, dev->setup_wLength); + if (dev->setup_in) { + retval = setup_req (dev->gadget->ep0, dev->req, len); + if (retval == 0) { diff --git a/queue-4.9/usb-gadgetfs-fix-use-after-free-bug.patch b/queue-4.9/usb-gadgetfs-fix-use-after-free-bug.patch new file mode 100644 index 00000000000..b6fea752989 --- /dev/null +++ b/queue-4.9/usb-gadgetfs-fix-use-after-free-bug.patch @@ -0,0 +1,74 @@ +From add333a81a16abbd4f106266a2553677a165725f Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 9 Dec 2016 15:18:43 -0500 +Subject: USB: gadgetfs: fix use-after-free bug + +From: Alan Stern + +commit add333a81a16abbd4f106266a2553677a165725f upstream. + +Andrey Konovalov reports that fuzz testing with syzkaller causes a +KASAN use-after-free bug report in gadgetfs: + +BUG: KASAN: use-after-free in gadgetfs_setup+0x208a/0x20e0 at addr ffff88003dfe5bf2 +Read of size 2 by task syz-executor0/22994 +CPU: 3 PID: 22994 Comm: syz-executor0 Not tainted 4.9.0-rc7+ #16 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 + ffff88006df06a18 ffffffff81f96aba ffffffffe0528500 1ffff1000dbe0cd6 + ffffed000dbe0cce ffff88006df068f0 0000000041b58ab3 ffffffff8598b4c8 + ffffffff81f96828 1ffff1000dbe0ccd ffff88006df06708 ffff88006df06748 +Call Trace: + [ 201.343209] [< inline >] __dump_stack lib/dump_stack.c:15 + [ 201.343209] [] dump_stack+0x292/0x398 lib/dump_stack.c:51 + [] kasan_object_err+0x1c/0x70 mm/kasan/report.c:159 + [< inline >] print_address_description mm/kasan/report.c:197 + [] kasan_report_error+0x1f0/0x4e0 mm/kasan/report.c:286 + [< inline >] kasan_report mm/kasan/report.c:306 + [] __asan_report_load_n_noabort+0x3a/0x40 mm/kasan/report.c:337 + [< inline >] config_buf drivers/usb/gadget/legacy/inode.c:1298 + [] gadgetfs_setup+0x208a/0x20e0 drivers/usb/gadget/legacy/inode.c:1368 + [] dummy_timer+0x11f0/0x36d0 drivers/usb/gadget/udc/dummy_hcd.c:1858 + [] call_timer_fn+0x241/0x800 kernel/time/timer.c:1308 + [< inline >] expire_timers kernel/time/timer.c:1348 + [] __run_timers+0xa06/0xec0 kernel/time/timer.c:1641 + [] run_timer_softirq+0x21/0x80 kernel/time/timer.c:1654 + [] __do_softirq+0x2fb/0xb63 kernel/softirq.c:284 + +The cause of the bug is subtle. The dev_config() routine gets called +twice by the fuzzer. The first time, the user data contains both a +full-speed configuration descriptor and a high-speed config +descriptor, causing dev->hs_config to be set. But it also contains an +invalid device descriptor, so the buffer containing the descriptors is +deallocated and dev_config() returns an error. + +The second time dev_config() is called, the user data contains only a +full-speed config descriptor. But dev->hs_config still has the stale +pointer remaining from the first call, causing the routine to think +that there is a valid high-speed config. Later on, when the driver +dereferences the stale pointer to copy that descriptor, we get a +use-after-free access. + +The fix is simple: Clear dev->hs_config if the passed-in data does not +contain a high-speed config descriptor. + +Signed-off-by: Alan Stern +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/legacy/inode.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/gadget/legacy/inode.c ++++ b/drivers/usb/gadget/legacy/inode.c +@@ -1800,6 +1800,8 @@ dev_config (struct file *fd, const char + goto fail; + kbuf += total; + length -= total; ++ } else { ++ dev->hs_config = NULL; + } + + /* could support multiple configs, using another encoding! */ diff --git a/queue-4.9/usb-gadgetfs-restrict-upper-bound-on-device-configuration-size.patch b/queue-4.9/usb-gadgetfs-restrict-upper-bound-on-device-configuration-size.patch new file mode 100644 index 00000000000..79a13c01603 --- /dev/null +++ b/queue-4.9/usb-gadgetfs-restrict-upper-bound-on-device-configuration-size.patch @@ -0,0 +1,36 @@ +From 0994b0a257557e18ee8f0b7c5f0f73fe2b54eec1 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Tue, 6 Dec 2016 08:36:29 +0100 +Subject: usb: gadgetfs: restrict upper bound on device configuration size + +From: Greg Kroah-Hartman + +commit 0994b0a257557e18ee8f0b7c5f0f73fe2b54eec1 upstream. + +Andrey Konovalov reported that we were not properly checking the upper +limit before of a device configuration size before calling +memdup_user(), which could cause some problems. + +So set the upper limit to PAGE_SIZE * 4, which should be good enough for +all devices. + +Reported-by: Andrey Konovalov +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/legacy/inode.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/legacy/inode.c ++++ b/drivers/usb/gadget/legacy/inode.c +@@ -1762,7 +1762,8 @@ dev_config (struct file *fd, const char + } + spin_unlock_irq(&dev->lock); + +- if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) ++ if ((len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) || ++ (len > PAGE_SIZE * 4)) + return -EINVAL; + + /* we might need to change message format someday */ diff --git a/queue-4.9/usb-musb-core-add-clear_ep_rxintr-to-musb_platform_ops.patch b/queue-4.9/usb-musb-core-add-clear_ep_rxintr-to-musb_platform_ops.patch new file mode 100644 index 00000000000..2f710522846 --- /dev/null +++ b/queue-4.9/usb-musb-core-add-clear_ep_rxintr-to-musb_platform_ops.patch @@ -0,0 +1,85 @@ +From 6def85a396ce7796bd9f4561c6ae8138833f7a52 Mon Sep 17 00:00:00 2001 +From: Bin Liu +Date: Tue, 3 Jan 2017 18:13:46 -0600 +Subject: usb: musb: core: add clear_ep_rxintr() to musb_platform_ops + +From: Bin Liu + +commit 6def85a396ce7796bd9f4561c6ae8138833f7a52 upstream. + +During dma teardown for dequque urb, if musb load is high, musb might +generate bogus rx ep interrupt even when the rx fifo is flushed. In such +case any of the follow log messages could happen. + + musb_host_rx 1853: BOGUS RX2 ready, csr 0000, count 0 + + musb_host_rx 1936: RX3 dma busy, csr 2020 + +As mentioned in the current inline comment, clearing ep interrupt in the +teardown path avoids the bogus interrupt. + +Clearing ep interrupt is platform dependent, so this patch adds a +platform callback to allow glue driver to clear the ep interrupt. + +This bug seems to be existing since the initial driver for musb support, +but I only validated the fix back to v4.1, so only cc stable for v4.1+. + +Signed-off-by: Bin Liu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/musb/musb_core.h | 7 +++++++ + drivers/usb/musb/musb_host.c | 10 ++++------ + 2 files changed, 11 insertions(+), 6 deletions(-) + +--- a/drivers/usb/musb/musb_core.h ++++ b/drivers/usb/musb/musb_core.h +@@ -216,6 +216,7 @@ struct musb_platform_ops { + void (*pre_root_reset_end)(struct musb *musb); + void (*post_root_reset_end)(struct musb *musb); + int (*phy_callback)(enum musb_vbus_id_status status); ++ void (*clear_ep_rxintr)(struct musb *musb, int epnum); + }; + + /* +@@ -626,4 +627,10 @@ static inline void musb_platform_post_ro + musb->ops->post_root_reset_end(musb); + } + ++static inline void musb_platform_clear_ep_rxintr(struct musb *musb, int epnum) ++{ ++ if (musb->ops->clear_ep_rxintr) ++ musb->ops->clear_ep_rxintr(musb, epnum); ++} ++ + #endif /* __MUSB_CORE_H__ */ +--- a/drivers/usb/musb/musb_host.c ++++ b/drivers/usb/musb/musb_host.c +@@ -2374,12 +2374,11 @@ static int musb_cleanup_urb(struct urb * + int is_in = usb_pipein(urb->pipe); + int status = 0; + u16 csr; ++ struct dma_channel *dma = NULL; + + musb_ep_select(regs, hw_end); + + if (is_dma_capable()) { +- struct dma_channel *dma; +- + dma = is_in ? ep->rx_channel : ep->tx_channel; + if (dma) { + status = ep->musb->dma_controller->channel_abort(dma); +@@ -2395,10 +2394,9 @@ static int musb_cleanup_urb(struct urb * + /* giveback saves bulk toggle */ + csr = musb_h_flush_rxfifo(ep, 0); + +- /* REVISIT we still get an irq; should likely clear the +- * endpoint's irq status here to avoid bogus irqs. +- * clearing that status is platform-specific... +- */ ++ /* clear the endpoint's irq status here to avoid bogus irqs */ ++ if (is_dma_capable() && dma) ++ musb_platform_clear_ep_rxintr(musb, ep->epnum); + } else if (ep->epnum) { + musb_h_tx_flush_fifo(ep); + csr = musb_readw(epio, MUSB_TXCSR); diff --git a/queue-4.9/usb-musb-dsps-implement-clear_ep_rxintr-callback.patch b/queue-4.9/usb-musb-dsps-implement-clear_ep_rxintr-callback.patch new file mode 100644 index 00000000000..bfd926e1190 --- /dev/null +++ b/queue-4.9/usb-musb-dsps-implement-clear_ep_rxintr-callback.patch @@ -0,0 +1,59 @@ +From c48400baa02155a5ddad63e8554602e48782278c Mon Sep 17 00:00:00 2001 +From: Bin Liu +Date: Tue, 3 Jan 2017 18:13:47 -0600 +Subject: usb: musb: dsps: implement clear_ep_rxintr() callback + +From: Bin Liu + +commit c48400baa02155a5ddad63e8554602e48782278c upstream. + +During dma teardown for dequque urb, if musb load is high, musb might +generate bogus rx ep interrupt even when the rx fifo is flushed. In such +case any of the follow log messages could happen. + + musb_host_rx 1853: BOGUS RX2 ready, csr 0000, count 0 + + musb_host_rx 1936: RX3 dma busy, csr 2020 + +As mentioned in the current inline comment, clearing ep interrupt in the +teardown path avoids the bogus interrupt, so implement clear_ep_rxintr() +callback. + +This bug seems to be existing since the initial driver for musb support, +but I only validated the fix back to v4.1, so only cc stable for v4.1+. + +Signed-off-by: Bin Liu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/musb/musb_dsps.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/usb/musb/musb_dsps.c ++++ b/drivers/usb/musb/musb_dsps.c +@@ -267,6 +267,17 @@ static void otg_timer(unsigned long _mus + pm_runtime_put_autosuspend(dev); + } + ++void dsps_musb_clear_ep_rxintr(struct musb *musb, int epnum) ++{ ++ u32 epintr; ++ struct dsps_glue *glue = dev_get_drvdata(musb->controller->parent); ++ const struct dsps_musb_wrapper *wrp = glue->wrp; ++ ++ /* musb->lock might already been held */ ++ epintr = (1 << epnum) << wrp->rxep_shift; ++ musb_writel(musb->ctrl_base, wrp->epintr_status, epintr); ++} ++ + static irqreturn_t dsps_interrupt(int irq, void *hci) + { + struct musb *musb = hci; +@@ -622,6 +633,7 @@ static struct musb_platform_ops dsps_ops + + .set_mode = dsps_musb_set_mode, + .recover = dsps_musb_recover, ++ .clear_ep_rxintr = dsps_musb_clear_ep_rxintr, + }; + + static u64 musb_dmamask = DMA_BIT_MASK(32); diff --git a/queue-4.9/usb-storage-unusual_uas-add-jmicron-jms56x-to-unusual-device.patch b/queue-4.9/usb-storage-unusual_uas-add-jmicron-jms56x-to-unusual-device.patch new file mode 100644 index 00000000000..e1c268d03e2 --- /dev/null +++ b/queue-4.9/usb-storage-unusual_uas-add-jmicron-jms56x-to-unusual-device.patch @@ -0,0 +1,40 @@ +From 674aea07e38200ea6f31ff6d5f200f0cf6cdb325 Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Mon, 2 Jan 2017 15:26:17 +0100 +Subject: usb: storage: unusual_uas: Add JMicron JMS56x to unusual device + +From: Oliver Neukum + +commit 674aea07e38200ea6f31ff6d5f200f0cf6cdb325 upstream. + +This device gives the following error on detection. +xhci_hcd 0000:00:11.0: ERROR Transfer event for disabled endpoint or +incorrect stream ring + +The same error is not seen when it is added to unusual_device +list with US_FL_NO_REPORT_OPCODES passed. + +Signed-off-by: George Cherian +Signed-off-by: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/unusual_devs.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -2109,6 +2109,13 @@ UNUSUAL_DEV( 0x152d, 0x2566, 0x0114, 0x + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BROKEN_FUA ), + ++/* Reported-by George Cherian */ ++UNUSUAL_DEV(0x152d, 0x9561, 0x0000, 0x9999, ++ "JMicron", ++ "JMS56x", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_NO_REPORT_OPCODES), ++ + /* + * Entrega Technologies U1-SC25 (later Xircom PortGear PGSCSI) + * and Mac USB Dock USB-SCSI */ diff --git a/queue-4.9/usb-xhci-fix-possible-wild-pointer.patch b/queue-4.9/usb-xhci-fix-possible-wild-pointer.patch new file mode 100644 index 00000000000..92ce651627b --- /dev/null +++ b/queue-4.9/usb-xhci-fix-possible-wild-pointer.patch @@ -0,0 +1,63 @@ +From 2b985467371a58ae44d76c7ba12b0951fee6ed98 Mon Sep 17 00:00:00 2001 +From: Lu Baolu +Date: Tue, 3 Jan 2017 18:28:46 +0200 +Subject: usb: xhci: fix possible wild pointer + +From: Lu Baolu + +commit 2b985467371a58ae44d76c7ba12b0951fee6ed98 upstream. + +handle_cmd_completion() frees a command structure which might be still +referenced by xhci->current_cmd. +This might cause problem when xhci->current_cmd is accessed after that. + +A real-life case could be like this. The host takes a very long time to +respond to a command, and the command timer is fired at the same time +when the command completion event arrives. The command completion +handler frees xhci->current_cmd before the timer function can grab +xhci->lock. Afterward, timer function grabs the lock and go ahead with +checking and setting members of xhci->current_cmd. + +Signed-off-by: Lu Baolu +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1271,14 +1271,18 @@ void xhci_handle_command_timeout(unsigne + bool second_timeout = false; + xhci = (struct xhci_hcd *) data; + +- /* mark this command to be cancelled */ + spin_lock_irqsave(&xhci->lock, flags); +- if (xhci->current_cmd) { +- if (xhci->current_cmd->status == COMP_CMD_ABORT) +- second_timeout = true; +- xhci->current_cmd->status = COMP_CMD_ABORT; ++ ++ if (!xhci->current_cmd) { ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ return; + } + ++ /* mark this command to be cancelled */ ++ if (xhci->current_cmd->status == COMP_CMD_ABORT) ++ second_timeout = true; ++ xhci->current_cmd->status = COMP_CMD_ABORT; ++ + /* Make sure command ring is running before aborting it */ + hw_ring_state = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); + if ((xhci->cmd_ring_state & CMD_RING_STATE_RUNNING) && +@@ -1427,6 +1431,8 @@ static void handle_cmd_completion(struct + xhci->current_cmd = list_entry(cmd->cmd_list.next, + struct xhci_command, cmd_list); + mod_timer(&xhci->cmd_timer, jiffies + XHCI_CMD_DEFAULT_TIMEOUT); ++ } else if (xhci->current_cmd == cmd) { ++ xhci->current_cmd = NULL; + } + + event_handled: