From 700b5fa62a6636e66f74994aa49b1709d3d4658b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 11 Jul 2016 15:48:03 -0700 Subject: [PATCH] 4.6-stable patches added patches: autofs-braino-fix-for-do_last.patch cfg80211-fix-proto-in-ieee80211_data_to_8023-for-frames-without-llc-header.patch cfg80211-remove-get-set-antenna-and-tx-power-warnings.patch cpuidle-do-not-access-cpuidle_devices-when-config_cpu_idle.patch edac-fix-workqueues-poll-period-resetting.patch edac-sb_edac-fix-rank-lookup-on-broadwell.patch extcon-palmas-fix-boot-up-state-of-vbus-when-using-gpio-detection.patch futex-calculate-the-futex-key-based-on-a-tail-page-for-file-based-futexes.patch gpio-make-library-immune-to-error-pointers.patch gpio-sch-fix-oops-on-module-load-on-asus-eee-pc-1201.patch ib-cm-fix-a-recently-introduced-locking-bug.patch ib-core-fix-bit-curruption-in-ib_device_cap_flags-structure.patch ib-mlx4-properly-initialize-grh-tclass-and-flowlabel-in-ahs.patch ib-rdmavt-correct-qp_priv_alloc-return-value-test.patch kprobes-x86-clear-tf-bit-in-fault-on-single-stepping.patch locking-qspinlock-fix-spin_unlock_wait-some-more.patch locking-static_key-fix-concurrent-static_key_slow_inc.patch locking-ww_mutex-report-recursive-ww_mutex-locking-early.patch mac80211-fix-fast_tx-header-alignment.patch mac80211-fix-mesh-estab_plinks-counting-in-sta-removal-case.patch mac80211-mesh-flush-mesh-paths-unconditionally.patch mac80211_hwsim-add-missing-check-for-hwsim_attr_signal.patch make-nfs_atomic_open-call-d_drop-on-all-open_context-errors.patch mnt-account-for-ms_rdonly-in-fs_fully_visible.patch mnt-fs_fully_visible-test-the-proper-mount-for-mnt_locked.patch mnt-if-fs_fully_visible-fails-call-put_filesystem.patch nfs-fix-a-double-page-unlock.patch nfs-fix-another-open_downgrade-bug.patch nfsd-always-lock-state-exclusively.patch nfsd-check-permissions-when-setting-acls.patch nfsd-extend-the-mutex-holding-region-around-in-nfsd4_process_open2.patch nfsd4-rpc-move-backchannel-create-logic-into-rpc-code.patch of-fix-autoloading-due-to-broken-modalias-with-no-compatible.patch of-irq-fix-of_irq_get-kernel-doc.patch perf-x86-fix-32-bit-perf-user-callgraph-collection.patch perf-x86-intel-rapl-fix-pmus-free-during-cleanup.patch pnfs_nfs-fix-_cancel_empty_pagelist.patch powerpc-iommu-remove-the-dependency-on-eeh-struct-in-ddw-mechanism.patch powerpc-pseries-fix-ibm_arch_vec_nrcores_offset-since-power8nvl-was-added.patch powerpc-pseries-fix-pci-config-address-for-ddw.patch powerpc-tm-always-reclaim-in-start_thread-for-exec-class-syscalls.patch revert-gpiolib-split-gpio-flags-parsing-and-gpio-configuration.patch rtlwifi-fix-scheduling-while-atomic-error-from-commit-49f86ec21c01.patch sd-fix-rw_max-for-devices-that-report-an-optimal-xfer-size.patch thermal-cpu_cooling-fix-improper-order-during-initialization.patch usb-common-otg-fsm-add-license-to-usb-otg-fsm.patch usb-don-t-free-bandwidth_mutex-too-early.patch usb-dwc2-fix-regression-on-big-endian-powerpc-arm-systems.patch usb-ehci-declare-hostpc-register-as-zero-length-array.patch uvc-forward-compat-ioctls-to-their-handlers-directly.patch writeback-use-higher-precision-calculation-in-domain_dirty_limits.patch x86-amd_nb-fix-boot-crash-on-non-amd-systems.patch x86-build-copy-ldlinux.c32-to-image.iso.patch x86-msr-use-the-proper-trace-point-conditional-for-writes.patch --- queue-4.6/autofs-braino-fix-for-do_last.patch | 55 +++++ ...o_8023-for-frames-without-llc-header.patch | 45 ++++ ...et-set-antenna-and-tx-power-warnings.patch | 35 +++ ...cpuidle_devices-when-config_cpu_idle.patch | 59 +++++ ...fix-workqueues-poll-period-resetting.patch | 72 ++++++ ...sb_edac-fix-rank-lookup-on-broadwell.patch | 69 ++++++ ...te-of-vbus-when-using-gpio-detection.patch | 34 +++ ...n-a-tail-page-for-file-based-futexes.patch | 90 ++++++++ ...ake-library-immune-to-error-pointers.patch | 63 ++++++ ...s-on-module-load-on-asus-eee-pc-1201.patch | 114 ++++++++++ ...ix-a-recently-introduced-locking-bug.patch | 78 +++++++ ...ion-in-ib_device_cap_flags-structure.patch | 40 ++++ ...lize-grh-tclass-and-flowlabel-in-ahs.patch | 43 ++++ ...rect-qp_priv_alloc-return-value-test.patch | 55 +++++ ...r-tf-bit-in-fault-on-single-stepping.patch | 84 +++++++ ...nlock-fix-spin_unlock_wait-some-more.patch | 214 ++++++++++++++++++ ...y-fix-concurrent-static_key_slow_inc.patch | 169 ++++++++++++++ ...ort-recursive-ww_mutex-locking-early.patch | 60 +++++ ...ac80211-fix-fast_tx-header-alignment.patch | 34 +++ ..._plinks-counting-in-sta-removal-case.patch | 52 +++++ ...esh-flush-mesh-paths-unconditionally.patch | 155 +++++++++++++ ...-missing-check-for-hwsim_attr_signal.patch | 35 +++ ...ll-d_drop-on-all-open_context-errors.patch | 44 ++++ ...nt-for-ms_rdonly-in-fs_fully_visible.patch | 45 ++++ ...test-the-proper-mount-for-mnt_locked.patch | 37 +++ ...ly_visible-fails-call-put_filesystem.patch | 33 +++ queue-4.6/nfs-fix-a-double-page-unlock.patch | 39 ++++ .../nfs-fix-another-open_downgrade-bug.patch | 49 ++++ .../nfsd-always-lock-state-exclusively.patch | 194 ++++++++++++++++ ...-check-permissions-when-setting-acls.patch | 150 ++++++++++++ ...region-around-in-nfsd4_process_open2.patch | 77 +++++++ ...ckchannel-create-logic-into-rpc-code.patch | 101 +++++++++ ...o-broken-modalias-with-no-compatible.patch | 38 ++++ .../of-irq-fix-of_irq_get-kernel-doc.patch | 65 ++++++ ...2-bit-perf-user-callgraph-collection.patch | 115 ++++++++++ ...el-rapl-fix-pmus-free-during-cleanup.patch | 38 ++++ .../pnfs_nfs-fix-_cancel_empty_pagelist.patch | 53 +++++ ...dency-on-eeh-struct-in-ddw-mechanism.patch | 89 ++++++++ ...res_offset-since-power8nvl-was-added.patch | 42 ++++ ...eries-fix-pci-config-address-for-ddw.patch | 49 ++++ ...start_thread-for-exec-class-syscalls.patch | 110 +++++++++ ...flags-parsing-and-gpio-configuration.patch | 187 +++++++++++++++ ...tomic-error-from-commit-49f86ec21c01.patch | 70 ++++++ ...ces-that-report-an-optimal-xfer-size.patch | 58 +++++ ...improper-order-during-initialization.patch | 60 +++++ ...n-otg-fsm-add-license-to-usb-otg-fsm.patch | 36 +++ ...don-t-free-bandwidth_mutex-too-early.patch | 122 ++++++++++ ...on-on-big-endian-powerpc-arm-systems.patch | 98 ++++++++ ...hostpc-register-as-zero-length-array.patch | 41 ++++ ...at-ioctls-to-their-handlers-directly.patch | 87 +++++++ ...n-calculation-in-domain_dirty_limits.patch | 85 +++++++ ...nb-fix-boot-crash-on-non-amd-systems.patch | 51 +++++ ...-build-copy-ldlinux.c32-to-image.iso.patch | 32 +++ ...r-trace-point-conditional-for-writes.patch | 42 ++++ 54 files changed, 3992 insertions(+) create mode 100644 queue-4.6/autofs-braino-fix-for-do_last.patch create mode 100644 queue-4.6/cfg80211-fix-proto-in-ieee80211_data_to_8023-for-frames-without-llc-header.patch create mode 100644 queue-4.6/cfg80211-remove-get-set-antenna-and-tx-power-warnings.patch create mode 100644 queue-4.6/cpuidle-do-not-access-cpuidle_devices-when-config_cpu_idle.patch create mode 100644 queue-4.6/edac-fix-workqueues-poll-period-resetting.patch create mode 100644 queue-4.6/edac-sb_edac-fix-rank-lookup-on-broadwell.patch create mode 100644 queue-4.6/extcon-palmas-fix-boot-up-state-of-vbus-when-using-gpio-detection.patch create mode 100644 queue-4.6/futex-calculate-the-futex-key-based-on-a-tail-page-for-file-based-futexes.patch create mode 100644 queue-4.6/gpio-make-library-immune-to-error-pointers.patch create mode 100644 queue-4.6/gpio-sch-fix-oops-on-module-load-on-asus-eee-pc-1201.patch create mode 100644 queue-4.6/ib-cm-fix-a-recently-introduced-locking-bug.patch create mode 100644 queue-4.6/ib-core-fix-bit-curruption-in-ib_device_cap_flags-structure.patch create mode 100644 queue-4.6/ib-mlx4-properly-initialize-grh-tclass-and-flowlabel-in-ahs.patch create mode 100644 queue-4.6/ib-rdmavt-correct-qp_priv_alloc-return-value-test.patch create mode 100644 queue-4.6/kprobes-x86-clear-tf-bit-in-fault-on-single-stepping.patch create mode 100644 queue-4.6/locking-qspinlock-fix-spin_unlock_wait-some-more.patch create mode 100644 queue-4.6/locking-static_key-fix-concurrent-static_key_slow_inc.patch create mode 100644 queue-4.6/locking-ww_mutex-report-recursive-ww_mutex-locking-early.patch create mode 100644 queue-4.6/mac80211-fix-fast_tx-header-alignment.patch create mode 100644 queue-4.6/mac80211-fix-mesh-estab_plinks-counting-in-sta-removal-case.patch create mode 100644 queue-4.6/mac80211-mesh-flush-mesh-paths-unconditionally.patch create mode 100644 queue-4.6/mac80211_hwsim-add-missing-check-for-hwsim_attr_signal.patch create mode 100644 queue-4.6/make-nfs_atomic_open-call-d_drop-on-all-open_context-errors.patch create mode 100644 queue-4.6/mnt-account-for-ms_rdonly-in-fs_fully_visible.patch create mode 100644 queue-4.6/mnt-fs_fully_visible-test-the-proper-mount-for-mnt_locked.patch create mode 100644 queue-4.6/mnt-if-fs_fully_visible-fails-call-put_filesystem.patch create mode 100644 queue-4.6/nfs-fix-a-double-page-unlock.patch create mode 100644 queue-4.6/nfs-fix-another-open_downgrade-bug.patch create mode 100644 queue-4.6/nfsd-always-lock-state-exclusively.patch create mode 100644 queue-4.6/nfsd-check-permissions-when-setting-acls.patch create mode 100644 queue-4.6/nfsd-extend-the-mutex-holding-region-around-in-nfsd4_process_open2.patch create mode 100644 queue-4.6/nfsd4-rpc-move-backchannel-create-logic-into-rpc-code.patch create mode 100644 queue-4.6/of-fix-autoloading-due-to-broken-modalias-with-no-compatible.patch create mode 100644 queue-4.6/of-irq-fix-of_irq_get-kernel-doc.patch create mode 100644 queue-4.6/perf-x86-fix-32-bit-perf-user-callgraph-collection.patch create mode 100644 queue-4.6/perf-x86-intel-rapl-fix-pmus-free-during-cleanup.patch create mode 100644 queue-4.6/pnfs_nfs-fix-_cancel_empty_pagelist.patch create mode 100644 queue-4.6/powerpc-iommu-remove-the-dependency-on-eeh-struct-in-ddw-mechanism.patch create mode 100644 queue-4.6/powerpc-pseries-fix-ibm_arch_vec_nrcores_offset-since-power8nvl-was-added.patch create mode 100644 queue-4.6/powerpc-pseries-fix-pci-config-address-for-ddw.patch create mode 100644 queue-4.6/powerpc-tm-always-reclaim-in-start_thread-for-exec-class-syscalls.patch create mode 100644 queue-4.6/revert-gpiolib-split-gpio-flags-parsing-and-gpio-configuration.patch create mode 100644 queue-4.6/rtlwifi-fix-scheduling-while-atomic-error-from-commit-49f86ec21c01.patch create mode 100644 queue-4.6/sd-fix-rw_max-for-devices-that-report-an-optimal-xfer-size.patch create mode 100644 queue-4.6/thermal-cpu_cooling-fix-improper-order-during-initialization.patch create mode 100644 queue-4.6/usb-common-otg-fsm-add-license-to-usb-otg-fsm.patch create mode 100644 queue-4.6/usb-don-t-free-bandwidth_mutex-too-early.patch create mode 100644 queue-4.6/usb-dwc2-fix-regression-on-big-endian-powerpc-arm-systems.patch create mode 100644 queue-4.6/usb-ehci-declare-hostpc-register-as-zero-length-array.patch create mode 100644 queue-4.6/uvc-forward-compat-ioctls-to-their-handlers-directly.patch create mode 100644 queue-4.6/writeback-use-higher-precision-calculation-in-domain_dirty_limits.patch create mode 100644 queue-4.6/x86-amd_nb-fix-boot-crash-on-non-amd-systems.patch create mode 100644 queue-4.6/x86-build-copy-ldlinux.c32-to-image.iso.patch create mode 100644 queue-4.6/x86-msr-use-the-proper-trace-point-conditional-for-writes.patch diff --git a/queue-4.6/autofs-braino-fix-for-do_last.patch b/queue-4.6/autofs-braino-fix-for-do_last.patch new file mode 100644 index 00000000000..57837d9b252 --- /dev/null +++ b/queue-4.6/autofs-braino-fix-for-do_last.patch @@ -0,0 +1,55 @@ +From e6ec03a25f12b312b7e0c037fe4a6471c4ee5665 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Sun, 5 Jun 2016 00:23:09 -0400 +Subject: autofs braino fix for do_last() + +From: Al Viro + +commit e6ec03a25f12b312b7e0c037fe4a6471c4ee5665 upstream. + +It's an analogue of commit 7500c38a (fix the braino in "namei: +massage lookup_slow() to be usable by lookup_one_len_unlocked()"). +The same problem (->lookup()-returned unhashed negative dentry +just might be an autofs one with ->d_manage() that would wait +until the daemon makes it positive) applies in do_last() - we +need to do follow_managed() first. + +Fortunately, remaining callers of follow_managed() are OK - only +autofs has that weirdness (negative dentry that does not mean +an instant -ENOENT)) and autofs never has its negative dentries +hashed, so we can't pick one from a dcache lookup. + +->d_manage() is a bloody mess ;-/ + +Spotted-by: Ian Kent +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/namei.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -3173,6 +3173,10 @@ retry_lookup: + got_write = false; + } + ++ error = follow_managed(&path, nd); ++ if (unlikely(error < 0)) ++ return error; ++ + if (unlikely(d_is_negative(path.dentry))) { + path_to_nameidata(&path, nd); + return -ENOENT; +@@ -3188,10 +3192,6 @@ retry_lookup: + return -EEXIST; + } + +- error = follow_managed(&path, nd); +- if (unlikely(error < 0)) +- return error; +- + seq = 0; /* out of RCU mode, so the value doesn't matter */ + inode = d_backing_inode(path.dentry); + finish_lookup: diff --git a/queue-4.6/cfg80211-fix-proto-in-ieee80211_data_to_8023-for-frames-without-llc-header.patch b/queue-4.6/cfg80211-fix-proto-in-ieee80211_data_to_8023-for-frames-without-llc-header.patch new file mode 100644 index 00000000000..5d2dcca173f --- /dev/null +++ b/queue-4.6/cfg80211-fix-proto-in-ieee80211_data_to_8023-for-frames-without-llc-header.patch @@ -0,0 +1,45 @@ +From c041778c966c92c964033f1cdfee60a9f2b5e465 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Wed, 29 Jun 2016 10:36:39 +0200 +Subject: cfg80211: fix proto in ieee80211_data_to_8023 for frames without LLC header + +From: Felix Fietkau + +commit c041778c966c92c964033f1cdfee60a9f2b5e465 upstream. + +The PDU length of incoming LLC frames is set to the total skb payload size +in __ieee80211_data_to_8023() of net/wireless/util.c which incorrectly +includes the length of the IEEE 802.11 header. + +The resulting LLC frame header has a too large PDU length, causing the +llc_fixup_skb() function of net/llc/llc_input.c to reject the incoming +skb, effectively breaking STP. + +Solve the problem by properly substracting the IEEE 802.11 frame header size +from the PDU length, allowing the LLC processor to pick up the incoming +control messages. + +Special thanks to Gerry Rozema for tracking down the regression and proposing +a suitable patch. + +Fixes: 2d1c304cb2d5 ("cfg80211: add function for 802.3 conversion with separate output buffer") +Reported-by: Gerry Rozema +Signed-off-by: Felix Fietkau +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/wireless/util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -509,7 +509,7 @@ static int __ieee80211_data_to_8023(stru + * replace EtherType */ + hdrlen += ETH_ALEN + 2; + else +- tmp.h_proto = htons(skb->len); ++ tmp.h_proto = htons(skb->len - hdrlen); + + pskb_pull(skb, hdrlen); + diff --git a/queue-4.6/cfg80211-remove-get-set-antenna-and-tx-power-warnings.patch b/queue-4.6/cfg80211-remove-get-set-antenna-and-tx-power-warnings.patch new file mode 100644 index 00000000000..766ecf7141b --- /dev/null +++ b/queue-4.6/cfg80211-remove-get-set-antenna-and-tx-power-warnings.patch @@ -0,0 +1,35 @@ +From 6cbf6236d54c24b9a29e6892549c25b6902b44ce Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Thu, 9 Jun 2016 09:40:55 +0200 +Subject: cfg80211: remove get/set antenna and tx power warnings + +From: Johannes Berg + +commit 6cbf6236d54c24b9a29e6892549c25b6902b44ce upstream. + +Since set_tx_power and set_antenna are frequently implemented +without the matching get_tx_power/get_antenna, we shouldn't +have added warnings for those. Remove them. + +The remaining ones are correct and need to be implemented +symmetrically for correct operation. + +Fixes: de3bb771f471 ("cfg80211: add more warnings for inconsistent ops") +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/wireless/core.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -360,8 +360,6 @@ struct wiphy *wiphy_new_nm(const struct + WARN_ON(ops->remain_on_channel && !ops->cancel_remain_on_channel); + WARN_ON(ops->tdls_channel_switch && !ops->tdls_cancel_channel_switch); + WARN_ON(ops->add_tx_ts && !ops->del_tx_ts); +- WARN_ON(ops->set_tx_power && !ops->get_tx_power); +- WARN_ON(ops->set_antenna && !ops->get_antenna); + + alloc_size = sizeof(*rdev) + sizeof_priv; + diff --git a/queue-4.6/cpuidle-do-not-access-cpuidle_devices-when-config_cpu_idle.patch b/queue-4.6/cpuidle-do-not-access-cpuidle_devices-when-config_cpu_idle.patch new file mode 100644 index 00000000000..4b2e0cbb06e --- /dev/null +++ b/queue-4.6/cpuidle-do-not-access-cpuidle_devices-when-config_cpu_idle.patch @@ -0,0 +1,59 @@ +From 9bd616e3dbedfc103f158197c8ad93678849b1ed Mon Sep 17 00:00:00 2001 +From: Catalin Marinas +Date: Wed, 1 Jun 2016 18:52:16 +0100 +Subject: cpuidle: Do not access cpuidle_devices when !CONFIG_CPU_IDLE + +From: Catalin Marinas + +commit 9bd616e3dbedfc103f158197c8ad93678849b1ed upstream. + +The cpuidle_devices per-CPU variable is only defined when CPU_IDLE is +enabled. Commit c8cc7d4de7a4 ("sched/idle: Reorganize the idle loop") +removed the #ifdef CONFIG_CPU_IDLE around cpuidle_idle_call() with the +compiler optimising away __this_cpu_read(cpuidle_devices). However, with +CONFIG_UBSAN && !CONFIG_CPU_IDLE, this optimisation no longer happens +and the kernel fails to link since cpuidle_devices is not defined. + +This patch introduces an accessor function for the current CPU cpuidle +device (returning NULL when !CONFIG_CPU_IDLE) and uses it in +cpuidle_idle_call(). + +Signed-off-by: Catalin Marinas +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/cpuidle.h | 3 +++ + kernel/sched/idle.c | 2 +- + 2 files changed, 4 insertions(+), 1 deletion(-) + +--- a/include/linux/cpuidle.h ++++ b/include/linux/cpuidle.h +@@ -152,6 +152,8 @@ extern void cpuidle_disable_device(struc + extern int cpuidle_play_dead(void); + + extern struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev); ++static inline struct cpuidle_device *cpuidle_get_device(void) ++{return __this_cpu_read(cpuidle_devices); } + #else + static inline void disable_cpuidle(void) { } + static inline bool cpuidle_not_available(struct cpuidle_driver *drv, +@@ -187,6 +189,7 @@ static inline void cpuidle_disable_devic + static inline int cpuidle_play_dead(void) {return -ENODEV; } + static inline struct cpuidle_driver *cpuidle_get_cpu_driver( + struct cpuidle_device *dev) {return NULL; } ++static inline struct cpuidle_device *cpuidle_get_device(void) {return NULL; } + #endif + + #if defined(CONFIG_CPU_IDLE) && defined(CONFIG_SUSPEND) +--- a/kernel/sched/idle.c ++++ b/kernel/sched/idle.c +@@ -127,7 +127,7 @@ static int call_cpuidle(struct cpuidle_d + */ + static void cpuidle_idle_call(void) + { +- struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); ++ struct cpuidle_device *dev = cpuidle_get_device(); + struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); + int next_state, entered_state; + diff --git a/queue-4.6/edac-fix-workqueues-poll-period-resetting.patch b/queue-4.6/edac-fix-workqueues-poll-period-resetting.patch new file mode 100644 index 00000000000..7979ee68d80 --- /dev/null +++ b/queue-4.6/edac-fix-workqueues-poll-period-resetting.patch @@ -0,0 +1,72 @@ +From fbedcaf43fba35677c01a4ae51e6f79edf4049ba Mon Sep 17 00:00:00 2001 +From: Nicholas Krause +Date: Thu, 19 May 2016 18:45:58 -0400 +Subject: EDAC: Fix workqueues poll period resetting + +From: Nicholas Krause + +commit fbedcaf43fba35677c01a4ae51e6f79edf4049ba upstream. + +After the workqueue cleanup, we're registering workqueues based on +the presence of an ->edac_check function. When that is the case, +we're setting OP_RUNNING_POLL. But we forgot to check that in +edac_mc_reset_delay_period(), leading to: + + BUG: unable to handle kernel paging request at 0000000000015d10 + IP: [ .. ] queued_spin_lock_slowpath + PGD 3ffcc8067 PUD 3ffc56067 PMD 0 + Oops: 0002 [#1] SMP + Modules linked in: ... + CPU: 1 PID: 2792 Comm: edactest Not tainted 4.6.0-dirty #1 + Hardware name: HP ProLiant MicroServer, BIOS O41 10/01/2013 + Stack: + Call Trace: + ? _raw_spin_lock_irqsave + ? lock_timer_base.isra.34 + ? del_timer + ? try_to_grab_pending + ? mod_delayed_work_on + ? edac_mc_reset_delay_period + ? edac_set_poll_msec + ? param_attr_store + ? module_attr_store + ? kernfs_fop_write + ? __vfs_write + ? __vfs_read + ? __alloc_fd + ? vfs_write + ? SyS_write + ? entry_SYSCALL_64_fastpath + Code: + RIP [ .. ] queued_spin_lock_slowpath + RSP <> + CR2: 0000000000015d10 + ---[ end trace 3f286bc71cca15d1 ]--- + Kernel panic - not syncing: Fatal exception + +Fix it. + +Signed-off-by: Nicholas Krause +Cc: Mauro Carvalho Chehab +Cc: linux-edac +Link: http://lkml.kernel.org/r/1463697958-13406-1-git-send-email-xerofoify@gmail.com +[ Rewrite commit message. ] +Signed-off-by: Borislav Petkov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/edac/edac_mc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/edac/edac_mc.c ++++ b/drivers/edac/edac_mc.c +@@ -565,7 +565,8 @@ void edac_mc_reset_delay_period(unsigned + list_for_each(item, &mc_devices) { + mci = list_entry(item, struct mem_ctl_info, link); + +- edac_mod_work(&mci->work, value); ++ if (mci->op_state == OP_RUNNING_POLL) ++ edac_mod_work(&mci->work, value); + } + mutex_unlock(&mem_ctls_mutex); + } diff --git a/queue-4.6/edac-sb_edac-fix-rank-lookup-on-broadwell.patch b/queue-4.6/edac-sb_edac-fix-rank-lookup-on-broadwell.patch new file mode 100644 index 00000000000..15da73c7640 --- /dev/null +++ b/queue-4.6/edac-sb_edac-fix-rank-lookup-on-broadwell.patch @@ -0,0 +1,69 @@ +From c7103f650a11328f28b9fa1c95027db331b7774b Mon Sep 17 00:00:00 2001 +From: Tony Luck +Date: Tue, 31 May 2016 11:50:28 -0700 +Subject: EDAC, sb_edac: Fix rank lookup on Broadwell + +From: Tony Luck + +commit c7103f650a11328f28b9fa1c95027db331b7774b upstream. + +Broadwell made a small change to the rank target register moving the +target rank ID field up from bits 16:19 to bits 20:23. + +Also found that the offset field grew by one bit in the IVY_BRIDGE to +HASWELL transition, so fix the RIR_OFFSET() macro too. + +Signed-off-by: Tony Luck +Cc: Aristeu Rozanski +Cc: Mauro Carvalho Chehab +Cc: linux-edac +Link: http://lkml.kernel.org/r/2943fb819b1f7e396681165db9c12bb3df0e0b16.1464735623.git.tony.luck@intel.com +Signed-off-by: Borislav Petkov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/edac/sb_edac.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/drivers/edac/sb_edac.c ++++ b/drivers/edac/sb_edac.c +@@ -239,8 +239,11 @@ static const u32 rir_offset[MAX_RIR_RANG + { 0x1a0, 0x1a4, 0x1a8, 0x1ac, 0x1b0, 0x1b4, 0x1b8, 0x1bc }, + }; + +-#define RIR_RNK_TGT(reg) GET_BITFIELD(reg, 16, 19) +-#define RIR_OFFSET(reg) GET_BITFIELD(reg, 2, 14) ++#define RIR_RNK_TGT(type, reg) (((type) == BROADWELL) ? \ ++ GET_BITFIELD(reg, 20, 23) : GET_BITFIELD(reg, 16, 19)) ++ ++#define RIR_OFFSET(type, reg) (((type) == HASWELL || (type) == BROADWELL) ? \ ++ GET_BITFIELD(reg, 2, 15) : GET_BITFIELD(reg, 2, 14)) + + /* Device 16, functions 2-7 */ + +@@ -1916,14 +1919,14 @@ static void get_memory_layout(const stru + pci_read_config_dword(pvt->pci_tad[i], + rir_offset[j][k], + ®); +- tmp_mb = RIR_OFFSET(reg) << 6; ++ tmp_mb = RIR_OFFSET(pvt->info.type, reg) << 6; + + gb = div_u64_rem(tmp_mb, 1024, &mb); + edac_dbg(0, "CH#%d RIR#%d INTL#%d, offset %u.%03u GB (0x%016Lx), tgt: %d, reg=0x%08x\n", + i, j, k, + gb, (mb*1000)/1024, + ((u64)tmp_mb) << 20L, +- (u32)RIR_RNK_TGT(reg), ++ (u32)RIR_RNK_TGT(pvt->info.type, reg), + reg); + } + } +@@ -2256,7 +2259,7 @@ static int get_memory_error_data(struct + pci_read_config_dword(pvt->pci_tad[ch_add + base_ch], + rir_offset[n_rir][idx], + ®); +- *rank = RIR_RNK_TGT(reg); ++ *rank = RIR_RNK_TGT(pvt->info.type, reg); + + edac_dbg(0, "RIR#%d: channel address 0x%08Lx < 0x%08Lx, RIR interleave %d, index %d\n", + n_rir, diff --git a/queue-4.6/extcon-palmas-fix-boot-up-state-of-vbus-when-using-gpio-detection.patch b/queue-4.6/extcon-palmas-fix-boot-up-state-of-vbus-when-using-gpio-detection.patch new file mode 100644 index 00000000000..95c4ec7537d --- /dev/null +++ b/queue-4.6/extcon-palmas-fix-boot-up-state-of-vbus-when-using-gpio-detection.patch @@ -0,0 +1,34 @@ +From 62e6d1e59c77316768a663d1328390b4cd33801f Mon Sep 17 00:00:00 2001 +From: Roger Quadros +Date: Wed, 15 Jun 2016 11:12:05 +0300 +Subject: extcon: palmas: Fix boot up state of VBUS when using GPIO detection + +From: Roger Quadros + +commit 62e6d1e59c77316768a663d1328390b4cd33801f upstream. + +If USB cable is connected prior to boot, we don't get any interrupts +so we must manually check the VBUS state and report it during probe. +If we don't do it then USB controller will never know that peripheral +cable was connected till the user unplugs and replugs the cable. + +Fixes: b7aad8e2685b ("extcon: palmas: Add the support for VBUS detection by using GPIO") +Signed-off-by: Roger Quadros +Signed-off-by: Chanwoo Choi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/extcon/extcon-palmas.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/extcon/extcon-palmas.c ++++ b/drivers/extcon/extcon-palmas.c +@@ -360,6 +360,8 @@ static int palmas_usb_probe(struct platf + + palmas_enable_irq(palmas_usb); + /* perform initial detection */ ++ if (palmas_usb->enable_gpio_vbus_detection) ++ palmas_vbus_irq_handler(palmas_usb->gpio_vbus_irq, palmas_usb); + palmas_gpio_id_detect(&palmas_usb->wq_detectid.work); + device_set_wakeup_capable(&pdev->dev, true); + return 0; diff --git a/queue-4.6/futex-calculate-the-futex-key-based-on-a-tail-page-for-file-based-futexes.patch b/queue-4.6/futex-calculate-the-futex-key-based-on-a-tail-page-for-file-based-futexes.patch new file mode 100644 index 00000000000..e8406406360 --- /dev/null +++ b/queue-4.6/futex-calculate-the-futex-key-based-on-a-tail-page-for-file-based-futexes.patch @@ -0,0 +1,90 @@ +From 077fa7aed17de5022e44bf07dbaf732078b7b5b2 Mon Sep 17 00:00:00 2001 +From: Mel Gorman +Date: Wed, 8 Jun 2016 14:25:22 +0100 +Subject: futex: Calculate the futex key based on a tail page for file-based futexes + +From: Mel Gorman + +commit 077fa7aed17de5022e44bf07dbaf732078b7b5b2 upstream. + +Mike Galbraith reported that the LTP test case futex_wake04 was broken +by commit 65d8fc777f6d ("futex: Remove requirement for lock_page() +in get_futex_key()"). + +This test case uses futexes backed by hugetlbfs pages and so there is an +associated inode with a futex stored on such pages. The problem is that +the key is being calculated based on the head page index of the hugetlbfs +page and not the tail page. + +Prior to the optimisation, the page lock was used to stabilise mappings and +pin the inode is file-backed which is overkill. If the page was a compound +page, the head page was automatically looked up as part of the page lock +operation but the tail page index was used to calculate the futex key. + +After the optimisation, the compound head is looked up early and the page +lock is only relied upon to identify truncated pages, special pages or a +shmem page moving to swapcache. The head page is looked up because without +the page lock, special care has to be taken to pin the inode correctly. +However, the tail page is still required to calculate the futex key so +this patch records the tail page. + +On vanilla 4.6, the output of the test case is; + +futex_wake04 0 TINFO : Hugepagesize 2097152 +futex_wake04 1 TFAIL : futex_wake04.c:126: Bug: wait_thread2 did not wake after 30 secs. + +With the patch applied + +futex_wake04 0 TINFO : Hugepagesize 2097152 +futex_wake04 1 TPASS : Hi hydra, thread2 awake! + +Fixes: 65d8fc777f6d "futex: Remove requirement for lock_page() in get_futex_key()" +Reported-and-tested-by: Mike Galbraith +Signed-off-by: Mel Gorman +Acked-by: Peter Zijlstra (Intel) +Reviewed-by: Davidlohr Bueso +Cc: Sebastian Andrzej Siewior +Link: http://lkml.kernel.org/r/20160608132522.GM2469@suse.de +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/futex.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -469,7 +469,7 @@ get_futex_key(u32 __user *uaddr, int fsh + { + unsigned long address = (unsigned long)uaddr; + struct mm_struct *mm = current->mm; +- struct page *page; ++ struct page *page, *tail; + struct address_space *mapping; + int err, ro = 0; + +@@ -530,7 +530,15 @@ again: + * considered here and page lock forces unnecessarily serialization + * From this point on, mapping will be re-verified if necessary and + * page lock will be acquired only if it is unavoidable ++ * ++ * Mapping checks require the head page for any compound page so the ++ * head page and mapping is looked up now. For anonymous pages, it ++ * does not matter if the page splits in the future as the key is ++ * based on the address. For filesystem-backed pages, the tail is ++ * required as the index of the page determines the key. For ++ * base pages, there is no tail page and tail == page. + */ ++ tail = page; + page = compound_head(page); + mapping = READ_ONCE(page->mapping); + +@@ -654,7 +662,7 @@ again: + + key->both.offset |= FUT_OFF_INODE; /* inode-based key */ + key->shared.inode = inode; +- key->shared.pgoff = basepage_index(page); ++ key->shared.pgoff = basepage_index(tail); + rcu_read_unlock(); + } + diff --git a/queue-4.6/gpio-make-library-immune-to-error-pointers.patch b/queue-4.6/gpio-make-library-immune-to-error-pointers.patch new file mode 100644 index 00000000000..c8498c0c432 --- /dev/null +++ b/queue-4.6/gpio-make-library-immune-to-error-pointers.patch @@ -0,0 +1,63 @@ +From c0a1ecb9f4e208f4b75d88fa9669748e3fd705ab Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Thu, 16 Jun 2016 11:55:55 +0200 +Subject: gpio: make library immune to error pointers + +From: Linus Walleij + +commit c0a1ecb9f4e208f4b75d88fa9669748e3fd705ab upstream. + +Most functions that take a GPIO descriptor in need to check the +descriptor for IS_ERR(). We do this mostly in the VALIDATE_DESC() +macro except for the gpiod_to_irq() function which needs special +handling. + +Reported-by: Grygorii Strashko +Reviewed-by: Grygorii Strashko +Acked-by: Alexandre Courbot +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpio/gpiolib.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -1345,8 +1345,12 @@ done: + #define VALIDATE_DESC(desc) do { \ + if (!desc) \ + return 0; \ ++ if (IS_ERR(desc)) { \ ++ pr_warn("%s: invalid GPIO (errorpointer)\n", __func__); \ ++ return PTR_ERR(desc); \ ++ } \ + if (!desc->gdev) { \ +- pr_warn("%s: invalid GPIO\n", __func__); \ ++ pr_warn("%s: invalid GPIO (no device)\n", __func__); \ + return -EINVAL; \ + } \ + if ( !desc->gdev->chip ) { \ +@@ -1358,8 +1362,12 @@ done: + #define VALIDATE_DESC_VOID(desc) do { \ + if (!desc) \ + return; \ ++ if (IS_ERR(desc)) { \ ++ pr_warn("%s: invalid GPIO (errorpointer)\n", __func__); \ ++ return; \ ++ } \ + if (!desc->gdev) { \ +- pr_warn("%s: invalid GPIO\n", __func__); \ ++ pr_warn("%s: invalid GPIO (no device)\n", __func__); \ + return; \ + } \ + if (!desc->gdev->chip) { \ +@@ -2011,7 +2019,7 @@ int gpiod_to_irq(const struct gpio_desc + * requires this function to not return zero on an invalid descriptor + * but rather a negative error number. + */ +- if (!desc || !desc->gdev || !desc->gdev->chip) ++ if (!desc || IS_ERR(desc) || !desc->gdev || !desc->gdev->chip) + return -EINVAL; + + chip = desc->gdev->chip; diff --git a/queue-4.6/gpio-sch-fix-oops-on-module-load-on-asus-eee-pc-1201.patch b/queue-4.6/gpio-sch-fix-oops-on-module-load-on-asus-eee-pc-1201.patch new file mode 100644 index 00000000000..ce24c8bfa77 --- /dev/null +++ b/queue-4.6/gpio-sch-fix-oops-on-module-load-on-asus-eee-pc-1201.patch @@ -0,0 +1,114 @@ +From 87041a58d3b19455d39baed2a5e5bb43b58fb915 Mon Sep 17 00:00:00 2001 +From: Colin Pitrat +Date: Sat, 18 Jun 2016 19:05:04 +0100 +Subject: gpio: sch: Fix Oops on module load on Asus Eee PC 1201 + +From: Colin Pitrat + +commit 87041a58d3b19455d39baed2a5e5bb43b58fb915 upstream. + +This fixes the issue descirbe in bug 117531 +(https://bugzilla.kernel.org/show_bug.cgi?id=117531). +It's a regression introduced in linux 4.5 that causes a Oops at load of +gpio_sch and prevents powering off the computer. + +The issue is that sch_gpio_reg_set is called in sch_gpio_probe before +gpio_chip data is initialized with the pointer to the sch_gpio struct. As +sch_gpio_reg_set calls gpiochip_get_data, it returns NULL which causes +the Oops. + +The patch follows Mika's advice (https://lkml.org/lkml/2016/5/9/61) and +consists in modifying sch_gpio_reg_get and sch_gpio_reg_set to take a +sch_gpio struct directly instead of a gpio_chip, which avoids the call to +gpiochip_get_data. + +Thanks Mika for your patience with me :-) + +Signed-off-by: Colin Pitrat +Acked-by: Alexandre Courbot +Acked-by: Mika Westerberg +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpio/gpio-sch.c | 21 ++++++++++----------- + 1 file changed, 10 insertions(+), 11 deletions(-) + +--- a/drivers/gpio/gpio-sch.c ++++ b/drivers/gpio/gpio-sch.c +@@ -61,9 +61,8 @@ static unsigned sch_gpio_bit(struct sch_ + return gpio % 8; + } + +-static int sch_gpio_reg_get(struct gpio_chip *gc, unsigned gpio, unsigned reg) ++static int sch_gpio_reg_get(struct sch_gpio *sch, unsigned gpio, unsigned reg) + { +- struct sch_gpio *sch = gpiochip_get_data(gc); + unsigned short offset, bit; + u8 reg_val; + +@@ -75,10 +74,9 @@ static int sch_gpio_reg_get(struct gpio_ + return reg_val; + } + +-static void sch_gpio_reg_set(struct gpio_chip *gc, unsigned gpio, unsigned reg, ++static void sch_gpio_reg_set(struct sch_gpio *sch, unsigned gpio, unsigned reg, + int val) + { +- struct sch_gpio *sch = gpiochip_get_data(gc); + unsigned short offset, bit; + u8 reg_val; + +@@ -98,14 +96,15 @@ static int sch_gpio_direction_in(struct + struct sch_gpio *sch = gpiochip_get_data(gc); + + spin_lock(&sch->lock); +- sch_gpio_reg_set(gc, gpio_num, GIO, 1); ++ sch_gpio_reg_set(sch, gpio_num, GIO, 1); + spin_unlock(&sch->lock); + return 0; + } + + static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num) + { +- return sch_gpio_reg_get(gc, gpio_num, GLV); ++ struct sch_gpio *sch = gpiochip_get_data(gc); ++ return sch_gpio_reg_get(sch, gpio_num, GLV); + } + + static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val) +@@ -113,7 +112,7 @@ static void sch_gpio_set(struct gpio_chi + struct sch_gpio *sch = gpiochip_get_data(gc); + + spin_lock(&sch->lock); +- sch_gpio_reg_set(gc, gpio_num, GLV, val); ++ sch_gpio_reg_set(sch, gpio_num, GLV, val); + spin_unlock(&sch->lock); + } + +@@ -123,7 +122,7 @@ static int sch_gpio_direction_out(struct + struct sch_gpio *sch = gpiochip_get_data(gc); + + spin_lock(&sch->lock); +- sch_gpio_reg_set(gc, gpio_num, GIO, 0); ++ sch_gpio_reg_set(sch, gpio_num, GIO, 0); + spin_unlock(&sch->lock); + + /* +@@ -182,13 +181,13 @@ static int sch_gpio_probe(struct platfor + * GPIO7 is configured by the CMC as SLPIOVR + * Enable GPIO[9:8] core powered gpios explicitly + */ +- sch_gpio_reg_set(&sch->chip, 8, GEN, 1); +- sch_gpio_reg_set(&sch->chip, 9, GEN, 1); ++ sch_gpio_reg_set(sch, 8, GEN, 1); ++ sch_gpio_reg_set(sch, 9, GEN, 1); + /* + * SUS_GPIO[2:0] enabled by default + * Enable SUS_GPIO3 resume powered gpio explicitly + */ +- sch_gpio_reg_set(&sch->chip, 13, GEN, 1); ++ sch_gpio_reg_set(sch, 13, GEN, 1); + break; + + case PCI_DEVICE_ID_INTEL_ITC_LPC: diff --git a/queue-4.6/ib-cm-fix-a-recently-introduced-locking-bug.patch b/queue-4.6/ib-cm-fix-a-recently-introduced-locking-bug.patch new file mode 100644 index 00000000000..6b649513cdb --- /dev/null +++ b/queue-4.6/ib-cm-fix-a-recently-introduced-locking-bug.patch @@ -0,0 +1,78 @@ +From 943f44d94aa26bfdcaafc40d3701e24eeb58edce Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Fri, 25 Mar 2016 08:33:16 -0700 +Subject: IB/cm: Fix a recently introduced locking bug + +From: Bart Van Assche + +commit 943f44d94aa26bfdcaafc40d3701e24eeb58edce upstream. + +ib_cm_notify() can be called from interrupt context. Hence do not +reenable interrupts unconditionally in cm_establish(). + +This patch avoids that lockdep reports the following warning: + +WARNING: CPU: 0 PID: 23317 at kernel/locking/lockdep.c:2624 trace _hardirqs_on_caller+0x112/0x1b0 +DEBUG_LOCKS_WARN_ON(current->hardirq_context) +Call Trace: + [] dump_stack+0x67/0x92 + [] __warn+0xc1/0xe0 + [] warn_slowpath_fmt+0x4a/0x50 + [] trace_hardirqs_on_caller+0x112/0x1b0 + [] trace_hardirqs_on+0xd/0x10 + [] _raw_spin_unlock_irq+0x27/0x40 + [] ib_cm_notify+0x25c/0x290 [ib_cm] + [] srpt_qp_event+0xa1/0xf0 [ib_srpt] + [] mlx4_ib_qp_event+0x67/0xd0 [mlx4_ib] + [] mlx4_qp_event+0x5a/0xc0 [mlx4_core] + [] mlx4_eq_int+0x3d8/0xcf0 [mlx4_core] + [] mlx4_msi_x_interrupt+0xc/0x20 [mlx4_core] + [] handle_irq_event_percpu+0x64/0x100 + [] handle_irq_event+0x34/0x60 + [] handle_edge_irq+0x6a/0x150 + [] handle_irq+0x15/0x20 + [] do_IRQ+0x5c/0x110 + [] common_interrupt+0x89/0x89 + [] blk_run_queue_async+0x37/0x40 + [] rq_completed+0x43/0x70 [dm_mod] + [] dm_softirq_done+0x176/0x280 [dm_mod] + [] blk_done_softirq+0x52/0x90 + [] __do_softirq+0x10f/0x230 + [] irq_exit+0xa8/0xb0 + [] smp_trace_call_function_single_interrupt+0x2e/0x30 + [] smp_call_function_single_interrupt+0x9/0x10 + [] call_function_single_interrupt+0x89/0x90 + + +Fixes: commit be4b499323bf (IB/cm: Do not queue work to a device that's going away) +Signed-off-by: Bart Van Assche +Cc: Erez Shitrit +Cc: Sean Hefty +Cc: Nikolay Borisov +Acked-by: Erez Shitrit +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/cm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/core/cm.c ++++ b/drivers/infiniband/core/cm.c +@@ -3452,14 +3452,14 @@ static int cm_establish(struct ib_cm_id + work->cm_event.event = IB_CM_USER_ESTABLISHED; + + /* Check if the device started its remove_one */ +- spin_lock_irq(&cm.lock); ++ spin_lock_irqsave(&cm.lock, flags); + if (!cm_dev->going_down) { + queue_delayed_work(cm.wq, &work->work, 0); + } else { + kfree(work); + ret = -ENODEV; + } +- spin_unlock_irq(&cm.lock); ++ spin_unlock_irqrestore(&cm.lock, flags); + + out: + return ret; diff --git a/queue-4.6/ib-core-fix-bit-curruption-in-ib_device_cap_flags-structure.patch b/queue-4.6/ib-core-fix-bit-curruption-in-ib_device_cap_flags-structure.patch new file mode 100644 index 00000000000..cbb2d67411c --- /dev/null +++ b/queue-4.6/ib-core-fix-bit-curruption-in-ib_device_cap_flags-structure.patch @@ -0,0 +1,40 @@ +From 47355b3cd7d3c9c5226bff7c449b9d269fb17fa6 Mon Sep 17 00:00:00 2001 +From: Max Gurtovoy +Date: Mon, 6 Jun 2016 19:34:39 +0300 +Subject: IB/core: Fix bit curruption in ib_device_cap_flags structure + +From: Max Gurtovoy + +commit 47355b3cd7d3c9c5226bff7c449b9d269fb17fa6 upstream. + +ib_device_cap_flags 64-bit expansion caused caps overlapping +and made consumers read wrong device capabilities. For example +IB_DEVICE_SG_GAPS_REG was falsely read by the iser driver causing +it to use a non-existing capability. This happened because signed +int becomes sign extended when converted it to u64. Fix this by +casting IB_DEVICE_ON_DEMAND_PAGING enumeration to ULL. + +Fixes: f5aa9159a418 ('IB/core: Add arbitrary sg_list support') +Reported-by: Robert LeBlanc +Acked-by: Sagi Grimberg +Signed-off-by: Max Gurtovoy +Signed-off-by: Matan Barak +Reviewed-by: Christoph Hellwig +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + include/rdma/ib_verbs.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/rdma/ib_verbs.h ++++ b/include/rdma/ib_verbs.h +@@ -217,7 +217,7 @@ enum ib_device_cap_flags { + IB_DEVICE_CROSS_CHANNEL = (1 << 27), + IB_DEVICE_MANAGED_FLOW_STEERING = (1 << 29), + IB_DEVICE_SIGNATURE_HANDOVER = (1 << 30), +- IB_DEVICE_ON_DEMAND_PAGING = (1 << 31), ++ IB_DEVICE_ON_DEMAND_PAGING = (1ULL << 31), + IB_DEVICE_SG_GAPS_REG = (1ULL << 32), + IB_DEVICE_VIRTUAL_FUNCTION = ((u64)1 << 33), + }; diff --git a/queue-4.6/ib-mlx4-properly-initialize-grh-tclass-and-flowlabel-in-ahs.patch b/queue-4.6/ib-mlx4-properly-initialize-grh-tclass-and-flowlabel-in-ahs.patch new file mode 100644 index 00000000000..b6d2e96ea41 --- /dev/null +++ b/queue-4.6/ib-mlx4-properly-initialize-grh-tclass-and-flowlabel-in-ahs.patch @@ -0,0 +1,43 @@ +From 8c5122e45a10a9262f872b53f151a592e870f905 Mon Sep 17 00:00:00 2001 +From: Jason Gunthorpe +Date: Wed, 8 Jun 2016 17:28:29 -0600 +Subject: IB/mlx4: Properly initialize GRH TClass and FlowLabel in AHs + +From: Jason Gunthorpe + +commit 8c5122e45a10a9262f872b53f151a592e870f905 upstream. + +When this code was reworked for IBoE support the order of assignments +for the sl_tclass_flowlabel got flipped around resulting in +TClass & FlowLabel being permanently set to 0 in the packet headers. + +This breaks IB routers that rely on these headers, but only affects +kernel users - libmlx4 does this properly for user space. + +Fixes: fa417f7b520e ("IB/mlx4: Add support for IBoE") +Signed-off-by: Jason Gunthorpe +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx4/ah.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/infiniband/hw/mlx4/ah.c ++++ b/drivers/infiniband/hw/mlx4/ah.c +@@ -47,6 +47,7 @@ static struct ib_ah *create_ib_ah(struct + + ah->av.ib.port_pd = cpu_to_be32(to_mpd(pd)->pdn | (ah_attr->port_num << 24)); + ah->av.ib.g_slid = ah_attr->src_path_bits; ++ ah->av.ib.sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 28); + if (ah_attr->ah_flags & IB_AH_GRH) { + ah->av.ib.g_slid |= 0x80; + ah->av.ib.gid_index = ah_attr->grh.sgid_index; +@@ -64,7 +65,6 @@ static struct ib_ah *create_ib_ah(struct + !(1 << ah->av.ib.stat_rate & dev->caps.stat_rate_support)) + --ah->av.ib.stat_rate; + } +- ah->av.ib.sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 28); + + return &ah->ibah; + } diff --git a/queue-4.6/ib-rdmavt-correct-qp_priv_alloc-return-value-test.patch b/queue-4.6/ib-rdmavt-correct-qp_priv_alloc-return-value-test.patch new file mode 100644 index 00000000000..fb0c7ca06bb --- /dev/null +++ b/queue-4.6/ib-rdmavt-correct-qp_priv_alloc-return-value-test.patch @@ -0,0 +1,55 @@ +From c755f4afa66ad3ed98870bd3254f37c47fb2c800 Mon Sep 17 00:00:00 2001 +From: Mike Marciniszyn +Date: Wed, 22 Jun 2016 13:29:33 -0700 +Subject: IB/rdmavt: Correct qp_priv_alloc() return value test + +From: Mike Marciniszyn + +commit c755f4afa66ad3ed98870bd3254f37c47fb2c800 upstream. + +The current drivers return errors from this calldown +wrapped in an ERR_PTR(). + +The rdmavt code incorrectly tests for NULL. + +The code is fixed to use IS_ERR() and change ret according +to the driver return value. + +Reviewed-by: Dennis Dalessandro +Signed-off-by: Mike Marciniszyn +Signed-off-by: Dennis Dalessandro +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/sw/rdmavt/qp.c | 4 +++- + include/rdma/rdma_vt.h | 4 +++- + 2 files changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/sw/rdmavt/qp.c ++++ b/drivers/infiniband/sw/rdmavt/qp.c +@@ -683,8 +683,10 @@ struct ib_qp *rvt_create_qp(struct ib_pd + * initialization that is needed. + */ + priv = rdi->driver_f.qp_priv_alloc(rdi, qp, gfp); +- if (!priv) ++ if (IS_ERR(priv)) { ++ ret = priv; + goto bail_qp; ++ } + qp->priv = priv; + qp->timeout_jiffies = + usecs_to_jiffies((4096UL * (1UL << qp->timeout)) / +--- a/include/rdma/rdma_vt.h ++++ b/include/rdma/rdma_vt.h +@@ -203,7 +203,9 @@ struct rvt_driver_provided { + + /* + * Allocate a private queue pair data structure for driver specific +- * information which is opaque to rdmavt. ++ * information which is opaque to rdmavt. Errors are returned via ++ * ERR_PTR(err). The driver is free to return NULL or a valid ++ * pointer. + */ + void * (*qp_priv_alloc)(struct rvt_dev_info *rdi, struct rvt_qp *qp, + gfp_t gfp); diff --git a/queue-4.6/kprobes-x86-clear-tf-bit-in-fault-on-single-stepping.patch b/queue-4.6/kprobes-x86-clear-tf-bit-in-fault-on-single-stepping.patch new file mode 100644 index 00000000000..d0b028dd334 --- /dev/null +++ b/queue-4.6/kprobes-x86-clear-tf-bit-in-fault-on-single-stepping.patch @@ -0,0 +1,84 @@ +From dcfc47248d3f7d28df6f531e6426b933de94370d Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu +Date: Sat, 11 Jun 2016 23:06:53 +0900 +Subject: kprobes/x86: Clear TF bit in fault on single-stepping + +From: Masami Hiramatsu + +commit dcfc47248d3f7d28df6f531e6426b933de94370d upstream. + +Fix kprobe_fault_handler() to clear the TF (trap flag) bit of +the flags register in the case of a fault fixup on single-stepping. + +If we put a kprobe on the instruction which caused a +page fault (e.g. actual mov instructions in copy_user_*), +that fault happens on the single-stepping buffer. In this +case, kprobes resets running instance so that the CPU can +retry execution on the original ip address. + +However, current code forgets to reset the TF bit. Since this +fault happens with TF bit set for enabling single-stepping, +when it retries, it causes a debug exception and kprobes +can not handle it because it already reset itself. + +On the most of x86-64 platform, it can be easily reproduced +by using kprobe tracer. E.g. + + # cd /sys/kernel/debug/tracing + # echo p copy_user_enhanced_fast_string+5 > kprobe_events + # echo 1 > events/kprobes/enable + +And you'll see a kernel panic on do_debug(), since the debug +trap is not handled by kprobes. + +To fix this problem, we just need to clear the TF bit when +resetting running kprobe. + +Signed-off-by: Masami Hiramatsu +Reviewed-by: Ananth N Mavinakayanahalli +Acked-by: Steven Rostedt +Cc: Alexander Shishkin +Cc: Andy Lutomirski +Cc: Arnaldo Carvalho de Melo +Cc: Borislav Petkov +Cc: Brian Gerst +Cc: Denys Vlasenko +Cc: H. Peter Anvin +Cc: Jiri Olsa +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Stephane Eranian +Cc: Thomas Gleixner +Cc: Vince Weaver +Cc: systemtap@sourceware.org +Link: http://lkml.kernel.org/r/20160611140648.25885.37482.stgit@devbox +[ Updated the comments. ] +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/kprobes/core.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/arch/x86/kernel/kprobes/core.c ++++ b/arch/x86/kernel/kprobes/core.c +@@ -960,7 +960,19 @@ int kprobe_fault_handler(struct pt_regs + * normal page fault. + */ + regs->ip = (unsigned long)cur->addr; ++ /* ++ * Trap flag (TF) has been set here because this fault ++ * happened where the single stepping will be done. ++ * So clear it by resetting the current kprobe: ++ */ ++ regs->flags &= ~X86_EFLAGS_TF; ++ ++ /* ++ * If the TF flag was set before the kprobe hit, ++ * don't touch it: ++ */ + regs->flags |= kcb->kprobe_old_flags; ++ + if (kcb->kprobe_status == KPROBE_REENTER) + restore_previous_kprobe(kcb); + else diff --git a/queue-4.6/locking-qspinlock-fix-spin_unlock_wait-some-more.patch b/queue-4.6/locking-qspinlock-fix-spin_unlock_wait-some-more.patch new file mode 100644 index 00000000000..eb1533153c4 --- /dev/null +++ b/queue-4.6/locking-qspinlock-fix-spin_unlock_wait-some-more.patch @@ -0,0 +1,214 @@ +From 2c610022711675ee908b903d242f0b90e1db661f Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Wed, 8 Jun 2016 10:19:51 +0200 +Subject: locking/qspinlock: Fix spin_unlock_wait() some more + +From: Peter Zijlstra + +commit 2c610022711675ee908b903d242f0b90e1db661f upstream. + +While this prior commit: + + 54cf809b9512 ("locking,qspinlock: Fix spin_is_locked() and spin_unlock_wait()") + +... fixes spin_is_locked() and spin_unlock_wait() for the usage +in ipc/sem and netfilter, it does not in fact work right for the +usage in task_work and futex. + +So while the 2 locks crossed problem: + + spin_lock(A) spin_lock(B) + if (!spin_is_locked(B)) spin_unlock_wait(A) + foo() foo(); + +... works with the smp_mb() injected by both spin_is_locked() and +spin_unlock_wait(), this is not sufficient for: + + flag = 1; + smp_mb(); spin_lock() + spin_unlock_wait() if (!flag) + // add to lockless list + // iterate lockless list + +... because in this scenario, the store from spin_lock() can be delayed +past the load of flag, uncrossing the variables and loosing the +guarantee. + +This patch reworks spin_is_locked() and spin_unlock_wait() to work in +both cases by exploiting the observation that while the lock byte +store can be delayed, the contender must have registered itself +visibly in other state contained in the word. + +It also allows for architectures to override both functions, as PPC +and ARM64 have an additional issue for which we currently have no +generic solution. + +Signed-off-by: Peter Zijlstra (Intel) +Cc: Andrew Morton +Cc: Boqun Feng +Cc: Davidlohr Bueso +Cc: Giovanni Gherdovich +Cc: Linus Torvalds +Cc: Pan Xinhui +Cc: Paul E. McKenney +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: Waiman Long +Cc: Will Deacon +Fixes: 54cf809b9512 ("locking,qspinlock: Fix spin_is_locked() and spin_unlock_wait()") +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + include/asm-generic/qspinlock.h | 53 +++++++++++------------------------ + kernel/locking/qspinlock.c | 60 ++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 77 insertions(+), 36 deletions(-) + +--- a/include/asm-generic/qspinlock.h ++++ b/include/asm-generic/qspinlock.h +@@ -22,37 +22,33 @@ + #include + + /** ++ * queued_spin_unlock_wait - wait until the _current_ lock holder releases the lock ++ * @lock : Pointer to queued spinlock structure ++ * ++ * There is a very slight possibility of live-lock if the lockers keep coming ++ * and the waiter is just unfortunate enough to not see any unlock state. ++ */ ++#ifndef queued_spin_unlock_wait ++extern void queued_spin_unlock_wait(struct qspinlock *lock); ++#endif ++ ++/** + * queued_spin_is_locked - is the spinlock locked? + * @lock: Pointer to queued spinlock structure + * Return: 1 if it is locked, 0 otherwise + */ ++#ifndef queued_spin_is_locked + static __always_inline int queued_spin_is_locked(struct qspinlock *lock) + { + /* +- * queued_spin_lock_slowpath() can ACQUIRE the lock before +- * issuing the unordered store that sets _Q_LOCKED_VAL. +- * +- * See both smp_cond_acquire() sites for more detail. +- * +- * This however means that in code like: +- * +- * spin_lock(A) spin_lock(B) +- * spin_unlock_wait(B) spin_is_locked(A) +- * do_something() do_something() +- * +- * Both CPUs can end up running do_something() because the store +- * setting _Q_LOCKED_VAL will pass through the loads in +- * spin_unlock_wait() and/or spin_is_locked(). ++ * See queued_spin_unlock_wait(). + * +- * Avoid this by issuing a full memory barrier between the spin_lock() +- * and the loads in spin_unlock_wait() and spin_is_locked(). +- * +- * Note that regular mutual exclusion doesn't care about this +- * delayed store. ++ * Any !0 state indicates it is locked, even if _Q_LOCKED_VAL ++ * isn't immediately observable. + */ +- smp_mb(); +- return atomic_read(&lock->val) & _Q_LOCKED_MASK; ++ return atomic_read(&lock->val); + } ++#endif + + /** + * queued_spin_value_unlocked - is the spinlock structure unlocked? +@@ -122,21 +118,6 @@ static __always_inline void queued_spin_ + } + #endif + +-/** +- * queued_spin_unlock_wait - wait until current lock holder releases the lock +- * @lock : Pointer to queued spinlock structure +- * +- * There is a very slight possibility of live-lock if the lockers keep coming +- * and the waiter is just unfortunate enough to not see any unlock state. +- */ +-static inline void queued_spin_unlock_wait(struct qspinlock *lock) +-{ +- /* See queued_spin_is_locked() */ +- smp_mb(); +- while (atomic_read(&lock->val) & _Q_LOCKED_MASK) +- cpu_relax(); +-} +- + #ifndef virt_spin_lock + static __always_inline bool virt_spin_lock(struct qspinlock *lock) + { +--- a/kernel/locking/qspinlock.c ++++ b/kernel/locking/qspinlock.c +@@ -267,6 +267,66 @@ static __always_inline u32 __pv_wait_he + #define queued_spin_lock_slowpath native_queued_spin_lock_slowpath + #endif + ++/* ++ * queued_spin_lock_slowpath() can (load-)ACQUIRE the lock before ++ * issuing an _unordered_ store to set _Q_LOCKED_VAL. ++ * ++ * This means that the store can be delayed, but no later than the ++ * store-release from the unlock. This means that simply observing ++ * _Q_LOCKED_VAL is not sufficient to determine if the lock is acquired. ++ * ++ * There are two paths that can issue the unordered store: ++ * ++ * (1) clear_pending_set_locked(): *,1,0 -> *,0,1 ++ * ++ * (2) set_locked(): t,0,0 -> t,0,1 ; t != 0 ++ * atomic_cmpxchg_relaxed(): t,0,0 -> 0,0,1 ++ * ++ * However, in both cases we have other !0 state we've set before to queue ++ * ourseves: ++ * ++ * For (1) we have the atomic_cmpxchg_acquire() that set _Q_PENDING_VAL, our ++ * load is constrained by that ACQUIRE to not pass before that, and thus must ++ * observe the store. ++ * ++ * For (2) we have a more intersting scenario. We enqueue ourselves using ++ * xchg_tail(), which ends up being a RELEASE. This in itself is not ++ * sufficient, however that is followed by an smp_cond_acquire() on the same ++ * word, giving a RELEASE->ACQUIRE ordering. This again constrains our load and ++ * guarantees we must observe that store. ++ * ++ * Therefore both cases have other !0 state that is observable before the ++ * unordered locked byte store comes through. This means we can use that to ++ * wait for the lock store, and then wait for an unlock. ++ */ ++#ifndef queued_spin_unlock_wait ++void queued_spin_unlock_wait(struct qspinlock *lock) ++{ ++ u32 val; ++ ++ for (;;) { ++ val = atomic_read(&lock->val); ++ ++ if (!val) /* not locked, we're done */ ++ goto done; ++ ++ if (val & _Q_LOCKED_MASK) /* locked, go wait for unlock */ ++ break; ++ ++ /* not locked, but pending, wait until we observe the lock */ ++ cpu_relax(); ++ } ++ ++ /* any unlock is good */ ++ while (atomic_read(&lock->val) & _Q_LOCKED_MASK) ++ cpu_relax(); ++ ++done: ++ smp_rmb(); /* CTRL + RMB -> ACQUIRE */ ++} ++EXPORT_SYMBOL(queued_spin_unlock_wait); ++#endif ++ + #endif /* _GEN_PV_LOCK_SLOWPATH */ + + /** diff --git a/queue-4.6/locking-static_key-fix-concurrent-static_key_slow_inc.patch b/queue-4.6/locking-static_key-fix-concurrent-static_key_slow_inc.patch new file mode 100644 index 00000000000..192501ecff9 --- /dev/null +++ b/queue-4.6/locking-static_key-fix-concurrent-static_key_slow_inc.patch @@ -0,0 +1,169 @@ +From 4c5ea0a9cd02d6aa8adc86e100b2a4cff8d614ff Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Tue, 21 Jun 2016 18:52:17 +0200 +Subject: locking/static_key: Fix concurrent static_key_slow_inc() + +From: Paolo Bonzini + +commit 4c5ea0a9cd02d6aa8adc86e100b2a4cff8d614ff upstream. + +The following scenario is possible: + + CPU 1 CPU 2 + static_key_slow_inc() + atomic_inc_not_zero() + -> key.enabled == 0, no increment + jump_label_lock() + atomic_inc_return() + -> key.enabled == 1 now + static_key_slow_inc() + atomic_inc_not_zero() + -> key.enabled == 1, inc to 2 + return + ** static key is wrong! + jump_label_update() + jump_label_unlock() + +Testing the static key at the point marked by (**) will follow the +wrong path for jumps that have not been patched yet. This can +actually happen when creating many KVM virtual machines with userspace +LAPIC emulation; just run several copies of the following program: + + #include + #include + #include + #include + + int main(void) + { + for (;;) { + int kvmfd = open("/dev/kvm", O_RDONLY); + int vmfd = ioctl(kvmfd, KVM_CREATE_VM, 0); + close(ioctl(vmfd, KVM_CREATE_VCPU, 1)); + close(vmfd); + close(kvmfd); + } + return 0; + } + +Every KVM_CREATE_VCPU ioctl will attempt a static_key_slow_inc() call. +The static key's purpose is to skip NULL pointer checks and indeed one +of the processes eventually dereferences NULL. + +As explained in the commit that introduced the bug: + + 706249c222f6 ("locking/static_keys: Rework update logic") + +jump_label_update() needs key.enabled to be true. The solution adopted +here is to temporarily make key.enabled == -1, and use go down the +slow path when key.enabled <= 0. + +Reported-by: Dmitry Vyukov +Signed-off-by: Paolo Bonzini +Signed-off-by: Peter Zijlstra (Intel) +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Fixes: 706249c222f6 ("locking/static_keys: Rework update logic") +Link: http://lkml.kernel.org/r/1466527937-69798-1-git-send-email-pbonzini@redhat.com +[ Small stylistic edits to the changelog and the code. ] +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/jump_label.h | 16 +++++++++++++--- + kernel/jump_label.c | 36 +++++++++++++++++++++++++++++++++--- + 2 files changed, 46 insertions(+), 6 deletions(-) + +--- a/include/linux/jump_label.h ++++ b/include/linux/jump_label.h +@@ -117,13 +117,18 @@ struct module; + + #include + ++#ifdef HAVE_JUMP_LABEL ++ + static inline int static_key_count(struct static_key *key) + { +- return atomic_read(&key->enabled); ++ /* ++ * -1 means the first static_key_slow_inc() is in progress. ++ * static_key_enabled() must return true, so return 1 here. ++ */ ++ int n = atomic_read(&key->enabled); ++ return n >= 0 ? n : 1; + } + +-#ifdef HAVE_JUMP_LABEL +- + #define JUMP_TYPE_FALSE 0UL + #define JUMP_TYPE_TRUE 1UL + #define JUMP_TYPE_MASK 1UL +@@ -162,6 +167,11 @@ extern void jump_label_apply_nops(struct + + #else /* !HAVE_JUMP_LABEL */ + ++static inline int static_key_count(struct static_key *key) ++{ ++ return atomic_read(&key->enabled); ++} ++ + static __always_inline void jump_label_init(void) + { + static_key_initialized = true; +--- a/kernel/jump_label.c ++++ b/kernel/jump_label.c +@@ -58,13 +58,36 @@ static void jump_label_update(struct sta + + void static_key_slow_inc(struct static_key *key) + { ++ int v, v1; ++ + STATIC_KEY_CHECK_USE(); +- if (atomic_inc_not_zero(&key->enabled)) +- return; ++ ++ /* ++ * Careful if we get concurrent static_key_slow_inc() calls; ++ * later calls must wait for the first one to _finish_ the ++ * jump_label_update() process. At the same time, however, ++ * the jump_label_update() call below wants to see ++ * static_key_enabled(&key) for jumps to be updated properly. ++ * ++ * So give a special meaning to negative key->enabled: it sends ++ * static_key_slow_inc() down the slow path, and it is non-zero ++ * so it counts as "enabled" in jump_label_update(). Note that ++ * atomic_inc_unless_negative() checks >= 0, so roll our own. ++ */ ++ for (v = atomic_read(&key->enabled); v > 0; v = v1) { ++ v1 = atomic_cmpxchg(&key->enabled, v, v + 1); ++ if (likely(v1 == v)) ++ return; ++ } + + jump_label_lock(); +- if (atomic_inc_return(&key->enabled) == 1) ++ if (atomic_read(&key->enabled) == 0) { ++ atomic_set(&key->enabled, -1); + jump_label_update(key); ++ atomic_set(&key->enabled, 1); ++ } else { ++ atomic_inc(&key->enabled); ++ } + jump_label_unlock(); + } + EXPORT_SYMBOL_GPL(static_key_slow_inc); +@@ -72,6 +95,13 @@ EXPORT_SYMBOL_GPL(static_key_slow_inc); + static void __static_key_slow_dec(struct static_key *key, + unsigned long rate_limit, struct delayed_work *work) + { ++ /* ++ * The negative count check is valid even when a negative ++ * key->enabled is in use by static_key_slow_inc(); a ++ * __static_key_slow_dec() before the first static_key_slow_inc() ++ * returns is unbalanced, because all other static_key_slow_inc() ++ * instances block while the update is in progress. ++ */ + if (!atomic_dec_and_mutex_lock(&key->enabled, &jump_label_mutex)) { + WARN(atomic_read(&key->enabled) < 0, + "jump label: negative count!\n"); diff --git a/queue-4.6/locking-ww_mutex-report-recursive-ww_mutex-locking-early.patch b/queue-4.6/locking-ww_mutex-report-recursive-ww_mutex-locking-early.patch new file mode 100644 index 00000000000..01ab60cfa0c --- /dev/null +++ b/queue-4.6/locking-ww_mutex-report-recursive-ww_mutex-locking-early.patch @@ -0,0 +1,60 @@ +From 0422e83d84ae24b933e4b0d4c1e0f0b4ae8a0a3b Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Thu, 26 May 2016 21:08:17 +0100 +Subject: locking/ww_mutex: Report recursive ww_mutex locking early + +From: Chris Wilson + +commit 0422e83d84ae24b933e4b0d4c1e0f0b4ae8a0a3b upstream. + +Recursive locking for ww_mutexes was originally conceived as an +exception. However, it is heavily used by the DRM atomic modesetting +code. Currently, the recursive deadlock is checked after we have queued +up for a busy-spin and as we never release the lock, we spin until +kicked, whereupon the deadlock is discovered and reported. + +A simple solution for the now common problem is to move the recursive +deadlock discovery to the first action when taking the ww_mutex. + +Suggested-by: Maarten Lankhorst +Signed-off-by: Chris Wilson +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Maarten Lankhorst +Cc: Andrew Morton +Cc: Linus Torvalds +Cc: Paul E. McKenney +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Link: http://lkml.kernel.org/r/1464293297-19777-1-git-send-email-chris@chris-wilson.co.uk +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/locking/mutex.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/kernel/locking/mutex.c ++++ b/kernel/locking/mutex.c +@@ -486,9 +486,6 @@ __ww_mutex_lock_check_stamp(struct mutex + if (!hold_ctx) + return 0; + +- if (unlikely(ctx == hold_ctx)) +- return -EALREADY; +- + if (ctx->stamp - hold_ctx->stamp <= LONG_MAX && + (ctx->stamp != hold_ctx->stamp || ctx > hold_ctx)) { + #ifdef CONFIG_DEBUG_MUTEXES +@@ -514,6 +511,12 @@ __mutex_lock_common(struct mutex *lock, + unsigned long flags; + int ret; + ++ if (use_ww_ctx) { ++ struct ww_mutex *ww = container_of(lock, struct ww_mutex, base); ++ if (unlikely(ww_ctx == READ_ONCE(ww->ctx))) ++ return -EALREADY; ++ } ++ + preempt_disable(); + mutex_acquire_nest(&lock->dep_map, subclass, 0, nest_lock, ip); + diff --git a/queue-4.6/mac80211-fix-fast_tx-header-alignment.patch b/queue-4.6/mac80211-fix-fast_tx-header-alignment.patch new file mode 100644 index 00000000000..6ca8f894c1e --- /dev/null +++ b/queue-4.6/mac80211-fix-fast_tx-header-alignment.patch @@ -0,0 +1,34 @@ +From 6fe04128f158c5ad27e7504bfdf1b12e63331bc9 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Thu, 19 May 2016 17:34:38 +0200 +Subject: mac80211: fix fast_tx header alignment + +From: Felix Fietkau + +commit 6fe04128f158c5ad27e7504bfdf1b12e63331bc9 upstream. + +The header field is defined as u8[] but also accessed as struct +ieee80211_hdr. Enforce an alignment of 2 to prevent unnecessary +unaligned accesses, which can be very harmful for performance on many +platforms. + +Fixes: e495c24731a2 ("mac80211: extend fast-xmit for more ciphers") +Signed-off-by: Felix Fietkau +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/sta_info.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -275,7 +275,7 @@ struct ieee80211_fast_tx { + u8 sa_offs, da_offs, pn_offs; + u8 band; + u8 hdr[30 + 2 + IEEE80211_FAST_XMIT_MAX_IV + +- sizeof(rfc1042_header)]; ++ sizeof(rfc1042_header)] __aligned(2); + + struct rcu_head rcu_head; + }; diff --git a/queue-4.6/mac80211-fix-mesh-estab_plinks-counting-in-sta-removal-case.patch b/queue-4.6/mac80211-fix-mesh-estab_plinks-counting-in-sta-removal-case.patch new file mode 100644 index 00000000000..7cb12382a50 --- /dev/null +++ b/queue-4.6/mac80211-fix-mesh-estab_plinks-counting-in-sta-removal-case.patch @@ -0,0 +1,52 @@ +From 126e7557328a1cd576be4fca95b133a2695283ff Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Sun, 19 Jun 2016 23:51:02 +0300 +Subject: mac80211: Fix mesh estab_plinks counting in STA removal case + +From: Jouni Malinen + +commit 126e7557328a1cd576be4fca95b133a2695283ff upstream. + +If a user space program (e.g., wpa_supplicant) deletes a STA entry that +is currently in NL80211_PLINK_ESTAB state, the number of established +plinks counter was not decremented and this could result in rejecting +new plink establishment before really hitting the real maximum plink +limit. For !user_mpm case, this decrementation is handled by +mesh_plink_deactive(). + +Fix this by decrementing estab_plinks on STA deletion +(mesh_sta_cleanup() gets called from there) so that the counter has a +correct value and the Beacon frame advertisement in Mesh Configuration +element shows the proper value for capability to accept additional +peers. + +Signed-off-by: Jouni Malinen +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/mesh.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -150,14 +150,17 @@ u32 mesh_accept_plinks_update(struct iee + void mesh_sta_cleanup(struct sta_info *sta) + { + struct ieee80211_sub_if_data *sdata = sta->sdata; +- u32 changed; ++ u32 changed = 0; + + /* + * maybe userspace handles peer allocation and peering, but in either + * case the beacon is still generated by the kernel and we might need + * an update. + */ +- changed = mesh_accept_plinks_update(sdata); ++ if (sdata->u.mesh.user_mpm && ++ sta->mesh->plink_state == NL80211_PLINK_ESTAB) ++ changed |= mesh_plink_dec_estab_count(sdata); ++ changed |= mesh_accept_plinks_update(sdata); + if (!sdata->u.mesh.user_mpm) { + changed |= mesh_plink_deactivate(sta); + del_timer_sync(&sta->mesh->plink_timer); diff --git a/queue-4.6/mac80211-mesh-flush-mesh-paths-unconditionally.patch b/queue-4.6/mac80211-mesh-flush-mesh-paths-unconditionally.patch new file mode 100644 index 00000000000..cba10484468 --- /dev/null +++ b/queue-4.6/mac80211-mesh-flush-mesh-paths-unconditionally.patch @@ -0,0 +1,155 @@ +From fe7a7c57629e8dcbc0e297363a9b2366d67a6dc5 Mon Sep 17 00:00:00 2001 +From: Bob Copeland +Date: Sun, 15 May 2016 13:19:16 -0400 +Subject: mac80211: mesh: flush mesh paths unconditionally + +From: Bob Copeland + +commit fe7a7c57629e8dcbc0e297363a9b2366d67a6dc5 upstream. + +Currently, the mesh paths associated with a nexthop station are cleaned +up in the following code path: + + __sta_info_destroy_part1 + synchronize_net() + __sta_info_destroy_part2 + -> cleanup_single_sta + -> mesh_sta_cleanup + -> mesh_plink_deactivate + -> mesh_path_flush_by_nexthop + +However, there are a couple of problems here: + +1) the paths aren't flushed at all if the MPM is running in userspace + (e.g. when using wpa_supplicant or authsae) + +2) there is no synchronize_rcu between removing the path and readers + accessing the nexthop, which means the following race is possible: + +CPU0 CPU1 +~~~~ ~~~~ + sta_info_destroy_part1() + synchronize_net() +rcu_read_lock() +mesh_nexthop_resolve() + mpath = mesh_path_lookup() + [...] -> mesh_path_flush_by_nexthop() + sta = rcu_dereference( + mpath->next_hop) + kfree(sta) + access sta <-- CRASH + +Fix both of these by unconditionally flushing paths before destroying +the sta, and by adding a synchronize_net() after path flush to ensure +no active readers can still dereference the sta. + +Fixes this crash: + +[ 348.529295] BUG: unable to handle kernel paging request at 00020040 +[ 348.530014] IP: [] ieee80211_mps_set_frame_flags+0x40/0xaa [mac80211] +[ 348.530014] *pde = 00000000 +[ 348.530014] Oops: 0000 [#1] PREEMPT +[ 348.530014] Modules linked in: drbg ansi_cprng ctr ccm ppp_generic slhc ipt_MASQUERADE nf_nat_masquerade_ipv4 8021q ] +[ 348.530014] CPU: 0 PID: 20597 Comm: wget Tainted: G O 4.6.0-rc5-wt=V1 #1 +[ 348.530014] Hardware name: To Be Filled By O.E.M./To be filled by O.E.M., BIOS 080016 11/07/2014 +[ 348.530014] task: f64fa280 ti: f4f9c000 task.ti: f4f9c000 +[ 348.530014] EIP: 0060:[] EFLAGS: 00010246 CPU: 0 +[ 348.530014] EIP is at ieee80211_mps_set_frame_flags+0x40/0xaa [mac80211] +[ 348.530014] EAX: f4ce63e0 EBX: 00000088 ECX: f3788416 EDX: 00020008 +[ 348.530014] ESI: 00000000 EDI: 00000088 EBP: f6409a4c ESP: f6409a40 +[ 348.530014] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068 +[ 348.530014] CR0: 80050033 CR2: 00020040 CR3: 33190000 CR4: 00000690 +[ 348.530014] Stack: +[ 348.530014] 00000000 f4ce63e0 f5f9bd80 f6409a64 f9291d80 0000ce67 f5d51e00 f4ce63e0 +[ 348.530014] f3788416 f6409a80 f9291dc1 f4ce8320 f4ce63e0 f5d51e00 f4ce63e0 f4ce8320 +[ 348.530014] f6409a98 f9277f6f 00000000 00000000 0000007c 00000000 f6409b2c f9278dd1 +[ 348.530014] Call Trace: +[ 348.530014] [] mesh_nexthop_lookup+0xbb/0xc8 [mac80211] +[ 348.530014] [] mesh_nexthop_resolve+0x34/0xd8 [mac80211] +[ 348.530014] [] ieee80211_xmit+0x92/0xc1 [mac80211] +[ 348.530014] [] __ieee80211_subif_start_xmit+0x807/0x83c [mac80211] +[ 348.530014] [] ? sch_direct_xmit+0xd7/0x1b3 +[ 348.530014] [] ? __local_bh_enable_ip+0x5d/0x7b +[ 348.530014] [] ? nf_nat_ipv4_out+0x4c/0xd0 [nf_nat_ipv4] +[ 348.530014] [] ? iptable_nat_ipv4_fn+0xf/0xf [iptable_nat] +[ 348.530014] [] ? netif_skb_features+0x14d/0x30a +[ 348.530014] [] ieee80211_subif_start_xmit+0xa/0xe [mac80211] +[ 348.530014] [] dev_hard_start_xmit+0x1f8/0x267 +[ 348.530014] [] ? validate_xmit_skb.isra.120.part.121+0x10/0x253 +[ 348.530014] [] sch_direct_xmit+0x8b/0x1b3 +[ 348.530014] [] __dev_queue_xmit+0x2c8/0x513 +[ 348.530014] [] dev_queue_xmit+0xa/0xc +[ 348.530014] [] batadv_send_skb_packet+0xd6/0xec [batman_adv] +[ 348.530014] [] batadv_send_unicast_skb+0x15/0x4a [batman_adv] +[ 348.530014] [] batadv_dat_send_data+0x27e/0x310 [batman_adv] +[ 348.530014] [] ? batadv_tt_global_hash_find.isra.11+0x8/0xa [batman_adv] +[ 348.530014] [] batadv_dat_snoop_outgoing_arp_request+0x208/0x23d [batman_adv] +[ 348.530014] [] batadv_interface_tx+0x206/0x385 [batman_adv] +[ 348.530014] [] dev_hard_start_xmit+0x1f8/0x267 +[ 348.530014] [] ? validate_xmit_skb.isra.120.part.121+0x10/0x253 +[ 348.530014] [] sch_direct_xmit+0x8b/0x1b3 +[ 348.530014] [] __dev_queue_xmit+0x2c8/0x513 +[ 348.530014] [] ? igb_xmit_frame+0x57/0x72 [igb] +[ 348.530014] [] dev_queue_xmit+0xa/0xc +[ 348.530014] [] br_dev_queue_push_xmit+0xeb/0xfb [bridge] +[ 348.530014] [] br_forward_finish+0x29/0x74 [bridge] +[ 348.530014] [] ? deliver_clone+0x3b/0x3b [bridge] +[ 348.530014] [] __br_forward+0x89/0xe7 [bridge] +[ 348.530014] [] ? br_dev_queue_push_xmit+0xfb/0xfb [bridge] +[ 348.530014] [] deliver_clone+0x34/0x3b [bridge] +[ 348.530014] [] ? br_flood+0x95/0x95 [bridge] +[ 348.530014] [] br_flood+0x77/0x95 [bridge] +[ 348.530014] [] br_flood_forward+0x13/0x1a [bridge] +[ 348.530014] [] ? br_flood+0x95/0x95 [bridge] +[ 348.530014] [] br_handle_frame_finish+0x392/0x3db [bridge] +[ 348.530014] [] ? nf_iterate+0x2b/0x6b +[ 348.530014] [] br_handle_frame+0x1e6/0x240 [bridge] +[ 348.530014] [] ? br_handle_local_finish+0x6a/0x6a [bridge] +[ 348.530014] [] __netif_receive_skb_core+0x43a/0x66b +[ 348.530014] [] ? br_handle_frame_finish+0x3db/0x3db [bridge] +[ 348.530014] [] ? resched_curr+0x19/0x37 +[ 348.530014] [] ? check_preempt_wakeup+0xbf/0xfe +[ 348.530014] [] ? ktime_get_with_offset+0x5c/0xfc +[ 348.530014] [] __netif_receive_skb+0x47/0x55 +[ 348.530014] [] netif_receive_skb_internal+0x40/0x5a +[ 348.530014] [] napi_gro_receive+0x3a/0x94 +[ 348.530014] [] igb_poll+0x6fd/0x9ad [igb] +[ 348.530014] [] ? swake_up_locked+0x14/0x26 +[ 348.530014] [] net_rx_action+0xde/0x250 +[ 348.530014] [] __do_softirq+0x8a/0x163 +[ 348.530014] [] ? __hrtimer_tasklet_trampoline+0x19/0x19 +[ 348.530014] [] do_softirq_own_stack+0x26/0x2c +[ 348.530014] +[ 348.530014] [] irq_exit+0x31/0x6f +[ 348.530014] [] do_IRQ+0x8d/0xa0 +[ 348.530014] [] common_interrupt+0x2c/0x40 +[ 348.530014] Code: e7 8c 00 66 81 ff 88 00 75 12 85 d2 75 0e b2 c3 b8 83 e9 29 f9 e8 a7 5f f9 c6 eb 74 66 81 e3 8c 005 +[ 348.530014] EIP: [] ieee80211_mps_set_frame_flags+0x40/0xaa [mac80211] SS:ESP 0068:f6409a40 +[ 348.530014] CR2: 0000000000020040 +[ 348.530014] ---[ end trace 48556ac26779732e ]--- +[ 348.530014] Kernel panic - not syncing: Fatal exception in interrupt +[ 348.530014] Kernel Offset: disabled + +Reported-by: Fred Veldini +Tested-by: Fred Veldini +Signed-off-by: Bob Copeland +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/mesh.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -163,6 +163,10 @@ void mesh_sta_cleanup(struct sta_info *s + del_timer_sync(&sta->mesh->plink_timer); + } + ++ /* make sure no readers can access nexthop sta from here on */ ++ mesh_path_flush_by_nexthop(sta); ++ synchronize_net(); ++ + if (changed) + ieee80211_mbss_info_change_notify(sdata, changed); + } diff --git a/queue-4.6/mac80211_hwsim-add-missing-check-for-hwsim_attr_signal.patch b/queue-4.6/mac80211_hwsim-add-missing-check-for-hwsim_attr_signal.patch new file mode 100644 index 00000000000..d80acb9119d --- /dev/null +++ b/queue-4.6/mac80211_hwsim-add-missing-check-for-hwsim_attr_signal.patch @@ -0,0 +1,35 @@ +From 62397da50bb20a6b812c949ef465d7e69fe54bb6 Mon Sep 17 00:00:00 2001 +From: Martin Willi +Date: Fri, 13 May 2016 12:41:48 +0200 +Subject: mac80211_hwsim: Add missing check for HWSIM_ATTR_SIGNAL + +From: Martin Willi + +commit 62397da50bb20a6b812c949ef465d7e69fe54bb6 upstream. + +A wmediumd that does not send this attribute causes a NULL pointer +dereference, as the attribute is accessed even if it does not exist. + +The attribute was required but never checked ever since userspace frame +forwarding has been introduced. The issue gets more problematic once we +allow wmediumd registration from user namespaces. + +Fixes: 7882513bacb1 ("mac80211_hwsim driver support userspace frame tx/rx") +Signed-off-by: Martin Willi +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/mac80211_hwsim.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/mac80211_hwsim.c ++++ b/drivers/net/wireless/mac80211_hwsim.c +@@ -2771,6 +2771,7 @@ static int hwsim_tx_info_frame_received_ + if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] || + !info->attrs[HWSIM_ATTR_FLAGS] || + !info->attrs[HWSIM_ATTR_COOKIE] || ++ !info->attrs[HWSIM_ATTR_SIGNAL] || + !info->attrs[HWSIM_ATTR_TX_INFO]) + goto out; + diff --git a/queue-4.6/make-nfs_atomic_open-call-d_drop-on-all-open_context-errors.patch b/queue-4.6/make-nfs_atomic_open-call-d_drop-on-all-open_context-errors.patch new file mode 100644 index 00000000000..9b7a9c6b2a0 --- /dev/null +++ b/queue-4.6/make-nfs_atomic_open-call-d_drop-on-all-open_context-errors.patch @@ -0,0 +1,44 @@ +From d20cb71dbf3487f24549ede1a8e2d67579b4632e Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Mon, 20 Jun 2016 13:14:36 -0400 +Subject: make nfs_atomic_open() call d_drop() on all ->open_context() errors. + +From: Al Viro + +commit d20cb71dbf3487f24549ede1a8e2d67579b4632e upstream. + +In "NFSv4: Move dentry instantiation into the NFSv4-specific atomic open code" +unconditional d_drop() after the ->open_context() had been removed. It had +been correct for success cases (there ->open_context() itself had been doing +dcache manipulations), but not for error ones. Only one of those (ENOENT) +got a compensatory d_drop() added in that commit, but in fact it should've +been done for all errors. As it is, the case of O_CREAT non-exclusive open +on a hashed negative dentry racing with e.g. symlink creation from another +client ended up with ->open_context() getting an error and proceeding to +call nfs_lookup(). On a hashed dentry, which would've instantly triggered +BUG_ON() in d_materialise_unique() (or, these days, its equivalent in +d_splice_alias()). + +Tested-by: Oleg Drokin +Signed-off-by: Al Viro +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/dir.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfs/dir.c ++++ b/fs/nfs/dir.c +@@ -1527,9 +1527,9 @@ int nfs_atomic_open(struct inode *dir, s + err = PTR_ERR(inode); + trace_nfs_atomic_open_exit(dir, ctx, open_flags, err); + put_nfs_open_context(ctx); ++ d_drop(dentry); + switch (err) { + case -ENOENT: +- d_drop(dentry); + d_add(dentry, NULL); + nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); + break; diff --git a/queue-4.6/mnt-account-for-ms_rdonly-in-fs_fully_visible.patch b/queue-4.6/mnt-account-for-ms_rdonly-in-fs_fully_visible.patch new file mode 100644 index 00000000000..b0ab035aa4b --- /dev/null +++ b/queue-4.6/mnt-account-for-ms_rdonly-in-fs_fully_visible.patch @@ -0,0 +1,45 @@ +From 695e9df010e40f407f4830dc11d53dce957710ba Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Fri, 10 Jun 2016 12:21:40 -0500 +Subject: mnt: Account for MS_RDONLY in fs_fully_visible + +From: Eric W. Biederman + +commit 695e9df010e40f407f4830dc11d53dce957710ba upstream. + +In rare cases it is possible for s_flags & MS_RDONLY to be set but +MNT_READONLY to be clear. This starting combination can cause +fs_fully_visible to fail to ensure that the new mount is readonly. +Therefore force MNT_LOCK_READONLY in the new mount if MS_RDONLY +is set on the source filesystem of the mount. + +In general both MS_RDONLY and MNT_READONLY are set at the same for +mounts so I don't expect any programs to care. Nor do I expect +MS_RDONLY to be set on proc or sysfs in the initial user namespace, +which further decreases the likelyhood of problems. + +Which means this change should only affect system configurations by +paranoid sysadmins who should welcome the additional protection +as it keeps people from wriggling out of their policies. + +Fixes: 8c6cf9cc829f ("mnt: Modify fs_fully_visible to deal with locked ro nodev and atime") +Signed-off-by: "Eric W. Biederman" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/namespace.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -3245,6 +3245,10 @@ static bool fs_fully_visible(struct file + if (mnt->mnt.mnt_sb->s_iflags & SB_I_NOEXEC) + mnt_flags &= ~(MNT_LOCK_NOSUID | MNT_LOCK_NOEXEC); + ++ /* Don't miss readonly hidden in the superblock flags */ ++ if (mnt->mnt.mnt_sb->s_flags & MS_RDONLY) ++ mnt_flags |= MNT_LOCK_READONLY; ++ + /* Verify the mount flags are equal to or more permissive + * than the proposed new mount. + */ diff --git a/queue-4.6/mnt-fs_fully_visible-test-the-proper-mount-for-mnt_locked.patch b/queue-4.6/mnt-fs_fully_visible-test-the-proper-mount-for-mnt_locked.patch new file mode 100644 index 00000000000..dc69588464f --- /dev/null +++ b/queue-4.6/mnt-fs_fully_visible-test-the-proper-mount-for-mnt_locked.patch @@ -0,0 +1,37 @@ +From d71ed6c930ac7d8f88f3cef6624a7e826392d61f Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Fri, 27 May 2016 14:50:05 -0500 +Subject: mnt: fs_fully_visible test the proper mount for MNT_LOCKED + +From: Eric W. Biederman + +commit d71ed6c930ac7d8f88f3cef6624a7e826392d61f upstream. + +MNT_LOCKED implies on a child mount implies the child is locked to the +parent. So while looping through the children the children should be +tested (not their parent). + +Typically an unshare of a mount namespace locks all mounts together +making both the parent and the slave as locked but there are a few +corner cases where other things work. + +Fixes: ceeb0e5d39fc ("vfs: Ignore unlocked mounts in fs_fully_visible") +Reported-by: Seth Forshee +Signed-off-by: "Eric W. Biederman" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/namespace.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -3271,7 +3271,7 @@ static bool fs_fully_visible(struct file + list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) { + struct inode *inode = child->mnt_mountpoint->d_inode; + /* Only worry about locked mounts */ +- if (!(mnt_flags & MNT_LOCKED)) ++ if (!(child->mnt.mnt_flags & MNT_LOCKED)) + continue; + /* Is the directory permanetly empty? */ + if (!is_empty_dir_inode(inode)) diff --git a/queue-4.6/mnt-if-fs_fully_visible-fails-call-put_filesystem.patch b/queue-4.6/mnt-if-fs_fully_visible-fails-call-put_filesystem.patch new file mode 100644 index 00000000000..93189d10755 --- /dev/null +++ b/queue-4.6/mnt-if-fs_fully_visible-fails-call-put_filesystem.patch @@ -0,0 +1,33 @@ +From 97c1df3e54e811aed484a036a798b4b25d002ecf Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Mon, 6 Jun 2016 15:36:07 -0500 +Subject: mnt: If fs_fully_visible fails call put_filesystem. + +From: Eric W. Biederman + +commit 97c1df3e54e811aed484a036a798b4b25d002ecf upstream. + +Add this trivial missing error handling. + +Fixes: 1b852bceb0d1 ("mnt: Refactor the logic for mounting sysfs and proc in a user namespace") +Signed-off-by: "Eric W. Biederman" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/namespace.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -2409,8 +2409,10 @@ static int do_new_mount(struct path *pat + mnt_flags |= MNT_NODEV | MNT_LOCK_NODEV; + } + if (type->fs_flags & FS_USERNS_VISIBLE) { +- if (!fs_fully_visible(type, &mnt_flags)) ++ if (!fs_fully_visible(type, &mnt_flags)) { ++ put_filesystem(type); + return -EPERM; ++ } + } + } + diff --git a/queue-4.6/nfs-fix-a-double-page-unlock.patch b/queue-4.6/nfs-fix-a-double-page-unlock.patch new file mode 100644 index 00000000000..925879275ad --- /dev/null +++ b/queue-4.6/nfs-fix-a-double-page-unlock.patch @@ -0,0 +1,39 @@ +From cbebaf897e5c4862567eb799dc84acc5d7ee2678 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Fri, 17 Jun 2016 16:48:25 -0400 +Subject: NFS: Fix a double page unlock + +From: Trond Myklebust + +commit cbebaf897e5c4862567eb799dc84acc5d7ee2678 upstream. + +Since commit 0bcbf039f6b2, nfs_readpage_release() has been used to +unlock the page in the read code. + +Fixes: 0bcbf039f6b2 ("nfs: handle request add failure properly") +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/read.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/nfs/read.c ++++ b/fs/nfs/read.c +@@ -367,13 +367,13 @@ readpage_async_filler(void *data, struct + nfs_list_remove_request(new); + nfs_readpage_release(new); + error = desc->pgio->pg_error; +- goto out_unlock; ++ goto out; + } + return 0; + out_error: + error = PTR_ERR(new); +-out_unlock: + unlock_page(page); ++out: + return error; + } + diff --git a/queue-4.6/nfs-fix-another-open_downgrade-bug.patch b/queue-4.6/nfs-fix-another-open_downgrade-bug.patch new file mode 100644 index 00000000000..5efdd2a1139 --- /dev/null +++ b/queue-4.6/nfs-fix-another-open_downgrade-bug.patch @@ -0,0 +1,49 @@ +From e547f2628327fec6afd2e03b46f113f614cca05b Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Sat, 25 Jun 2016 19:19:28 -0400 +Subject: NFS: Fix another OPEN_DOWNGRADE bug + +From: Trond Myklebust + +commit e547f2628327fec6afd2e03b46f113f614cca05b upstream. + +Olga Kornievskaia reports that the following test fails to trigger +an OPEN_DOWNGRADE on the wire, and only triggers the final CLOSE. + + fd0 = open(foo, RDRW) -- should be open on the wire for "both" + fd1 = open(foo, RDONLY) -- should be open on the wire for "read" + close(fd0) -- should trigger an open_downgrade + read(fd1) + close(fd1) + +The issue is that we're missing a check for whether or not the current +state transitioned from an O_RDWR state as opposed to having transitioned +from a combination of O_RDONLY and O_WRONLY. + +Reported-by: Olga Kornievskaia +Fixes: cd9288ffaea4 ("NFSv4: Fix another bug in the close/open_downgrade code") +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4proc.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -2860,12 +2860,11 @@ static void nfs4_close_prepare(struct rp + call_close |= is_wronly; + else if (is_wronly) + calldata->arg.fmode |= FMODE_WRITE; ++ if (calldata->arg.fmode != (FMODE_READ|FMODE_WRITE)) ++ call_close |= is_rdwr; + } else if (is_rdwr) + calldata->arg.fmode |= FMODE_READ|FMODE_WRITE; + +- if (calldata->arg.fmode == 0) +- call_close |= is_rdwr; +- + if (!nfs4_valid_open_stateid(state)) + call_close = 0; + spin_unlock(&state->owner->so_lock); diff --git a/queue-4.6/nfsd-always-lock-state-exclusively.patch b/queue-4.6/nfsd-always-lock-state-exclusively.patch new file mode 100644 index 00000000000..7e9de7944cf --- /dev/null +++ b/queue-4.6/nfsd-always-lock-state-exclusively.patch @@ -0,0 +1,194 @@ +From feb9dad5209280085d5b0c094fa67e7a8d75c81a Mon Sep 17 00:00:00 2001 +From: Oleg Drokin +Date: Tue, 14 Jun 2016 23:28:04 -0400 +Subject: nfsd: Always lock state exclusively. + +From: Oleg Drokin + +commit feb9dad5209280085d5b0c094fa67e7a8d75c81a upstream. + +It used to be the case that state had an rwlock that was locked for write +by downgrades, but for read for upgrades (opens). Well, the problem is +if there are two competing opens for the same state, they step on +each other toes potentially leading to leaking file descriptors +from the state structure, since access mode is a bitmap only set once. + +Signed-off-by: Oleg Drokin +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs4state.c | 40 ++++++++++++++++++++-------------------- + fs/nfsd/state.h | 2 +- + 2 files changed, 21 insertions(+), 21 deletions(-) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -3502,7 +3502,7 @@ init_open_stateid(struct nfs4_ol_stateid + stp->st_access_bmap = 0; + stp->st_deny_bmap = 0; + stp->st_openstp = NULL; +- init_rwsem(&stp->st_rwsem); ++ mutex_init(&stp->st_mutex); + list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids); + list_add(&stp->st_perfile, &fp->fi_stateids); + +@@ -4335,10 +4335,10 @@ nfsd4_process_open2(struct svc_rqst *rqs + */ + if (stp) { + /* Stateid was found, this is an OPEN upgrade */ +- down_read(&stp->st_rwsem); ++ mutex_lock(&stp->st_mutex); + status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open); + if (status) { +- up_read(&stp->st_rwsem); ++ mutex_unlock(&stp->st_mutex); + goto out; + } + } else { +@@ -4348,19 +4348,19 @@ nfsd4_process_open2(struct svc_rqst *rqs + if (swapstp) { + nfs4_put_stid(&stp->st_stid); + stp = swapstp; +- down_read(&stp->st_rwsem); ++ mutex_lock(&stp->st_mutex); + status = nfs4_upgrade_open(rqstp, fp, current_fh, + stp, open); + if (status) { +- up_read(&stp->st_rwsem); ++ mutex_unlock(&stp->st_mutex); + goto out; + } + goto upgrade_out; + } +- down_read(&stp->st_rwsem); ++ mutex_lock(&stp->st_mutex); + status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open); + if (status) { +- up_read(&stp->st_rwsem); ++ mutex_unlock(&stp->st_mutex); + release_open_stateid(stp); + goto out; + } +@@ -4372,7 +4372,7 @@ nfsd4_process_open2(struct svc_rqst *rqs + } + upgrade_out: + nfs4_inc_and_copy_stateid(&open->op_stateid, &stp->st_stid); +- up_read(&stp->st_rwsem); ++ mutex_unlock(&stp->st_mutex); + + if (nfsd4_has_session(&resp->cstate)) { + if (open->op_deleg_want & NFS4_SHARE_WANT_NO_DELEG) { +@@ -4983,12 +4983,12 @@ static __be32 nfs4_seqid_op_checks(struc + * revoked delegations are kept only for free_stateid. + */ + return nfserr_bad_stateid; +- down_write(&stp->st_rwsem); ++ mutex_lock(&stp->st_mutex); + status = check_stateid_generation(stateid, &stp->st_stid.sc_stateid, nfsd4_has_session(cstate)); + if (status == nfs_ok) + status = nfs4_check_fh(current_fh, &stp->st_stid); + if (status != nfs_ok) +- up_write(&stp->st_rwsem); ++ mutex_unlock(&stp->st_mutex); + return status; + } + +@@ -5036,7 +5036,7 @@ static __be32 nfs4_preprocess_confirmed_ + return status; + oo = openowner(stp->st_stateowner); + if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) { +- up_write(&stp->st_rwsem); ++ mutex_unlock(&stp->st_mutex); + nfs4_put_stid(&stp->st_stid); + return nfserr_bad_stateid; + } +@@ -5068,12 +5068,12 @@ nfsd4_open_confirm(struct svc_rqst *rqst + oo = openowner(stp->st_stateowner); + status = nfserr_bad_stateid; + if (oo->oo_flags & NFS4_OO_CONFIRMED) { +- up_write(&stp->st_rwsem); ++ mutex_unlock(&stp->st_mutex); + goto put_stateid; + } + oo->oo_flags |= NFS4_OO_CONFIRMED; + nfs4_inc_and_copy_stateid(&oc->oc_resp_stateid, &stp->st_stid); +- up_write(&stp->st_rwsem); ++ mutex_unlock(&stp->st_mutex); + dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n", + __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid)); + +@@ -5149,7 +5149,7 @@ nfsd4_open_downgrade(struct svc_rqst *rq + nfs4_inc_and_copy_stateid(&od->od_stateid, &stp->st_stid); + status = nfs_ok; + put_stateid: +- up_write(&stp->st_rwsem); ++ mutex_unlock(&stp->st_mutex); + nfs4_put_stid(&stp->st_stid); + out: + nfsd4_bump_seqid(cstate, status); +@@ -5202,7 +5202,7 @@ nfsd4_close(struct svc_rqst *rqstp, stru + if (status) + goto out; + nfs4_inc_and_copy_stateid(&close->cl_stateid, &stp->st_stid); +- up_write(&stp->st_rwsem); ++ mutex_unlock(&stp->st_mutex); + + nfsd4_close_open_stateid(stp); + +@@ -5428,7 +5428,7 @@ init_lock_stateid(struct nfs4_ol_stateid + stp->st_access_bmap = 0; + stp->st_deny_bmap = open_stp->st_deny_bmap; + stp->st_openstp = open_stp; +- init_rwsem(&stp->st_rwsem); ++ mutex_init(&stp->st_mutex); + list_add(&stp->st_locks, &open_stp->st_locks); + list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids); + spin_lock(&fp->fi_lock); +@@ -5597,7 +5597,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struc + &open_stp, nn); + if (status) + goto out; +- up_write(&open_stp->st_rwsem); ++ mutex_unlock(&open_stp->st_mutex); + open_sop = openowner(open_stp->st_stateowner); + status = nfserr_bad_stateid; + if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid, +@@ -5606,7 +5606,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struc + status = lookup_or_create_lock_state(cstate, open_stp, lock, + &lock_stp, &new); + if (status == nfs_ok) +- down_write(&lock_stp->st_rwsem); ++ mutex_lock(&lock_stp->st_mutex); + } else { + status = nfs4_preprocess_seqid_op(cstate, + lock->lk_old_lock_seqid, +@@ -5710,7 +5710,7 @@ out: + seqid_mutating_err(ntohl(status))) + lock_sop->lo_owner.so_seqid++; + +- up_write(&lock_stp->st_rwsem); ++ mutex_unlock(&lock_stp->st_mutex); + + /* + * If this is a new, never-before-used stateid, and we are +@@ -5880,7 +5880,7 @@ nfsd4_locku(struct svc_rqst *rqstp, stru + fput: + fput(filp); + put_stateid: +- up_write(&stp->st_rwsem); ++ mutex_unlock(&stp->st_mutex); + nfs4_put_stid(&stp->st_stid); + out: + nfsd4_bump_seqid(cstate, status); +--- a/fs/nfsd/state.h ++++ b/fs/nfsd/state.h +@@ -535,7 +535,7 @@ struct nfs4_ol_stateid { + unsigned char st_access_bmap; + unsigned char st_deny_bmap; + struct nfs4_ol_stateid *st_openstp; +- struct rw_semaphore st_rwsem; ++ struct mutex st_mutex; + }; + + static inline struct nfs4_ol_stateid *openlockstateid(struct nfs4_stid *s) diff --git a/queue-4.6/nfsd-check-permissions-when-setting-acls.patch b/queue-4.6/nfsd-check-permissions-when-setting-acls.patch new file mode 100644 index 00000000000..748459297c2 --- /dev/null +++ b/queue-4.6/nfsd-check-permissions-when-setting-acls.patch @@ -0,0 +1,150 @@ +From 999653786df6954a31044528ac3f7a5dadca08f4 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Wed, 22 Jun 2016 19:43:35 +0100 +Subject: nfsd: check permissions when setting ACLs + +From: Ben Hutchings + +commit 999653786df6954a31044528ac3f7a5dadca08f4 upstream. + +Use set_posix_acl, which includes proper permission checks, instead of +calling ->set_acl directly. Without this anyone may be able to grant +themselves permissions to a file by setting the ACL. + +Lock the inode to make the new checks atomic with respect to set_acl. +(Also, nfsd was the only caller of set_acl not locking the inode, so I +suspect this may fix other races.) + +This also simplifies the code, and ensures our ACLs are checked by +posix_acl_valid. + +The permission checks and the inode locking were lost with commit +4ac7249e, which changed nfsd to use the set_acl inode operation directly +instead of going through xattr handlers. + +Reported-by: David Sinquin +[agreunba@redhat.com: use set_posix_acl] +Fixes: 4ac7249e +Cc: Christoph Hellwig +Cc: Al Viro +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs2acl.c | 20 ++++++++++---------- + fs/nfsd/nfs3acl.c | 16 +++++++--------- + fs/nfsd/nfs4acl.c | 16 ++++++++-------- + 3 files changed, 25 insertions(+), 27 deletions(-) + +--- a/fs/nfsd/nfs2acl.c ++++ b/fs/nfsd/nfs2acl.c +@@ -104,22 +104,21 @@ static __be32 nfsacld_proc_setacl(struct + goto out; + + inode = d_inode(fh->fh_dentry); +- if (!IS_POSIXACL(inode) || !inode->i_op->set_acl) { +- error = -EOPNOTSUPP; +- goto out_errno; +- } + + error = fh_want_write(fh); + if (error) + goto out_errno; + +- error = inode->i_op->set_acl(inode, argp->acl_access, ACL_TYPE_ACCESS); ++ fh_lock(fh); ++ ++ error = set_posix_acl(inode, ACL_TYPE_ACCESS, argp->acl_access); + if (error) +- goto out_drop_write; +- error = inode->i_op->set_acl(inode, argp->acl_default, +- ACL_TYPE_DEFAULT); ++ goto out_drop_lock; ++ error = set_posix_acl(inode, ACL_TYPE_DEFAULT, argp->acl_default); + if (error) +- goto out_drop_write; ++ goto out_drop_lock; ++ ++ fh_unlock(fh); + + fh_drop_write(fh); + +@@ -131,7 +130,8 @@ out: + posix_acl_release(argp->acl_access); + posix_acl_release(argp->acl_default); + return nfserr; +-out_drop_write: ++out_drop_lock: ++ fh_unlock(fh); + fh_drop_write(fh); + out_errno: + nfserr = nfserrno(error); +--- a/fs/nfsd/nfs3acl.c ++++ b/fs/nfsd/nfs3acl.c +@@ -95,22 +95,20 @@ static __be32 nfsd3_proc_setacl(struct s + goto out; + + inode = d_inode(fh->fh_dentry); +- if (!IS_POSIXACL(inode) || !inode->i_op->set_acl) { +- error = -EOPNOTSUPP; +- goto out_errno; +- } + + error = fh_want_write(fh); + if (error) + goto out_errno; + +- error = inode->i_op->set_acl(inode, argp->acl_access, ACL_TYPE_ACCESS); ++ fh_lock(fh); ++ ++ error = set_posix_acl(inode, ACL_TYPE_ACCESS, argp->acl_access); + if (error) +- goto out_drop_write; +- error = inode->i_op->set_acl(inode, argp->acl_default, +- ACL_TYPE_DEFAULT); ++ goto out_drop_lock; ++ error = set_posix_acl(inode, ACL_TYPE_DEFAULT, argp->acl_default); + +-out_drop_write: ++out_drop_lock: ++ fh_unlock(fh); + fh_drop_write(fh); + out_errno: + nfserr = nfserrno(error); +--- a/fs/nfsd/nfs4acl.c ++++ b/fs/nfsd/nfs4acl.c +@@ -770,9 +770,6 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst + dentry = fhp->fh_dentry; + inode = d_inode(dentry); + +- if (!inode->i_op->set_acl || !IS_POSIXACL(inode)) +- return nfserr_attrnotsupp; +- + if (S_ISDIR(inode->i_mode)) + flags = NFS4_ACL_DIR; + +@@ -782,16 +779,19 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst + if (host_error < 0) + goto out_nfserr; + +- host_error = inode->i_op->set_acl(inode, pacl, ACL_TYPE_ACCESS); ++ fh_lock(fhp); ++ ++ host_error = set_posix_acl(inode, ACL_TYPE_ACCESS, pacl); + if (host_error < 0) +- goto out_release; ++ goto out_drop_lock; + + if (S_ISDIR(inode->i_mode)) { +- host_error = inode->i_op->set_acl(inode, dpacl, +- ACL_TYPE_DEFAULT); ++ host_error = set_posix_acl(inode, ACL_TYPE_DEFAULT, dpacl); + } + +-out_release: ++out_drop_lock: ++ fh_unlock(fhp); ++ + posix_acl_release(pacl); + posix_acl_release(dpacl); + out_nfserr: diff --git a/queue-4.6/nfsd-extend-the-mutex-holding-region-around-in-nfsd4_process_open2.patch b/queue-4.6/nfsd-extend-the-mutex-holding-region-around-in-nfsd4_process_open2.patch new file mode 100644 index 00000000000..5c9f2ef3382 --- /dev/null +++ b/queue-4.6/nfsd-extend-the-mutex-holding-region-around-in-nfsd4_process_open2.patch @@ -0,0 +1,77 @@ +From 5cc1fb2a093e254b656c64ff24b0b76bed1d34d9 Mon Sep 17 00:00:00 2001 +From: Oleg Drokin +Date: Tue, 14 Jun 2016 23:28:05 -0400 +Subject: nfsd: Extend the mutex holding region around in nfsd4_process_open2() + +From: Oleg Drokin + +commit 5cc1fb2a093e254b656c64ff24b0b76bed1d34d9 upstream. + +To avoid racing entry into nfs4_get_vfs_file(). +Make init_open_stateid() return with locked stateid to be unlocked +by the caller. + +Signed-off-by: Oleg Drokin +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs4state.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -3487,6 +3487,10 @@ init_open_stateid(struct nfs4_ol_stateid + struct nfs4_openowner *oo = open->op_openowner; + struct nfs4_ol_stateid *retstp = NULL; + ++ /* We are moving these outside of the spinlocks to avoid the warnings */ ++ mutex_init(&stp->st_mutex); ++ mutex_lock(&stp->st_mutex); ++ + spin_lock(&oo->oo_owner.so_client->cl_lock); + spin_lock(&fp->fi_lock); + +@@ -3502,13 +3506,17 @@ init_open_stateid(struct nfs4_ol_stateid + stp->st_access_bmap = 0; + stp->st_deny_bmap = 0; + stp->st_openstp = NULL; +- mutex_init(&stp->st_mutex); + list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids); + list_add(&stp->st_perfile, &fp->fi_stateids); + + out_unlock: + spin_unlock(&fp->fi_lock); + spin_unlock(&oo->oo_owner.so_client->cl_lock); ++ if (retstp) { ++ mutex_lock(&retstp->st_mutex); ++ /* Not that we need to, just for neatness */ ++ mutex_unlock(&stp->st_mutex); ++ } + return retstp; + } + +@@ -4344,11 +4352,14 @@ nfsd4_process_open2(struct svc_rqst *rqs + } else { + stp = open->op_stp; + open->op_stp = NULL; ++ /* ++ * init_open_stateid() either returns a locked stateid ++ * it found, or initializes and locks the new one we passed in ++ */ + swapstp = init_open_stateid(stp, fp, open); + if (swapstp) { + nfs4_put_stid(&stp->st_stid); + stp = swapstp; +- mutex_lock(&stp->st_mutex); + status = nfs4_upgrade_open(rqstp, fp, current_fh, + stp, open); + if (status) { +@@ -4357,7 +4368,6 @@ nfsd4_process_open2(struct svc_rqst *rqs + } + goto upgrade_out; + } +- mutex_lock(&stp->st_mutex); + status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open); + if (status) { + mutex_unlock(&stp->st_mutex); diff --git a/queue-4.6/nfsd4-rpc-move-backchannel-create-logic-into-rpc-code.patch b/queue-4.6/nfsd4-rpc-move-backchannel-create-logic-into-rpc-code.patch new file mode 100644 index 00000000000..3c2d88f8889 --- /dev/null +++ b/queue-4.6/nfsd4-rpc-move-backchannel-create-logic-into-rpc-code.patch @@ -0,0 +1,101 @@ +From d50039ea5ee63c589b0434baa5ecf6e5075bb6f9 Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Mon, 16 May 2016 17:03:42 -0400 +Subject: nfsd4/rpc: move backchannel create logic into rpc code + +From: J. Bruce Fields + +commit d50039ea5ee63c589b0434baa5ecf6e5075bb6f9 upstream. + +Also simplify the logic a bit. + +Signed-off-by: J. Bruce Fields +Acked-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs4callback.c | 18 +----------------- + include/linux/sunrpc/clnt.h | 2 -- + net/sunrpc/clnt.c | 12 ++++++++++-- + 3 files changed, 11 insertions(+), 21 deletions(-) + +--- a/fs/nfsd/nfs4callback.c ++++ b/fs/nfsd/nfs4callback.c +@@ -710,22 +710,6 @@ static struct rpc_cred *get_backchannel_ + } + } + +-static struct rpc_clnt *create_backchannel_client(struct rpc_create_args *args) +-{ +- struct rpc_xprt *xprt; +- +- if (args->protocol != XPRT_TRANSPORT_BC_TCP) +- return rpc_create(args); +- +- xprt = args->bc_xprt->xpt_bc_xprt; +- if (xprt) { +- xprt_get(xprt); +- return rpc_create_xprt(args, xprt); +- } +- +- return rpc_create(args); +-} +- + static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses) + { + int maxtime = max_cb_time(clp->net); +@@ -768,7 +752,7 @@ static int setup_callback_client(struct + args.authflavor = ses->se_cb_sec.flavor; + } + /* Create RPC client */ +- client = create_backchannel_client(&args); ++ client = rpc_create(&args); + if (IS_ERR(client)) { + dprintk("NFSD: couldn't create callback client: %ld\n", + PTR_ERR(client)); +--- a/include/linux/sunrpc/clnt.h ++++ b/include/linux/sunrpc/clnt.h +@@ -137,8 +137,6 @@ struct rpc_create_args { + #define RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT (1UL << 9) + + struct rpc_clnt *rpc_create(struct rpc_create_args *args); +-struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args, +- struct rpc_xprt *xprt); + struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *, + const struct rpc_program *, u32); + struct rpc_clnt *rpc_clone_client(struct rpc_clnt *); +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -446,7 +446,7 @@ out_no_rpciod: + return ERR_PTR(err); + } + +-struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args, ++static struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args, + struct rpc_xprt *xprt) + { + struct rpc_clnt *clnt = NULL; +@@ -483,7 +483,6 @@ struct rpc_clnt *rpc_create_xprt(struct + + return clnt; + } +-EXPORT_SYMBOL_GPL(rpc_create_xprt); + + /** + * rpc_create - create an RPC client and transport with one call +@@ -509,6 +508,15 @@ struct rpc_clnt *rpc_create(struct rpc_c + }; + char servername[48]; + ++ if (args->bc_xprt) { ++ WARN_ON(args->protocol != XPRT_TRANSPORT_BC_TCP); ++ xprt = args->bc_xprt->xpt_bc_xprt; ++ if (xprt) { ++ xprt_get(xprt); ++ return rpc_create_xprt(args, xprt); ++ } ++ } ++ + if (args->flags & RPC_CLNT_CREATE_INFINITE_SLOTS) + xprtargs.flags |= XPRT_CREATE_INFINITE_SLOTS; + if (args->flags & RPC_CLNT_CREATE_NO_IDLE_TIMEOUT) diff --git a/queue-4.6/of-fix-autoloading-due-to-broken-modalias-with-no-compatible.patch b/queue-4.6/of-fix-autoloading-due-to-broken-modalias-with-no-compatible.patch new file mode 100644 index 00000000000..98f5df0ce6f --- /dev/null +++ b/queue-4.6/of-fix-autoloading-due-to-broken-modalias-with-no-compatible.patch @@ -0,0 +1,38 @@ +From b3c0a4dab7e35a9b6d69c0415641d2280fdefb2b Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +Date: Mon, 6 Jun 2016 18:48:38 +0200 +Subject: of: fix autoloading due to broken modalias with no 'compatible' + +From: Wolfram Sang + +commit b3c0a4dab7e35a9b6d69c0415641d2280fdefb2b upstream. + +Because of an improper dereference, a stray 'C' character was output to +the modalias when no 'compatible' was specified. This is the case for +some old PowerMac drivers which only set the 'name' property. Fix it to +let them match again. + +Reported-by: Mathieu Malaterre +Signed-off-by: Wolfram Sang +Tested-by: Mathieu Malaterre +Cc: Philipp Zabel +Cc: Andreas Schwab +Fixes: 6543becf26fff6 ("mod/file2alias: make modalias generation safe for cross compiling") +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + scripts/mod/file2alias.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/scripts/mod/file2alias.c ++++ b/scripts/mod/file2alias.c +@@ -384,7 +384,7 @@ static void do_of_entry_multi(void *symv + len = sprintf(alias, "of:N%sT%s", (*name)[0] ? *name : "*", + (*type)[0] ? *type : "*"); + +- if (compatible[0]) ++ if ((*compatible)[0]) + sprintf(&alias[len], "%sC%s", (*type)[0] ? "*" : "", + *compatible); + diff --git a/queue-4.6/of-irq-fix-of_irq_get-kernel-doc.patch b/queue-4.6/of-irq-fix-of_irq_get-kernel-doc.patch new file mode 100644 index 00000000000..1c556124b89 --- /dev/null +++ b/queue-4.6/of-irq-fix-of_irq_get-kernel-doc.patch @@ -0,0 +1,65 @@ +From 3993546646baf1dab5f5c4f7d9bb58f2046fd1c1 Mon Sep 17 00:00:00 2001 +From: Sergei Shtylyov +Date: Sat, 28 May 2016 23:02:50 +0300 +Subject: of: irq: fix of_irq_get[_byname]() kernel-doc + +From: Sergei Shtylyov + +commit 3993546646baf1dab5f5c4f7d9bb58f2046fd1c1 upstream. + +The kernel-doc for the of_irq_get[_byname]() is clearly inadequate in +describing the return values -- of_irq_get_byname() is documented better +than of_irq_get() but it still doesn't mention that 0 is returned iff +irq_create_of_mapping() fails (it doesn't return an error code in this +case). Document all possible return value variants, making the writing +of the word "IRQ" consistent, while at it... + +Fixes: 9ec36cafe43b ("of/irq: do irq resolution in platform_get_irq") +Fixes: ad69674e73a1 ("of/irq: do irq resolution in platform_get_irq_byname()") +Signed-off-by: Sergei Shtylyov +Signed-off-by: Rob Herring +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/of/irq.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +--- a/drivers/of/irq.c ++++ b/drivers/of/irq.c +@@ -386,13 +386,13 @@ int of_irq_to_resource(struct device_nod + EXPORT_SYMBOL_GPL(of_irq_to_resource); + + /** +- * of_irq_get - Decode a node's IRQ and return it as a Linux irq number ++ * of_irq_get - Decode a node's IRQ and return it as a Linux IRQ number + * @dev: pointer to device tree node +- * @index: zero-based index of the irq +- * +- * Returns Linux irq number on success, or -EPROBE_DEFER if the irq domain +- * is not yet created. ++ * @index: zero-based index of the IRQ + * ++ * Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or ++ * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case ++ * of any other failure. + */ + int of_irq_get(struct device_node *dev, int index) + { +@@ -413,12 +413,13 @@ int of_irq_get(struct device_node *dev, + EXPORT_SYMBOL_GPL(of_irq_get); + + /** +- * of_irq_get_byname - Decode a node's IRQ and return it as a Linux irq number ++ * of_irq_get_byname - Decode a node's IRQ and return it as a Linux IRQ number + * @dev: pointer to device tree node +- * @name: irq name ++ * @name: IRQ name + * +- * Returns Linux irq number on success, or -EPROBE_DEFER if the irq domain +- * is not yet created, or error code in case of any other failure. ++ * Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or ++ * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case ++ * of any other failure. + */ + int of_irq_get_byname(struct device_node *dev, const char *name) + { diff --git a/queue-4.6/perf-x86-fix-32-bit-perf-user-callgraph-collection.patch b/queue-4.6/perf-x86-fix-32-bit-perf-user-callgraph-collection.patch new file mode 100644 index 00000000000..6b89798e6ae --- /dev/null +++ b/queue-4.6/perf-x86-fix-32-bit-perf-user-callgraph-collection.patch @@ -0,0 +1,115 @@ +From fc18822510721fe694d273c5211c71ea52796d76 Mon Sep 17 00:00:00 2001 +From: Josh Poimboeuf +Date: Fri, 1 Jul 2016 23:02:05 -0500 +Subject: perf/x86: Fix 32-bit perf user callgraph collection + +From: Josh Poimboeuf + +commit fc18822510721fe694d273c5211c71ea52796d76 upstream. + +A basic perf callgraph record operation causes an immediate panic on a +32-bit kernel compiled with CONFIG_CC_STACKPROTECTOR=y: + + $ perf record -g ls + Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: c0404fbd + + CPU: 0 PID: 998 Comm: ls Not tainted 4.7.0-rc5+ #1 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.1-1.fc24 04/01/2014 + c0dd5967 ff7afe1c 00000086 f41dbc2c c07445a0 464c457f f41dbca8 f41dbc44 + c05646f4 f41dbca8 464c457f f41dbca8 464c457f f41dbc54 c04625be c0ce56fc + c0404fbd f41dbc88 c0404fbd b74668f0 f41dc000 00000000 c0000000 00000000 + Call Trace: + [] dump_stack+0x58/0x78 + [] panic+0x8e/0x1c6 + [] __stack_chk_fail+0x1e/0x30 + [] ? perf_callchain_user+0x22d/0x230 + [] perf_callchain_user+0x22d/0x230 + [] get_perf_callchain+0x1ff/0x270 + [] perf_callchain+0x78/0x90 + [] perf_prepare_sample+0x24b/0x370 + [] perf_event_output_forward+0x24/0x70 + [] __perf_event_overflow+0xa0/0x210 + [] ? cpu_clock_event_read+0x43/0x50 + [] perf_swevent_hrtimer+0x101/0x180 + [] ? kmap_atomic_prot+0x35/0x140 + [] ? get_page_from_freelist+0x279/0x950 + [] ? vma_interval_tree_remove+0x158/0x230 + [] ? wp_page_copy.isra.82+0x2f4/0x630 + [] ? page_add_file_rmap+0x1d/0x50 + [] ? unlock_page+0x61/0x80 + [] ? filemap_map_pages+0x305/0x320 + [] ? handle_mm_fault+0xb7f/0x1560 + [] ? timerqueue_del+0x1b/0x70 + [] ? __remove_hrtimer+0x2e/0x60 + [] __hrtimer_run_queues+0xcb/0x2a0 + [] ? __perf_event_overflow+0x210/0x210 + [] hrtimer_interrupt+0x8a/0x180 + [] local_apic_timer_interrupt+0x32/0x60 + [] smp_apic_timer_interrupt+0x33/0x50 + [] apic_timer_interrupt+0x34/0x3c + Kernel Offset: disabled + ---[ end Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: c0404fbd + +The panic is caused by the fact that perf_callchain_user() mistakenly +assumes it's 64-bit only and ends up corrupting the stack. + +Signed-off-by: Josh Poimboeuf +Cc: Alexander Shishkin +Cc: Arnaldo Carvalho de Melo +Cc: Arnaldo Carvalho de Melo +Cc: Jiri Olsa +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Stephane Eranian +Cc: Thomas Gleixner +Cc: Vince Weaver +Fixes: 75925e1ad7f5 ("perf/x86: Optimize stack walk user accesses") +Link: http://lkml.kernel.org/r/1a547f5077ec30f75f9b57074837c3c80df86e5e.1467432113.git.jpoimboe@redhat.com +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/events/core.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/arch/x86/events/core.c ++++ b/arch/x86/events/core.c +@@ -2313,7 +2313,7 @@ void + perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) + { + struct stack_frame frame; +- const void __user *fp; ++ const unsigned long __user *fp; + + if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { + /* TODO: We don't support guest os callchain now */ +@@ -2326,7 +2326,7 @@ perf_callchain_user(struct perf_callchai + if (regs->flags & (X86_VM_MASK | PERF_EFLAGS_VM)) + return; + +- fp = (void __user *)regs->bp; ++ fp = (unsigned long __user *)regs->bp; + + perf_callchain_store(entry, regs->ip); + +@@ -2339,16 +2339,17 @@ perf_callchain_user(struct perf_callchai + pagefault_disable(); + while (entry->nr < PERF_MAX_STACK_DEPTH) { + unsigned long bytes; ++ + frame.next_frame = NULL; + frame.return_address = 0; + +- if (!access_ok(VERIFY_READ, fp, 16)) ++ if (!access_ok(VERIFY_READ, fp, sizeof(*fp) * 2)) + break; + +- bytes = __copy_from_user_nmi(&frame.next_frame, fp, 8); ++ bytes = __copy_from_user_nmi(&frame.next_frame, fp, sizeof(*fp)); + if (bytes != 0) + break; +- bytes = __copy_from_user_nmi(&frame.return_address, fp+8, 8); ++ bytes = __copy_from_user_nmi(&frame.return_address, fp + 1, sizeof(*fp)); + if (bytes != 0) + break; + diff --git a/queue-4.6/perf-x86-intel-rapl-fix-pmus-free-during-cleanup.patch b/queue-4.6/perf-x86-intel-rapl-fix-pmus-free-during-cleanup.patch new file mode 100644 index 00000000000..41a4c64ba17 --- /dev/null +++ b/queue-4.6/perf-x86-intel-rapl-fix-pmus-free-during-cleanup.patch @@ -0,0 +1,38 @@ +From 275ae411e56f8f900fa364da29c4706f9af4e1f3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Vincent=20Stehl=C3=A9?= +Date: Tue, 24 May 2016 16:53:49 +0200 +Subject: perf/x86/intel/rapl: Fix pmus free during cleanup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Vincent Stehlé + +commit 275ae411e56f8f900fa364da29c4706f9af4e1f3 upstream. + +On rapl cleanup path, kfree() is given by mistake the address of the +pointer of the structure to free (rapl_pmus->pmus + i). Pass the pointer +instead (rapl_pmus->pmus[i]). + +Fixes: 9de8d686955b "perf/x86/intel/rapl: Convert it to a per package facility" +Signed-off-by: Vincent Stehlé +Cc: Peter Zijlstra +Link: http://lkml.kernel.org/r/1464101629-14905-1-git-send-email-vincent.stehle@intel.com +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/events/intel/rapl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/events/intel/rapl.c ++++ b/arch/x86/events/intel/rapl.c +@@ -665,7 +665,7 @@ static void __init cleanup_rapl_pmus(voi + int i; + + for (i = 0; i < rapl_pmus->maxpkg; i++) +- kfree(rapl_pmus->pmus + i); ++ kfree(rapl_pmus->pmus[i]); + kfree(rapl_pmus); + } + diff --git a/queue-4.6/pnfs_nfs-fix-_cancel_empty_pagelist.patch b/queue-4.6/pnfs_nfs-fix-_cancel_empty_pagelist.patch new file mode 100644 index 00000000000..599da24da9b --- /dev/null +++ b/queue-4.6/pnfs_nfs-fix-_cancel_empty_pagelist.patch @@ -0,0 +1,53 @@ +From 5e3a98883e7ebdd1440f829a9e9dd5c3d2c5903b Mon Sep 17 00:00:00 2001 +From: Weston Andros Adamson +Date: Fri, 17 Jun 2016 16:48:24 -0400 +Subject: pnfs_nfs: fix _cancel_empty_pagelist + +From: Weston Andros Adamson + +commit 5e3a98883e7ebdd1440f829a9e9dd5c3d2c5903b upstream. + +pnfs_generic_commit_cancel_empty_pagelist calls nfs_commitdata_release, +but that is wrong: nfs_commitdata_release puts the open context, something +that isn't valid until nfs_init_commit is called, which is never the case +when pnfs_generic_commit_cancel_empty_pagelist is called. + +This was introduced in "nfs: avoid race that crashes nfs_init_commit". + +Signed-off-by: Weston Andros Adamson +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/pnfs_nfs.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/fs/nfs/pnfs_nfs.c ++++ b/fs/nfs/pnfs_nfs.c +@@ -247,7 +247,11 @@ void pnfs_fetch_commit_bucket_list(struc + } + + /* Helper function for pnfs_generic_commit_pagelist to catch an empty +- * page list. This can happen when two commits race. */ ++ * page list. This can happen when two commits race. ++ * ++ * This must be called instead of nfs_init_commit - call one or the other, but ++ * not both! ++ */ + static bool + pnfs_generic_commit_cancel_empty_pagelist(struct list_head *pages, + struct nfs_commit_data *data, +@@ -256,7 +260,11 @@ pnfs_generic_commit_cancel_empty_pagelis + if (list_empty(pages)) { + if (atomic_dec_and_test(&cinfo->mds->rpcs_out)) + wake_up_atomic_t(&cinfo->mds->rpcs_out); +- nfs_commitdata_release(data); ++ /* don't call nfs_commitdata_release - it tries to put ++ * the open_context which is not acquired until nfs_init_commit ++ * which has not been called on @data */ ++ WARN_ON_ONCE(data->context); ++ nfs_commit_free(data); + return true; + } + diff --git a/queue-4.6/powerpc-iommu-remove-the-dependency-on-eeh-struct-in-ddw-mechanism.patch b/queue-4.6/powerpc-iommu-remove-the-dependency-on-eeh-struct-in-ddw-mechanism.patch new file mode 100644 index 00000000000..38d885c2a3b --- /dev/null +++ b/queue-4.6/powerpc-iommu-remove-the-dependency-on-eeh-struct-in-ddw-mechanism.patch @@ -0,0 +1,89 @@ +From 8445a87f7092bc8336ea1305be9306f26b846d93 Mon Sep 17 00:00:00 2001 +From: "Guilherme G. Piccoli" +Date: Mon, 11 Apr 2016 16:17:23 -0300 +Subject: powerpc/iommu: Remove the dependency on EEH struct in DDW mechanism + +From: Guilherme G. Piccoli + +commit 8445a87f7092bc8336ea1305be9306f26b846d93 upstream. + +Commit 39baadbf36ce ("powerpc/eeh: Remove eeh information from pci_dn") +changed the pci_dn struct by removing its EEH-related members. +As part of this clean-up, DDW mechanism was modified to read the device +configuration address from eeh_dev struct. + +As a consequence, now if we disable EEH mechanism on kernel command-line +for example, the DDW mechanism will fail, generating a kernel oops by +dereferencing a NULL pointer (which turns to be the eeh_dev pointer). + +This patch just changes the configuration address calculation on DDW +functions to a manual calculation based on pci_dn members instead of +using eeh_dev-based address. + +No functional changes were made. This was tested on pSeries, both +in PHyp and qemu guest. + +Fixes: 39baadbf36ce ("powerpc/eeh: Remove eeh information from pci_dn") +Reviewed-by: Gavin Shan +Signed-off-by: Guilherme G. Piccoli +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/platforms/pseries/iommu.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +--- a/arch/powerpc/platforms/pseries/iommu.c ++++ b/arch/powerpc/platforms/pseries/iommu.c +@@ -912,7 +912,8 @@ machine_arch_initcall(pseries, find_exis + static int query_ddw(struct pci_dev *dev, const u32 *ddw_avail, + struct ddw_query_response *query) + { +- struct eeh_dev *edev; ++ struct device_node *dn; ++ struct pci_dn *pdn; + u32 cfg_addr; + u64 buid; + int ret; +@@ -923,11 +924,10 @@ static int query_ddw(struct pci_dev *dev + * Retrieve them from the pci device, not the node with the + * dma-window property + */ +- edev = pci_dev_to_eeh_dev(dev); +- cfg_addr = edev->config_addr; +- if (edev->pe_config_addr) +- cfg_addr = edev->pe_config_addr; +- buid = edev->phb->buid; ++ dn = pci_device_to_OF_node(dev); ++ pdn = PCI_DN(dn); ++ buid = pdn->phb->buid; ++ cfg_addr = (pdn->busno << 8) | pdn->devfn; + + ret = rtas_call(ddw_avail[0], 3, 5, (u32 *)query, + cfg_addr, BUID_HI(buid), BUID_LO(buid)); +@@ -941,7 +941,8 @@ static int create_ddw(struct pci_dev *de + struct ddw_create_response *create, int page_shift, + int window_shift) + { +- struct eeh_dev *edev; ++ struct device_node *dn; ++ struct pci_dn *pdn; + u32 cfg_addr; + u64 buid; + int ret; +@@ -952,11 +953,10 @@ static int create_ddw(struct pci_dev *de + * Retrieve them from the pci device, not the node with the + * dma-window property + */ +- edev = pci_dev_to_eeh_dev(dev); +- cfg_addr = edev->config_addr; +- if (edev->pe_config_addr) +- cfg_addr = edev->pe_config_addr; +- buid = edev->phb->buid; ++ dn = pci_device_to_OF_node(dev); ++ pdn = PCI_DN(dn); ++ buid = pdn->phb->buid; ++ cfg_addr = (pdn->busno << 8) | pdn->devfn; + + do { + /* extra outputs are LIOBN and dma-addr (hi, lo) */ diff --git a/queue-4.6/powerpc-pseries-fix-ibm_arch_vec_nrcores_offset-since-power8nvl-was-added.patch b/queue-4.6/powerpc-pseries-fix-ibm_arch_vec_nrcores_offset-since-power8nvl-was-added.patch new file mode 100644 index 00000000000..7076987ac53 --- /dev/null +++ b/queue-4.6/powerpc-pseries-fix-ibm_arch_vec_nrcores_offset-since-power8nvl-was-added.patch @@ -0,0 +1,42 @@ +From 2c2a63e301fd19ccae673e79de59b30a232ff7f9 Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Wed, 8 Jun 2016 10:01:23 +1000 +Subject: powerpc/pseries: Fix IBM_ARCH_VEC_NRCORES_OFFSET since POWER8NVL was added + +From: Michael Ellerman + +commit 2c2a63e301fd19ccae673e79de59b30a232ff7f9 upstream. + +The recent commit 7cc851039d64 ("powerpc/pseries: Add POWER8NVL support +to ibm,client-architecture-support call") added a new PVR mask & value +to the start of the ibm_architecture_vec[] array. + +However it missed the fact that further down in the array, we hard code +the offset of one of the fields, and then at boot use that value to +patch the value in the array. This means every update to the array must +also update the #define, ugh. + +This means that on pseries machines we will misreport to firmware the +number of cores we support, by a factor of threads_per_core. + +Fix it for now by updating the #define. + +Fixes: 7cc851039d64 ("powerpc/pseries: Add POWER8NVL support to ibm,client-architecture-support call") +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/prom_init.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/powerpc/kernel/prom_init.c ++++ b/arch/powerpc/kernel/prom_init.c +@@ -719,7 +719,7 @@ unsigned char ibm_architecture_vec[] = { + * must match by the macro below. Update the definition if + * the structure layout changes. + */ +-#define IBM_ARCH_VEC_NRCORES_OFFSET 125 ++#define IBM_ARCH_VEC_NRCORES_OFFSET 133 + W(NR_CPUS), /* number of cores supported */ + 0, + 0, diff --git a/queue-4.6/powerpc-pseries-fix-pci-config-address-for-ddw.patch b/queue-4.6/powerpc-pseries-fix-pci-config-address-for-ddw.patch new file mode 100644 index 00000000000..12d59707a65 --- /dev/null +++ b/queue-4.6/powerpc-pseries-fix-pci-config-address-for-ddw.patch @@ -0,0 +1,49 @@ +From 8a934efe94347eee843aeea65bdec8077a79e259 Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Thu, 26 May 2016 09:56:07 +1000 +Subject: powerpc/pseries: Fix PCI config address for DDW + +From: Gavin Shan + +commit 8a934efe94347eee843aeea65bdec8077a79e259 upstream. + +In commit 8445a87f7092 "powerpc/iommu: Remove the dependency on EEH +struct in DDW mechanism", the PE address was replaced with the PCI +config address in order to remove dependency on EEH. According to PAPR +spec, firmware (pHyp or QEMU) should accept "xxBBSSxx" format PCI config +address, not "xxxxBBSS" provided by the patch. Note that "BB" is PCI bus +number and "SS" is the combination of slot and function number. + +This fixes the PCI address passed to DDW RTAS calls. + +Fixes: 8445a87f7092 ("powerpc/iommu: Remove the dependency on EEH struct in DDW mechanism") +Reported-by: Guilherme G. Piccoli +Signed-off-by: Gavin Shan +Tested-by: Guilherme G. Piccoli +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/platforms/pseries/iommu.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/platforms/pseries/iommu.c ++++ b/arch/powerpc/platforms/pseries/iommu.c +@@ -927,7 +927,7 @@ static int query_ddw(struct pci_dev *dev + dn = pci_device_to_OF_node(dev); + pdn = PCI_DN(dn); + buid = pdn->phb->buid; +- cfg_addr = (pdn->busno << 8) | pdn->devfn; ++ cfg_addr = ((pdn->busno << 16) | (pdn->devfn << 8)); + + ret = rtas_call(ddw_avail[0], 3, 5, (u32 *)query, + cfg_addr, BUID_HI(buid), BUID_LO(buid)); +@@ -956,7 +956,7 @@ static int create_ddw(struct pci_dev *de + dn = pci_device_to_OF_node(dev); + pdn = PCI_DN(dn); + buid = pdn->phb->buid; +- cfg_addr = (pdn->busno << 8) | pdn->devfn; ++ cfg_addr = ((pdn->busno << 16) | (pdn->devfn << 8)); + + do { + /* extra outputs are LIOBN and dma-addr (hi, lo) */ diff --git a/queue-4.6/powerpc-tm-always-reclaim-in-start_thread-for-exec-class-syscalls.patch b/queue-4.6/powerpc-tm-always-reclaim-in-start_thread-for-exec-class-syscalls.patch new file mode 100644 index 00000000000..072d1a7833b --- /dev/null +++ b/queue-4.6/powerpc-tm-always-reclaim-in-start_thread-for-exec-class-syscalls.patch @@ -0,0 +1,110 @@ +From 8e96a87c5431c256feb65bcfc5aec92d9f7839b6 Mon Sep 17 00:00:00 2001 +From: Cyril Bur +Date: Fri, 17 Jun 2016 14:58:34 +1000 +Subject: powerpc/tm: Always reclaim in start_thread() for exec() class syscalls + +From: Cyril Bur + +commit 8e96a87c5431c256feb65bcfc5aec92d9f7839b6 upstream. + +Userspace can quite legitimately perform an exec() syscall with a +suspended transaction. exec() does not return to the old process, rather +it load a new one and starts that, the expectation therefore is that the +new process starts not in a transaction. Currently exec() is not treated +any differently to any other syscall which creates problems. + +Firstly it could allow a new process to start with a suspended +transaction for a binary that no longer exists. This means that the +checkpointed state won't be valid and if the suspended transaction were +ever to be resumed and subsequently aborted (a possibility which is +exceedingly likely as exec()ing will likely doom the transaction) the +new process will jump to invalid state. + +Secondly the incorrect attempt to keep the transactional state while +still zeroing state for the new process creates at least two TM Bad +Things. The first triggers on the rfid to return to userspace as +start_thread() has given the new process a 'clean' MSR but the suspend +will still be set in the hardware MSR. The second TM Bad Thing triggers +in __switch_to() as the processor is still transactionally suspended but +__switch_to() wants to zero the TM sprs for the new process. + +This is an example of the outcome of calling exec() with a suspended +transaction. Note the first 700 is likely the first TM bad thing +decsribed earlier only the kernel can't report it as we've loaded +userspace registers. c000000000009980 is the rfid in +fast_exception_return() + + Bad kernel stack pointer 3fffcfa1a370 at c000000000009980 + Oops: Bad kernel stack pointer, sig: 6 [#1] + CPU: 0 PID: 2006 Comm: tm-execed Not tainted + NIP: c000000000009980 LR: 0000000000000000 CTR: 0000000000000000 + REGS: c00000003ffefd40 TRAP: 0700 Not tainted + MSR: 8000000300201031 CR: 00000000 XER: 00000000 + CFAR: c0000000000098b4 SOFTE: 0 + PACATMSCRATCH: b00000010000d033 + GPR00: 0000000000000000 00003fffcfa1a370 0000000000000000 0000000000000000 + GPR04: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 + GPR08: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 + GPR12: 00003fff966611c0 0000000000000000 0000000000000000 0000000000000000 + NIP [c000000000009980] fast_exception_return+0xb0/0xb8 + LR [0000000000000000] (null) + Call Trace: + Instruction dump: + f84d0278 e9a100d8 7c7b03a6 e84101a0 7c4ff120 e8410170 7c5a03a6 e8010070 + e8410080 e8610088 e8810090 e8210078 <4c000024> 48000000 e8610178 88ed023b + + Kernel BUG at c000000000043e80 [verbose debug info unavailable] + Unexpected TM Bad Thing exception at c000000000043e80 (msr 0x201033) + Oops: Unrecoverable exception, sig: 6 [#2] + CPU: 0 PID: 2006 Comm: tm-execed Tainted: G D + task: c0000000fbea6d80 ti: c00000003ffec000 task.ti: c0000000fb7ec000 + NIP: c000000000043e80 LR: c000000000015a24 CTR: 0000000000000000 + REGS: c00000003ffef7e0 TRAP: 0700 Tainted: G D + MSR: 8000000300201033 CR: 28002828 XER: 00000000 + CFAR: c000000000015a20 SOFTE: 0 + PACATMSCRATCH: b00000010000d033 + GPR00: 0000000000000000 c00000003ffefa60 c000000000db5500 c0000000fbead000 + GPR04: 8000000300001033 2222222222222222 2222222222222222 00000000ff160000 + GPR08: 0000000000000000 800000010000d033 c0000000fb7e3ea0 c00000000fe00004 + GPR12: 0000000000002200 c00000000fe00000 0000000000000000 0000000000000000 + GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 + GPR20: 0000000000000000 0000000000000000 c0000000fbea7410 00000000ff160000 + GPR24: c0000000ffe1f600 c0000000fbea8700 c0000000fbea8700 c0000000fbead000 + GPR28: c000000000e20198 c0000000fbea6d80 c0000000fbeab680 c0000000fbea6d80 + NIP [c000000000043e80] tm_restore_sprs+0xc/0x1c + LR [c000000000015a24] __switch_to+0x1f4/0x420 + Call Trace: + Instruction dump: + 7c800164 4e800020 7c0022a6 f80304a8 7c0222a6 f80304b0 7c0122a6 f80304b8 + 4e800020 e80304a8 7c0023a6 e80304b0 <7c0223a6> e80304b8 7c0123a6 4e800020 + +This fixes CVE-2016-5828. + +Fixes: bc2a9408fa65 ("powerpc: Hook in new transactional memory code") +Signed-off-by: Cyril Bur +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/process.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/arch/powerpc/kernel/process.c ++++ b/arch/powerpc/kernel/process.c +@@ -1501,6 +1501,16 @@ void start_thread(struct pt_regs *regs, + current->thread.regs = regs - 1; + } + ++#ifdef CONFIG_PPC_TRANSACTIONAL_MEM ++ /* ++ * Clear any transactional state, we're exec()ing. The cause is ++ * not important as there will never be a recheckpoint so it's not ++ * user visible. ++ */ ++ if (MSR_TM_SUSPENDED(mfmsr())) ++ tm_reclaim_current(0); ++#endif ++ + memset(regs->gpr, 0, sizeof(regs->gpr)); + regs->ctr = 0; + regs->link = 0; diff --git a/queue-4.6/revert-gpiolib-split-gpio-flags-parsing-and-gpio-configuration.patch b/queue-4.6/revert-gpiolib-split-gpio-flags-parsing-and-gpio-configuration.patch new file mode 100644 index 00000000000..39d079909fd --- /dev/null +++ b/queue-4.6/revert-gpiolib-split-gpio-flags-parsing-and-gpio-configuration.patch @@ -0,0 +1,187 @@ +From 85b03b3033fd4eba82665b3b9902c095a08cc52f Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Sun, 3 Jul 2016 18:32:05 +0200 +Subject: Revert "gpiolib: Split GPIO flags parsing and GPIO configuration" + +From: Johan Hovold + +commit 85b03b3033fd4eba82665b3b9902c095a08cc52f upstream. + +This reverts commit 923b93e451db876d1479d3e4458fce14fec31d1c. + +Make sure consumers do not overwrite gpio flags for pins that have +already been claimed. + +While adding support for gpio drivers to refuse a request using +unsupported flags, the order of when the requested flag was checked and +the new flags were applied was reversed to that consumers could +overwrite flags for already requested gpios. + +This not only affects device-tree setups where two drivers could request +the same gpio using conflicting configurations, but also allowed user +space to clear gpio flags for already claimed pins simply by attempting +to export them through the sysfs interface. By for example clearing the +FLAG_ACTIVE_LOW flag this way, user space could effectively change the +polarity of a signal. + +Reverting this change obviously prevents gpio drivers from doing sanity +checks on the flags in their request callbacks. Fortunately only one +recently added driver (gpio-tps65218 in v4.6) appears to do this, and a +follow up patch could restore this functionality through a different +interface. + +Signed-off-by: Johan Hovold +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpio/gpiolib-legacy.c | 8 +++--- + drivers/gpio/gpiolib.c | 52 ++++++++++++------------------------------ + 2 files changed, 20 insertions(+), 40 deletions(-) + +--- a/drivers/gpio/gpiolib-legacy.c ++++ b/drivers/gpio/gpiolib-legacy.c +@@ -28,6 +28,10 @@ int gpio_request_one(unsigned gpio, unsi + if (!desc && gpio_is_valid(gpio)) + return -EPROBE_DEFER; + ++ err = gpiod_request(desc, label); ++ if (err) ++ return err; ++ + if (flags & GPIOF_OPEN_DRAIN) + set_bit(FLAG_OPEN_DRAIN, &desc->flags); + +@@ -37,10 +41,6 @@ int gpio_request_one(unsigned gpio, unsi + if (flags & GPIOF_ACTIVE_LOW) + set_bit(FLAG_ACTIVE_LOW, &desc->flags); + +- err = gpiod_request(desc, label); +- if (err) +- return err; +- + if (flags & GPIOF_DIR_IN) + err = gpiod_direction_input(desc); + else +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -1324,14 +1324,6 @@ static int __gpiod_request(struct gpio_d + spin_lock_irqsave(&gpio_lock, flags); + } + done: +- if (status < 0) { +- /* Clear flags that might have been set by the caller before +- * requesting the GPIO. +- */ +- clear_bit(FLAG_ACTIVE_LOW, &desc->flags); +- clear_bit(FLAG_OPEN_DRAIN, &desc->flags); +- clear_bit(FLAG_OPEN_SOURCE, &desc->flags); +- } + spin_unlock_irqrestore(&gpio_lock, flags); + return status; + } +@@ -2515,28 +2507,13 @@ struct gpio_desc *__must_check gpiod_get + } + EXPORT_SYMBOL_GPL(gpiod_get_optional); + +-/** +- * gpiod_parse_flags - helper function to parse GPIO lookup flags +- * @desc: gpio to be setup +- * @lflags: gpio_lookup_flags - returned from of_find_gpio() or +- * of_get_gpio_hog() +- * +- * Set the GPIO descriptor flags based on the given GPIO lookup flags. +- */ +-static void gpiod_parse_flags(struct gpio_desc *desc, unsigned long lflags) +-{ +- if (lflags & GPIO_ACTIVE_LOW) +- set_bit(FLAG_ACTIVE_LOW, &desc->flags); +- if (lflags & GPIO_OPEN_DRAIN) +- set_bit(FLAG_OPEN_DRAIN, &desc->flags); +- if (lflags & GPIO_OPEN_SOURCE) +- set_bit(FLAG_OPEN_SOURCE, &desc->flags); +-} + + /** + * gpiod_configure_flags - helper function to configure a given GPIO + * @desc: gpio whose value will be assigned + * @con_id: function within the GPIO consumer ++ * @lflags: gpio_lookup_flags - returned from of_find_gpio() or ++ * of_get_gpio_hog() + * @dflags: gpiod_flags - optional GPIO initialization flags + * + * Return 0 on success, -ENOENT if no GPIO has been assigned to the +@@ -2544,10 +2521,17 @@ static void gpiod_parse_flags(struct gpi + * occurred while trying to acquire the GPIO. + */ + static int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id, +- enum gpiod_flags dflags) ++ unsigned long lflags, enum gpiod_flags dflags) + { + int status; + ++ if (lflags & GPIO_ACTIVE_LOW) ++ set_bit(FLAG_ACTIVE_LOW, &desc->flags); ++ if (lflags & GPIO_OPEN_DRAIN) ++ set_bit(FLAG_OPEN_DRAIN, &desc->flags); ++ if (lflags & GPIO_OPEN_SOURCE) ++ set_bit(FLAG_OPEN_SOURCE, &desc->flags); ++ + /* No particular flag request, return here... */ + if (!(dflags & GPIOD_FLAGS_BIT_DIR_SET)) { + pr_debug("no flags found for %s\n", con_id); +@@ -2614,13 +2598,11 @@ struct gpio_desc *__must_check gpiod_get + return desc; + } + +- gpiod_parse_flags(desc, lookupflags); +- + status = gpiod_request(desc, con_id); + if (status < 0) + return ERR_PTR(status); + +- status = gpiod_configure_flags(desc, con_id, flags); ++ status = gpiod_configure_flags(desc, con_id, lookupflags, flags); + if (status < 0) { + dev_dbg(dev, "setup of GPIO %s failed\n", con_id); + gpiod_put(desc); +@@ -2676,6 +2658,10 @@ struct gpio_desc *fwnode_get_named_gpiod + if (IS_ERR(desc)) + return desc; + ++ ret = gpiod_request(desc, NULL); ++ if (ret) ++ return ERR_PTR(ret); ++ + if (active_low) + set_bit(FLAG_ACTIVE_LOW, &desc->flags); + +@@ -2686,10 +2672,6 @@ struct gpio_desc *fwnode_get_named_gpiod + set_bit(FLAG_OPEN_SOURCE, &desc->flags); + } + +- ret = gpiod_request(desc, NULL); +- if (ret) +- return ERR_PTR(ret); +- + return desc; + } + EXPORT_SYMBOL_GPL(fwnode_get_named_gpiod); +@@ -2742,8 +2724,6 @@ int gpiod_hog(struct gpio_desc *desc, co + chip = gpiod_to_chip(desc); + hwnum = gpio_chip_hwgpio(desc); + +- gpiod_parse_flags(desc, lflags); +- + local_desc = gpiochip_request_own_desc(chip, hwnum, name); + if (IS_ERR(local_desc)) { + pr_err("requesting hog GPIO %s (chip %s, offset %d) failed\n", +@@ -2751,7 +2731,7 @@ int gpiod_hog(struct gpio_desc *desc, co + return PTR_ERR(local_desc); + } + +- status = gpiod_configure_flags(desc, name, dflags); ++ status = gpiod_configure_flags(desc, name, lflags, dflags); + if (status < 0) { + pr_err("setup of hog GPIO %s (chip %s, offset %d) failed\n", + name, chip->label, hwnum); diff --git a/queue-4.6/rtlwifi-fix-scheduling-while-atomic-error-from-commit-49f86ec21c01.patch b/queue-4.6/rtlwifi-fix-scheduling-while-atomic-error-from-commit-49f86ec21c01.patch new file mode 100644 index 00000000000..f442d5e4401 --- /dev/null +++ b/queue-4.6/rtlwifi-fix-scheduling-while-atomic-error-from-commit-49f86ec21c01.patch @@ -0,0 +1,70 @@ +From de26859dcf363d520cc44e59f6dcaf20ebe0aadf Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Sat, 21 May 2016 11:50:35 -0500 +Subject: rtlwifi: Fix scheduling while atomic error from commit 49f86ec21c01 + +From: Larry Finger + +commit de26859dcf363d520cc44e59f6dcaf20ebe0aadf upstream. + +Commit 49f86ec21c01 ("rtlwifi: Change long delays to sleeps") was correct +for most cases; however, driver rtl8192ce calls the affected routines while +in atomic context. The kernel bug output is as follows: + +BUG: scheduling while atomic: wpa_supplicant/627/0x00000002 +[...] + [] __schedule+0x899/0xad0 + [] schedule+0x3c/0x90 + [] schedule_hrtimeout_range_clock+0xa2/0x120 + [] ? hrtimer_init+0x120/0x120 + [] ? schedule_hrtimeout_range_clock+0x96/0x120 + [] schedule_hrtimeout_range+0x13/0x20 + [] usleep_range+0x4f/0x70 + [] rtl_rfreg_delay+0x38/0x50 [rtlwifi] + [] rtl92c_phy_config_rf_with_headerfile+0xc7/0xe0 [rtl8192ce] + +To fix this bug, three of the changes from delay to sleep are reverted. +Unfortunately, one of the changes involves a delay of 50 msec. The calling +code will be modified so that this long delay can be avoided; however, +this change is being pushed now to fix the problem in kernel 4.6.0. + +Fixes: 49f86ec21c01 ("rtlwifi: Change long delays to sleeps") +Reported-by: James Feeney +Signed-off-by: Larry Finger +Cc: James Feeney +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/realtek/rtlwifi/core.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/realtek/rtlwifi/core.c ++++ b/drivers/net/wireless/realtek/rtlwifi/core.c +@@ -54,7 +54,7 @@ EXPORT_SYMBOL(channel5g_80m); + void rtl_addr_delay(u32 addr) + { + if (addr == 0xfe) +- msleep(50); ++ mdelay(50); + else if (addr == 0xfd) + msleep(5); + else if (addr == 0xfc) +@@ -75,7 +75,7 @@ void rtl_rfreg_delay(struct ieee80211_hw + rtl_addr_delay(addr); + } else { + rtl_set_rfreg(hw, rfpath, addr, mask, data); +- usleep_range(1, 2); ++ udelay(1); + } + } + EXPORT_SYMBOL(rtl_rfreg_delay); +@@ -86,7 +86,7 @@ void rtl_bb_delay(struct ieee80211_hw *h + rtl_addr_delay(addr); + } else { + rtl_set_bbreg(hw, addr, MASKDWORD, data); +- usleep_range(1, 2); ++ udelay(1); + } + } + EXPORT_SYMBOL(rtl_bb_delay); diff --git a/queue-4.6/sd-fix-rw_max-for-devices-that-report-an-optimal-xfer-size.patch b/queue-4.6/sd-fix-rw_max-for-devices-that-report-an-optimal-xfer-size.patch new file mode 100644 index 00000000000..97f6ec826fc --- /dev/null +++ b/queue-4.6/sd-fix-rw_max-for-devices-that-report-an-optimal-xfer-size.patch @@ -0,0 +1,58 @@ +From 6b7e9cde49691e04314342b7dce90c67ad567fcc Mon Sep 17 00:00:00 2001 +From: "Martin K. Petersen" +Date: Thu, 12 May 2016 22:17:34 -0400 +Subject: sd: Fix rw_max for devices that report an optimal xfer size + +From: Martin K. Petersen + +commit 6b7e9cde49691e04314342b7dce90c67ad567fcc upstream. + +For historic reasons, io_opt is in bytes and max_sectors in block layer +sectors. This interface inconsistency is error prone and should be +fixed. But for 4.4--4.7 let's make the unit difference explicit via a +wrapper function. + +Fixes: d0eb20a863ba ("sd: Optimal I/O size is in bytes, not sectors") +Reported-by: Fam Zheng +Reviewed-by: Bart Van Assche +Reviewed-by: Christoph Hellwig +Tested-by: Andrew Patterson +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/sd.c | 8 ++++---- + drivers/scsi/sd.h | 5 +++++ + 2 files changed, 9 insertions(+), 4 deletions(-) + +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -2862,10 +2862,10 @@ static int sd_revalidate_disk(struct gen + if (sdkp->opt_xfer_blocks && + sdkp->opt_xfer_blocks <= dev_max && + sdkp->opt_xfer_blocks <= SD_DEF_XFER_BLOCKS && +- sdkp->opt_xfer_blocks * sdp->sector_size >= PAGE_SIZE) +- rw_max = q->limits.io_opt = +- sdkp->opt_xfer_blocks * sdp->sector_size; +- else ++ logical_to_bytes(sdp, sdkp->opt_xfer_blocks) >= PAGE_SIZE) { ++ q->limits.io_opt = logical_to_bytes(sdp, sdkp->opt_xfer_blocks); ++ rw_max = logical_to_sectors(sdp, sdkp->opt_xfer_blocks); ++ } else + rw_max = BLK_DEF_MAX_SECTORS; + + /* Combine with controller limits */ +--- a/drivers/scsi/sd.h ++++ b/drivers/scsi/sd.h +@@ -151,6 +151,11 @@ static inline sector_t logical_to_sector + return blocks << (ilog2(sdev->sector_size) - 9); + } + ++static inline unsigned int logical_to_bytes(struct scsi_device *sdev, sector_t blocks) ++{ ++ return blocks * sdev->sector_size; ++} ++ + /* + * A DIF-capable target device can be formatted with different + * protection schemes. Currently 0 through 3 are defined: diff --git a/queue-4.6/thermal-cpu_cooling-fix-improper-order-during-initialization.patch b/queue-4.6/thermal-cpu_cooling-fix-improper-order-during-initialization.patch new file mode 100644 index 00000000000..244c6e7674d --- /dev/null +++ b/queue-4.6/thermal-cpu_cooling-fix-improper-order-during-initialization.patch @@ -0,0 +1,60 @@ +From f840ab18bdf2e415dac21d09fbbbd2873111bd48 Mon Sep 17 00:00:00 2001 +From: Lukasz Luba +Date: Tue, 31 May 2016 11:32:02 +0100 +Subject: thermal: cpu_cooling: fix improper order during initialization + +From: Lukasz Luba + +commit f840ab18bdf2e415dac21d09fbbbd2873111bd48 upstream. + +The freq_table array is not populated before calling +thermal_of_cooling_register. The code which populates the freq table was +introduced in commit f6859014. +This should be done before registering new thermal cooling device. +The log shows effects of this wrong decision. +[ 2.172614] cpu cpu1: Failed to get voltage for frequency 1984518656000: -34 +[ 2.220863] cpu cpu0: Failed to get voltage for frequency 1984524416000: -34 + +Fixes: f6859014c7e7 ("thermal: cpu_cooling: Store frequencies in descending order") +Signed-off-by: Lukasz Luba +Acked-by: Javi Merino +Acked-by: Viresh Kumar +Signed-off-by: Zhang Rui +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/thermal/cpu_cooling.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/thermal/cpu_cooling.c ++++ b/drivers/thermal/cpu_cooling.c +@@ -857,14 +857,6 @@ __cpufreq_cooling_register(struct device + goto free_power_table; + } + +- snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", +- cpufreq_dev->id); +- +- cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev, +- &cpufreq_cooling_ops); +- if (IS_ERR(cool_dev)) +- goto remove_idr; +- + /* Fill freq-table in descending order of frequencies */ + for (i = 0, freq = -1; i <= cpufreq_dev->max_level; i++) { + freq = find_next_max(table, freq); +@@ -877,6 +869,14 @@ __cpufreq_cooling_register(struct device + pr_debug("%s: freq:%u KHz\n", __func__, freq); + } + ++ snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", ++ cpufreq_dev->id); ++ ++ cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev, ++ &cpufreq_cooling_ops); ++ if (IS_ERR(cool_dev)) ++ goto remove_idr; ++ + cpufreq_dev->clipped_freq = cpufreq_dev->freq_table[0]; + cpufreq_dev->cool_dev = cool_dev; + diff --git a/queue-4.6/usb-common-otg-fsm-add-license-to-usb-otg-fsm.patch b/queue-4.6/usb-common-otg-fsm-add-license-to-usb-otg-fsm.patch new file mode 100644 index 00000000000..be67ebb2702 --- /dev/null +++ b/queue-4.6/usb-common-otg-fsm-add-license-to-usb-otg-fsm.patch @@ -0,0 +1,36 @@ +From ea1d39a31d3b1b6060b6e83e5a29c069a124c68a Mon Sep 17 00:00:00 2001 +From: Oscar +Date: Tue, 14 Jun 2016 14:14:35 +0800 +Subject: usb: common: otg-fsm: add license to usb-otg-fsm + +From: Oscar + +commit ea1d39a31d3b1b6060b6e83e5a29c069a124c68a upstream. + +Fix warning about tainted kernel because usb-otg-fsm has no license. +WARNING: with this patch usb-otg-fsm module can be loaded +but then the kernel will hang. Tested with a udoo quad board. + +Signed-off-by: Oscar +Signed-off-by: Peter Chen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/common/usb-otg-fsm.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/common/usb-otg-fsm.c ++++ b/drivers/usb/common/usb-otg-fsm.c +@@ -21,6 +21,7 @@ + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + ++#include + #include + #include + #include +@@ -452,3 +453,4 @@ int otg_statemachine(struct otg_fsm *fsm + return state_changed; + } + EXPORT_SYMBOL_GPL(otg_statemachine); ++MODULE_LICENSE("GPL"); diff --git a/queue-4.6/usb-don-t-free-bandwidth_mutex-too-early.patch b/queue-4.6/usb-don-t-free-bandwidth_mutex-too-early.patch new file mode 100644 index 00000000000..df493b35975 --- /dev/null +++ b/queue-4.6/usb-don-t-free-bandwidth_mutex-too-early.patch @@ -0,0 +1,122 @@ +From ab2a4bf83902c170d29ba130a8abb5f9d90559e1 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Mon, 27 Jun 2016 10:23:10 -0400 +Subject: USB: don't free bandwidth_mutex too early + +From: Alan Stern + +commit ab2a4bf83902c170d29ba130a8abb5f9d90559e1 upstream. + +The USB core contains a bug that can show up when a USB-3 host +controller is removed. If the primary (USB-2) hcd structure is +released before the shared (USB-3) hcd, the core will try to do a +double-free of the common bandwidth_mutex. + +The problem was described in graphical form by Chung-Geol Kim, who +first reported it: + +================================================= + At *remove USB(3.0) Storage + sequence <1> --> <5> ((Problem Case)) +================================================= + VOLD +------------------------------------|------------ + (uevent) + ________|_________ + |<1> | + |dwc3_otg_sm_work | + |usb_put_hcd | + |peer_hcd(kref=2)| + |__________________| + ________|_________ + |<2> | + |New USB BUS #2 | + | | + |peer_hcd(kref=1) | + | | + --(Link)-bandXX_mutex| + | |__________________| + | + ___________________ | + |<3> | | + |dwc3_otg_sm_work | | + |usb_put_hcd | | + |primary_hcd(kref=1)| | + |___________________| | + _________|_________ | + |<4> | | + |New USB BUS #1 | | + |hcd_release | | + |primary_hcd(kref=0)| | + | | | + |bandXX_mutex(free) |<- + |___________________| + (( VOLD )) + ______|___________ + |<5> | + | SCSI | + |usb_put_hcd | + |peer_hcd(kref=0) | + |*hcd_release | + |bandXX_mutex(free*)|<- double free + |__________________| + +================================================= + +This happens because hcd_release() frees the bandwidth_mutex whenever +it sees a primary hcd being released (which is not a very good idea +in any case), but in the course of releasing the primary hcd, it +changes the pointers in the shared hcd in such a way that the shared +hcd will appear to be primary when it gets released. + +This patch fixes the problem by changing hcd_release() so that it +deallocates the bandwidth_mutex only when the _last_ hcd structure +referencing it is released. The patch also removes an unnecessary +test, so that when an hcd is released, both the shared_hcd and +primary_hcd pointers in the hcd's peer will be cleared. + +Signed-off-by: Alan Stern +Reported-by: Chung-Geol Kim +Tested-by: Chung-Geol Kim +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hcd.c | 17 +++++++---------- + 1 file changed, 7 insertions(+), 10 deletions(-) + +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -2597,26 +2597,23 @@ EXPORT_SYMBOL_GPL(usb_create_hcd); + * Don't deallocate the bandwidth_mutex until the last shared usb_hcd is + * deallocated. + * +- * Make sure to only deallocate the bandwidth_mutex when the primary HCD is +- * freed. When hcd_release() is called for either hcd in a peer set +- * invalidate the peer's ->shared_hcd and ->primary_hcd pointers to +- * block new peering attempts ++ * Make sure to deallocate the bandwidth_mutex only when the last HCD is ++ * freed. When hcd_release() is called for either hcd in a peer set, ++ * invalidate the peer's ->shared_hcd and ->primary_hcd pointers. + */ + static void hcd_release(struct kref *kref) + { + struct usb_hcd *hcd = container_of (kref, struct usb_hcd, kref); + + mutex_lock(&usb_port_peer_mutex); +- if (usb_hcd_is_primary_hcd(hcd)) { +- kfree(hcd->address0_mutex); +- kfree(hcd->bandwidth_mutex); +- } + if (hcd->shared_hcd) { + struct usb_hcd *peer = hcd->shared_hcd; + + peer->shared_hcd = NULL; +- if (peer->primary_hcd == hcd) +- peer->primary_hcd = NULL; ++ peer->primary_hcd = NULL; ++ } else { ++ kfree(hcd->address0_mutex); ++ kfree(hcd->bandwidth_mutex); + } + mutex_unlock(&usb_port_peer_mutex); + kfree(hcd); diff --git a/queue-4.6/usb-dwc2-fix-regression-on-big-endian-powerpc-arm-systems.patch b/queue-4.6/usb-dwc2-fix-regression-on-big-endian-powerpc-arm-systems.patch new file mode 100644 index 00000000000..f357494e29a --- /dev/null +++ b/queue-4.6/usb-dwc2-fix-regression-on-big-endian-powerpc-arm-systems.patch @@ -0,0 +1,98 @@ +From 23e3439296a55affce3ef0ab78f1c2e03aec8767 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Fri, 13 May 2016 15:52:27 +0200 +Subject: usb: dwc2: fix regression on big-endian PowerPC/ARM systems + +From: Arnd Bergmann + +commit 23e3439296a55affce3ef0ab78f1c2e03aec8767 upstream. + +A patch that went into Linux-4.4 to fix big-endian mode on a Lantiq +MIPS system unfortunately broke big-endian operation on PowerPC +APM82181 as reported by Christian Lamparter, and likely other +systems. + +It actually introduced multiple issues: + +- it broke big-endian ARM kernels: any machine that was working + correctly with a little-endian kernel is no longer using byteswaps + on big-endian kernels, which clearly breaks them. +- On PowerPC the same thing must be true: if it was working before, + using big-endian kernels is now broken. Unlike ARM, 32-bit PowerPC + usually uses big-endian kernels, so they are likely all broken. +- The barrier for dwc2_writel is on the wrong side of the __raw_writel(), + so the MMIO no longer synchronizes with DMA operations. +- On architectures that require specific CPU instructions for MMIO + access, using the __raw_ variant may turn this into a pointer + dereference that does not have the same effect as the readl/writel. + +This patch is a simple revert for all architectures other than MIPS, +in the hope that we can more easily backport it to fix the regression +on PowerPC and ARM systems without breaking the Lantiq system again. + +We should follow this up with a more elaborate change to add runtime +detection of endianness, to make sure it also works on all other +combinations of architectures and implementations of the usb-dwc2 +device. That patch however will be fairly large and not appropriate +for backports to stable kernels. + +Felipe suggested a different approach, using an endianness switching +register to always put the device into LE mode, but unfortunately +the dwc2 hardware does not provide a generic way to do that. Also, +I see no practical way of addressing the problem more generally by +patching architecture specific code on MIPS. + +Fixes: 95c8bc360944 ("usb: dwc2: Use platform endianness when accessing registers") +Acked-by: John Youn +Tested-by: Christian Lamparter +Signed-off-by: Arnd Bergmann +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc2/core.h | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +--- a/drivers/usb/dwc2/core.h ++++ b/drivers/usb/dwc2/core.h +@@ -64,6 +64,17 @@ + DWC2_TRACE_SCHEDULER_VB(pr_fmt("%s: SCH: " fmt), \ + dev_name(hsotg->dev), ##__VA_ARGS__) + ++#ifdef CONFIG_MIPS ++/* ++ * There are some MIPS machines that can run in either big-endian ++ * or little-endian mode and that use the dwc2 register without ++ * a byteswap in both ways. ++ * Unlike other architectures, MIPS apparently does not require a ++ * barrier before the __raw_writel() to synchronize with DMA but does ++ * require the barrier after the __raw_writel() to serialize a set of ++ * writes. This set of operations was added specifically for MIPS and ++ * should only be used there. ++ */ + static inline u32 dwc2_readl(const void __iomem *addr) + { + u32 value = __raw_readl(addr); +@@ -90,6 +101,22 @@ static inline void dwc2_writel(u32 value + pr_info("INFO:: wrote %08x to %p\n", value, addr); + #endif + } ++#else ++/* Normal architectures just use readl/write */ ++static inline u32 dwc2_readl(const void __iomem *addr) ++{ ++ return readl(addr); ++} ++ ++static inline void dwc2_writel(u32 value, void __iomem *addr) ++{ ++ writel(value, addr); ++ ++#ifdef DWC2_LOG_WRITES ++ pr_info("info:: wrote %08x to %p\n", value, addr); ++#endif ++} ++#endif + + /* Maximum number of Endpoints/HostChannels */ + #define MAX_EPS_CHANNELS 16 diff --git a/queue-4.6/usb-ehci-declare-hostpc-register-as-zero-length-array.patch b/queue-4.6/usb-ehci-declare-hostpc-register-as-zero-length-array.patch new file mode 100644 index 00000000000..f0774153799 --- /dev/null +++ b/queue-4.6/usb-ehci-declare-hostpc-register-as-zero-length-array.patch @@ -0,0 +1,41 @@ +From 7e8b3dfef16375dbfeb1f36a83eb9f27117c51fd Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Thu, 23 Jun 2016 14:54:37 -0400 +Subject: USB: EHCI: declare hostpc register as zero-length array + +From: Alan Stern + +commit 7e8b3dfef16375dbfeb1f36a83eb9f27117c51fd upstream. + +The HOSTPC extension registers found in some EHCI implementations form +a variable-length array, with one element for each port. Therefore +the hostpc field in struct ehci_regs should be declared as a +zero-length array, not a single-element array. + +This fixes a problem reported by UBSAN. + +Signed-off-by: Alan Stern +Reported-by: Wilfried Klaebe +Tested-by: Wilfried Klaebe +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/usb/ehci_def.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/include/linux/usb/ehci_def.h ++++ b/include/linux/usb/ehci_def.h +@@ -180,11 +180,11 @@ struct ehci_regs { + * PORTSCx + */ + /* HOSTPC: offset 0x84 */ +- u32 hostpc[1]; /* HOSTPC extension */ ++ u32 hostpc[0]; /* HOSTPC extension */ + #define HOSTPC_PHCD (1<<22) /* Phy clock disable */ + #define HOSTPC_PSPD (3<<25) /* Port speed detection */ + +- u32 reserved5[16]; ++ u32 reserved5[17]; + + /* USBMODE_EX: offset 0xc8 */ + u32 usbmode_ex; /* USB Device mode extension */ diff --git a/queue-4.6/uvc-forward-compat-ioctls-to-their-handlers-directly.patch b/queue-4.6/uvc-forward-compat-ioctls-to-their-handlers-directly.patch new file mode 100644 index 00000000000..aab42977c92 --- /dev/null +++ b/queue-4.6/uvc-forward-compat-ioctls-to-their-handlers-directly.patch @@ -0,0 +1,87 @@ +From a44323e2a8f342848bb77e8e04fcd85fcb91b3b4 Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +Date: Tue, 24 May 2016 15:13:02 -0700 +Subject: uvc: Forward compat ioctls to their handlers directly + +From: Andy Lutomirski + +commit a44323e2a8f342848bb77e8e04fcd85fcb91b3b4 upstream. + +The current code goes through a lot of indirection just to call a +known handler. Simplify it: just call the handlers directly. + +Signed-off-by: Andy Lutomirski +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/usb/uvc/uvc_v4l2.c | 39 ++++++++++++++++++--------------------- + 1 file changed, 18 insertions(+), 21 deletions(-) + +--- a/drivers/media/usb/uvc/uvc_v4l2.c ++++ b/drivers/media/usb/uvc/uvc_v4l2.c +@@ -1408,47 +1408,44 @@ static int uvc_v4l2_put_xu_query(const s + static long uvc_v4l2_compat_ioctl32(struct file *file, + unsigned int cmd, unsigned long arg) + { ++ struct uvc_fh *handle = file->private_data; + union { + struct uvc_xu_control_mapping xmap; + struct uvc_xu_control_query xqry; + } karg; + void __user *up = compat_ptr(arg); +- mm_segment_t old_fs; + long ret; + + switch (cmd) { + case UVCIOC_CTRL_MAP32: +- cmd = UVCIOC_CTRL_MAP; + ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up); ++ if (ret) ++ return ret; ++ ret = uvc_ioctl_ctrl_map(handle->chain, &karg.xmap); ++ if (ret) ++ return ret; ++ ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up); ++ if (ret) ++ return ret; ++ + break; + + case UVCIOC_CTRL_QUERY32: +- cmd = UVCIOC_CTRL_QUERY; + ret = uvc_v4l2_get_xu_query(&karg.xqry, up); ++ if (ret) ++ return ret; ++ ret = uvc_xu_ctrl_query(handle->chain, &karg.xqry); ++ if (ret) ++ return ret; ++ ret = uvc_v4l2_put_xu_query(&karg.xqry, up); ++ if (ret) ++ return ret; + break; + + default: + return -ENOIOCTLCMD; + } + +- old_fs = get_fs(); +- set_fs(KERNEL_DS); +- ret = video_ioctl2(file, cmd, (unsigned long)&karg); +- set_fs(old_fs); +- +- if (ret < 0) +- return ret; +- +- switch (cmd) { +- case UVCIOC_CTRL_MAP: +- ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up); +- break; +- +- case UVCIOC_CTRL_QUERY: +- ret = uvc_v4l2_put_xu_query(&karg.xqry, up); +- break; +- } +- + return ret; + } + #endif diff --git a/queue-4.6/writeback-use-higher-precision-calculation-in-domain_dirty_limits.patch b/queue-4.6/writeback-use-higher-precision-calculation-in-domain_dirty_limits.patch new file mode 100644 index 00000000000..a91c7d9dd59 --- /dev/null +++ b/queue-4.6/writeback-use-higher-precision-calculation-in-domain_dirty_limits.patch @@ -0,0 +1,85 @@ +From 62a584fe05eef1f80ed49a286a29328f1a224fb9 Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Fri, 27 May 2016 14:34:46 -0400 +Subject: writeback: use higher precision calculation in domain_dirty_limits() + +From: Tejun Heo + +commit 62a584fe05eef1f80ed49a286a29328f1a224fb9 upstream. + +As vm.dirty_[background_]bytes can't be applied verbatim to multiple +cgroup writeback domains, they get converted to percentages in +domain_dirty_limits() and applied the same way as +vm.dirty_[background]ratio. However, if the specified bytes is lower +than 1% of available memory, the calculated ratios become zero and the +writeback domain gets throttled constantly. + +Fix it by using per-PAGE_SIZE instead of percentage for ratio +calculations. Also, the updated DIV_ROUND_UP() usages now should +yield 1/4096 (0.0244%) as the minimum ratio as long as the specified +bytes are above zero. + +Signed-off-by: Tejun Heo +Reported-by: Miao Xie +Link: http://lkml.kernel.org/g/57333E75.3080309@huawei.com +Fixes: 9fc3a43e1757 ("writeback: separate out domain_dirty_limits()") +Reviewed-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +Adjusted comment based on Jan's suggestion. +Signed-off-by: Jens Axboe + +--- + mm/page-writeback.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +--- a/mm/page-writeback.c ++++ b/mm/page-writeback.c +@@ -369,8 +369,9 @@ static void domain_dirty_limits(struct d + struct dirty_throttle_control *gdtc = mdtc_gdtc(dtc); + unsigned long bytes = vm_dirty_bytes; + unsigned long bg_bytes = dirty_background_bytes; +- unsigned long ratio = vm_dirty_ratio; +- unsigned long bg_ratio = dirty_background_ratio; ++ /* convert ratios to per-PAGE_SIZE for higher precision */ ++ unsigned long ratio = (vm_dirty_ratio * PAGE_SIZE) / 100; ++ unsigned long bg_ratio = (dirty_background_ratio * PAGE_SIZE) / 100; + unsigned long thresh; + unsigned long bg_thresh; + struct task_struct *tsk; +@@ -382,26 +383,28 @@ static void domain_dirty_limits(struct d + /* + * The byte settings can't be applied directly to memcg + * domains. Convert them to ratios by scaling against +- * globally available memory. ++ * globally available memory. As the ratios are in ++ * per-PAGE_SIZE, they can be obtained by dividing bytes by ++ * number of pages. + */ + if (bytes) +- ratio = min(DIV_ROUND_UP(bytes, PAGE_SIZE) * 100 / +- global_avail, 100UL); ++ ratio = min(DIV_ROUND_UP(bytes, global_avail), ++ PAGE_SIZE); + if (bg_bytes) +- bg_ratio = min(DIV_ROUND_UP(bg_bytes, PAGE_SIZE) * 100 / +- global_avail, 100UL); ++ bg_ratio = min(DIV_ROUND_UP(bg_bytes, global_avail), ++ PAGE_SIZE); + bytes = bg_bytes = 0; + } + + if (bytes) + thresh = DIV_ROUND_UP(bytes, PAGE_SIZE); + else +- thresh = (ratio * available_memory) / 100; ++ thresh = (ratio * available_memory) / PAGE_SIZE; + + if (bg_bytes) + bg_thresh = DIV_ROUND_UP(bg_bytes, PAGE_SIZE); + else +- bg_thresh = (bg_ratio * available_memory) / 100; ++ bg_thresh = (bg_ratio * available_memory) / PAGE_SIZE; + + if (bg_thresh >= thresh) + bg_thresh = thresh / 2; diff --git a/queue-4.6/x86-amd_nb-fix-boot-crash-on-non-amd-systems.patch b/queue-4.6/x86-amd_nb-fix-boot-crash-on-non-amd-systems.patch new file mode 100644 index 00000000000..97b66056514 --- /dev/null +++ b/queue-4.6/x86-amd_nb-fix-boot-crash-on-non-amd-systems.patch @@ -0,0 +1,51 @@ +From 1ead852dd88779eda12cb09cc894a03d9abfe1ec Mon Sep 17 00:00:00 2001 +From: Borislav Petkov +Date: Thu, 16 Jun 2016 19:13:49 +0200 +Subject: x86/amd_nb: Fix boot crash on non-AMD systems + +From: Borislav Petkov + +commit 1ead852dd88779eda12cb09cc894a03d9abfe1ec upstream. + +Fix boot crash that triggers if this driver is built into a kernel and +run on non-AMD systems. + +AMD northbridges users call amd_cache_northbridges() and it returns +a negative value to signal that we weren't able to cache/detect any +northbridges on the system. + +At least, it should do so as all its callers expect it to do so. But it +does return a negative value only when kmalloc() fails. + +Fix it to return -ENODEV if there are no NBs cached as otherwise, amd_nb +users like amd64_edac, for example, which relies on it to know whether +it should load or not, gets loaded on systems like Intel Xeons where it +shouldn't. + +Reported-and-tested-by: Tony Battersby +Signed-off-by: Borislav Petkov +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Link: http://lkml.kernel.org/r/1466097230-5333-2-git-send-email-bp@alien8.de +Link: https://lkml.kernel.org/r/5761BEB0.9000807@cybernetics.com +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/amd_nb.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/x86/kernel/amd_nb.c ++++ b/arch/x86/kernel/amd_nb.c +@@ -71,8 +71,8 @@ int amd_cache_northbridges(void) + while ((misc = next_northbridge(misc, amd_nb_misc_ids)) != NULL) + i++; + +- if (i == 0) +- return 0; ++ if (!i) ++ return -ENODEV; + + nb = kzalloc(i * sizeof(struct amd_northbridge), GFP_KERNEL); + if (!nb) diff --git a/queue-4.6/x86-build-copy-ldlinux.c32-to-image.iso.patch b/queue-4.6/x86-build-copy-ldlinux.c32-to-image.iso.patch new file mode 100644 index 00000000000..42e7ce0a4f8 --- /dev/null +++ b/queue-4.6/x86-build-copy-ldlinux.c32-to-image.iso.patch @@ -0,0 +1,32 @@ +From 9c77679cadb118c0aa99e6f88533d91765a131ba Mon Sep 17 00:00:00 2001 +From: "H. Peter Anvin" +Date: Tue, 5 Apr 2016 17:01:33 -0700 +Subject: x86, build: copy ldlinux.c32 to image.iso + +From: H. Peter Anvin + +commit 9c77679cadb118c0aa99e6f88533d91765a131ba upstream. + +For newer versions of Syslinux, we need ldlinux.c32 in addition to +isolinux.bin to reside on the boot disk, so if the latter is found, +copy it, too, to the isoimage tree. + +Signed-off-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/boot/Makefile | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/x86/boot/Makefile ++++ b/arch/x86/boot/Makefile +@@ -171,6 +171,9 @@ isoimage: $(obj)/bzImage + for i in lib lib64 share end ; do \ + if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \ + cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \ ++ if [ -f /usr/$$i/syslinux/ldlinux.c32 ]; then \ ++ cp /usr/$$i/syslinux/ldlinux.c32 $(obj)/isoimage ; \ ++ fi ; \ + break ; \ + fi ; \ + if [ $$i = end ] ; then exit 1 ; fi ; \ diff --git a/queue-4.6/x86-msr-use-the-proper-trace-point-conditional-for-writes.patch b/queue-4.6/x86-msr-use-the-proper-trace-point-conditional-for-writes.patch new file mode 100644 index 00000000000..7a112d3f50a --- /dev/null +++ b/queue-4.6/x86-msr-use-the-proper-trace-point-conditional-for-writes.patch @@ -0,0 +1,42 @@ +From 08dd8cd06ed95625b9e2fac43c78fcb45b7eaf94 Mon Sep 17 00:00:00 2001 +From: "Dr. David Alan Gilbert" +Date: Fri, 3 Jun 2016 19:00:59 +0100 +Subject: x86/msr: Use the proper trace point conditional for writes + +From: Dr. David Alan Gilbert + +commit 08dd8cd06ed95625b9e2fac43c78fcb45b7eaf94 upstream. + +The msr tracing for writes is incorrectly conditional on the read trace. + +Fixes: 7f47d8cc039f "x86, tracing, perf: Add trace point for MSR accesses" +Signed-off-by: Dr. David Alan Gilbert +Cc: ak@linux.intel.com +Link: http://lkml.kernel.org/r/1464976859-21850-1-git-send-email-dgilbert@redhat.com +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/msr.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/x86/include/asm/msr.h ++++ b/arch/x86/include/asm/msr.h +@@ -112,7 +112,7 @@ static inline void native_write_msr(unsi + unsigned low, unsigned high) + { + asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory"); +- if (msr_tracepoint_active(__tracepoint_read_msr)) ++ if (msr_tracepoint_active(__tracepoint_write_msr)) + do_trace_write_msr(msr, ((u64)high << 32 | low), 0); + } + +@@ -131,7 +131,7 @@ notrace static inline int native_write_m + : "c" (msr), "0" (low), "d" (high), + [fault] "i" (-EIO) + : "memory"); +- if (msr_tracepoint_active(__tracepoint_read_msr)) ++ if (msr_tracepoint_active(__tracepoint_write_msr)) + do_trace_write_msr(msr, ((u64)high << 32 | low), err); + return err; + } -- 2.47.3