From: Greg Kroah-Hartman Date: Mon, 11 Jul 2016 22:47:41 +0000 (-0700) Subject: 4.4-stable patches X-Git-Tag: v4.6.5~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=32b370f0405a814b93fe2a0a39d5ae6aa5f85f02;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: edac-sb_edac-fix-rank-lookup-on-broadwell.patch ib-cm-fix-a-recently-introduced-locking-bug.patch ib-mlx4-properly-initialize-grh-tclass-and-flowlabel-in-ahs.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-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 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 thermal-cpu_cooling-fix-improper-order-during-initialization.patch usb-common-otg-fsm-add-license-to-usb-otg-fsm.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 --- diff --git a/queue-4.4/edac-sb_edac-fix-rank-lookup-on-broadwell.patch b/queue-4.4/edac-sb_edac-fix-rank-lookup-on-broadwell.patch new file mode 100644 index 00000000000..59335e3b358 --- /dev/null +++ b/queue-4.4/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 +@@ -218,8 +218,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 */ + +@@ -1175,14 +1178,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); + } + } +@@ -1512,7 +1515,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.4/ib-cm-fix-a-recently-introduced-locking-bug.patch b/queue-4.4/ib-cm-fix-a-recently-introduced-locking-bug.patch new file mode 100644 index 00000000000..fbdce4877a3 --- /dev/null +++ b/queue-4.4/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 +@@ -3430,14 +3430,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.4/ib-mlx4-properly-initialize-grh-tclass-and-flowlabel-in-ahs.patch b/queue-4.4/ib-mlx4-properly-initialize-grh-tclass-and-flowlabel-in-ahs.patch new file mode 100644 index 00000000000..b6d2e96ea41 --- /dev/null +++ b/queue-4.4/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.4/kprobes-x86-clear-tf-bit-in-fault-on-single-stepping.patch b/queue-4.4/kprobes-x86-clear-tf-bit-in-fault-on-single-stepping.patch new file mode 100644 index 00000000000..9745a538aa4 --- /dev/null +++ b/queue-4.4/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 +@@ -959,7 +959,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.4/locking-qspinlock-fix-spin_unlock_wait-some-more.patch b/queue-4.4/locking-qspinlock-fix-spin_unlock_wait-some-more.patch new file mode 100644 index 00000000000..13b09cf8367 --- /dev/null +++ b/queue-4.4/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 +@@ -21,37 +21,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? +@@ -121,21 +117,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 +@@ -255,6 +255,66 @@ static __always_inline void __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.4/locking-static_key-fix-concurrent-static_key_slow_inc.patch b/queue-4.4/locking-static_key-fix-concurrent-static_key_slow_inc.patch new file mode 100644 index 00000000000..192501ecff9 --- /dev/null +++ b/queue-4.4/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.4/locking-ww_mutex-report-recursive-ww_mutex-locking-early.patch b/queue-4.4/locking-ww_mutex-report-recursive-ww_mutex-locking-early.patch new file mode 100644 index 00000000000..01ab60cfa0c --- /dev/null +++ b/queue-4.4/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.4/mac80211-fix-fast_tx-header-alignment.patch b/queue-4.4/mac80211-fix-fast_tx-header-alignment.patch new file mode 100644 index 00000000000..1ec521eb965 --- /dev/null +++ b/queue-4.4/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 +@@ -269,7 +269,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.4/mac80211-fix-mesh-estab_plinks-counting-in-sta-removal-case.patch b/queue-4.4/mac80211-fix-mesh-estab_plinks-counting-in-sta-removal-case.patch new file mode 100644 index 00000000000..65b1ba627a8 --- /dev/null +++ b/queue-4.4/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 +@@ -151,14 +151,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.4/mac80211-mesh-flush-mesh-paths-unconditionally.patch b/queue-4.4/mac80211-mesh-flush-mesh-paths-unconditionally.patch new file mode 100644 index 00000000000..9765a94e885 --- /dev/null +++ b/queue-4.4/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 +@@ -164,6 +164,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.4/mac80211_hwsim-add-missing-check-for-hwsim_attr_signal.patch b/queue-4.4/mac80211_hwsim-add-missing-check-for-hwsim_attr_signal.patch new file mode 100644 index 00000000000..077c1e14b28 --- /dev/null +++ b/queue-4.4/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 +@@ -2723,6 +2723,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.4/make-nfs_atomic_open-call-d_drop-on-all-open_context-errors.patch b/queue-4.4/make-nfs_atomic_open-call-d_drop-on-all-open_context-errors.patch new file mode 100644 index 00000000000..20e732f0a3d --- /dev/null +++ b/queue-4.4/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 +@@ -1531,9 +1531,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.4/mnt-account-for-ms_rdonly-in-fs_fully_visible.patch b/queue-4.4/mnt-account-for-ms_rdonly-in-fs_fully_visible.patch new file mode 100644 index 00000000000..c364151795d --- /dev/null +++ b/queue-4.4/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 +@@ -3236,6 +3236,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.4/mnt-fs_fully_visible-test-the-proper-mount-for-mnt_locked.patch b/queue-4.4/mnt-fs_fully_visible-test-the-proper-mount-for-mnt_locked.patch new file mode 100644 index 00000000000..b3413242eda --- /dev/null +++ b/queue-4.4/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 +@@ -3262,7 +3262,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.4/mnt-if-fs_fully_visible-fails-call-put_filesystem.patch b/queue-4.4/mnt-if-fs_fully_visible-fails-call-put_filesystem.patch new file mode 100644 index 00000000000..97e719e439f --- /dev/null +++ b/queue-4.4/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 +@@ -2401,8 +2401,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.4/nfs-fix-another-open_downgrade-bug.patch b/queue-4.4/nfs-fix-another-open_downgrade-bug.patch new file mode 100644 index 00000000000..4596c006986 --- /dev/null +++ b/queue-4.4/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 +@@ -2854,12 +2854,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.4/nfsd-always-lock-state-exclusively.patch b/queue-4.4/nfsd-always-lock-state-exclusively.patch new file mode 100644 index 00000000000..21155c12a59 --- /dev/null +++ b/queue-4.4/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 +@@ -3467,7 +3467,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); + +@@ -4300,10 +4300,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 { +@@ -4313,19 +4313,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; + } +@@ -4337,7 +4337,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) { +@@ -4950,12 +4950,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; + } + +@@ -5003,7 +5003,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; + } +@@ -5035,12 +5035,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)); + +@@ -5116,7 +5116,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); +@@ -5169,7 +5169,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); + +@@ -5395,7 +5395,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); +@@ -5564,7 +5564,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, +@@ -5573,7 +5573,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, +@@ -5677,7 +5677,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 +@@ -5847,7 +5847,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.4/nfsd-check-permissions-when-setting-acls.patch b/queue-4.4/nfsd-check-permissions-when-setting-acls.patch new file mode 100644 index 00000000000..748459297c2 --- /dev/null +++ b/queue-4.4/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.4/nfsd-extend-the-mutex-holding-region-around-in-nfsd4_process_open2.patch b/queue-4.4/nfsd-extend-the-mutex-holding-region-around-in-nfsd4_process_open2.patch new file mode 100644 index 00000000000..fa3211419c8 --- /dev/null +++ b/queue-4.4/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 +@@ -3452,6 +3452,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); + +@@ -3467,13 +3471,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; + } + +@@ -4309,11 +4317,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) { +@@ -4322,7 +4333,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.4/nfsd4-rpc-move-backchannel-create-logic-into-rpc-code.patch b/queue-4.4/nfsd4-rpc-move-backchannel-create-logic-into-rpc-code.patch new file mode 100644 index 00000000000..51f0c83a052 --- /dev/null +++ b/queue-4.4/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 +@@ -135,8 +135,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); + void rpc_task_reset_client(struct rpc_task *task, struct rpc_clnt *clnt); +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -442,7 +442,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; +@@ -474,7 +474,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 +@@ -500,6 +499,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.4/of-fix-autoloading-due-to-broken-modalias-with-no-compatible.patch b/queue-4.4/of-fix-autoloading-due-to-broken-modalias-with-no-compatible.patch new file mode 100644 index 00000000000..98e27eb82f6 --- /dev/null +++ b/queue-4.4/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 +@@ -695,7 +695,7 @@ static int do_of_entry (const char *file + 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.4/of-irq-fix-of_irq_get-kernel-doc.patch b/queue-4.4/of-irq-fix-of_irq_get-kernel-doc.patch new file mode 100644 index 00000000000..1c556124b89 --- /dev/null +++ b/queue-4.4/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.4/powerpc-iommu-remove-the-dependency-on-eeh-struct-in-ddw-mechanism.patch b/queue-4.4/powerpc-iommu-remove-the-dependency-on-eeh-struct-in-ddw-mechanism.patch new file mode 100644 index 00000000000..38d885c2a3b --- /dev/null +++ b/queue-4.4/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.4/powerpc-pseries-fix-ibm_arch_vec_nrcores_offset-since-power8nvl-was-added.patch b/queue-4.4/powerpc-pseries-fix-ibm_arch_vec_nrcores_offset-since-power8nvl-was-added.patch new file mode 100644 index 00000000000..5b988bd750a --- /dev/null +++ b/queue-4.4/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 +@@ -718,7 +718,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.4/powerpc-pseries-fix-pci-config-address-for-ddw.patch b/queue-4.4/powerpc-pseries-fix-pci-config-address-for-ddw.patch new file mode 100644 index 00000000000..12d59707a65 --- /dev/null +++ b/queue-4.4/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.4/powerpc-tm-always-reclaim-in-start_thread-for-exec-class-syscalls.patch b/queue-4.4/powerpc-tm-always-reclaim-in-start_thread-for-exec-class-syscalls.patch new file mode 100644 index 00000000000..7247304ca05 --- /dev/null +++ b/queue-4.4/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 +@@ -1239,6 +1239,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.4/revert-gpiolib-split-gpio-flags-parsing-and-gpio-configuration.patch b/queue-4.4/revert-gpiolib-split-gpio-flags-parsing-and-gpio-configuration.patch new file mode 100644 index 00000000000..161180d55a4 --- /dev/null +++ b/queue-4.4/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 +@@ -927,14 +927,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; + } +@@ -2062,28 +2054,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 +@@ -2091,10 +2068,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); +@@ -2161,13 +2145,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); +@@ -2223,6 +2205,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); + +@@ -2233,10 +2219,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); +@@ -2289,8 +2271,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", +@@ -2298,7 +2278,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.4/series b/queue-4.4/series new file mode 100644 index 00000000000..4b7cb2dba66 --- /dev/null +++ b/queue-4.4/series @@ -0,0 +1,35 @@ +mac80211-fix-fast_tx-header-alignment.patch +mac80211-mesh-flush-mesh-paths-unconditionally.patch +mac80211_hwsim-add-missing-check-for-hwsim_attr_signal.patch +mac80211-fix-mesh-estab_plinks-counting-in-sta-removal-case.patch +edac-sb_edac-fix-rank-lookup-on-broadwell.patch +ib-cm-fix-a-recently-introduced-locking-bug.patch +ib-mlx4-properly-initialize-grh-tclass-and-flowlabel-in-ahs.patch +powerpc-iommu-remove-the-dependency-on-eeh-struct-in-ddw-mechanism.patch +powerpc-pseries-fix-pci-config-address-for-ddw.patch +powerpc-pseries-fix-ibm_arch_vec_nrcores_offset-since-power8nvl-was-added.patch +powerpc-tm-always-reclaim-in-start_thread-for-exec-class-syscalls.patch +usb-dwc2-fix-regression-on-big-endian-powerpc-arm-systems.patch +usb-ehci-declare-hostpc-register-as-zero-length-array.patch +usb-common-otg-fsm-add-license-to-usb-otg-fsm.patch +mnt-fs_fully_visible-test-the-proper-mount-for-mnt_locked.patch +mnt-account-for-ms_rdonly-in-fs_fully_visible.patch +mnt-if-fs_fully_visible-fails-call-put_filesystem.patch +of-fix-autoloading-due-to-broken-modalias-with-no-compatible.patch +of-irq-fix-of_irq_get-kernel-doc.patch +locking-ww_mutex-report-recursive-ww_mutex-locking-early.patch +locking-qspinlock-fix-spin_unlock_wait-some-more.patch +locking-static_key-fix-concurrent-static_key_slow_inc.patch +x86-build-copy-ldlinux.c32-to-image.iso.patch +kprobes-x86-clear-tf-bit-in-fault-on-single-stepping.patch +x86-amd_nb-fix-boot-crash-on-non-amd-systems.patch +revert-gpiolib-split-gpio-flags-parsing-and-gpio-configuration.patch +uvc-forward-compat-ioctls-to-their-handlers-directly.patch +thermal-cpu_cooling-fix-improper-order-during-initialization.patch +writeback-use-higher-precision-calculation-in-domain_dirty_limits.patch +nfsd4-rpc-move-backchannel-create-logic-into-rpc-code.patch +nfsd-always-lock-state-exclusively.patch +nfsd-extend-the-mutex-holding-region-around-in-nfsd4_process_open2.patch +nfsd-check-permissions-when-setting-acls.patch +make-nfs_atomic_open-call-d_drop-on-all-open_context-errors.patch +nfs-fix-another-open_downgrade-bug.patch diff --git a/queue-4.4/thermal-cpu_cooling-fix-improper-order-during-initialization.patch b/queue-4.4/thermal-cpu_cooling-fix-improper-order-during-initialization.patch new file mode 100644 index 00000000000..244c6e7674d --- /dev/null +++ b/queue-4.4/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.4/usb-common-otg-fsm-add-license-to-usb-otg-fsm.patch b/queue-4.4/usb-common-otg-fsm-add-license-to-usb-otg-fsm.patch new file mode 100644 index 00000000000..1a2b255ae78 --- /dev/null +++ b/queue-4.4/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 +@@ -365,3 +366,4 @@ int otg_statemachine(struct otg_fsm *fsm + return state_changed; + } + EXPORT_SYMBOL_GPL(otg_statemachine); ++MODULE_LICENSE("GPL"); diff --git a/queue-4.4/usb-dwc2-fix-regression-on-big-endian-powerpc-arm-systems.patch b/queue-4.4/usb-dwc2-fix-regression-on-big-endian-powerpc-arm-systems.patch new file mode 100644 index 00000000000..bc363f6cebe --- /dev/null +++ b/queue-4.4/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 +@@ -44,6 +44,17 @@ + #include + #include "hw.h" + ++#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); +@@ -70,6 +81,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.4/usb-ehci-declare-hostpc-register-as-zero-length-array.patch b/queue-4.4/usb-ehci-declare-hostpc-register-as-zero-length-array.patch new file mode 100644 index 00000000000..f0774153799 --- /dev/null +++ b/queue-4.4/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.4/uvc-forward-compat-ioctls-to-their-handlers-directly.patch b/queue-4.4/uvc-forward-compat-ioctls-to-their-handlers-directly.patch new file mode 100644 index 00000000000..37dcd87b2e2 --- /dev/null +++ b/queue-4.4/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 +@@ -1388,47 +1388,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.4/writeback-use-higher-precision-calculation-in-domain_dirty_limits.patch b/queue-4.4/writeback-use-higher-precision-calculation-in-domain_dirty_limits.patch new file mode 100644 index 00000000000..51b159aec30 --- /dev/null +++ b/queue-4.4/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 +@@ -359,8 +359,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; +@@ -372,26 +373,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.4/x86-amd_nb-fix-boot-crash-on-non-amd-systems.patch b/queue-4.4/x86-amd_nb-fix-boot-crash-on-non-amd-systems.patch new file mode 100644 index 00000000000..97b66056514 --- /dev/null +++ b/queue-4.4/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.4/x86-build-copy-ldlinux.c32-to-image.iso.patch b/queue-4.4/x86-build-copy-ldlinux.c32-to-image.iso.patch new file mode 100644 index 00000000000..1823e9d3c8d --- /dev/null +++ b/queue-4.4/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 +@@ -162,6 +162,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/series b/queue-4.6/series new file mode 100644 index 00000000000..63c2e70f4e2 --- /dev/null +++ b/queue-4.6/series @@ -0,0 +1,54 @@ +cfg80211-remove-get-set-antenna-and-tx-power-warnings.patch +mac80211-fix-fast_tx-header-alignment.patch +mac80211-mesh-flush-mesh-paths-unconditionally.patch +mac80211_hwsim-add-missing-check-for-hwsim_attr_signal.patch +mac80211-fix-mesh-estab_plinks-counting-in-sta-removal-case.patch +cfg80211-fix-proto-in-ieee80211_data_to_8023-for-frames-without-llc-header.patch +edac-fix-workqueues-poll-period-resetting.patch +edac-sb_edac-fix-rank-lookup-on-broadwell.patch +futex-calculate-the-futex-key-based-on-a-tail-page-for-file-based-futexes.patch +ib-core-fix-bit-curruption-in-ib_device_cap_flags-structure.patch +ib-cm-fix-a-recently-introduced-locking-bug.patch +ib-rdmavt-correct-qp_priv_alloc-return-value-test.patch +ib-mlx4-properly-initialize-grh-tclass-and-flowlabel-in-ahs.patch +powerpc-iommu-remove-the-dependency-on-eeh-struct-in-ddw-mechanism.patch +powerpc-pseries-fix-pci-config-address-for-ddw.patch +powerpc-pseries-fix-ibm_arch_vec_nrcores_offset-since-power8nvl-was-added.patch +powerpc-tm-always-reclaim-in-start_thread-for-exec-class-syscalls.patch +usb-dwc2-fix-regression-on-big-endian-powerpc-arm-systems.patch +usb-ehci-declare-hostpc-register-as-zero-length-array.patch +usb-don-t-free-bandwidth_mutex-too-early.patch +usb-common-otg-fsm-add-license-to-usb-otg-fsm.patch +mnt-fs_fully_visible-test-the-proper-mount-for-mnt_locked.patch +mnt-account-for-ms_rdonly-in-fs_fully_visible.patch +mnt-if-fs_fully_visible-fails-call-put_filesystem.patch +of-fix-autoloading-due-to-broken-modalias-with-no-compatible.patch +of-irq-fix-of_irq_get-kernel-doc.patch +x86-msr-use-the-proper-trace-point-conditional-for-writes.patch +locking-ww_mutex-report-recursive-ww_mutex-locking-early.patch +locking-qspinlock-fix-spin_unlock_wait-some-more.patch +locking-static_key-fix-concurrent-static_key_slow_inc.patch +cpuidle-do-not-access-cpuidle_devices-when-config_cpu_idle.patch +x86-build-copy-ldlinux.c32-to-image.iso.patch +kprobes-x86-clear-tf-bit-in-fault-on-single-stepping.patch +perf-x86-intel-rapl-fix-pmus-free-during-cleanup.patch +x86-amd_nb-fix-boot-crash-on-non-amd-systems.patch +perf-x86-fix-32-bit-perf-user-callgraph-collection.patch +extcon-palmas-fix-boot-up-state-of-vbus-when-using-gpio-detection.patch +gpio-make-library-immune-to-error-pointers.patch +gpio-sch-fix-oops-on-module-load-on-asus-eee-pc-1201.patch +revert-gpiolib-split-gpio-flags-parsing-and-gpio-configuration.patch +autofs-braino-fix-for-do_last.patch +rtlwifi-fix-scheduling-while-atomic-error-from-commit-49f86ec21c01.patch +uvc-forward-compat-ioctls-to-their-handlers-directly.patch +thermal-cpu_cooling-fix-improper-order-during-initialization.patch +writeback-use-higher-precision-calculation-in-domain_dirty_limits.patch +sd-fix-rw_max-for-devices-that-report-an-optimal-xfer-size.patch +nfsd4-rpc-move-backchannel-create-logic-into-rpc-code.patch +nfsd-always-lock-state-exclusively.patch +nfsd-extend-the-mutex-holding-region-around-in-nfsd4_process_open2.patch +nfsd-check-permissions-when-setting-acls.patch +pnfs_nfs-fix-_cancel_empty_pagelist.patch +nfs-fix-a-double-page-unlock.patch +make-nfs_atomic_open-call-d_drop-on-all-open_context-errors.patch +nfs-fix-another-open_downgrade-bug.patch