diff options
Diffstat (limited to '3.2.44/1026_linux-3.2.27.patch')
-rw-r--r-- | 3.2.44/1026_linux-3.2.27.patch | 3188 |
1 files changed, 3188 insertions, 0 deletions
diff --git a/3.2.44/1026_linux-3.2.27.patch b/3.2.44/1026_linux-3.2.27.patch new file mode 100644 index 0000000..5878eb4 --- /dev/null +++ b/3.2.44/1026_linux-3.2.27.patch @@ -0,0 +1,3188 @@ +diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt +index edad99a..69820b2 100644 +--- a/Documentation/sound/alsa/HD-Audio-Models.txt ++++ b/Documentation/sound/alsa/HD-Audio-Models.txt +@@ -60,10 +60,11 @@ ALC267/268 + ========== + N/A + +-ALC269 ++ALC269/270/275/276/280/282 + ====== + laptop-amic Laptops with analog-mic input + laptop-dmic Laptops with digital-mic input ++ lenovo-dock Enables docking station I/O for some Lenovos + + ALC662/663/272 + ============== +diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt +index e1f856b..22bf11b 100644 +--- a/Documentation/stable_kernel_rules.txt ++++ b/Documentation/stable_kernel_rules.txt +@@ -1,4 +1,4 @@ +-Everything you ever wanted to know about Linux 2.6 -stable releases. ++Everything you ever wanted to know about Linux -stable releases. + + Rules on what kind of patches are accepted, and which ones are not, into the + "-stable" tree: +@@ -41,10 +41,10 @@ Procedure for submitting patches to the -stable tree: + cherry-picked than this can be specified in the following format in + the sign-off area: + +- Cc: <stable@vger.kernel.org> # .32.x: a1f84a3: sched: Check for idle +- Cc: <stable@vger.kernel.org> # .32.x: 1b9508f: sched: Rate-limit newidle +- Cc: <stable@vger.kernel.org> # .32.x: fd21073: sched: Fix affinity logic +- Cc: <stable@vger.kernel.org> # .32.x ++ Cc: <stable@vger.kernel.org> # 3.3.x: a1f84a3: sched: Check for idle ++ Cc: <stable@vger.kernel.org> # 3.3.x: 1b9508f: sched: Rate-limit newidle ++ Cc: <stable@vger.kernel.org> # 3.3.x: fd21073: sched: Fix affinity logic ++ Cc: <stable@vger.kernel.org> # 3.3.x + Signed-off-by: Ingo Molnar <mingo@elte.hu> + + The tag sequence has the meaning of: +@@ -78,6 +78,15 @@ Review cycle: + security kernel team, and not go through the normal review cycle. + Contact the kernel security team for more details on this procedure. + ++Trees: ++ ++ - The queues of patches, for both completed versions and in progress ++ versions can be found at: ++ http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git ++ - The finalized and tagged releases of all stable kernels can be found ++ in separate branches per version at: ++ http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git ++ + + Review committee: + +diff --git a/Makefile b/Makefile +index fa5acc83..bdf851f 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 2 +-SUBLEVEL = 26 ++SUBLEVEL = 27 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/include/asm/mutex.h b/arch/arm/include/asm/mutex.h +index 93226cf..b1479fd 100644 +--- a/arch/arm/include/asm/mutex.h ++++ b/arch/arm/include/asm/mutex.h +@@ -7,121 +7,10 @@ + */ + #ifndef _ASM_MUTEX_H + #define _ASM_MUTEX_H +- +-#if __LINUX_ARM_ARCH__ < 6 +-/* On pre-ARMv6 hardware the swp based implementation is the most efficient. */ +-# include <asm-generic/mutex-xchg.h> +-#else +- + /* +- * Attempting to lock a mutex on ARMv6+ can be done with a bastardized +- * atomic decrement (it is not a reliable atomic decrement but it satisfies +- * the defined semantics for our purpose, while being smaller and faster +- * than a real atomic decrement or atomic swap. The idea is to attempt +- * decrementing the lock value only once. If once decremented it isn't zero, +- * or if its store-back fails due to a dispute on the exclusive store, we +- * simply bail out immediately through the slow path where the lock will be +- * reattempted until it succeeds. ++ * On pre-ARMv6 hardware this results in a swp-based implementation, ++ * which is the most efficient. For ARMv6+, we emit a pair of exclusive ++ * accesses instead. + */ +-static inline void +-__mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *)) +-{ +- int __ex_flag, __res; +- +- __asm__ ( +- +- "ldrex %0, [%2] \n\t" +- "sub %0, %0, #1 \n\t" +- "strex %1, %0, [%2] " +- +- : "=&r" (__res), "=&r" (__ex_flag) +- : "r" (&(count)->counter) +- : "cc","memory" ); +- +- __res |= __ex_flag; +- if (unlikely(__res != 0)) +- fail_fn(count); +-} +- +-static inline int +-__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) +-{ +- int __ex_flag, __res; +- +- __asm__ ( +- +- "ldrex %0, [%2] \n\t" +- "sub %0, %0, #1 \n\t" +- "strex %1, %0, [%2] " +- +- : "=&r" (__res), "=&r" (__ex_flag) +- : "r" (&(count)->counter) +- : "cc","memory" ); +- +- __res |= __ex_flag; +- if (unlikely(__res != 0)) +- __res = fail_fn(count); +- return __res; +-} +- +-/* +- * Same trick is used for the unlock fast path. However the original value, +- * rather than the result, is used to test for success in order to have +- * better generated assembly. +- */ +-static inline void +-__mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *)) +-{ +- int __ex_flag, __res, __orig; +- +- __asm__ ( +- +- "ldrex %0, [%3] \n\t" +- "add %1, %0, #1 \n\t" +- "strex %2, %1, [%3] " +- +- : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) +- : "r" (&(count)->counter) +- : "cc","memory" ); +- +- __orig |= __ex_flag; +- if (unlikely(__orig != 0)) +- fail_fn(count); +-} +- +-/* +- * If the unlock was done on a contended lock, or if the unlock simply fails +- * then the mutex remains locked. +- */ +-#define __mutex_slowpath_needs_to_unlock() 1 +- +-/* +- * For __mutex_fastpath_trylock we use another construct which could be +- * described as a "single value cmpxchg". +- * +- * This provides the needed trylock semantics like cmpxchg would, but it is +- * lighter and less generic than a true cmpxchg implementation. +- */ +-static inline int +-__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *)) +-{ +- int __ex_flag, __res, __orig; +- +- __asm__ ( +- +- "1: ldrex %0, [%3] \n\t" +- "subs %1, %0, #1 \n\t" +- "strexeq %2, %1, [%3] \n\t" +- "movlt %0, #0 \n\t" +- "cmpeq %2, #0 \n\t" +- "bgt 1b " +- +- : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) +- : "r" (&count->counter) +- : "cc", "memory" ); +- +- return __orig; +-} +- +-#endif ++#include <asm-generic/mutex-xchg.h> + #endif +diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S +index b145f16..ece0996 100644 +--- a/arch/arm/kernel/entry-armv.S ++++ b/arch/arm/kernel/entry-armv.S +@@ -242,6 +242,19 @@ svc_preempt: + b 1b + #endif + ++__und_fault: ++ @ Correct the PC such that it is pointing at the instruction ++ @ which caused the fault. If the faulting instruction was ARM ++ @ the PC will be pointing at the next instruction, and have to ++ @ subtract 4. Otherwise, it is Thumb, and the PC will be ++ @ pointing at the second half of the Thumb instruction. We ++ @ have to subtract 2. ++ ldr r2, [r0, #S_PC] ++ sub r2, r2, r1 ++ str r2, [r0, #S_PC] ++ b do_undefinstr ++ENDPROC(__und_fault) ++ + .align 5 + __und_svc: + #ifdef CONFIG_KPROBES +@@ -259,25 +272,32 @@ __und_svc: + @ + @ r0 - instruction + @ +-#ifndef CONFIG_THUMB2_KERNEL ++#ifndef CONFIG_THUMB2_KERNEL + ldr r0, [r4, #-4] + #else ++ mov r1, #2 + ldrh r0, [r4, #-2] @ Thumb instruction at LR - 2 + cmp r0, #0xe800 @ 32-bit instruction if xx >= 0 +- ldrhhs r9, [r4] @ bottom 16 bits +- orrhs r0, r9, r0, lsl #16 ++ blo __und_svc_fault ++ ldrh r9, [r4] @ bottom 16 bits ++ add r4, r4, #2 ++ str r4, [sp, #S_PC] ++ orr r0, r9, r0, lsl #16 + #endif +- adr r9, BSYM(1f) ++ adr r9, BSYM(__und_svc_finish) + mov r2, r4 + bl call_fpe + ++ mov r1, #4 @ PC correction to apply ++__und_svc_fault: + mov r0, sp @ struct pt_regs *regs +- bl do_undefinstr ++ bl __und_fault + + @ + @ IRQs off again before pulling preserved data off the stack + @ +-1: disable_irq_notrace ++__und_svc_finish: ++ disable_irq_notrace + + @ + @ restore SPSR and restart the instruction +@@ -421,25 +441,33 @@ __und_usr: + mov r2, r4 + mov r3, r5 + ++ @ r2 = regs->ARM_pc, which is either 2 or 4 bytes ahead of the ++ @ faulting instruction depending on Thumb mode. ++ @ r3 = regs->ARM_cpsr + @ +- @ fall through to the emulation code, which returns using r9 if +- @ it has emulated the instruction, or the more conventional lr +- @ if we are to treat this as a real undefined instruction +- @ +- @ r0 - instruction ++ @ The emulation code returns using r9 if it has emulated the ++ @ instruction, or the more conventional lr if we are to treat ++ @ this as a real undefined instruction + @ + adr r9, BSYM(ret_from_exception) +- adr lr, BSYM(__und_usr_unknown) ++ + tst r3, #PSR_T_BIT @ Thumb mode? +- itet eq @ explicit IT needed for the 1f label +- subeq r4, r2, #4 @ ARM instr at LR - 4 +- subne r4, r2, #2 @ Thumb instr at LR - 2 +-1: ldreqt r0, [r4] ++ bne __und_usr_thumb ++ sub r4, r2, #4 @ ARM instr at LR - 4 ++1: ldrt r0, [r4] + #ifdef CONFIG_CPU_ENDIAN_BE8 +- reveq r0, r0 @ little endian instruction ++ rev r0, r0 @ little endian instruction + #endif +- beq call_fpe ++ @ r0 = 32-bit ARM instruction which caused the exception ++ @ r2 = PC value for the following instruction (:= regs->ARM_pc) ++ @ r4 = PC value for the faulting instruction ++ @ lr = 32-bit undefined instruction function ++ adr lr, BSYM(__und_usr_fault_32) ++ b call_fpe ++ ++__und_usr_thumb: + @ Thumb instruction ++ sub r4, r2, #2 @ First half of thumb instr at LR - 2 + #if CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7 + /* + * Thumb-2 instruction handling. Note that because pre-v6 and >= v6 platforms +@@ -453,7 +481,7 @@ __und_usr: + ldr r5, .LCcpu_architecture + ldr r5, [r5] + cmp r5, #CPU_ARCH_ARMv7 +- blo __und_usr_unknown ++ blo __und_usr_fault_16 @ 16bit undefined instruction + /* + * The following code won't get run unless the running CPU really is v7, so + * coding round the lack of ldrht on older arches is pointless. Temporarily +@@ -461,15 +489,18 @@ __und_usr: + */ + .arch armv6t2 + #endif +-2: +- ARM( ldrht r5, [r4], #2 ) +- THUMB( ldrht r5, [r4] ) +- THUMB( add r4, r4, #2 ) ++2: ldrht r5, [r4] + cmp r5, #0xe800 @ 32bit instruction if xx != 0 +- blo __und_usr_unknown +-3: ldrht r0, [r4] ++ blo __und_usr_fault_16 @ 16bit undefined instruction ++3: ldrht r0, [r2] + add r2, r2, #2 @ r2 is PC + 2, make it PC + 4 ++ str r2, [sp, #S_PC] @ it's a 2x16bit instr, update + orr r0, r0, r5, lsl #16 ++ adr lr, BSYM(__und_usr_fault_32) ++ @ r0 = the two 16-bit Thumb instructions which caused the exception ++ @ r2 = PC value for the following Thumb instruction (:= regs->ARM_pc) ++ @ r4 = PC value for the first 16-bit Thumb instruction ++ @ lr = 32bit undefined instruction function + + #if __LINUX_ARM_ARCH__ < 7 + /* If the target arch was overridden, change it back: */ +@@ -480,17 +511,13 @@ __und_usr: + #endif + #endif /* __LINUX_ARM_ARCH__ < 7 */ + #else /* !(CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7) */ +- b __und_usr_unknown ++ b __und_usr_fault_16 + #endif +- UNWIND(.fnend ) ++ UNWIND(.fnend) + ENDPROC(__und_usr) + +- @ +- @ fallthrough to call_fpe +- @ +- + /* +- * The out of line fixup for the ldrt above. ++ * The out of line fixup for the ldrt instructions above. + */ + .pushsection .fixup, "ax" + 4: mov pc, r9 +@@ -521,11 +548,12 @@ ENDPROC(__und_usr) + * NEON handler code. + * + * Emulators may wish to make use of the following registers: +- * r0 = instruction opcode. +- * r2 = PC+4 ++ * r0 = instruction opcode (32-bit ARM or two 16-bit Thumb) ++ * r2 = PC value to resume execution after successful emulation + * r9 = normal "successful" return address +- * r10 = this threads thread_info structure. ++ * r10 = this threads thread_info structure + * lr = unrecognised instruction return address ++ * IRQs disabled, FIQs enabled. + */ + @ + @ Fall-through from Thumb-2 __und_usr +@@ -660,12 +688,17 @@ ENTRY(no_fp) + mov pc, lr + ENDPROC(no_fp) + +-__und_usr_unknown: +- enable_irq ++__und_usr_fault_32: ++ mov r1, #4 ++ b 1f ++__und_usr_fault_16: ++ mov r1, #2 ++1: enable_irq + mov r0, sp + adr lr, BSYM(ret_from_exception) +- b do_undefinstr +-ENDPROC(__und_usr_unknown) ++ b __und_fault ++ENDPROC(__und_usr_fault_32) ++ENDPROC(__und_usr_fault_16) + + .align 5 + __pabt_usr: +diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c +index 3d0c6fb..e68d251 100644 +--- a/arch/arm/kernel/process.c ++++ b/arch/arm/kernel/process.c +@@ -125,6 +125,7 @@ void arm_machine_restart(char mode, const char *cmd) + */ + mdelay(1000); + printk("Reboot failed -- System halted\n"); ++ local_irq_disable(); + while (1); + } + +@@ -240,6 +241,7 @@ void machine_shutdown(void) + void machine_halt(void) + { + machine_shutdown(); ++ local_irq_disable(); + while (1); + } + +diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c +index 160cb16..8380bd1 100644 +--- a/arch/arm/kernel/traps.c ++++ b/arch/arm/kernel/traps.c +@@ -362,18 +362,10 @@ static int call_undef_hook(struct pt_regs *regs, unsigned int instr) + + asmlinkage void __exception do_undefinstr(struct pt_regs *regs) + { +- unsigned int correction = thumb_mode(regs) ? 2 : 4; + unsigned int instr; + siginfo_t info; + void __user *pc; + +- /* +- * According to the ARM ARM, PC is 2 or 4 bytes ahead, +- * depending whether we're in Thumb mode or not. +- * Correct this offset. +- */ +- regs->ARM_pc -= correction; +- + pc = (void __user *)instruction_pointer(regs); + + if (processor_mode(regs) == SVC_MODE) { +diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S +index 845f461..c202113 100644 +--- a/arch/arm/mm/tlb-v7.S ++++ b/arch/arm/mm/tlb-v7.S +@@ -38,11 +38,19 @@ ENTRY(v7wbi_flush_user_tlb_range) + dsb + mov r0, r0, lsr #PAGE_SHIFT @ align address + mov r1, r1, lsr #PAGE_SHIFT ++#ifdef CONFIG_ARM_ERRATA_720789 ++ mov r3, #0 ++#else + asid r3, r3 @ mask ASID ++#endif + orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA + mov r1, r1, lsl #PAGE_SHIFT + 1: ++#ifdef CONFIG_ARM_ERRATA_720789 ++ ALT_SMP(mcr p15, 0, r0, c8, c3, 3) @ TLB invalidate U MVA all ASID (shareable) ++#else + ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable) ++#endif + ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA + + add r0, r0, #PAGE_SZ +@@ -67,7 +75,11 @@ ENTRY(v7wbi_flush_kern_tlb_range) + mov r0, r0, lsl #PAGE_SHIFT + mov r1, r1, lsl #PAGE_SHIFT + 1: ++#ifdef CONFIG_ARM_ERRATA_720789 ++ ALT_SMP(mcr p15, 0, r0, c8, c3, 3) @ TLB invalidate U MVA all ASID (shareable) ++#else + ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable) ++#endif + ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA + add r0, r0, #PAGE_SZ + cmp r0, r1 +diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S +index 4fa9903..cc926c9 100644 +--- a/arch/arm/vfp/entry.S ++++ b/arch/arm/vfp/entry.S +@@ -7,18 +7,20 @@ + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +- * +- * Basic entry code, called from the kernel's undefined instruction trap. +- * r0 = faulted instruction +- * r5 = faulted PC+4 +- * r9 = successful return +- * r10 = thread_info structure +- * lr = failure return + */ + #include <asm/thread_info.h> + #include <asm/vfpmacros.h> + #include "../kernel/entry-header.S" + ++@ VFP entry point. ++@ ++@ r0 = instruction opcode (32-bit ARM or two 16-bit Thumb) ++@ r2 = PC value to resume execution after successful emulation ++@ r9 = normal "successful" return address ++@ r10 = this threads thread_info structure ++@ lr = unrecognised instruction return address ++@ IRQs disabled. ++@ + ENTRY(do_vfp) + #ifdef CONFIG_PREEMPT + ldr r4, [r10, #TI_PREEMPT] @ get preempt count +diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S +index 2d30c7f..3a0efaa 100644 +--- a/arch/arm/vfp/vfphw.S ++++ b/arch/arm/vfp/vfphw.S +@@ -61,13 +61,13 @@ + + @ VFP hardware support entry point. + @ +-@ r0 = faulted instruction +-@ r2 = faulted PC+4 +-@ r9 = successful return ++@ r0 = instruction opcode (32-bit ARM or two 16-bit Thumb) ++@ r2 = PC value to resume execution after successful emulation ++@ r9 = normal "successful" return address + @ r10 = vfp_state union + @ r11 = CPU number +-@ lr = failure return +- ++@ lr = unrecognised instruction return address ++@ IRQs enabled. + ENTRY(vfp_support_entry) + DBGSTR3 "instr %08x pc %08x state %p", r0, r2, r10 + +@@ -161,9 +161,12 @@ vfp_hw_state_valid: + @ exception before retrying branch + @ out before setting an FPEXC that + @ stops us reading stuff +- VFPFMXR FPEXC, r1 @ restore FPEXC last +- sub r2, r2, #4 +- str r2, [sp, #S_PC] @ retry the instruction ++ VFPFMXR FPEXC, r1 @ Restore FPEXC last ++ sub r2, r2, #4 @ Retry current instruction - if Thumb ++ str r2, [sp, #S_PC] @ mode it's two 16-bit instructions, ++ @ else it's one 32-bit instruction, so ++ @ always subtract 4 from the following ++ @ instruction address. + #ifdef CONFIG_PREEMPT + get_thread_info r10 + ldr r4, [r10, #TI_PREEMPT] @ get preempt count +diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c +index 8ea07e4..ad83dad 100644 +--- a/arch/arm/vfp/vfpmodule.c ++++ b/arch/arm/vfp/vfpmodule.c +@@ -453,10 +453,16 @@ static int vfp_pm_suspend(void) + + /* disable, just in case */ + fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); ++ } else if (vfp_current_hw_state[ti->cpu]) { ++#ifndef CONFIG_SMP ++ fmxr(FPEXC, fpexc | FPEXC_EN); ++ vfp_save_state(vfp_current_hw_state[ti->cpu], fpexc); ++ fmxr(FPEXC, fpexc); ++#endif + } + + /* clear any information we had about last context state */ +- memset(vfp_current_hw_state, 0, sizeof(vfp_current_hw_state)); ++ vfp_current_hw_state[ti->cpu] = NULL; + + return 0; + } +diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h +index 3fad89e..2fc214b 100644 +--- a/arch/ia64/include/asm/atomic.h ++++ b/arch/ia64/include/asm/atomic.h +@@ -18,8 +18,8 @@ + #include <asm/system.h> + + +-#define ATOMIC_INIT(i) ((atomic_t) { (i) }) +-#define ATOMIC64_INIT(i) ((atomic64_t) { (i) }) ++#define ATOMIC_INIT(i) { (i) } ++#define ATOMIC64_INIT(i) { (i) } + + #define atomic_read(v) (*(volatile int *)&(v)->counter) + #define atomic64_read(v) (*(volatile long *)&(v)->counter) +diff --git a/arch/m68k/include/asm/entry.h b/arch/m68k/include/asm/entry.h +index c3c5a86..8798ebc 100644 +--- a/arch/m68k/include/asm/entry.h ++++ b/arch/m68k/include/asm/entry.h +@@ -33,8 +33,8 @@ + + /* the following macro is used when enabling interrupts */ + #if defined(MACH_ATARI_ONLY) +- /* block out HSYNC on the atari */ +-#define ALLOWINT (~0x400) ++ /* block out HSYNC = ipl 2 on the atari */ ++#define ALLOWINT (~0x500) + #define MAX_NOINT_IPL 3 + #else + /* portable version */ +diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c +index 8623f8d..9a5932e 100644 +--- a/arch/m68k/kernel/sys_m68k.c ++++ b/arch/m68k/kernel/sys_m68k.c +@@ -479,9 +479,13 @@ sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5, + goto bad_access; + } + +- mem_value = *mem; ++ /* ++ * No need to check for EFAULT; we know that the page is ++ * present and writable. ++ */ ++ __get_user(mem_value, mem); + if (mem_value == oldval) +- *mem = newval; ++ __put_user(newval, mem); + + pte_unmap_unlock(pte, ptl); + up_read(&mm->mmap_sem); +diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h +index 5682f16..20f0e01 100644 +--- a/arch/s390/include/asm/mmu_context.h ++++ b/arch/s390/include/asm/mmu_context.h +@@ -12,7 +12,6 @@ + #include <asm/pgalloc.h> + #include <asm/uaccess.h> + #include <asm/tlbflush.h> +-#include <asm-generic/mm_hooks.h> + + static inline int init_new_context(struct task_struct *tsk, + struct mm_struct *mm) +@@ -92,4 +91,17 @@ static inline void activate_mm(struct mm_struct *prev, + switch_mm(prev, next, current); + } + ++static inline void arch_dup_mmap(struct mm_struct *oldmm, ++ struct mm_struct *mm) ++{ ++#ifdef CONFIG_64BIT ++ if (oldmm->context.asce_limit < mm->context.asce_limit) ++ crst_table_downgrade(mm, oldmm->context.asce_limit); ++#endif ++} ++ ++static inline void arch_exit_mmap(struct mm_struct *mm) ++{ ++} ++ + #endif /* __S390_MMU_CONTEXT_H */ +diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h +index 5f33d37..172550d 100644 +--- a/arch/s390/include/asm/processor.h ++++ b/arch/s390/include/asm/processor.h +@@ -130,7 +130,9 @@ struct stack_frame { + regs->psw.mask = psw_user_bits | PSW_MASK_BA; \ + regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ + regs->gprs[15] = new_stackp; \ ++ __tlb_flush_mm(current->mm); \ + crst_table_downgrade(current->mm, 1UL << 31); \ ++ update_mm(current->mm, current); \ + } while (0) + + /* Forward declaration, a strange C thing */ +diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c +index b28aaa4..0fc0a7e 100644 +--- a/arch/s390/mm/fault.c ++++ b/arch/s390/mm/fault.c +@@ -453,6 +453,7 @@ int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write) + struct pt_regs regs; + int access, fault; + ++ /* Emulate a uaccess fault from kernel mode. */ + regs.psw.mask = psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_MCHECK; + if (!irqs_disabled()) + regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT; +@@ -461,12 +462,12 @@ int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write) + uaddr &= PAGE_MASK; + access = write ? VM_WRITE : VM_READ; + fault = do_exception(®s, access, uaddr | 2); +- if (unlikely(fault)) { +- if (fault & VM_FAULT_OOM) +- return -EFAULT; +- else if (fault & VM_FAULT_SIGBUS) +- do_sigbus(®s, pgm_int_code, uaddr); +- } ++ /* ++ * Since the fault happened in kernel mode while performing a uaccess ++ * all we need to do now is emulating a fixup in case "fault" is not ++ * zero. ++ * For the calling uaccess functions this results always in -EFAULT. ++ */ + return fault ? -EFAULT : 0; + } + +diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c +index a0155c0..c70b3d8 100644 +--- a/arch/s390/mm/mmap.c ++++ b/arch/s390/mm/mmap.c +@@ -106,9 +106,15 @@ EXPORT_SYMBOL_GPL(arch_pick_mmap_layout); + + int s390_mmap_check(unsigned long addr, unsigned long len) + { ++ int rc; ++ + if (!is_compat_task() && +- len >= TASK_SIZE && TASK_SIZE < (1UL << 53)) +- return crst_table_upgrade(current->mm, 1UL << 53); ++ len >= TASK_SIZE && TASK_SIZE < (1UL << 53)) { ++ rc = crst_table_upgrade(current->mm, 1UL << 53); ++ if (rc) ++ return rc; ++ update_mm(current->mm, current); ++ } + return 0; + } + +@@ -128,6 +134,7 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr, + rc = crst_table_upgrade(mm, 1UL << 53); + if (rc) + return (unsigned long) rc; ++ update_mm(mm, current); + area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); + } + return area; +@@ -150,6 +157,7 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, + rc = crst_table_upgrade(mm, 1UL << 53); + if (rc) + return (unsigned long) rc; ++ update_mm(mm, current); + area = arch_get_unmapped_area_topdown(filp, addr, len, + pgoff, flags); + } +diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c +index f8ceac4..f8e92f8 100644 +--- a/arch/s390/mm/pgtable.c ++++ b/arch/s390/mm/pgtable.c +@@ -97,7 +97,6 @@ repeat: + crst_table_free(mm, table); + if (mm->context.asce_limit < limit) + goto repeat; +- update_mm(mm, current); + return 0; + } + +@@ -105,9 +104,6 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit) + { + pgd_t *pgd; + +- if (mm->context.asce_limit <= limit) +- return; +- __tlb_flush_mm(mm); + while (mm->context.asce_limit > limit) { + pgd = mm->pgd; + switch (pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) { +@@ -130,7 +126,6 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit) + mm->task_size = mm->context.asce_limit; + crst_table_free(mm, (unsigned long *) pgd); + } +- update_mm(mm, current); + } + #endif + +diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c +index 1f84794..73ef56c 100644 +--- a/arch/x86/kernel/alternative.c ++++ b/arch/x86/kernel/alternative.c +@@ -219,7 +219,7 @@ void __init arch_init_ideal_nops(void) + ideal_nops = intel_nops; + #endif + } +- ++ break; + default: + #ifdef CONFIG_X86_64 + ideal_nops = k8_nops; +diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c +index 1b267e7..00a0385 100644 +--- a/arch/x86/xen/p2m.c ++++ b/arch/x86/xen/p2m.c +@@ -686,6 +686,7 @@ int m2p_add_override(unsigned long mfn, struct page *page, + unsigned long uninitialized_var(address); + unsigned level; + pte_t *ptep = NULL; ++ int ret = 0; + + pfn = page_to_pfn(page); + if (!PageHighMem(page)) { +@@ -721,6 +722,24 @@ int m2p_add_override(unsigned long mfn, struct page *page, + list_add(&page->lru, &m2p_overrides[mfn_hash(mfn)]); + spin_unlock_irqrestore(&m2p_override_lock, flags); + ++ /* p2m(m2p(mfn)) == mfn: the mfn is already present somewhere in ++ * this domain. Set the FOREIGN_FRAME_BIT in the p2m for the other ++ * pfn so that the following mfn_to_pfn(mfn) calls will return the ++ * pfn from the m2p_override (the backend pfn) instead. ++ * We need to do this because the pages shared by the frontend ++ * (xen-blkfront) can be already locked (lock_page, called by ++ * do_read_cache_page); when the userspace backend tries to use them ++ * with direct_IO, mfn_to_pfn returns the pfn of the frontend, so ++ * do_blockdev_direct_IO is going to try to lock the same pages ++ * again resulting in a deadlock. ++ * As a side effect get_user_pages_fast might not be safe on the ++ * frontend pages while they are being shared with the backend, ++ * because mfn_to_pfn (that ends up being called by GUPF) will ++ * return the backend pfn rather than the frontend pfn. */ ++ ret = __get_user(pfn, &machine_to_phys_mapping[mfn]); ++ if (ret == 0 && get_phys_to_machine(pfn) == mfn) ++ set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)); ++ + return 0; + } + EXPORT_SYMBOL_GPL(m2p_add_override); +@@ -732,6 +751,7 @@ int m2p_remove_override(struct page *page, bool clear_pte) + unsigned long uninitialized_var(address); + unsigned level; + pte_t *ptep = NULL; ++ int ret = 0; + + pfn = page_to_pfn(page); + mfn = get_phys_to_machine(pfn); +@@ -801,6 +821,22 @@ int m2p_remove_override(struct page *page, bool clear_pte) + } else + set_phys_to_machine(pfn, page->index); + ++ /* p2m(m2p(mfn)) == FOREIGN_FRAME(mfn): the mfn is already present ++ * somewhere in this domain, even before being added to the ++ * m2p_override (see comment above in m2p_add_override). ++ * If there are no other entries in the m2p_override corresponding ++ * to this mfn, then remove the FOREIGN_FRAME_BIT from the p2m for ++ * the original pfn (the one shared by the frontend): the backend ++ * cannot do any IO on this page anymore because it has been ++ * unshared. Removing the FOREIGN_FRAME_BIT from the p2m entry of ++ * the original pfn causes mfn_to_pfn(mfn) to return the frontend ++ * pfn again. */ ++ mfn &= ~FOREIGN_FRAME_BIT; ++ ret = __get_user(pfn, &machine_to_phys_mapping[mfn]); ++ if (ret == 0 && get_phys_to_machine(pfn) == FOREIGN_FRAME(mfn) && ++ m2p_find_override(mfn) == NULL) ++ set_phys_to_machine(pfn, mfn); ++ + return 0; + } + EXPORT_SYMBOL_GPL(m2p_remove_override); +diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c +index 9955a53..c864add 100644 +--- a/drivers/block/floppy.c ++++ b/drivers/block/floppy.c +@@ -4369,8 +4369,14 @@ out_unreg_blkdev: + out_put_disk: + while (dr--) { + del_timer_sync(&motor_off_timer[dr]); +- if (disks[dr]->queue) ++ if (disks[dr]->queue) { + blk_cleanup_queue(disks[dr]->queue); ++ /* ++ * put_disk() is not paired with add_disk() and ++ * will put queue reference one extra time. fix it. ++ */ ++ disks[dr]->queue = NULL; ++ } + put_disk(disks[dr]); + } + return err; +diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c +index e46f2f7..650a308 100644 +--- a/drivers/block/virtio_blk.c ++++ b/drivers/block/virtio_blk.c +@@ -20,8 +20,6 @@ struct workqueue_struct *virtblk_wq; + + struct virtio_blk + { +- spinlock_t lock; +- + struct virtio_device *vdev; + struct virtqueue *vq; + +@@ -62,7 +60,7 @@ static void blk_done(struct virtqueue *vq) + unsigned int len; + unsigned long flags; + +- spin_lock_irqsave(&vblk->lock, flags); ++ spin_lock_irqsave(vblk->disk->queue->queue_lock, flags); + while ((vbr = virtqueue_get_buf(vblk->vq, &len)) != NULL) { + int error; + +@@ -97,7 +95,7 @@ static void blk_done(struct virtqueue *vq) + } + /* In case queue is stopped waiting for more buffers. */ + blk_start_queue(vblk->disk->queue); +- spin_unlock_irqrestore(&vblk->lock, flags); ++ spin_unlock_irqrestore(vblk->disk->queue->queue_lock, flags); + } + + static bool do_req(struct request_queue *q, struct virtio_blk *vblk, +@@ -384,7 +382,6 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) + } + + INIT_LIST_HEAD(&vblk->reqs); +- spin_lock_init(&vblk->lock); + vblk->vdev = vdev; + vblk->sg_elems = sg_elems; + sg_init_table(vblk->sg, vblk->sg_elems); +@@ -410,7 +407,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) + goto out_mempool; + } + +- q = vblk->disk->queue = blk_init_queue(do_virtblk_request, &vblk->lock); ++ q = vblk->disk->queue = blk_init_queue(do_virtblk_request, NULL); + if (!q) { + err = -ENOMEM; + goto out_put_disk; +diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c +index 5c0d96a..b12ffea 100644 +--- a/drivers/char/mspec.c ++++ b/drivers/char/mspec.c +@@ -284,7 +284,7 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma, + vdata->flags = flags; + vdata->type = type; + spin_lock_init(&vdata->lock); +- vdata->refcnt = ATOMIC_INIT(1); ++ atomic_set(&vdata->refcnt, 1); + vma->vm_private_data = vdata; + + vma->vm_flags |= (VM_IO | VM_RESERVED | VM_PFNMAP | VM_DONTEXPAND); +diff --git a/drivers/char/random.c b/drivers/char/random.c +index 6035ab8..631d4f6 100644 +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -125,21 +125,26 @@ + * The current exported interfaces for gathering environmental noise + * from the devices are: + * ++ * void add_device_randomness(const void *buf, unsigned int size); + * void add_input_randomness(unsigned int type, unsigned int code, + * unsigned int value); +- * void add_interrupt_randomness(int irq); ++ * void add_interrupt_randomness(int irq, int irq_flags); + * void add_disk_randomness(struct gendisk *disk); + * ++ * add_device_randomness() is for adding data to the random pool that ++ * is likely to differ between two devices (or possibly even per boot). ++ * This would be things like MAC addresses or serial numbers, or the ++ * read-out of the RTC. This does *not* add any actual entropy to the ++ * pool, but it initializes the pool to different values for devices ++ * that might otherwise be identical and have very little entropy ++ * available to them (particularly common in the embedded world). ++ * + * add_input_randomness() uses the input layer interrupt timing, as well as + * the event type information from the hardware. + * +- * add_interrupt_randomness() uses the inter-interrupt timing as random +- * inputs to the entropy pool. Note that not all interrupts are good +- * sources of randomness! For example, the timer interrupts is not a +- * good choice, because the periodicity of the interrupts is too +- * regular, and hence predictable to an attacker. Network Interface +- * Controller interrupts are a better measure, since the timing of the +- * NIC interrupts are more unpredictable. ++ * add_interrupt_randomness() uses the interrupt timing as random ++ * inputs to the entropy pool. Using the cycle counters and the irq source ++ * as inputs, it feeds the randomness roughly once a second. + * + * add_disk_randomness() uses what amounts to the seek time of block + * layer request events, on a per-disk_devt basis, as input to the +@@ -248,6 +253,8 @@ + #include <linux/percpu.h> + #include <linux/cryptohash.h> + #include <linux/fips.h> ++#include <linux/ptrace.h> ++#include <linux/kmemcheck.h> + + #ifdef CONFIG_GENERIC_HARDIRQS + # include <linux/irq.h> +@@ -256,6 +263,7 @@ + #include <asm/processor.h> + #include <asm/uaccess.h> + #include <asm/irq.h> ++#include <asm/irq_regs.h> + #include <asm/io.h> + + /* +@@ -266,6 +274,8 @@ + #define SEC_XFER_SIZE 512 + #define EXTRACT_SIZE 10 + ++#define LONGS(x) (((x) + sizeof(unsigned long) - 1)/sizeof(unsigned long)) ++ + /* + * The minimum number of bits of entropy before we wake up a read on + * /dev/random. Should be enough to do a significant reseed. +@@ -420,8 +430,10 @@ struct entropy_store { + /* read-write data: */ + spinlock_t lock; + unsigned add_ptr; ++ unsigned input_rotate; + int entropy_count; +- int input_rotate; ++ int entropy_total; ++ unsigned int initialized:1; + __u8 last_data[EXTRACT_SIZE]; + }; + +@@ -454,6 +466,10 @@ static struct entropy_store nonblocking_pool = { + .pool = nonblocking_pool_data + }; + ++static __u32 const twist_table[8] = { ++ 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158, ++ 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 }; ++ + /* + * This function adds bytes into the entropy "pool". It does not + * update the entropy estimate. The caller should call +@@ -464,29 +480,24 @@ static struct entropy_store nonblocking_pool = { + * it's cheap to do so and helps slightly in the expected case where + * the entropy is concentrated in the low-order bits. + */ +-static void mix_pool_bytes_extract(struct entropy_store *r, const void *in, +- int nbytes, __u8 out[64]) ++static void __mix_pool_bytes(struct entropy_store *r, const void *in, ++ int nbytes, __u8 out[64]) + { +- static __u32 const twist_table[8] = { +- 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158, +- 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 }; + unsigned long i, j, tap1, tap2, tap3, tap4, tap5; + int input_rotate; + int wordmask = r->poolinfo->poolwords - 1; + const char *bytes = in; + __u32 w; +- unsigned long flags; + +- /* Taps are constant, so we can load them without holding r->lock. */ + tap1 = r->poolinfo->tap1; + tap2 = r->poolinfo->tap2; + tap3 = r->poolinfo->tap3; + tap4 = r->poolinfo->tap4; + tap5 = r->poolinfo->tap5; + +- spin_lock_irqsave(&r->lock, flags); +- input_rotate = r->input_rotate; +- i = r->add_ptr; ++ smp_rmb(); ++ input_rotate = ACCESS_ONCE(r->input_rotate); ++ i = ACCESS_ONCE(r->add_ptr); + + /* mix one byte at a time to simplify size handling and churn faster */ + while (nbytes--) { +@@ -513,19 +524,53 @@ static void mix_pool_bytes_extract(struct entropy_store *r, const void *in, + input_rotate += i ? 7 : 14; + } + +- r->input_rotate = input_rotate; +- r->add_ptr = i; ++ ACCESS_ONCE(r->input_rotate) = input_rotate; ++ ACCESS_ONCE(r->add_ptr) = i; ++ smp_wmb(); + + if (out) + for (j = 0; j < 16; j++) + ((__u32 *)out)[j] = r->pool[(i - j) & wordmask]; ++} ++ ++static void mix_pool_bytes(struct entropy_store *r, const void *in, ++ int nbytes, __u8 out[64]) ++{ ++ unsigned long flags; + ++ spin_lock_irqsave(&r->lock, flags); ++ __mix_pool_bytes(r, in, nbytes, out); + spin_unlock_irqrestore(&r->lock, flags); + } + +-static void mix_pool_bytes(struct entropy_store *r, const void *in, int bytes) ++struct fast_pool { ++ __u32 pool[4]; ++ unsigned long last; ++ unsigned short count; ++ unsigned char rotate; ++ unsigned char last_timer_intr; ++}; ++ ++/* ++ * This is a fast mixing routine used by the interrupt randomness ++ * collector. It's hardcoded for an 128 bit pool and assumes that any ++ * locks that might be needed are taken by the caller. ++ */ ++static void fast_mix(struct fast_pool *f, const void *in, int nbytes) + { +- mix_pool_bytes_extract(r, in, bytes, NULL); ++ const char *bytes = in; ++ __u32 w; ++ unsigned i = f->count; ++ unsigned input_rotate = f->rotate; ++ ++ while (nbytes--) { ++ w = rol32(*bytes++, input_rotate & 31) ^ f->pool[i & 3] ^ ++ f->pool[(i + 1) & 3]; ++ f->pool[i & 3] = (w >> 3) ^ twist_table[w & 7]; ++ input_rotate += (i++ & 3) ? 7 : 14; ++ } ++ f->count = i; ++ f->rotate = input_rotate; + } + + /* +@@ -533,30 +578,34 @@ static void mix_pool_bytes(struct entropy_store *r, const void *in, int bytes) + */ + static void credit_entropy_bits(struct entropy_store *r, int nbits) + { +- unsigned long flags; +- int entropy_count; ++ int entropy_count, orig; + + if (!nbits) + return; + +- spin_lock_irqsave(&r->lock, flags); +- + DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name); +- entropy_count = r->entropy_count; ++retry: ++ entropy_count = orig = ACCESS_ONCE(r->entropy_count); + entropy_count += nbits; + if (entropy_count < 0) { + DEBUG_ENT("negative entropy/overflow\n"); + entropy_count = 0; + } else if (entropy_count > r->poolinfo->POOLBITS) + entropy_count = r->poolinfo->POOLBITS; +- r->entropy_count = entropy_count; ++ if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) ++ goto retry; ++ ++ if (!r->initialized && nbits > 0) { ++ r->entropy_total += nbits; ++ if (r->entropy_total > 128) ++ r->initialized = 1; ++ } + + /* should we wake readers? */ + if (r == &input_pool && entropy_count >= random_read_wakeup_thresh) { + wake_up_interruptible(&random_read_wait); + kill_fasync(&fasync, SIGIO, POLL_IN); + } +- spin_unlock_irqrestore(&r->lock, flags); + } + + /********************************************************************* +@@ -609,6 +658,25 @@ static void set_timer_rand_state(unsigned int irq, + } + #endif + ++/* ++ * Add device- or boot-specific data to the input and nonblocking ++ * pools to help initialize them to unique values. ++ * ++ * None of this adds any entropy, it is meant to avoid the ++ * problem of the nonblocking pool having similar initial state ++ * across largely identical devices. ++ */ ++void add_device_randomness(const void *buf, unsigned int size) ++{ ++ unsigned long time = get_cycles() ^ jiffies; ++ ++ mix_pool_bytes(&input_pool, buf, size, NULL); ++ mix_pool_bytes(&input_pool, &time, sizeof(time), NULL); ++ mix_pool_bytes(&nonblocking_pool, buf, size, NULL); ++ mix_pool_bytes(&nonblocking_pool, &time, sizeof(time), NULL); ++} ++EXPORT_SYMBOL(add_device_randomness); ++ + static struct timer_rand_state input_timer_state; + + /* +@@ -624,8 +692,8 @@ static struct timer_rand_state input_timer_state; + static void add_timer_randomness(struct timer_rand_state *state, unsigned num) + { + struct { +- cycles_t cycles; + long jiffies; ++ unsigned cycles; + unsigned num; + } sample; + long delta, delta2, delta3; +@@ -639,7 +707,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) + sample.jiffies = jiffies; + sample.cycles = get_cycles(); + sample.num = num; +- mix_pool_bytes(&input_pool, &sample, sizeof(sample)); ++ mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL); + + /* + * Calculate number of bits of randomness we probably added. +@@ -696,17 +764,48 @@ void add_input_randomness(unsigned int type, unsigned int code, + } + EXPORT_SYMBOL_GPL(add_input_randomness); + +-void add_interrupt_randomness(int irq) ++static DEFINE_PER_CPU(struct fast_pool, irq_randomness); ++ ++void add_interrupt_randomness(int irq, int irq_flags) + { +- struct timer_rand_state *state; ++ struct entropy_store *r; ++ struct fast_pool *fast_pool = &__get_cpu_var(irq_randomness); ++ struct pt_regs *regs = get_irq_regs(); ++ unsigned long now = jiffies; ++ __u32 input[4], cycles = get_cycles(); ++ ++ input[0] = cycles ^ jiffies; ++ input[1] = irq; ++ if (regs) { ++ __u64 ip = instruction_pointer(regs); ++ input[2] = ip; ++ input[3] = ip >> 32; ++ } + +- state = get_timer_rand_state(irq); ++ fast_mix(fast_pool, input, sizeof(input)); + +- if (state == NULL) ++ if ((fast_pool->count & 1023) && ++ !time_after(now, fast_pool->last + HZ)) + return; + +- DEBUG_ENT("irq event %d\n", irq); +- add_timer_randomness(state, 0x100 + irq); ++ fast_pool->last = now; ++ ++ r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool; ++ __mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool), NULL); ++ /* ++ * If we don't have a valid cycle counter, and we see ++ * back-to-back timer interrupts, then skip giving credit for ++ * any entropy. ++ */ ++ if (cycles == 0) { ++ if (irq_flags & __IRQF_TIMER) { ++ if (fast_pool->last_timer_intr) ++ return; ++ fast_pool->last_timer_intr = 1; ++ } else ++ fast_pool->last_timer_intr = 0; ++ } ++ credit_entropy_bits(r, 1); + } + + #ifdef CONFIG_BLOCK +@@ -738,7 +837,7 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, + */ + static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) + { +- __u32 tmp[OUTPUT_POOL_WORDS]; ++ __u32 tmp[OUTPUT_POOL_WORDS]; + + if (r->pull && r->entropy_count < nbytes * 8 && + r->entropy_count < r->poolinfo->POOLBITS) { +@@ -757,7 +856,7 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) + + bytes = extract_entropy(r->pull, tmp, bytes, + random_read_wakeup_thresh / 8, rsvd); +- mix_pool_bytes(r, tmp, bytes); ++ mix_pool_bytes(r, tmp, bytes, NULL); + credit_entropy_bits(r, bytes*8); + } + } +@@ -816,13 +915,19 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, + static void extract_buf(struct entropy_store *r, __u8 *out) + { + int i; +- __u32 hash[5], workspace[SHA_WORKSPACE_WORDS]; ++ union { ++ __u32 w[5]; ++ unsigned long l[LONGS(EXTRACT_SIZE)]; ++ } hash; ++ __u32 workspace[SHA_WORKSPACE_WORDS]; + __u8 extract[64]; ++ unsigned long flags; + + /* Generate a hash across the pool, 16 words (512 bits) at a time */ +- sha_init(hash); ++ sha_init(hash.w); ++ spin_lock_irqsave(&r->lock, flags); + for (i = 0; i < r->poolinfo->poolwords; i += 16) +- sha_transform(hash, (__u8 *)(r->pool + i), workspace); ++ sha_transform(hash.w, (__u8 *)(r->pool + i), workspace); + + /* + * We mix the hash back into the pool to prevent backtracking +@@ -833,13 +938,14 @@ static void extract_buf(struct entropy_store *r, __u8 *out) + * brute-forcing the feedback as hard as brute-forcing the + * hash. + */ +- mix_pool_bytes_extract(r, hash, sizeof(hash), extract); ++ __mix_pool_bytes(r, hash.w, sizeof(hash.w), extract); ++ spin_unlock_irqrestore(&r->lock, flags); + + /* + * To avoid duplicates, we atomically extract a portion of the + * pool while mixing, and hash one final time. + */ +- sha_transform(hash, extract, workspace); ++ sha_transform(hash.w, extract, workspace); + memset(extract, 0, sizeof(extract)); + memset(workspace, 0, sizeof(workspace)); + +@@ -848,19 +954,30 @@ static void extract_buf(struct entropy_store *r, __u8 *out) + * pattern, we fold it in half. Thus, we always feed back + * twice as much data as we output. + */ +- hash[0] ^= hash[3]; +- hash[1] ^= hash[4]; +- hash[2] ^= rol32(hash[2], 16); +- memcpy(out, hash, EXTRACT_SIZE); +- memset(hash, 0, sizeof(hash)); ++ hash.w[0] ^= hash.w[3]; ++ hash.w[1] ^= hash.w[4]; ++ hash.w[2] ^= rol32(hash.w[2], 16); ++ ++ /* ++ * If we have a architectural hardware random number ++ * generator, mix that in, too. ++ */ ++ for (i = 0; i < LONGS(EXTRACT_SIZE); i++) { ++ unsigned long v; ++ if (!arch_get_random_long(&v)) ++ break; ++ hash.l[i] ^= v; ++ } ++ ++ memcpy(out, &hash, EXTRACT_SIZE); ++ memset(&hash, 0, sizeof(hash)); + } + + static ssize_t extract_entropy(struct entropy_store *r, void *buf, +- size_t nbytes, int min, int reserved) ++ size_t nbytes, int min, int reserved) + { + ssize_t ret = 0, i; + __u8 tmp[EXTRACT_SIZE]; +- unsigned long flags; + + xfer_secondary_pool(r, nbytes); + nbytes = account(r, nbytes, min, reserved); +@@ -869,6 +986,8 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, + extract_buf(r, tmp); + + if (fips_enabled) { ++ unsigned long flags; ++ + spin_lock_irqsave(&r->lock, flags); + if (!memcmp(tmp, r->last_data, EXTRACT_SIZE)) + panic("Hardware RNG duplicated output!\n"); +@@ -927,17 +1046,34 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf, + + /* + * This function is the exported kernel interface. It returns some +- * number of good random numbers, suitable for seeding TCP sequence +- * numbers, etc. ++ * number of good random numbers, suitable for key generation, seeding ++ * TCP sequence numbers, etc. It does not use the hw random number ++ * generator, if available; use get_random_bytes_arch() for that. + */ + void get_random_bytes(void *buf, int nbytes) + { ++ extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0); ++} ++EXPORT_SYMBOL(get_random_bytes); ++ ++/* ++ * This function will use the architecture-specific hardware random ++ * number generator if it is available. The arch-specific hw RNG will ++ * almost certainly be faster than what we can do in software, but it ++ * is impossible to verify that it is implemented securely (as ++ * opposed, to, say, the AES encryption of a sequence number using a ++ * key known by the NSA). So it's useful if we need the speed, but ++ * only if we're willing to trust the hardware manufacturer not to ++ * have put in a back door. ++ */ ++void get_random_bytes_arch(void *buf, int nbytes) ++{ + char *p = buf; + + while (nbytes) { + unsigned long v; + int chunk = min(nbytes, (int)sizeof(unsigned long)); +- ++ + if (!arch_get_random_long(&v)) + break; + +@@ -946,9 +1082,11 @@ void get_random_bytes(void *buf, int nbytes) + nbytes -= chunk; + } + +- extract_entropy(&nonblocking_pool, p, nbytes, 0, 0); ++ if (nbytes) ++ extract_entropy(&nonblocking_pool, p, nbytes, 0, 0); + } +-EXPORT_SYMBOL(get_random_bytes); ++EXPORT_SYMBOL(get_random_bytes_arch); ++ + + /* + * init_std_data - initialize pool with system data +@@ -961,16 +1099,19 @@ EXPORT_SYMBOL(get_random_bytes); + */ + static void init_std_data(struct entropy_store *r) + { +- ktime_t now; +- unsigned long flags; ++ int i; ++ ktime_t now = ktime_get_real(); ++ unsigned long rv; + +- spin_lock_irqsave(&r->lock, flags); + r->entropy_count = 0; +- spin_unlock_irqrestore(&r->lock, flags); +- +- now = ktime_get_real(); +- mix_pool_bytes(r, &now, sizeof(now)); +- mix_pool_bytes(r, utsname(), sizeof(*(utsname()))); ++ r->entropy_total = 0; ++ mix_pool_bytes(r, &now, sizeof(now), NULL); ++ for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(rv)) { ++ if (!arch_get_random_long(&rv)) ++ break; ++ mix_pool_bytes(r, &rv, sizeof(rv), NULL); ++ } ++ mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL); + } + + static int rand_initialize(void) +@@ -1107,7 +1248,7 @@ write_pool(struct entropy_store *r, const char __user *buffer, size_t count) + count -= bytes; + p += bytes; + +- mix_pool_bytes(r, buf, bytes); ++ mix_pool_bytes(r, buf, bytes, NULL); + cond_resched(); + } + +diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c +index 51e0e2d..a330492 100644 +--- a/drivers/firmware/pcdp.c ++++ b/drivers/firmware/pcdp.c +@@ -95,7 +95,7 @@ efi_setup_pcdp_console(char *cmdline) + if (efi.hcdp == EFI_INVALID_TABLE_ADDR) + return -ENODEV; + +- pcdp = ioremap(efi.hcdp, 4096); ++ pcdp = early_ioremap(efi.hcdp, 4096); + printk(KERN_INFO "PCDP: v%d at 0x%lx\n", pcdp->rev, efi.hcdp); + + if (strstr(cmdline, "console=hcdp")) { +@@ -131,6 +131,6 @@ efi_setup_pcdp_console(char *cmdline) + } + + out: +- iounmap(pcdp); ++ early_iounmap(pcdp, 4096); + return rc; + } +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index d4c4937..fae2050 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -708,8 +708,8 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, + + bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; + +- for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { +- for (clock = 0; clock <= max_clock; clock++) { ++ for (clock = 0; clock <= max_clock; clock++) { ++ for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { + int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); + + if (intel_dp_link_required(mode->clock, bpp) +diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c +index a6dcd18..96532bc 100644 +--- a/drivers/input/mouse/synaptics.c ++++ b/drivers/input/mouse/synaptics.c +@@ -40,11 +40,28 @@ + * Note that newer firmware allows querying device for maximum useable + * coordinates. + */ ++#define XMIN 0 ++#define XMAX 6143 ++#define YMIN 0 ++#define YMAX 6143 + #define XMIN_NOMINAL 1472 + #define XMAX_NOMINAL 5472 + #define YMIN_NOMINAL 1408 + #define YMAX_NOMINAL 4448 + ++/* Size in bits of absolute position values reported by the hardware */ ++#define ABS_POS_BITS 13 ++ ++/* ++ * Any position values from the hardware above the following limits are ++ * treated as "wrapped around negative" values that have been truncated to ++ * the 13-bit reporting range of the hardware. These are just reasonable ++ * guesses and can be adjusted if hardware is found that operates outside ++ * of these parameters. ++ */ ++#define X_MAX_POSITIVE (((1 << ABS_POS_BITS) + XMAX) / 2) ++#define Y_MAX_POSITIVE (((1 << ABS_POS_BITS) + YMAX) / 2) ++ + /* + * Synaptics touchpads report the y coordinate from bottom to top, which is + * opposite from what userspace expects. +@@ -544,6 +561,12 @@ static int synaptics_parse_hw_state(const unsigned char buf[], + hw->right = (buf[0] & 0x02) ? 1 : 0; + } + ++ /* Convert wrap-around values to negative */ ++ if (hw->x > X_MAX_POSITIVE) ++ hw->x -= 1 << ABS_POS_BITS; ++ if (hw->y > Y_MAX_POSITIVE) ++ hw->y -= 1 << ABS_POS_BITS; ++ + return 0; + } + +diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c +index 532a902..d432032 100644 +--- a/drivers/md/dm-thin.c ++++ b/drivers/md/dm-thin.c +@@ -19,7 +19,7 @@ + /* + * Tunable constants + */ +-#define ENDIO_HOOK_POOL_SIZE 10240 ++#define ENDIO_HOOK_POOL_SIZE 1024 + #define DEFERRED_SET_SIZE 64 + #define MAPPING_POOL_SIZE 1024 + #define PRISON_CELLS 1024 +@@ -857,7 +857,7 @@ static void process_prepared_mapping(struct new_mapping *m) + + if (m->err) { + cell_error(m->cell); +- return; ++ goto out; + } + + /* +@@ -869,7 +869,7 @@ static void process_prepared_mapping(struct new_mapping *m) + if (r) { + DMERR("dm_thin_insert_block() failed"); + cell_error(m->cell); +- return; ++ goto out; + } + + /* +@@ -884,6 +884,7 @@ static void process_prepared_mapping(struct new_mapping *m) + } else + cell_defer(tc, m->cell, m->data_block); + ++out: + list_del(&m->list); + mempool_free(m, tc->pool->mapping_pool); + } +diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c +index 2d97bf0..62306e5 100644 +--- a/drivers/md/raid1.c ++++ b/drivers/md/raid1.c +@@ -2321,7 +2321,10 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipp + /* There is nowhere to write, so all non-sync + * drives must be failed - so we are finished + */ +- sector_t rv = max_sector - sector_nr; ++ sector_t rv; ++ if (min_bad > 0) ++ max_sector = sector_nr + min_bad; ++ rv = max_sector - sector_nr; + *skipped = 1; + put_buf(r1_bio); + return rv; +diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c +index ed77c6d..5327061 100644 +--- a/drivers/media/rc/ene_ir.c ++++ b/drivers/media/rc/ene_ir.c +@@ -1018,6 +1018,8 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) + + spin_lock_init(&dev->hw_lock); + ++ dev->hw_io = pnp_port_start(pnp_dev, 0); ++ + pnp_set_drvdata(pnp_dev, dev); + dev->pnp_dev = pnp_dev; + +@@ -1072,7 +1074,6 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) + + /* claim the resources */ + error = -EBUSY; +- dev->hw_io = pnp_port_start(pnp_dev, 0); + if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) { + dev->hw_io = -1; + dev->irq = -1; +diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c +index 60107ee..4eec7b7 100644 +--- a/drivers/mfd/ab3100-core.c ++++ b/drivers/mfd/ab3100-core.c +@@ -409,8 +409,6 @@ static irqreturn_t ab3100_irq_handler(int irq, void *data) + u32 fatevent; + int err; + +- add_interrupt_randomness(irq); +- + err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1, + event_regs, 3); + if (err) +diff --git a/drivers/mfd/wm831x-otp.c b/drivers/mfd/wm831x-otp.c +index f742745..b90f3e0 100644 +--- a/drivers/mfd/wm831x-otp.c ++++ b/drivers/mfd/wm831x-otp.c +@@ -18,6 +18,7 @@ + #include <linux/bcd.h> + #include <linux/delay.h> + #include <linux/mfd/core.h> ++#include <linux/random.h> + + #include <linux/mfd/wm831x/core.h> + #include <linux/mfd/wm831x/otp.h> +@@ -66,6 +67,7 @@ static DEVICE_ATTR(unique_id, 0444, wm831x_unique_id_show, NULL); + + int wm831x_otp_init(struct wm831x *wm831x) + { ++ char uuid[WM831X_UNIQUE_ID_LEN]; + int ret; + + ret = device_create_file(wm831x->dev, &dev_attr_unique_id); +@@ -73,6 +75,12 @@ int wm831x_otp_init(struct wm831x *wm831x) + dev_err(wm831x->dev, "Unique ID attribute not created: %d\n", + ret); + ++ ret = wm831x_unique_id_read(wm831x, uuid); ++ if (ret == 0) ++ add_device_randomness(uuid, sizeof(uuid)); ++ else ++ dev_err(wm831x->dev, "Failed to read UUID: %d\n", ret); ++ + return ret; + } + +diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c +index bdf960b..ae7528b 100644 +--- a/drivers/net/wireless/rt2x00/rt2800usb.c ++++ b/drivers/net/wireless/rt2x00/rt2800usb.c +@@ -925,6 +925,7 @@ static struct usb_device_id rt2800usb_device_table[] = { + { USB_DEVICE(0x0411, 0x015d) }, + { USB_DEVICE(0x0411, 0x016f) }, + { USB_DEVICE(0x0411, 0x01a2) }, ++ { USB_DEVICE(0x0411, 0x01ee) }, + /* Corega */ + { USB_DEVICE(0x07aa, 0x002f) }, + { USB_DEVICE(0x07aa, 0x003c) }, +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index d1049ee..26fba2d 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -1431,14 +1431,9 @@ static int asus_wmi_platform_init(struct asus_wmi *asus) + */ + if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, 0, 0, NULL)) + asus->dsts_id = ASUS_WMI_METHODID_DSTS; +- else if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS2, 0, 0, NULL)) ++ else + asus->dsts_id = ASUS_WMI_METHODID_DSTS2; + +- if (!asus->dsts_id) { +- pr_err("Can't find DSTS"); +- return -ENODEV; +- } +- + /* CWAP allow to define the behavior of the Fn+F2 key, + * this method doesn't seems to be present on Eee PCs */ + if (asus->driver->wapf >= 0) +diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c +index bdc909b..f3c2110 100644 +--- a/drivers/rtc/rtc-wm831x.c ++++ b/drivers/rtc/rtc-wm831x.c +@@ -24,7 +24,7 @@ + #include <linux/mfd/wm831x/core.h> + #include <linux/delay.h> + #include <linux/platform_device.h> +- ++#include <linux/random.h> + + /* + * R16416 (0x4020) - RTC Write Counter +@@ -96,6 +96,26 @@ struct wm831x_rtc { + unsigned int alarm_enabled:1; + }; + ++static void wm831x_rtc_add_randomness(struct wm831x *wm831x) ++{ ++ int ret; ++ u16 reg; ++ ++ /* ++ * The write counter contains a pseudo-random number which is ++ * regenerated every time we set the RTC so it should be a ++ * useful per-system source of entropy. ++ */ ++ ret = wm831x_reg_read(wm831x, WM831X_RTC_WRITE_COUNTER); ++ if (ret >= 0) { ++ reg = ret; ++ add_device_randomness(®, sizeof(reg)); ++ } else { ++ dev_warn(wm831x->dev, "Failed to read RTC write counter: %d\n", ++ ret); ++ } ++} ++ + /* + * Read current time and date in RTC + */ +@@ -449,6 +469,8 @@ static int wm831x_rtc_probe(struct platform_device *pdev) + alm_irq, ret); + } + ++ wm831x_rtc_add_randomness(wm831x); ++ + return 0; + + err: +diff --git a/drivers/staging/media/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c +index 6903d39..90e9e32 100644 +--- a/drivers/staging/media/lirc/lirc_sir.c ++++ b/drivers/staging/media/lirc/lirc_sir.c +@@ -53,6 +53,7 @@ + #include <linux/io.h> + #include <asm/irq.h> + #include <linux/fcntl.h> ++#include <linux/platform_device.h> + #ifdef LIRC_ON_SA1100 + #include <asm/hardware.h> + #ifdef CONFIG_SA1100_COLLIE +@@ -488,9 +489,11 @@ static struct lirc_driver driver = { + .owner = THIS_MODULE, + }; + ++static struct platform_device *lirc_sir_dev; + + static int init_chrdev(void) + { ++ driver.dev = &lirc_sir_dev->dev; + driver.minor = lirc_register_driver(&driver); + if (driver.minor < 0) { + printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n"); +@@ -1216,20 +1219,71 @@ static int init_lirc_sir(void) + return 0; + } + ++static int __devinit lirc_sir_probe(struct platform_device *dev) ++{ ++ return 0; ++} ++ ++static int __devexit lirc_sir_remove(struct platform_device *dev) ++{ ++ return 0; ++} ++ ++static struct platform_driver lirc_sir_driver = { ++ .probe = lirc_sir_probe, ++ .remove = __devexit_p(lirc_sir_remove), ++ .driver = { ++ .name = "lirc_sir", ++ .owner = THIS_MODULE, ++ }, ++}; + + static int __init lirc_sir_init(void) + { + int retval; + ++ retval = platform_driver_register(&lirc_sir_driver); ++ if (retval) { ++ printk(KERN_ERR LIRC_DRIVER_NAME ": Platform driver register " ++ "failed!\n"); ++ return -ENODEV; ++ } ++ ++ lirc_sir_dev = platform_device_alloc("lirc_dev", 0); ++ if (!lirc_sir_dev) { ++ printk(KERN_ERR LIRC_DRIVER_NAME ": Platform device alloc " ++ "failed!\n"); ++ retval = -ENOMEM; ++ goto pdev_alloc_fail; ++ } ++ ++ retval = platform_device_add(lirc_sir_dev); ++ if (retval) { ++ printk(KERN_ERR LIRC_DRIVER_NAME ": Platform device add " ++ "failed!\n"); ++ retval = -ENODEV; ++ goto pdev_add_fail; ++ } ++ + retval = init_chrdev(); + if (retval < 0) +- return retval; ++ goto fail; ++ + retval = init_lirc_sir(); + if (retval) { + drop_chrdev(); +- return retval; ++ goto fail; + } ++ + return 0; ++ ++fail: ++ platform_device_del(lirc_sir_dev); ++pdev_add_fail: ++ platform_device_put(lirc_sir_dev); ++pdev_alloc_fail: ++ platform_driver_unregister(&lirc_sir_driver); ++ return retval; + } + + static void __exit lirc_sir_exit(void) +@@ -1237,6 +1291,8 @@ static void __exit lirc_sir_exit(void) + drop_hardware(); + drop_chrdev(); + drop_port(); ++ platform_device_unregister(lirc_sir_dev); ++ platform_driver_unregister(&lirc_sir_driver); + printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n"); + } + +diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c +index a4b192d..08b92a6 100644 +--- a/drivers/tty/serial/pch_uart.c ++++ b/drivers/tty/serial/pch_uart.c +@@ -660,7 +660,8 @@ static void pch_dma_rx_complete(void *arg) + tty_flip_buffer_push(tty); + tty_kref_put(tty); + async_tx_ack(priv->desc_rx); +- pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT); ++ pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT | ++ PCH_UART_HAL_RX_ERR_INT); + } + + static void pch_dma_tx_complete(void *arg) +@@ -715,7 +716,8 @@ static int handle_rx_to(struct eg20t_port *priv) + int rx_size; + int ret; + if (!priv->start_rx) { +- pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT); ++ pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT | ++ PCH_UART_HAL_RX_ERR_INT); + return 0; + } + buf = &priv->rxbuf; +@@ -977,11 +979,13 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) + case PCH_UART_IID_RDR: /* Received Data Ready */ + if (priv->use_dma) { + pch_uart_hal_disable_interrupt(priv, +- PCH_UART_HAL_RX_INT); ++ PCH_UART_HAL_RX_INT | ++ PCH_UART_HAL_RX_ERR_INT); + ret = dma_handle_rx(priv); + if (!ret) + pch_uart_hal_enable_interrupt(priv, +- PCH_UART_HAL_RX_INT); ++ PCH_UART_HAL_RX_INT | ++ PCH_UART_HAL_RX_ERR_INT); + } else { + ret = handle_rx(priv); + } +@@ -1107,7 +1111,8 @@ static void pch_uart_stop_rx(struct uart_port *port) + struct eg20t_port *priv; + priv = container_of(port, struct eg20t_port, port); + priv->start_rx = 0; +- pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT); ++ pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT | ++ PCH_UART_HAL_RX_ERR_INT); + priv->int_dis_flag = 1; + } + +@@ -1163,6 +1168,7 @@ static int pch_uart_startup(struct uart_port *port) + break; + case 16: + fifo_size = PCH_UART_HAL_FIFO16; ++ break; + case 1: + default: + fifo_size = PCH_UART_HAL_FIFO_DIS; +@@ -1200,7 +1206,8 @@ static int pch_uart_startup(struct uart_port *port) + pch_request_dma(port); + + priv->start_rx = 1; +- pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT); ++ pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT | ++ PCH_UART_HAL_RX_ERR_INT); + uart_update_timeout(port, CS8, default_baud); + + return 0; +@@ -1258,7 +1265,7 @@ static void pch_uart_set_termios(struct uart_port *port, + stb = PCH_UART_HAL_STB1; + + if (termios->c_cflag & PARENB) { +- if (!(termios->c_cflag & PARODD)) ++ if (termios->c_cflag & PARODD) + parity = PCH_UART_HAL_PARITY_ODD; + else + parity = PCH_UART_HAL_PARITY_EVEN; +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 175b6bb..52340cc 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -24,6 +24,7 @@ + #include <linux/kthread.h> + #include <linux/mutex.h> + #include <linux/freezer.h> ++#include <linux/random.h> + + #include <asm/uaccess.h> + #include <asm/byteorder.h> +@@ -1897,6 +1898,14 @@ int usb_new_device(struct usb_device *udev) + /* Tell the world! */ + announce_device(udev); + ++ if (udev->serial) ++ add_device_randomness(udev->serial, strlen(udev->serial)); ++ if (udev->product) ++ add_device_randomness(udev->product, strlen(udev->product)); ++ if (udev->manufacturer) ++ add_device_randomness(udev->manufacturer, ++ strlen(udev->manufacturer)); ++ + device_enable_async_suspend(&udev->dev); + /* Register the device. The device driver is responsible + * for configuring the device and invoking the add-device +diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c +index 1fc8f12..347bb05 100644 +--- a/drivers/usb/early/ehci-dbgp.c ++++ b/drivers/usb/early/ehci-dbgp.c +@@ -450,7 +450,7 @@ static int dbgp_ehci_startup(void) + writel(FLAG_CF, &ehci_regs->configured_flag); + + /* Wait until the controller is no longer halted */ +- loop = 10; ++ loop = 1000; + do { + status = readl(&ehci_regs->status); + if (!(status & STS_HALT)) +diff --git a/drivers/video/smscufx.c b/drivers/video/smscufx.c +index aaccffa..dd9533a 100644 +--- a/drivers/video/smscufx.c ++++ b/drivers/video/smscufx.c +@@ -904,7 +904,7 @@ static ssize_t ufx_ops_write(struct fb_info *info, const char __user *buf, + result = fb_sys_write(info, buf, count, ppos); + + if (result > 0) { +- int start = max((int)(offset / info->fix.line_length) - 1, 0); ++ int start = max((int)(offset / info->fix.line_length), 0); + int lines = min((u32)((result / info->fix.line_length) + 1), + (u32)info->var.yres); + +diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c +index 24a49d4..1585db1 100644 +--- a/fs/exofs/ore.c ++++ b/fs/exofs/ore.c +@@ -837,11 +837,11 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp) + bio->bi_rw |= REQ_WRITE; + } + +- osd_req_write(or, _ios_obj(ios, dev), per_dev->offset, +- bio, per_dev->length); ++ osd_req_write(or, _ios_obj(ios, cur_comp), ++ per_dev->offset, bio, per_dev->length); + ORE_DBGMSG("write(0x%llx) offset=0x%llx " + "length=0x%llx dev=%d\n", +- _LLU(_ios_obj(ios, dev)->id), ++ _LLU(_ios_obj(ios, cur_comp)->id), + _LLU(per_dev->offset), + _LLU(per_dev->length), dev); + } else if (ios->kern_buff) { +@@ -853,20 +853,20 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp) + (ios->si.unit_off + ios->length > + ios->layout->stripe_unit)); + +- ret = osd_req_write_kern(or, _ios_obj(ios, per_dev->dev), ++ ret = osd_req_write_kern(or, _ios_obj(ios, cur_comp), + per_dev->offset, + ios->kern_buff, ios->length); + if (unlikely(ret)) + goto out; + ORE_DBGMSG2("write_kern(0x%llx) offset=0x%llx " + "length=0x%llx dev=%d\n", +- _LLU(_ios_obj(ios, dev)->id), ++ _LLU(_ios_obj(ios, cur_comp)->id), + _LLU(per_dev->offset), + _LLU(ios->length), per_dev->dev); + } else { +- osd_req_set_attributes(or, _ios_obj(ios, dev)); ++ osd_req_set_attributes(or, _ios_obj(ios, cur_comp)); + ORE_DBGMSG2("obj(0x%llx) set_attributes=%d dev=%d\n", +- _LLU(_ios_obj(ios, dev)->id), ++ _LLU(_ios_obj(ios, cur_comp)->id), + ios->out_attr_len, dev); + } + +diff --git a/fs/nfs/file.c b/fs/nfs/file.c +index c43a452..961e562 100644 +--- a/fs/nfs/file.c ++++ b/fs/nfs/file.c +@@ -452,8 +452,11 @@ static int nfs_release_page(struct page *page, gfp_t gfp) + + dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page); + +- /* Only do I/O if gfp is a superset of GFP_KERNEL */ +- if (mapping && (gfp & GFP_KERNEL) == GFP_KERNEL) { ++ /* Only do I/O if gfp is a superset of GFP_KERNEL, and we're not ++ * doing this memory reclaim for a fs-related allocation. ++ */ ++ if (mapping && (gfp & GFP_KERNEL) == GFP_KERNEL && ++ !(current->flags & PF_FSTRANS)) { + int how = FLUSH_SYNC; + + /* Don't let kswapd deadlock waiting for OOM RPC calls */ +diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c +index 9cfa60a..87a1746 100644 +--- a/fs/nfsd/nfs4xdr.c ++++ b/fs/nfsd/nfs4xdr.c +@@ -2236,7 +2236,7 @@ out_acl: + if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) { + if ((buflen -= 4) < 0) + goto out_resource; +- WRITE32(1); ++ WRITE32(0); + } + if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) { + if ((buflen -= 4) < 0) +diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c +index ac258be..c598cfb 100644 +--- a/fs/nilfs2/ioctl.c ++++ b/fs/nilfs2/ioctl.c +@@ -182,7 +182,7 @@ static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp, + if (copy_from_user(&cpmode, argp, sizeof(cpmode))) + goto out; + +- down_read(&inode->i_sb->s_umount); ++ mutex_lock(&nilfs->ns_snapshot_mount_mutex); + + nilfs_transaction_begin(inode->i_sb, &ti, 0); + ret = nilfs_cpfile_change_cpmode( +@@ -192,7 +192,7 @@ static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp, + else + nilfs_transaction_commit(inode->i_sb); /* never fails */ + +- up_read(&inode->i_sb->s_umount); ++ mutex_unlock(&nilfs->ns_snapshot_mount_mutex); + out: + mnt_drop_write(filp->f_path.mnt); + return ret; +diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c +index 8351c44..97bfbdd 100644 +--- a/fs/nilfs2/super.c ++++ b/fs/nilfs2/super.c +@@ -951,6 +951,8 @@ static int nilfs_attach_snapshot(struct super_block *s, __u64 cno, + struct nilfs_root *root; + int ret; + ++ mutex_lock(&nilfs->ns_snapshot_mount_mutex); ++ + down_read(&nilfs->ns_segctor_sem); + ret = nilfs_cpfile_is_snapshot(nilfs->ns_cpfile, cno); + up_read(&nilfs->ns_segctor_sem); +@@ -975,6 +977,7 @@ static int nilfs_attach_snapshot(struct super_block *s, __u64 cno, + ret = nilfs_get_root_dentry(s, root, root_dentry); + nilfs_put_root(root); + out: ++ mutex_unlock(&nilfs->ns_snapshot_mount_mutex); + return ret; + } + +diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c +index 35a8970..1c98f53 100644 +--- a/fs/nilfs2/the_nilfs.c ++++ b/fs/nilfs2/the_nilfs.c +@@ -76,6 +76,7 @@ struct the_nilfs *alloc_nilfs(struct block_device *bdev) + nilfs->ns_bdev = bdev; + atomic_set(&nilfs->ns_ndirtyblks, 0); + init_rwsem(&nilfs->ns_sem); ++ mutex_init(&nilfs->ns_snapshot_mount_mutex); + INIT_LIST_HEAD(&nilfs->ns_dirty_files); + INIT_LIST_HEAD(&nilfs->ns_gc_inodes); + spin_lock_init(&nilfs->ns_inode_lock); +diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h +index 9992b11..de7435f 100644 +--- a/fs/nilfs2/the_nilfs.h ++++ b/fs/nilfs2/the_nilfs.h +@@ -47,6 +47,7 @@ enum { + * @ns_flags: flags + * @ns_bdev: block device + * @ns_sem: semaphore for shared states ++ * @ns_snapshot_mount_mutex: mutex to protect snapshot mounts + * @ns_sbh: buffer heads of on-disk super blocks + * @ns_sbp: pointers to super block data + * @ns_sbwtime: previous write time of super block +@@ -99,6 +100,7 @@ struct the_nilfs { + + struct block_device *ns_bdev; + struct rw_semaphore ns_sem; ++ struct mutex ns_snapshot_mount_mutex; + + /* + * used for +diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h +index c5ed2f1..a2227f7 100644 +--- a/include/linux/hugetlb.h ++++ b/include/linux/hugetlb.h +@@ -41,6 +41,9 @@ int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, + unsigned long *, int *, int, unsigned int flags); + void unmap_hugepage_range(struct vm_area_struct *, + unsigned long, unsigned long, struct page *); ++void __unmap_hugepage_range_final(struct vm_area_struct *vma, ++ unsigned long start, unsigned long end, ++ struct page *ref_page); + void __unmap_hugepage_range(struct vm_area_struct *, + unsigned long, unsigned long, struct page *); + int hugetlb_prefault(struct address_space *, struct vm_area_struct *); +@@ -99,6 +102,13 @@ static inline unsigned long hugetlb_total_pages(void) + #define copy_hugetlb_page_range(src, dst, vma) ({ BUG(); 0; }) + #define hugetlb_prefault(mapping, vma) ({ BUG(); 0; }) + #define unmap_hugepage_range(vma, start, end, page) BUG() ++static inline void __unmap_hugepage_range_final(struct vm_area_struct *vma, ++ unsigned long start, unsigned long end, ++ struct page *ref_page) ++{ ++ BUG(); ++} ++ + static inline void hugetlb_report_meminfo(struct seq_file *m) + { + } +diff --git a/include/linux/init_task.h b/include/linux/init_task.h +index df53fdf..cdde2b3 100644 +--- a/include/linux/init_task.h ++++ b/include/linux/init_task.h +@@ -124,8 +124,17 @@ extern struct group_info init_groups; + + extern struct cred init_cred; + ++extern struct task_group root_task_group; ++ ++#ifdef CONFIG_CGROUP_SCHED ++# define INIT_CGROUP_SCHED(tsk) \ ++ .sched_task_group = &root_task_group, ++#else ++# define INIT_CGROUP_SCHED(tsk) ++#endif ++ + #ifdef CONFIG_PERF_EVENTS +-# define INIT_PERF_EVENTS(tsk) \ ++# define INIT_PERF_EVENTS(tsk) \ + .perf_event_mutex = \ + __MUTEX_INITIALIZER(tsk.perf_event_mutex), \ + .perf_event_list = LIST_HEAD_INIT(tsk.perf_event_list), +@@ -162,6 +171,7 @@ extern struct cred init_cred; + }, \ + .tasks = LIST_HEAD_INIT(tsk.tasks), \ + INIT_PUSHABLE_TASKS(tsk) \ ++ INIT_CGROUP_SCHED(tsk) \ + .ptraced = LIST_HEAD_INIT(tsk.ptraced), \ + .ptrace_entry = LIST_HEAD_INIT(tsk.ptrace_entry), \ + .real_parent = &tsk, \ +diff --git a/include/linux/random.h b/include/linux/random.h +index 8f74538..29e217a 100644 +--- a/include/linux/random.h ++++ b/include/linux/random.h +@@ -50,11 +50,13 @@ struct rnd_state { + + extern void rand_initialize_irq(int irq); + ++extern void add_device_randomness(const void *, unsigned int); + extern void add_input_randomness(unsigned int type, unsigned int code, + unsigned int value); +-extern void add_interrupt_randomness(int irq); ++extern void add_interrupt_randomness(int irq, int irq_flags); + + extern void get_random_bytes(void *buf, int nbytes); ++extern void get_random_bytes_arch(void *buf, int nbytes); + void generate_random_uuid(unsigned char uuid_out[16]); + + #ifndef MODULE +diff --git a/include/linux/sched.h b/include/linux/sched.h +index d336c35..1e86bb4 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -1236,6 +1236,9 @@ struct task_struct { + const struct sched_class *sched_class; + struct sched_entity se; + struct sched_rt_entity rt; ++#ifdef CONFIG_CGROUP_SCHED ++ struct task_group *sched_task_group; ++#endif + + #ifdef CONFIG_PREEMPT_NOTIFIERS + /* list of struct preempt_notifier: */ +@@ -2646,7 +2649,7 @@ extern int sched_group_set_rt_period(struct task_group *tg, + extern long sched_group_rt_period(struct task_group *tg); + extern int sched_rt_can_attach(struct task_group *tg, struct task_struct *tsk); + #endif +-#endif ++#endif /* CONFIG_CGROUP_SCHED */ + + extern int task_can_switch_user(struct user_struct *up, + struct task_struct *tsk); +diff --git a/kernel/futex.c b/kernel/futex.c +index 866c9d5..80fb1c6 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -2231,11 +2231,11 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb, + * @uaddr2: the pi futex we will take prior to returning to user-space + * + * The caller will wait on uaddr and will be requeued by futex_requeue() to +- * uaddr2 which must be PI aware. Normal wakeup will wake on uaddr2 and +- * complete the acquisition of the rt_mutex prior to returning to userspace. +- * This ensures the rt_mutex maintains an owner when it has waiters; without +- * one, the pi logic wouldn't know which task to boost/deboost, if there was a +- * need to. ++ * uaddr2 which must be PI aware and unique from uaddr. Normal wakeup will wake ++ * on uaddr2 and complete the acquisition of the rt_mutex prior to returning to ++ * userspace. This ensures the rt_mutex maintains an owner when it has waiters; ++ * without one, the pi logic would not know which task to boost/deboost, if ++ * there was a need to. + * + * We call schedule in futex_wait_queue_me() when we enqueue and return there + * via the following: +@@ -2272,6 +2272,9 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, + struct futex_q q = futex_q_init; + int res, ret; + ++ if (uaddr == uaddr2) ++ return -EINVAL; ++ + if (!bitset) + return -EINVAL; + +@@ -2343,7 +2346,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, + * signal. futex_unlock_pi() will not destroy the lock_ptr nor + * the pi_state. + */ +- WARN_ON(!&q.pi_state); ++ WARN_ON(!q.pi_state); + pi_mutex = &q.pi_state->pi_mutex; + ret = rt_mutex_finish_proxy_lock(pi_mutex, to, &rt_waiter, 1); + debug_rt_mutex_free_waiter(&rt_waiter); +@@ -2370,7 +2373,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, + * fault, unlock the rt_mutex and return the fault to userspace. + */ + if (ret == -EFAULT) { +- if (rt_mutex_owner(pi_mutex) == current) ++ if (pi_mutex && rt_mutex_owner(pi_mutex) == current) + rt_mutex_unlock(pi_mutex); + } else if (ret == -EINTR) { + /* +diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c +index 470d08c..10e0772 100644 +--- a/kernel/irq/handle.c ++++ b/kernel/irq/handle.c +@@ -117,7 +117,7 @@ irqreturn_t + handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action) + { + irqreturn_t retval = IRQ_NONE; +- unsigned int random = 0, irq = desc->irq_data.irq; ++ unsigned int flags = 0, irq = desc->irq_data.irq; + + do { + irqreturn_t res; +@@ -145,7 +145,7 @@ handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action) + + /* Fall through to add to randomness */ + case IRQ_HANDLED: +- random |= action->flags; ++ flags |= action->flags; + break; + + default: +@@ -156,8 +156,7 @@ handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action) + action = action->next; + } while (action); + +- if (random & IRQF_SAMPLE_RANDOM) +- add_interrupt_randomness(irq); ++ add_interrupt_randomness(irq, flags); + + if (!noirqdebug) + note_interrupt(irq, desc, retval); +diff --git a/kernel/sched.c b/kernel/sched.c +index 9cd8ca7..e0431c4 100644 +--- a/kernel/sched.c ++++ b/kernel/sched.c +@@ -746,22 +746,19 @@ static inline int cpu_of(struct rq *rq) + /* + * Return the group to which this tasks belongs. + * +- * We use task_subsys_state_check() and extend the RCU verification with +- * pi->lock and rq->lock because cpu_cgroup_attach() holds those locks for each +- * task it moves into the cgroup. Therefore by holding either of those locks, +- * we pin the task to the current cgroup. ++ * We cannot use task_subsys_state() and friends because the cgroup ++ * subsystem changes that value before the cgroup_subsys::attach() method ++ * is called, therefore we cannot pin it and might observe the wrong value. ++ * ++ * The same is true for autogroup's p->signal->autogroup->tg, the autogroup ++ * core changes this before calling sched_move_task(). ++ * ++ * Instead we use a 'copy' which is updated from sched_move_task() while ++ * holding both task_struct::pi_lock and rq::lock. + */ + static inline struct task_group *task_group(struct task_struct *p) + { +- struct task_group *tg; +- struct cgroup_subsys_state *css; +- +- css = task_subsys_state_check(p, cpu_cgroup_subsys_id, +- lockdep_is_held(&p->pi_lock) || +- lockdep_is_held(&task_rq(p)->lock)); +- tg = container_of(css, struct task_group, css); +- +- return autogroup_task_group(p, tg); ++ return p->sched_task_group; + } + + /* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */ +@@ -2372,7 +2369,7 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu) + * a task's CPU. ->pi_lock for waking tasks, rq->lock for runnable tasks. + * + * sched_move_task() holds both and thus holding either pins the cgroup, +- * see set_task_rq(). ++ * see task_group(). + * + * Furthermore, all task_rq users should acquire both locks, see + * task_rq_lock(). +@@ -8952,6 +8949,7 @@ void sched_destroy_group(struct task_group *tg) + */ + void sched_move_task(struct task_struct *tsk) + { ++ struct task_group *tg; + int on_rq, running; + unsigned long flags; + struct rq *rq; +@@ -8966,6 +8964,12 @@ void sched_move_task(struct task_struct *tsk) + if (unlikely(running)) + tsk->sched_class->put_prev_task(rq, tsk); + ++ tg = container_of(task_subsys_state_check(tsk, cpu_cgroup_subsys_id, ++ lockdep_is_held(&tsk->sighand->siglock)), ++ struct task_group, css); ++ tg = autogroup_task_group(tsk, tg); ++ tsk->sched_task_group = tg; ++ + #ifdef CONFIG_FAIR_GROUP_SCHED + if (tsk->sched_class->task_move_group) + tsk->sched_class->task_move_group(tsk, on_rq); +diff --git a/lib/vsprintf.c b/lib/vsprintf.c +index 993599e..d74c317 100644 +--- a/lib/vsprintf.c ++++ b/lib/vsprintf.c +@@ -886,7 +886,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, + * %pK cannot be used in IRQ context because its test + * for CAP_SYSLOG would be meaningless. + */ +- if (in_irq() || in_serving_softirq() || in_nmi()) { ++ if (kptr_restrict && (in_irq() || in_serving_softirq() || ++ in_nmi())) { + if (spec.field_width == -1) + spec.field_width = 2 * sizeof(void *); + return string(buf, end, "pK-error", spec); +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index b1e1bad..0f897b8 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -2382,6 +2382,25 @@ void __unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, + } + } + ++void __unmap_hugepage_range_final(struct vm_area_struct *vma, ++ unsigned long start, unsigned long end, ++ struct page *ref_page) ++{ ++ __unmap_hugepage_range(vma, start, end, ref_page); ++ ++ /* ++ * Clear this flag so that x86's huge_pmd_share page_table_shareable ++ * test will fail on a vma being torn down, and not grab a page table ++ * on its way out. We're lucky that the flag has such an appropriate ++ * name, and can in fact be safely cleared here. We could clear it ++ * before the __unmap_hugepage_range above, but all that's necessary ++ * is to clear it before releasing the i_mmap_mutex. This works ++ * because in the context this is called, the VMA is about to be ++ * destroyed and the i_mmap_mutex is held. ++ */ ++ vma->vm_flags &= ~VM_MAYSHARE; ++} ++ + void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end, struct page *ref_page) + { +@@ -2939,9 +2958,14 @@ void hugetlb_change_protection(struct vm_area_struct *vma, + } + } + spin_unlock(&mm->page_table_lock); +- mutex_unlock(&vma->vm_file->f_mapping->i_mmap_mutex); +- ++ /* ++ * Must flush TLB before releasing i_mmap_mutex: x86's huge_pmd_unshare ++ * may have cleared our pud entry and done put_page on the page table: ++ * once we release i_mmap_mutex, another task can do the final put_page ++ * and that page table be reused and filled with junk. ++ */ + flush_tlb_range(vma, start, end); ++ mutex_unlock(&vma->vm_file->f_mapping->i_mmap_mutex); + } + + int hugetlb_reserve_pages(struct inode *inode, +diff --git a/mm/internal.h b/mm/internal.h +index 2189af4..0c26b5e 100644 +--- a/mm/internal.h ++++ b/mm/internal.h +@@ -309,3 +309,5 @@ extern u64 hwpoison_filter_flags_mask; + extern u64 hwpoison_filter_flags_value; + extern u64 hwpoison_filter_memcg; + extern u32 hwpoison_filter_enable; ++ ++extern void set_pageblock_order(void); +diff --git a/mm/memory.c b/mm/memory.c +index 1b1ca17..70f5daf 100644 +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -1358,8 +1358,11 @@ unsigned long unmap_vmas(struct mmu_gather *tlb, + * Since no pte has actually been setup, it is + * safe to do nothing in this case. + */ +- if (vma->vm_file) +- unmap_hugepage_range(vma, start, end, NULL); ++ if (vma->vm_file) { ++ mutex_lock(&vma->vm_file->f_mapping->i_mmap_mutex); ++ __unmap_hugepage_range_final(vma, start, end, NULL); ++ mutex_unlock(&vma->vm_file->f_mapping->i_mmap_mutex); ++ } + + start = end; + } else +diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c +index 9a611d3..862b608 100644 +--- a/mm/mmu_notifier.c ++++ b/mm/mmu_notifier.c +@@ -33,6 +33,24 @@ + void __mmu_notifier_release(struct mm_struct *mm) + { + struct mmu_notifier *mn; ++ struct hlist_node *n; ++ ++ /* ++ * RCU here will block mmu_notifier_unregister until ++ * ->release returns. ++ */ ++ rcu_read_lock(); ++ hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) ++ /* ++ * if ->release runs before mmu_notifier_unregister it ++ * must be handled as it's the only way for the driver ++ * to flush all existing sptes and stop the driver ++ * from establishing any more sptes before all the ++ * pages in the mm are freed. ++ */ ++ if (mn->ops->release) ++ mn->ops->release(mn, mm); ++ rcu_read_unlock(); + + spin_lock(&mm->mmu_notifier_mm->lock); + while (unlikely(!hlist_empty(&mm->mmu_notifier_mm->list))) { +@@ -46,23 +64,6 @@ void __mmu_notifier_release(struct mm_struct *mm) + * mmu_notifier_unregister to return. + */ + hlist_del_init_rcu(&mn->hlist); +- /* +- * RCU here will block mmu_notifier_unregister until +- * ->release returns. +- */ +- rcu_read_lock(); +- spin_unlock(&mm->mmu_notifier_mm->lock); +- /* +- * if ->release runs before mmu_notifier_unregister it +- * must be handled as it's the only way for the driver +- * to flush all existing sptes and stop the driver +- * from establishing any more sptes before all the +- * pages in the mm are freed. +- */ +- if (mn->ops->release) +- mn->ops->release(mn, mm); +- rcu_read_unlock(); +- spin_lock(&mm->mmu_notifier_mm->lock); + } + spin_unlock(&mm->mmu_notifier_mm->lock); + +@@ -284,16 +285,13 @@ void mmu_notifier_unregister(struct mmu_notifier *mn, struct mm_struct *mm) + { + BUG_ON(atomic_read(&mm->mm_count) <= 0); + +- spin_lock(&mm->mmu_notifier_mm->lock); + if (!hlist_unhashed(&mn->hlist)) { +- hlist_del_rcu(&mn->hlist); +- + /* + * RCU here will force exit_mmap to wait ->release to finish + * before freeing the pages. + */ + rcu_read_lock(); +- spin_unlock(&mm->mmu_notifier_mm->lock); ++ + /* + * exit_mmap will block in mmu_notifier_release to + * guarantee ->release is called before freeing the +@@ -302,8 +300,11 @@ void mmu_notifier_unregister(struct mmu_notifier *mn, struct mm_struct *mm) + if (mn->ops->release) + mn->ops->release(mn, mm); + rcu_read_unlock(); +- } else ++ ++ spin_lock(&mm->mmu_notifier_mm->lock); ++ hlist_del_rcu(&mn->hlist); + spin_unlock(&mm->mmu_notifier_mm->lock); ++ } + + /* + * Wait any running method to finish, of course including +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 065dbe8..6e51bf0 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -4281,25 +4281,24 @@ static inline void setup_usemap(struct pglist_data *pgdat, + + #ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE + +-/* Return a sensible default order for the pageblock size. */ +-static inline int pageblock_default_order(void) +-{ +- if (HPAGE_SHIFT > PAGE_SHIFT) +- return HUGETLB_PAGE_ORDER; +- +- return MAX_ORDER-1; +-} +- + /* Initialise the number of pages represented by NR_PAGEBLOCK_BITS */ +-static inline void __init set_pageblock_order(unsigned int order) ++void __init set_pageblock_order(void) + { ++ unsigned int order; ++ + /* Check that pageblock_nr_pages has not already been setup */ + if (pageblock_order) + return; + ++ if (HPAGE_SHIFT > PAGE_SHIFT) ++ order = HUGETLB_PAGE_ORDER; ++ else ++ order = MAX_ORDER - 1; ++ + /* + * Assume the largest contiguous order of interest is a huge page. +- * This value may be variable depending on boot parameters on IA64 ++ * This value may be variable depending on boot parameters on IA64 and ++ * powerpc. + */ + pageblock_order = order; + } +@@ -4307,15 +4306,13 @@ static inline void __init set_pageblock_order(unsigned int order) + + /* + * When CONFIG_HUGETLB_PAGE_SIZE_VARIABLE is not set, set_pageblock_order() +- * and pageblock_default_order() are unused as pageblock_order is set +- * at compile-time. See include/linux/pageblock-flags.h for the values of +- * pageblock_order based on the kernel config ++ * is unused as pageblock_order is set at compile-time. See ++ * include/linux/pageblock-flags.h for the values of pageblock_order based on ++ * the kernel config + */ +-static inline int pageblock_default_order(unsigned int order) ++void __init set_pageblock_order(void) + { +- return MAX_ORDER-1; + } +-#define set_pageblock_order(x) do {} while (0) + + #endif /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */ + +@@ -4403,7 +4400,7 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat, + if (!size) + continue; + +- set_pageblock_order(pageblock_default_order()); ++ set_pageblock_order(); + setup_usemap(pgdat, zone, size); + ret = init_currently_empty_zone(zone, zone_start_pfn, + size, MEMMAP_EARLY); +diff --git a/mm/sparse.c b/mm/sparse.c +index a8bc7d3..bf7d3cc 100644 +--- a/mm/sparse.c ++++ b/mm/sparse.c +@@ -486,6 +486,9 @@ void __init sparse_init(void) + struct page **map_map; + #endif + ++ /* Setup pageblock_order for HUGETLB_PAGE_SIZE_VARIABLE */ ++ set_pageblock_order(); ++ + /* + * map is using big page (aka 2M in x86 64 bit) + * usemap is less one page (aka 24 bytes) +diff --git a/net/core/dev.c b/net/core/dev.c +index 5738654..4b18703 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1177,6 +1177,7 @@ static int __dev_open(struct net_device *dev) + net_dmaengine_get(); + dev_set_rx_mode(dev); + dev_activate(dev); ++ add_device_randomness(dev->dev_addr, dev->addr_len); + } + + return ret; +@@ -4841,6 +4842,7 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa) + err = ops->ndo_set_mac_address(dev, sa); + if (!err) + call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); ++ add_device_randomness(dev->dev_addr, dev->addr_len); + return err; + } + EXPORT_SYMBOL(dev_set_mac_address); +@@ -5621,6 +5623,7 @@ int register_netdevice(struct net_device *dev) + dev_init_scheduler(dev); + dev_hold(dev); + list_netdevice(dev); ++ add_device_randomness(dev->dev_addr, dev->addr_len); + + /* Notify protocols, that a new device appeared. */ + ret = call_netdevice_notifiers(NETDEV_REGISTER, dev); +diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c +index 7f36b38..b856f87 100644 +--- a/net/core/drop_monitor.c ++++ b/net/core/drop_monitor.c +@@ -33,22 +33,19 @@ + #define TRACE_ON 1 + #define TRACE_OFF 0 + +-static void send_dm_alert(struct work_struct *unused); +- +- + /* + * Globals, our netlink socket pointer + * and the work handle that will send up + * netlink alerts + */ + static int trace_state = TRACE_OFF; +-static DEFINE_SPINLOCK(trace_state_lock); ++static DEFINE_MUTEX(trace_state_mutex); + + struct per_cpu_dm_data { +- struct work_struct dm_alert_work; +- struct sk_buff *skb; +- atomic_t dm_hit_count; +- struct timer_list send_timer; ++ spinlock_t lock; ++ struct sk_buff *skb; ++ struct work_struct dm_alert_work; ++ struct timer_list send_timer; + }; + + struct dm_hw_stat_delta { +@@ -74,56 +71,59 @@ static int dm_delay = 1; + static unsigned long dm_hw_check_delta = 2*HZ; + static LIST_HEAD(hw_stats_list); + +-static void reset_per_cpu_data(struct per_cpu_dm_data *data) ++static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data) + { + size_t al; + struct net_dm_alert_msg *msg; + struct nlattr *nla; ++ struct sk_buff *skb; ++ unsigned long flags; + + al = sizeof(struct net_dm_alert_msg); + al += dm_hit_limit * sizeof(struct net_dm_drop_point); + al += sizeof(struct nlattr); + +- data->skb = genlmsg_new(al, GFP_KERNEL); +- genlmsg_put(data->skb, 0, 0, &net_drop_monitor_family, +- 0, NET_DM_CMD_ALERT); +- nla = nla_reserve(data->skb, NLA_UNSPEC, sizeof(struct net_dm_alert_msg)); +- msg = nla_data(nla); +- memset(msg, 0, al); +- atomic_set(&data->dm_hit_count, dm_hit_limit); ++ skb = genlmsg_new(al, GFP_KERNEL); ++ ++ if (skb) { ++ genlmsg_put(skb, 0, 0, &net_drop_monitor_family, ++ 0, NET_DM_CMD_ALERT); ++ nla = nla_reserve(skb, NLA_UNSPEC, ++ sizeof(struct net_dm_alert_msg)); ++ msg = nla_data(nla); ++ memset(msg, 0, al); ++ } else { ++ mod_timer(&data->send_timer, jiffies + HZ / 10); ++ } ++ ++ spin_lock_irqsave(&data->lock, flags); ++ swap(data->skb, skb); ++ spin_unlock_irqrestore(&data->lock, flags); ++ ++ return skb; + } + +-static void send_dm_alert(struct work_struct *unused) ++static void send_dm_alert(struct work_struct *work) + { + struct sk_buff *skb; +- struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data); ++ struct per_cpu_dm_data *data; + +- /* +- * Grab the skb we're about to send +- */ +- skb = data->skb; ++ data = container_of(work, struct per_cpu_dm_data, dm_alert_work); + +- /* +- * Replace it with a new one +- */ +- reset_per_cpu_data(data); +- +- /* +- * Ship it! +- */ +- genlmsg_multicast(skb, 0, NET_DM_GRP_ALERT, GFP_KERNEL); ++ skb = reset_per_cpu_data(data); + ++ if (skb) ++ genlmsg_multicast(skb, 0, NET_DM_GRP_ALERT, GFP_KERNEL); + } + + /* + * This is the timer function to delay the sending of an alert + * in the event that more drops will arrive during the +- * hysteresis period. Note that it operates under the timer interrupt +- * so we don't need to disable preemption here ++ * hysteresis period. + */ +-static void sched_send_work(unsigned long unused) ++static void sched_send_work(unsigned long _data) + { +- struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data); ++ struct per_cpu_dm_data *data = (struct per_cpu_dm_data *)_data; + + schedule_work(&data->dm_alert_work); + } +@@ -134,17 +134,19 @@ static void trace_drop_common(struct sk_buff *skb, void *location) + struct nlmsghdr *nlh; + struct nlattr *nla; + int i; +- struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data); ++ struct sk_buff *dskb; ++ struct per_cpu_dm_data *data; ++ unsigned long flags; + ++ local_irq_save(flags); ++ data = &__get_cpu_var(dm_cpu_data); ++ spin_lock(&data->lock); ++ dskb = data->skb; + +- if (!atomic_add_unless(&data->dm_hit_count, -1, 0)) { +- /* +- * we're already at zero, discard this hit +- */ ++ if (!dskb) + goto out; +- } + +- nlh = (struct nlmsghdr *)data->skb->data; ++ nlh = (struct nlmsghdr *)dskb->data; + nla = genlmsg_data(nlmsg_data(nlh)); + msg = nla_data(nla); + for (i = 0; i < msg->entries; i++) { +@@ -153,11 +155,12 @@ static void trace_drop_common(struct sk_buff *skb, void *location) + goto out; + } + } +- ++ if (msg->entries == dm_hit_limit) ++ goto out; + /* + * We need to create a new entry + */ +- __nla_reserve_nohdr(data->skb, sizeof(struct net_dm_drop_point)); ++ __nla_reserve_nohdr(dskb, sizeof(struct net_dm_drop_point)); + nla->nla_len += NLA_ALIGN(sizeof(struct net_dm_drop_point)); + memcpy(msg->points[msg->entries].pc, &location, sizeof(void *)); + msg->points[msg->entries].count = 1; +@@ -165,11 +168,11 @@ static void trace_drop_common(struct sk_buff *skb, void *location) + + if (!timer_pending(&data->send_timer)) { + data->send_timer.expires = jiffies + dm_delay * HZ; +- add_timer_on(&data->send_timer, smp_processor_id()); ++ add_timer(&data->send_timer); + } + + out: +- return; ++ spin_unlock_irqrestore(&data->lock, flags); + } + + static void trace_kfree_skb_hit(void *ignore, struct sk_buff *skb, void *location) +@@ -213,7 +216,7 @@ static int set_all_monitor_traces(int state) + struct dm_hw_stat_delta *new_stat = NULL; + struct dm_hw_stat_delta *temp; + +- spin_lock(&trace_state_lock); ++ mutex_lock(&trace_state_mutex); + + if (state == trace_state) { + rc = -EAGAIN; +@@ -252,7 +255,7 @@ static int set_all_monitor_traces(int state) + rc = -EINPROGRESS; + + out_unlock: +- spin_unlock(&trace_state_lock); ++ mutex_unlock(&trace_state_mutex); + + return rc; + } +@@ -295,12 +298,12 @@ static int dropmon_net_event(struct notifier_block *ev_block, + + new_stat->dev = dev; + new_stat->last_rx = jiffies; +- spin_lock(&trace_state_lock); ++ mutex_lock(&trace_state_mutex); + list_add_rcu(&new_stat->list, &hw_stats_list); +- spin_unlock(&trace_state_lock); ++ mutex_unlock(&trace_state_mutex); + break; + case NETDEV_UNREGISTER: +- spin_lock(&trace_state_lock); ++ mutex_lock(&trace_state_mutex); + list_for_each_entry_safe(new_stat, tmp, &hw_stats_list, list) { + if (new_stat->dev == dev) { + new_stat->dev = NULL; +@@ -311,7 +314,7 @@ static int dropmon_net_event(struct notifier_block *ev_block, + } + } + } +- spin_unlock(&trace_state_lock); ++ mutex_unlock(&trace_state_mutex); + break; + } + out: +@@ -367,13 +370,15 @@ static int __init init_net_drop_monitor(void) + + for_each_present_cpu(cpu) { + data = &per_cpu(dm_cpu_data, cpu); +- reset_per_cpu_data(data); + INIT_WORK(&data->dm_alert_work, send_dm_alert); + init_timer(&data->send_timer); +- data->send_timer.data = cpu; ++ data->send_timer.data = (unsigned long)data; + data->send_timer.function = sched_send_work; ++ spin_lock_init(&data->lock); ++ reset_per_cpu_data(data); + } + ++ + goto out; + + out_unreg: +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index 2ef859a..05842ab 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -1354,6 +1354,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, + goto errout; + send_addr_notify = 1; + modified = 1; ++ add_device_randomness(dev->dev_addr, dev->addr_len); + } + + if (tb[IFLA_MTU]) { +diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c +index 8761bf8..337c68b 100644 +--- a/net/sunrpc/rpcb_clnt.c ++++ b/net/sunrpc/rpcb_clnt.c +@@ -246,7 +246,7 @@ static int rpcb_create_local_unix(void) + if (IS_ERR(clnt)) { + dprintk("RPC: failed to create AF_LOCAL rpcbind " + "client (errno %ld).\n", PTR_ERR(clnt)); +- result = -PTR_ERR(clnt); ++ result = PTR_ERR(clnt); + goto out; + } + +@@ -293,7 +293,7 @@ static int rpcb_create_local_net(void) + if (IS_ERR(clnt)) { + dprintk("RPC: failed to create local rpcbind " + "client (errno %ld).\n", PTR_ERR(clnt)); +- result = -PTR_ERR(clnt); ++ result = PTR_ERR(clnt); + goto out; + } + +diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c +index 4e2b3b4..c90b832 100644 +--- a/net/sunrpc/sched.c ++++ b/net/sunrpc/sched.c +@@ -755,7 +755,9 @@ void rpc_execute(struct rpc_task *task) + + static void rpc_async_schedule(struct work_struct *work) + { ++ current->flags |= PF_FSTRANS; + __rpc_execute(container_of(work, struct rpc_task, u.tk_work)); ++ current->flags &= ~PF_FSTRANS; + } + + /** +diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c +index b446e10..06cdbff 100644 +--- a/net/sunrpc/xprtrdma/transport.c ++++ b/net/sunrpc/xprtrdma/transport.c +@@ -200,6 +200,7 @@ xprt_rdma_connect_worker(struct work_struct *work) + int rc = 0; + + if (!xprt->shutdown) { ++ current->flags |= PF_FSTRANS; + xprt_clear_connected(xprt); + + dprintk("RPC: %s: %sconnect\n", __func__, +@@ -212,10 +213,10 @@ xprt_rdma_connect_worker(struct work_struct *work) + + out: + xprt_wake_pending_tasks(xprt, rc); +- + out_clear: + dprintk("RPC: %s: exit\n", __func__); + xprt_clear_connecting(xprt); ++ current->flags &= ~PF_FSTRANS; + } + + /* +diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c +index 55472c4..1a6edc7 100644 +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -1895,6 +1895,8 @@ static void xs_local_setup_socket(struct work_struct *work) + if (xprt->shutdown) + goto out; + ++ current->flags |= PF_FSTRANS; ++ + clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); + status = __sock_create(xprt->xprt_net, AF_LOCAL, + SOCK_STREAM, 0, &sock, 1); +@@ -1928,6 +1930,7 @@ static void xs_local_setup_socket(struct work_struct *work) + out: + xprt_clear_connecting(xprt); + xprt_wake_pending_tasks(xprt, status); ++ current->flags &= ~PF_FSTRANS; + } + + static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) +@@ -1970,6 +1973,8 @@ static void xs_udp_setup_socket(struct work_struct *work) + if (xprt->shutdown) + goto out; + ++ current->flags |= PF_FSTRANS; ++ + /* Start by resetting any existing state */ + xs_reset_transport(transport); + sock = xs_create_sock(xprt, transport, +@@ -1988,6 +1993,7 @@ static void xs_udp_setup_socket(struct work_struct *work) + out: + xprt_clear_connecting(xprt); + xprt_wake_pending_tasks(xprt, status); ++ current->flags &= ~PF_FSTRANS; + } + + /* +@@ -2113,6 +2119,8 @@ static void xs_tcp_setup_socket(struct work_struct *work) + if (xprt->shutdown) + goto out; + ++ current->flags |= PF_FSTRANS; ++ + if (!sock) { + clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); + sock = xs_create_sock(xprt, transport, +@@ -2162,6 +2170,7 @@ static void xs_tcp_setup_socket(struct work_struct *work) + case -EINPROGRESS: + case -EALREADY: + xprt_clear_connecting(xprt); ++ current->flags &= ~PF_FSTRANS; + return; + case -EINVAL: + /* Happens, for instance, if the user specified a link +@@ -2174,6 +2183,7 @@ out_eagain: + out: + xprt_clear_connecting(xprt); + xprt_wake_pending_tasks(xprt, status); ++ current->flags &= ~PF_FSTRANS; + } + + /** +diff --git a/net/wireless/util.c b/net/wireless/util.c +index 74d5292..b5e4c1c 100644 +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -981,6 +981,9 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, + } + mutex_unlock(&rdev->devlist_mtx); + ++ if (total == 1) ++ return 0; ++ + for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) { + const struct ieee80211_iface_combination *c; + struct ieee80211_iface_limit *limits; +diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c +index 1cff331..4608c2c 100644 +--- a/sound/drivers/mpu401/mpu401_uart.c ++++ b/sound/drivers/mpu401/mpu401_uart.c +@@ -554,6 +554,7 @@ int snd_mpu401_uart_new(struct snd_card *card, int device, + spin_lock_init(&mpu->output_lock); + spin_lock_init(&mpu->timer_lock); + mpu->hardware = hardware; ++ mpu->irq = -1; + if (! (info_flags & MPU401_INFO_INTEGRATED)) { + int res_size = hardware == MPU401_HW_PC98II ? 4 : 2; + mpu->res = request_region(port, res_size, "MPU401 UART"); +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 191fd78..2e2eb93 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -4809,6 +4809,15 @@ static int alc269_resume(struct hda_codec *codec) + } + #endif /* CONFIG_PM */ + ++static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec, ++ const struct alc_fixup *fix, int action) ++{ ++ struct alc_spec *spec = codec->spec; ++ ++ if (action == ALC_FIXUP_ACT_PRE_PROBE) ++ spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; ++} ++ + static void alc269_fixup_hweq(struct hda_codec *codec, + const struct alc_fixup *fix, int action) + { +@@ -4909,6 +4918,8 @@ enum { + ALC269_FIXUP_DMIC, + ALC269VB_FIXUP_AMIC, + ALC269VB_FIXUP_DMIC, ++ ALC269_FIXUP_LENOVO_DOCK, ++ ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, + }; + + static const struct alc_fixup alc269_fixups[] = { +@@ -5029,6 +5040,20 @@ static const struct alc_fixup alc269_fixups[] = { + { } + }, + }, ++ [ALC269_FIXUP_LENOVO_DOCK] = { ++ .type = ALC_FIXUP_PINS, ++ .v.pins = (const struct alc_pincfg[]) { ++ { 0x19, 0x23a11040 }, /* dock mic */ ++ { 0x1b, 0x2121103f }, /* dock headphone */ ++ { } ++ }, ++ .chained = true, ++ .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT ++ }, ++ [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = { ++ .type = ALC_FIXUP_FUNC, ++ .v.func = alc269_fixup_pincfg_no_hp_to_lineout, ++ }, + }; + + static const struct snd_pci_quirk alc269_fixup_tbl[] = { +@@ -5051,6 +5076,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), + SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), + SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), ++ SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK), ++ SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), + SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_QUANTA_MUTE), + SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K), + SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), +@@ -5109,6 +5136,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + static const struct alc_model_fixup alc269_fixup_models[] = { + {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, + {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, ++ {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, + {} + }; + +diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c +index 1fe1308..7160ff2 100644 +--- a/sound/pci/hda/patch_via.c ++++ b/sound/pci/hda/patch_via.c +@@ -3227,7 +3227,7 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec) + { + struct via_spec *spec = codec->spec; + int imux_is_smixer; +- unsigned int parm; ++ unsigned int parm, parm2; + /* MUX6 (1eh) = stereo mixer */ + imux_is_smixer = + snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; +@@ -3250,7 +3250,7 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec) + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x27, &parm); + snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, parm); +- snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm); ++ parm2 = parm; /* for pin 0x0b */ + + /* PW2 (26h), AOW2 (ah) */ + parm = AC_PWRST_D3; +@@ -3265,6 +3265,9 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec) + if (!spec->hp_independent_mode) /* check for redirected HP */ + set_pin_power_state(codec, 0x28, &parm); + snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm); ++ if (!spec->hp_independent_mode && parm2 != AC_PWRST_D3) ++ parm = parm2; ++ snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm); + /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ + snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE, + imux_is_smixer ? AC_PWRST_D0 : parm); +diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c +index 07dd7eb..e97df24 100644 +--- a/sound/soc/codecs/wm8962.c ++++ b/sound/soc/codecs/wm8962.c +@@ -3105,6 +3105,9 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec, + /* VMID 2*250k */ + snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, + WM8962_VMID_SEL_MASK, 0x100); ++ ++ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) ++ msleep(100); + break; + + case SND_SOC_BIAS_OFF: +diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c +index de61b8a..98c5774 100644 +--- a/sound/soc/codecs/wm8994.c ++++ b/sound/soc/codecs/wm8994.c +@@ -2508,7 +2508,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, + return -EINVAL; + } + +- bclk_rate = params_rate(params) * 2; ++ bclk_rate = params_rate(params) * 4; + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + bclk_rate *= 16; +diff --git a/sound/usb/clock.c b/sound/usb/clock.c +index 379baad..5e634a2 100644 +--- a/sound/usb/clock.c ++++ b/sound/usb/clock.c +@@ -111,7 +111,8 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id) + return 0; + + /* If a clock source can't tell us whether it's valid, we assume it is */ +- if (!uac2_control_is_readable(cs_desc->bmControls, UAC2_CS_CONTROL_CLOCK_VALID)) ++ if (!uac2_control_is_readable(cs_desc->bmControls, ++ UAC2_CS_CONTROL_CLOCK_VALID - 1)) + return 1; + + err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, |