diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2012-11-19 21:19:27 -0500 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2012-11-19 21:19:27 -0500 |
commit | 8eff7a1e79f245f5bfe7c20ee7d61d243ef332b8 (patch) | |
tree | 32bf02b57d842a7ba75e1f7fd2da99c7ccdcee83 | |
parent | Grsec/PaX: 2.9.1-{2.6.32.60,3.2.33,3.6.6}-201211122213 (diff) | |
download | hardened-patchset-20121118.tar.gz hardened-patchset-20121118.tar.bz2 hardened-patchset-20121118.zip |
Grsec/PaX: 2.9.1-{2.6.32.60,3.2.34,3.6.7}-20121118110520121118
-rw-r--r-- | 2.6.32/0000_README | 2 | ||||
-rw-r--r-- | 2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201211181103.patch (renamed from 2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201211122212.patch) | 474 | ||||
-rw-r--r-- | 3.2.34/0000_README (renamed from 3.2.33/0000_README) | 6 | ||||
-rw-r--r-- | 3.2.34/1021_linux-3.2.22.patch (renamed from 3.2.33/1021_linux-3.2.22.patch) | 0 | ||||
-rw-r--r-- | 3.2.34/1022_linux-3.2.23.patch (renamed from 3.2.33/1022_linux-3.2.23.patch) | 0 | ||||
-rw-r--r-- | 3.2.34/1023_linux-3.2.24.patch (renamed from 3.2.33/1023_linux-3.2.24.patch) | 0 | ||||
-rw-r--r-- | 3.2.34/1024_linux-3.2.25.patch (renamed from 3.2.33/1024_linux-3.2.25.patch) | 0 | ||||
-rw-r--r-- | 3.2.34/1025_linux-3.2.26.patch (renamed from 3.2.33/1025_linux-3.2.26.patch) | 0 | ||||
-rw-r--r-- | 3.2.34/1026_linux-3.2.27.patch (renamed from 3.2.33/1026_linux-3.2.27.patch) | 0 | ||||
-rw-r--r-- | 3.2.34/1027_linux-3.2.28.patch (renamed from 3.2.33/1027_linux-3.2.28.patch) | 0 | ||||
-rw-r--r-- | 3.2.34/1028_linux-3.2.29.patch (renamed from 3.2.33/1028_linux-3.2.29.patch) | 0 | ||||
-rw-r--r-- | 3.2.34/1029_linux-3.2.30.patch (renamed from 3.2.33/1029_linux-3.2.30.patch) | 0 | ||||
-rw-r--r-- | 3.2.34/1030_linux-3.2.31.patch (renamed from 3.2.33/1030_linux-3.2.31.patch) | 0 | ||||
-rw-r--r-- | 3.2.34/1031_linux-3.2.32.patch (renamed from 3.2.33/1031_linux-3.2.32.patch) | 0 | ||||
-rw-r--r-- | 3.2.34/1032_linux-3.2.33.patch (renamed from 3.2.33/1032_linux-3.2.33.patch) | 0 | ||||
-rw-r--r-- | 3.2.34/1033_linux-3.2.34.patch | 3678 | ||||
-rw-r--r-- | 3.2.34/4420_grsecurity-2.9.1-3.2.34-201211181104.patch (renamed from 3.2.33/4420_grsecurity-2.9.1-3.2.33-201211122213.patch) | 876 | ||||
-rw-r--r-- | 3.2.34/4425-tmpfs-user-namespace.patch (renamed from 3.2.33/4425-tmpfs-user-namespace.patch) | 0 | ||||
-rw-r--r-- | 3.2.34/4430_grsec-remove-localversion-grsec.patch (renamed from 3.2.33/4430_grsec-remove-localversion-grsec.patch) | 0 | ||||
-rw-r--r-- | 3.2.34/4435_grsec-mute-warnings.patch (renamed from 3.2.33/4435_grsec-mute-warnings.patch) | 0 | ||||
-rw-r--r-- | 3.2.34/4440_grsec-remove-protected-paths.patch (renamed from 3.2.33/4440_grsec-remove-protected-paths.patch) | 0 | ||||
-rw-r--r-- | 3.2.34/4450_grsec-kconfig-default-gids.patch (renamed from 3.2.33/4450_grsec-kconfig-default-gids.patch) | 0 | ||||
-rw-r--r-- | 3.2.34/4465_selinux-avc_audit-log-curr_ip.patch (renamed from 3.2.33/4465_selinux-avc_audit-log-curr_ip.patch) | 0 | ||||
-rw-r--r-- | 3.2.34/4470_disable-compat_vdso.patch (renamed from 3.2.33/4470_disable-compat_vdso.patch) | 0 | ||||
-rw-r--r-- | 3.6.7/0000_README (renamed from 3.6.6/0000_README) | 6 | ||||
-rw-r--r-- | 3.6.7/1006_linux-3.6.7.patch | 3082 | ||||
-rw-r--r-- | 3.6.7/4420_grsecurity-2.9.1-3.6.7-201211181105.patch (renamed from 3.6.6/4420_grsecurity-2.9.1-3.6.6-201211122213.patch) | 1067 | ||||
-rw-r--r-- | 3.6.7/4425-tmpfs-user-namespace.patch (renamed from 3.6.6/4425-tmpfs-user-namespace.patch) | 0 | ||||
-rw-r--r-- | 3.6.7/4430_grsec-remove-localversion-grsec.patch (renamed from 3.6.6/4430_grsec-remove-localversion-grsec.patch) | 0 | ||||
-rw-r--r-- | 3.6.7/4435_grsec-mute-warnings.patch (renamed from 3.6.6/4435_grsec-mute-warnings.patch) | 0 | ||||
-rw-r--r-- | 3.6.7/4440_grsec-remove-protected-paths.patch (renamed from 3.6.6/4440_grsec-remove-protected-paths.patch) | 0 | ||||
-rw-r--r-- | 3.6.7/4450_grsec-kconfig-default-gids.patch (renamed from 3.6.6/4450_grsec-kconfig-default-gids.patch) | 0 | ||||
-rw-r--r-- | 3.6.7/4465_selinux-avc_audit-log-curr_ip.patch (renamed from 3.6.6/4465_selinux-avc_audit-log-curr_ip.patch) | 0 | ||||
-rw-r--r-- | 3.6.7/4470_disable-compat_vdso.patch (renamed from 3.6.6/4470_disable-compat_vdso.patch) | 0 |
34 files changed, 7969 insertions, 1222 deletions
diff --git a/2.6.32/0000_README b/2.6.32/0000_README index ac627bb..00e77a9 100644 --- a/2.6.32/0000_README +++ b/2.6.32/0000_README @@ -34,7 +34,7 @@ Patch: 1059_linux-2.6.32.60.patch From: http://www.kernel.org Desc: Linux 2.6.32.59 -Patch: 4420_grsecurity-2.9.1-2.6.32.60-201211122212.patch +Patch: 4420_grsecurity-2.9.1-2.6.32.60-201211181103.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201211122212.patch b/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201211181103.patch index 4b4bbbc..4688218 100644 --- a/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201211122212.patch +++ b/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201211181103.patch @@ -17770,7 +17770,7 @@ index c097e7d..a3f1930 100644 /* * End of kprobes section diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S -index 34a56a9..0d13843 100644 +index 34a56a9..9df0232 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -53,6 +53,8 @@ @@ -17846,7 +17846,7 @@ index 34a56a9..0d13843 100644 retq #endif -@@ -174,6 +182,280 @@ ENTRY(native_usergs_sysret64) +@@ -174,6 +182,273 @@ ENTRY(native_usergs_sysret64) ENDPROC(native_usergs_sysret64) #endif /* CONFIG_PARAVIRT */ @@ -17932,13 +17932,6 @@ index 34a56a9..0d13843 100644 + ljmpq __KERNEL_CS,3f +3: SET_RDI_INTO_CR0 + jmp 1b -+#ifdef CONFIG_PARAVIRT -+ PV_RESTORE_REGS(CLBR_RDI); -+#endif -+ -+ popq %rdi -+ pax_force_retaddr -+ retq +ENDPROC(pax_exit_kernel) +#endif + @@ -18127,7 +18120,7 @@ index 34a56a9..0d13843 100644 .macro TRACE_IRQS_IRETQ offset=ARGOFFSET #ifdef CONFIG_TRACE_IRQFLAGS -@@ -233,8 +515,8 @@ ENDPROC(native_usergs_sysret64) +@@ -233,8 +508,8 @@ ENDPROC(native_usergs_sysret64) .endm .macro UNFAKE_STACK_FRAME @@ -18138,7 +18131,7 @@ index 34a56a9..0d13843 100644 .endm /* -@@ -317,7 +599,7 @@ ENTRY(save_args) +@@ -317,7 +592,7 @@ ENTRY(save_args) leaq -ARGOFFSET+16(%rsp),%rdi /* arg1 for handler */ movq_cfi rbp, 8 /* push %rbp */ leaq 8(%rsp), %rbp /* mov %rsp, %ebp */ @@ -18147,7 +18140,7 @@ index 34a56a9..0d13843 100644 je 1f SWAPGS /* -@@ -337,9 +619,10 @@ ENTRY(save_args) +@@ -337,9 +612,10 @@ ENTRY(save_args) * We entered an interrupt context - irqs are off: */ 2: TRACE_IRQS_OFF @@ -18159,7 +18152,7 @@ index 34a56a9..0d13843 100644 ENTRY(save_rest) PARTIAL_FRAME 1 REST_SKIP+8 -@@ -352,9 +635,10 @@ ENTRY(save_rest) +@@ -352,9 +628,10 @@ ENTRY(save_rest) movq_cfi r15, R15+16 movq %r11, 8(%rsp) /* return address */ FIXUP_TOP_OF_STACK %r11, 16 @@ -18171,7 +18164,7 @@ index 34a56a9..0d13843 100644 /* save complete stack frame */ .pushsection .kprobes.text, "ax" -@@ -383,9 +667,10 @@ ENTRY(save_paranoid) +@@ -383,9 +660,10 @@ ENTRY(save_paranoid) js 1f /* negative -> in kernel */ SWAPGS xorl %ebx,%ebx @@ -18184,7 +18177,7 @@ index 34a56a9..0d13843 100644 .popsection /* -@@ -409,7 +694,7 @@ ENTRY(ret_from_fork) +@@ -409,7 +687,7 @@ ENTRY(ret_from_fork) RESTORE_REST @@ -18193,7 +18186,7 @@ index 34a56a9..0d13843 100644 je int_ret_from_sys_call testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET -@@ -419,7 +704,7 @@ ENTRY(ret_from_fork) +@@ -419,7 +697,7 @@ ENTRY(ret_from_fork) jmp ret_from_sys_call # go to the SYSRET fastpath CFI_ENDPROC @@ -18202,7 +18195,7 @@ index 34a56a9..0d13843 100644 /* * System call entry. Upto 6 arguments in registers are supported. -@@ -455,7 +740,7 @@ END(ret_from_fork) +@@ -455,7 +733,7 @@ END(ret_from_fork) ENTRY(system_call) CFI_STARTPROC simple CFI_SIGNAL_FRAME @@ -18211,7 +18204,7 @@ index 34a56a9..0d13843 100644 CFI_REGISTER rip,rcx /*CFI_REGISTER rflags,r11*/ SWAPGS_UNSAFE_STACK -@@ -468,12 +753,18 @@ ENTRY(system_call_after_swapgs) +@@ -468,12 +746,18 @@ ENTRY(system_call_after_swapgs) movq %rsp,PER_CPU_VAR(old_rsp) movq PER_CPU_VAR(kernel_stack),%rsp @@ -18231,7 +18224,7 @@ index 34a56a9..0d13843 100644 movq %rax,ORIG_RAX-ARGOFFSET(%rsp) movq %rcx,RIP-ARGOFFSET(%rsp) CFI_REL_OFFSET rip,RIP-ARGOFFSET -@@ -483,7 +774,7 @@ ENTRY(system_call_after_swapgs) +@@ -483,7 +767,7 @@ ENTRY(system_call_after_swapgs) system_call_fastpath: cmpq $__NR_syscall_max,%rax ja badsys @@ -18240,7 +18233,7 @@ index 34a56a9..0d13843 100644 call *sys_call_table(,%rax,8) # XXX: rip relative movq %rax,RAX-ARGOFFSET(%rsp) /* -@@ -502,6 +793,8 @@ sysret_check: +@@ -502,6 +786,8 @@ sysret_check: andl %edi,%edx jnz sysret_careful CFI_REMEMBER_STATE @@ -18249,7 +18242,7 @@ index 34a56a9..0d13843 100644 /* * sysretq will re-enable interrupts: */ -@@ -555,14 +848,18 @@ badsys: +@@ -555,14 +841,18 @@ badsys: * jump back to the normal fast path. */ auditsys: @@ -18269,7 +18262,7 @@ index 34a56a9..0d13843 100644 jmp system_call_fastpath /* -@@ -592,16 +889,20 @@ tracesys: +@@ -592,16 +882,20 @@ tracesys: FIXUP_TOP_OF_STACK %rdi movq %rsp,%rdi call syscall_trace_enter @@ -18291,7 +18284,7 @@ index 34a56a9..0d13843 100644 call *sys_call_table(,%rax,8) movq %rax,RAX-ARGOFFSET(%rsp) /* Use IRET because user could have changed frame */ -@@ -613,7 +914,7 @@ tracesys: +@@ -613,7 +907,7 @@ tracesys: GLOBAL(int_ret_from_sys_call) DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF @@ -18300,7 +18293,7 @@ index 34a56a9..0d13843 100644 je retint_restore_args movl $_TIF_ALLWORK_MASK,%edi /* edi: mask to check */ -@@ -624,7 +925,9 @@ GLOBAL(int_with_check) +@@ -624,7 +918,9 @@ GLOBAL(int_with_check) andl %edi,%edx jnz int_careful andl $~TS_COMPAT,TI_status(%rcx) @@ -18311,7 +18304,7 @@ index 34a56a9..0d13843 100644 /* Either reschedule or signal or syscall exit tracking needed. */ /* First do a reschedule test. */ -@@ -674,7 +977,7 @@ int_restore_rest: +@@ -674,7 +970,7 @@ int_restore_rest: TRACE_IRQS_OFF jmp int_with_check CFI_ENDPROC @@ -18320,7 +18313,7 @@ index 34a56a9..0d13843 100644 /* * Certain special system calls that need to save a complete full stack frame. -@@ -690,7 +993,7 @@ ENTRY(\label) +@@ -690,7 +986,7 @@ ENTRY(\label) call \func jmp ptregscall_common CFI_ENDPROC @@ -18329,7 +18322,7 @@ index 34a56a9..0d13843 100644 .endm PTREGSCALL stub_clone, sys_clone, %r8 -@@ -708,9 +1011,10 @@ ENTRY(ptregscall_common) +@@ -708,9 +1004,10 @@ ENTRY(ptregscall_common) movq_cfi_restore R12+8, r12 movq_cfi_restore RBP+8, rbp movq_cfi_restore RBX+8, rbx @@ -18341,7 +18334,7 @@ index 34a56a9..0d13843 100644 ENTRY(stub_execve) CFI_STARTPROC -@@ -726,7 +1030,7 @@ ENTRY(stub_execve) +@@ -726,7 +1023,7 @@ ENTRY(stub_execve) RESTORE_REST jmp int_ret_from_sys_call CFI_ENDPROC @@ -18350,7 +18343,7 @@ index 34a56a9..0d13843 100644 /* * sigreturn is special because it needs to restore all registers on return. -@@ -744,7 +1048,7 @@ ENTRY(stub_rt_sigreturn) +@@ -744,7 +1041,7 @@ ENTRY(stub_rt_sigreturn) RESTORE_REST jmp int_ret_from_sys_call CFI_ENDPROC @@ -18359,7 +18352,7 @@ index 34a56a9..0d13843 100644 /* * Build the entry stubs and pointer table with some assembler magic. -@@ -780,7 +1084,7 @@ vector=vector+1 +@@ -780,7 +1077,7 @@ vector=vector+1 2: jmp common_interrupt .endr CFI_ENDPROC @@ -18368,7 +18361,7 @@ index 34a56a9..0d13843 100644 .previous END(interrupt) -@@ -800,6 +1104,16 @@ END(interrupt) +@@ -800,6 +1097,16 @@ END(interrupt) CFI_ADJUST_CFA_OFFSET 10*8 call save_args PARTIAL_FRAME 0 @@ -18385,7 +18378,7 @@ index 34a56a9..0d13843 100644 call \func .endm -@@ -822,7 +1136,7 @@ ret_from_intr: +@@ -822,7 +1129,7 @@ ret_from_intr: CFI_ADJUST_CFA_OFFSET -8 exit_intr: GET_THREAD_INFO(%rcx) @@ -18394,7 +18387,7 @@ index 34a56a9..0d13843 100644 je retint_kernel /* Interrupt came from user space */ -@@ -844,12 +1158,16 @@ retint_swapgs: /* return to user-space */ +@@ -844,12 +1151,16 @@ retint_swapgs: /* return to user-space */ * The iretq could re-enable interrupts: */ DISABLE_INTERRUPTS(CLBR_ANY) @@ -18411,7 +18404,7 @@ index 34a56a9..0d13843 100644 /* * The iretq could re-enable interrupts: */ -@@ -940,7 +1258,7 @@ ENTRY(retint_kernel) +@@ -940,7 +1251,7 @@ ENTRY(retint_kernel) #endif CFI_ENDPROC @@ -18420,7 +18413,7 @@ index 34a56a9..0d13843 100644 /* * APIC interrupts. -@@ -953,7 +1271,7 @@ ENTRY(\sym) +@@ -953,7 +1264,7 @@ ENTRY(\sym) interrupt \do_sym jmp ret_from_intr CFI_ENDPROC @@ -18429,7 +18422,7 @@ index 34a56a9..0d13843 100644 .endm #ifdef CONFIG_SMP -@@ -1032,12 +1350,22 @@ ENTRY(\sym) +@@ -1032,12 +1343,22 @@ ENTRY(\sym) CFI_ADJUST_CFA_OFFSET 15*8 call error_entry DEFAULT_FRAME 0 @@ -18453,7 +18446,7 @@ index 34a56a9..0d13843 100644 .endm .macro paranoidzeroentry sym do_sym -@@ -1049,12 +1377,22 @@ ENTRY(\sym) +@@ -1049,12 +1370,22 @@ ENTRY(\sym) subq $15*8, %rsp call save_paranoid TRACE_IRQS_OFF @@ -18477,7 +18470,7 @@ index 34a56a9..0d13843 100644 .endm .macro paranoidzeroentry_ist sym do_sym ist -@@ -1066,15 +1404,30 @@ ENTRY(\sym) +@@ -1066,15 +1397,30 @@ ENTRY(\sym) subq $15*8, %rsp call save_paranoid TRACE_IRQS_OFF @@ -18510,7 +18503,7 @@ index 34a56a9..0d13843 100644 .endm .macro errorentry sym do_sym -@@ -1085,13 +1438,23 @@ ENTRY(\sym) +@@ -1085,13 +1431,23 @@ ENTRY(\sym) CFI_ADJUST_CFA_OFFSET 15*8 call error_entry DEFAULT_FRAME 0 @@ -18535,7 +18528,7 @@ index 34a56a9..0d13843 100644 .endm /* error code is on the stack already */ -@@ -1104,13 +1467,23 @@ ENTRY(\sym) +@@ -1104,13 +1460,23 @@ ENTRY(\sym) call save_paranoid DEFAULT_FRAME 0 TRACE_IRQS_OFF @@ -18560,7 +18553,7 @@ index 34a56a9..0d13843 100644 .endm zeroentry divide_error do_divide_error -@@ -1141,9 +1514,10 @@ gs_change: +@@ -1141,9 +1507,10 @@ gs_change: SWAPGS popf CFI_ADJUST_CFA_OFFSET -8 @@ -18572,7 +18565,7 @@ index 34a56a9..0d13843 100644 .section __ex_table,"a" .align 8 -@@ -1193,11 +1567,12 @@ ENTRY(kernel_thread) +@@ -1193,11 +1560,12 @@ ENTRY(kernel_thread) * of hacks for example to fork off the per-CPU idle tasks. * [Hopefully no generic code relies on the reschedule -AK] */ @@ -18587,7 +18580,7 @@ index 34a56a9..0d13843 100644 ENTRY(child_rip) pushq $0 # fake return address -@@ -1208,13 +1583,14 @@ ENTRY(child_rip) +@@ -1208,13 +1576,14 @@ ENTRY(child_rip) */ movq %rdi, %rax movq %rsi, %rdi @@ -18603,7 +18596,7 @@ index 34a56a9..0d13843 100644 /* * execve(). This function needs to use IRET, not SYSRET, to set up all state properly. -@@ -1241,11 +1617,11 @@ ENTRY(kernel_execve) +@@ -1241,11 +1610,11 @@ ENTRY(kernel_execve) RESTORE_REST testq %rax,%rax je int_ret_from_sys_call @@ -18617,7 +18610,7 @@ index 34a56a9..0d13843 100644 /* Call softirq on interrupt stack. Interrupts are off. */ ENTRY(call_softirq) -@@ -1263,9 +1639,10 @@ ENTRY(call_softirq) +@@ -1263,9 +1632,10 @@ ENTRY(call_softirq) CFI_DEF_CFA_REGISTER rsp CFI_ADJUST_CFA_OFFSET -8 decl PER_CPU_VAR(irq_count) @@ -18629,7 +18622,7 @@ index 34a56a9..0d13843 100644 #ifdef CONFIG_XEN zeroentry xen_hypervisor_callback xen_do_hypervisor_callback -@@ -1303,7 +1680,7 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) +@@ -1303,7 +1673,7 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) decl PER_CPU_VAR(irq_count) jmp error_exit CFI_ENDPROC @@ -18638,7 +18631,7 @@ index 34a56a9..0d13843 100644 /* * Hypervisor uses this for application faults while it executes. -@@ -1362,7 +1739,7 @@ ENTRY(xen_failsafe_callback) +@@ -1362,7 +1732,7 @@ ENTRY(xen_failsafe_callback) SAVE_ALL jmp error_exit CFI_ENDPROC @@ -18647,7 +18640,7 @@ index 34a56a9..0d13843 100644 #endif /* CONFIG_XEN */ -@@ -1405,16 +1782,31 @@ ENTRY(paranoid_exit) +@@ -1405,16 +1775,31 @@ ENTRY(paranoid_exit) TRACE_IRQS_OFF testl %ebx,%ebx /* swapgs needed? */ jnz paranoid_restore @@ -18680,7 +18673,7 @@ index 34a56a9..0d13843 100644 jmp irq_return paranoid_userspace: GET_THREAD_INFO(%rcx) -@@ -1443,7 +1835,7 @@ paranoid_schedule: +@@ -1443,7 +1828,7 @@ paranoid_schedule: TRACE_IRQS_OFF jmp paranoid_userspace CFI_ENDPROC @@ -18689,7 +18682,7 @@ index 34a56a9..0d13843 100644 /* * Exception entry point. This expects an error code/orig_rax on the stack. -@@ -1470,12 +1862,13 @@ ENTRY(error_entry) +@@ -1470,12 +1855,13 @@ ENTRY(error_entry) movq_cfi r14, R14+8 movq_cfi r15, R15+8 xorl %ebx,%ebx @@ -18704,7 +18697,7 @@ index 34a56a9..0d13843 100644 ret CFI_ENDPROC -@@ -1497,7 +1890,7 @@ error_kernelspace: +@@ -1497,7 +1883,7 @@ error_kernelspace: cmpq $gs_change,RIP+8(%rsp) je error_swapgs jmp error_sti @@ -18713,7 +18706,7 @@ index 34a56a9..0d13843 100644 /* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */ -@@ -1517,7 +1910,7 @@ ENTRY(error_exit) +@@ -1517,7 +1903,7 @@ ENTRY(error_exit) jnz retint_careful jmp retint_swapgs CFI_ENDPROC @@ -18722,7 +18715,7 @@ index 34a56a9..0d13843 100644 /* runs on exception stack */ -@@ -1529,6 +1922,16 @@ ENTRY(nmi) +@@ -1529,6 +1915,16 @@ ENTRY(nmi) CFI_ADJUST_CFA_OFFSET 15*8 call save_paranoid DEFAULT_FRAME 0 @@ -18739,7 +18732,7 @@ index 34a56a9..0d13843 100644 /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */ movq %rsp,%rdi movq $-1,%rsi -@@ -1539,12 +1942,28 @@ ENTRY(nmi) +@@ -1539,12 +1935,28 @@ ENTRY(nmi) DISABLE_INTERRUPTS(CLBR_NONE) testl %ebx,%ebx /* swapgs needed? */ jnz nmi_restore @@ -18769,7 +18762,7 @@ index 34a56a9..0d13843 100644 jmp irq_return nmi_userspace: GET_THREAD_INFO(%rcx) -@@ -1573,14 +1992,14 @@ nmi_schedule: +@@ -1573,14 +1985,14 @@ nmi_schedule: jmp paranoid_exit CFI_ENDPROC #endif @@ -29869,7 +29862,7 @@ index 2be0a97..bded3fd 100644 goto error; diff --git a/crypto/cryptd.c b/crypto/cryptd.c -index 3533582..f143117 100644 +index 3533582..0efffdb 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c @@ -50,7 +50,7 @@ struct cryptd_blkcipher_ctx { @@ -29881,6 +29874,28 @@ index 3533582..f143117 100644 struct cryptd_hash_ctx { struct crypto_shash *child; +@@ -116,13 +116,18 @@ static void cryptd_queue_worker(struct work_struct *work) + struct crypto_async_request *req, *backlog; + + cpu_queue = container_of(work, struct cryptd_cpu_queue, work); +- /* Only handle one request at a time to avoid hogging crypto +- * workqueue. preempt_disable/enable is used to prevent +- * being preempted by cryptd_enqueue_request() */ ++ /* ++ * Only handle one request at a time to avoid hogging crypto workqueue. ++ * preempt_disable/enable is used to prevent being preempted by ++ * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent ++ * cryptd_enqueue_request() being accessed from software interrupts. ++ */ ++ local_bh_disable(); + preempt_disable(); + backlog = crypto_get_backlog(&cpu_queue->queue); + req = crypto_dequeue_request(&cpu_queue->queue); + preempt_enable(); ++ local_bh_enable(); + + if (!req) + return; diff --git a/crypto/gf128mul.c b/crypto/gf128mul.c index a90d260..7a9765e 100644 --- a/crypto/gf128mul.c @@ -74350,7 +74365,7 @@ index 0133b5a..3710d09 100644 (unsigned long) create_aout_tables((char __user *) bprm->p, bprm); #ifdef __alpha__ diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c -index a64fde6..89649d4 100644 +index a64fde6..0f8c4d1 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -31,6 +31,7 @@ @@ -74498,7 +74513,7 @@ index a64fde6..89649d4 100644 error = -ENOMEM; goto out_close; } -@@ -532,6 +555,311 @@ out: +@@ -532,6 +555,315 @@ out: return error; } @@ -74732,7 +74747,7 @@ index a64fde6..89649d4 100644 + unsigned long pax_flags_hardmode = 0UL, pax_flags_softmode = 0UL; + + xattr_size = vfs_getxattr(file->f_path.dentry, XATTR_NAME_PAX_FLAGS, xattr_value, sizeof xattr_value); -+ if (xattr_size <= 0) ++ if (xattr_size <= 0 || xattr_size > 5) + return ~0UL; + + for (i = 0; i < xattr_size; i++) @@ -74742,9 +74757,13 @@ index a64fde6..89649d4 100644 + +#define parse_flag(option1, option2, flag) \ + case option1: \ ++ if (pax_flags_hardmode & MF_PAX_##flag) \ ++ return ~0UL; \ + pax_flags_hardmode |= MF_PAX_##flag; \ + break; \ + case option2: \ ++ if (pax_flags_softmode & MF_PAX_##flag) \ ++ return ~0UL; \ + pax_flags_softmode |= MF_PAX_##flag; \ + break; + @@ -74810,7 +74829,7 @@ index a64fde6..89649d4 100644 /* * These are the functions used to load ELF style executables and shared * libraries. There is no binary dependent code anywhere else. -@@ -548,6 +876,11 @@ static unsigned long randomize_stack_top(unsigned long stack_top) +@@ -548,6 +880,11 @@ static unsigned long randomize_stack_top(unsigned long stack_top) { unsigned int random_variable = 0; @@ -74822,7 +74841,7 @@ index a64fde6..89649d4 100644 if ((current->flags & PF_RANDOMIZE) && !(current->personality & ADDR_NO_RANDOMIZE)) { random_variable = get_random_int() & STACK_RND_MASK; -@@ -566,7 +899,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +@@ -566,7 +903,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) unsigned long load_addr = 0, load_bias = 0; int load_addr_set = 0; char * elf_interpreter = NULL; @@ -74831,7 +74850,7 @@ index a64fde6..89649d4 100644 struct elf_phdr *elf_ppnt, *elf_phdata; unsigned long elf_bss, elf_brk; int retval, i; -@@ -576,11 +909,11 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +@@ -576,11 +913,11 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) unsigned long start_code, end_code, start_data, end_data; unsigned long reloc_func_desc = 0; int executable_stack = EXSTACK_DEFAULT; @@ -74844,7 +74863,7 @@ index a64fde6..89649d4 100644 loc = kmalloc(sizeof(*loc), GFP_KERNEL); if (!loc) { -@@ -718,11 +1051,80 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +@@ -718,11 +1055,80 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) /* OK, This is the point of no return */ current->flags &= ~PF_FORKNOEXEC; @@ -74926,7 +74945,7 @@ index a64fde6..89649d4 100644 if (elf_read_implies_exec(loc->elf_ex, executable_stack)) current->personality |= READ_IMPLIES_EXEC; -@@ -800,10 +1202,27 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +@@ -800,10 +1206,27 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) * might try to exec. This is because the brk will * follow the loader, and is not movable. */ #ifdef CONFIG_X86 @@ -74955,7 +74974,7 @@ index a64fde6..89649d4 100644 } error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, -@@ -836,9 +1255,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +@@ -836,9 +1259,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) * allowed task size. Note that p_filesz must always be * <= p_memsz so it is only necessary to check p_memsz. */ @@ -74968,7 +74987,7 @@ index a64fde6..89649d4 100644 /* set_brk can never work. Avoid overflows. */ send_sig(SIGKILL, current, 0); retval = -EINVAL; -@@ -877,17 +1296,43 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +@@ -877,17 +1300,43 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) goto out_free_dentry; } if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) { @@ -75018,7 +75037,7 @@ index a64fde6..89649d4 100644 load_bias); if (!IS_ERR((void *)elf_entry)) { /* -@@ -1112,8 +1557,10 @@ static int dump_seek(struct file *file, loff_t off) +@@ -1112,8 +1561,10 @@ static int dump_seek(struct file *file, loff_t off) unsigned long n = off; if (n > PAGE_SIZE) n = PAGE_SIZE; @@ -75030,7 +75049,7 @@ index a64fde6..89649d4 100644 off -= n; } free_page((unsigned long)buf); -@@ -1125,7 +1572,7 @@ static int dump_seek(struct file *file, loff_t off) +@@ -1125,7 +1576,7 @@ static int dump_seek(struct file *file, loff_t off) * Decide what to dump of a segment, part, all or none. */ static unsigned long vma_dump_size(struct vm_area_struct *vma, @@ -75039,7 +75058,7 @@ index a64fde6..89649d4 100644 { #define FILTER(type) (mm_flags & (1UL << MMF_DUMP_##type)) -@@ -1159,7 +1606,7 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma, +@@ -1159,7 +1610,7 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma, if (vma->vm_file == NULL) return 0; @@ -75048,7 +75067,7 @@ index a64fde6..89649d4 100644 goto whole; /* -@@ -1255,8 +1702,11 @@ static int writenote(struct memelfnote *men, struct file *file, +@@ -1255,8 +1706,11 @@ static int writenote(struct memelfnote *men, struct file *file, #undef DUMP_WRITE #define DUMP_WRITE(addr, nr) \ @@ -75061,7 +75080,7 @@ index a64fde6..89649d4 100644 static void fill_elf_header(struct elfhdr *elf, int segs, u16 machine, u32 flags, u8 osabi) -@@ -1385,9 +1835,9 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm) +@@ -1385,9 +1839,9 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm) { elf_addr_t *auxv = (elf_addr_t *) mm->saved_auxv; int i = 0; @@ -75073,7 +75092,7 @@ index a64fde6..89649d4 100644 fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv); } -@@ -1973,7 +2423,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un +@@ -1973,7 +2427,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un phdr.p_offset = offset; phdr.p_vaddr = vma->vm_start; phdr.p_paddr = 0; @@ -75082,7 +75101,7 @@ index a64fde6..89649d4 100644 phdr.p_memsz = vma->vm_end - vma->vm_start; offset += phdr.p_filesz; phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; -@@ -2006,7 +2456,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un +@@ -2006,7 +2460,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un unsigned long addr; unsigned long end; @@ -75091,7 +75110,7 @@ index a64fde6..89649d4 100644 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) { struct page *page; -@@ -2015,6 +2465,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un +@@ -2015,6 +2469,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un page = get_dump_page(addr); if (page) { void *kaddr = kmap(page); @@ -75099,7 +75118,7 @@ index a64fde6..89649d4 100644 stop = ((size += PAGE_SIZE) > limit) || !dump_write(file, kaddr, PAGE_SIZE); kunmap(page); -@@ -2042,6 +2493,97 @@ out: +@@ -2042,6 +2497,97 @@ out: #endif /* USE_ELF_CORE_DUMP */ @@ -106275,6 +106294,48 @@ index 9ecd6e8..12c94c1 100644 WARN_ON(release == (void (*)(struct kref *))kfree); if (atomic_dec_and_test(&kref->refcount)) { +diff --git a/lib/list_debug.c b/lib/list_debug.c +index 1a39f4e..c2714ca 100644 +--- a/lib/list_debug.c ++++ b/lib/list_debug.c +@@ -20,14 +20,15 @@ void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) + { +- WARN(next->prev != prev, ++ if (WARN(next->prev != prev, + "list_add corruption. next->prev should be " + "prev (%p), but was %p. (next=%p).\n", +- prev, next->prev, next); +- WARN(prev->next != next, ++ prev, next->prev, next) || ++ WARN(prev->next != next, + "list_add corruption. prev->next should be " + "next (%p), but was %p. (prev=%p).\n", +- next, prev->next, prev); ++ next, prev->next, prev)) ++ return; + next->prev = new; + new->next = next; + new->prev = prev; +@@ -43,12 +44,13 @@ EXPORT_SYMBOL(__list_add); + */ + void list_del(struct list_head *entry) + { +- WARN(entry->prev->next != entry, ++ if (WARN(entry->prev->next != entry, + "list_del corruption. prev->next should be %p, " +- "but was %p\n", entry, entry->prev->next); +- WARN(entry->next->prev != entry, ++ "but was %p\n", entry, entry->prev->next) || ++ WARN(entry->next->prev != entry, + "list_del corruption. next->prev should be %p, " +- "but was %p\n", entry, entry->next->prev); ++ "but was %p\n", entry, entry->next->prev)) ++ return; + __list_del(entry->prev, entry->next); + entry->next = LIST_POISON1; + entry->prev = LIST_POISON2; diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 92cdd99..a8149d7 100644 --- a/lib/radix-tree.c @@ -110534,7 +110595,7 @@ index e48b493..24a601d 100644 mm->unmap_area = arch_unmap_area; } diff --git a/mm/vmalloc.c b/mm/vmalloc.c -index f34ffd0..4b76d56 100644 +index f34ffd0..1251316 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -40,8 +40,19 @@ static void vunmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end) @@ -110559,15 +110620,7 @@ index f34ffd0..4b76d56 100644 } while (pte++, addr += PAGE_SIZE, addr != end); } -@@ -92,6 +103,7 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, - unsigned long end, pgprot_t prot, struct page **pages, int *nr) - { - pte_t *pte; -+ int ret = -ENOMEM; - - /* - * nr is a running index into the array which helps higher level -@@ -101,17 +113,32 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, +@@ -101,16 +112,31 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, pte = pte_alloc_kernel(pmd, addr); if (!pte) return -ENOMEM; @@ -110577,35 +110630,31 @@ index f34ffd0..4b76d56 100644 struct page *page = pages[*nr]; - if (WARN_ON(!pte_none(*pte))) -- return -EBUSY; -- if (WARN_ON(!page)) -- return -ENOMEM; +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) + if (!(pgprot_val(prot) & _PAGE_NX)) + BUG_ON(!pte_exec(*pte) || pte_pfn(*pte) != __pa(addr) >> PAGE_SHIFT); + else +#endif + -+ if (WARN_ON(!pte_none(*pte))) { -+ ret = -EBUSY; -+ goto out; ++ if (!pte_none(*pte)) { ++ pax_close_kernel(); ++ WARN_ON(1); + return -EBUSY; +- if (WARN_ON(!page)) + } -+ if (WARN_ON(!page)) { -+ ret = -ENOMEM; -+ goto out; ++ if (!page) { ++ pax_close_kernel(); ++ WARN_ON(1); + return -ENOMEM; + } set_pte_at(&init_mm, addr, pte, mk_pte(page, prot)); (*nr)++; } while (pte++, addr += PAGE_SIZE, addr != end); -- return 0; -+ ret = 0; -+out: + pax_close_kernel(); -+ return ret; + return 0; } - static int vmap_pmd_range(pud_t *pud, unsigned long addr, -@@ -120,7 +147,7 @@ static int vmap_pmd_range(pud_t *pud, unsigned long addr, +@@ -120,7 +146,7 @@ static int vmap_pmd_range(pud_t *pud, unsigned long addr, pmd_t *pmd; unsigned long next; @@ -110614,7 +110663,7 @@ index f34ffd0..4b76d56 100644 if (!pmd) return -ENOMEM; do { -@@ -137,7 +164,7 @@ static int vmap_pud_range(pgd_t *pgd, unsigned long addr, +@@ -137,7 +163,7 @@ static int vmap_pud_range(pgd_t *pgd, unsigned long addr, pud_t *pud; unsigned long next; @@ -110623,7 +110672,7 @@ index f34ffd0..4b76d56 100644 if (!pud) return -ENOMEM; do { -@@ -192,11 +219,20 @@ int is_vmalloc_or_module_addr(const void *x) +@@ -192,11 +218,20 @@ int is_vmalloc_or_module_addr(const void *x) * and fall back on vmalloc() if that fails. Others * just put it in the vmalloc space. */ @@ -110645,7 +110694,7 @@ index f34ffd0..4b76d56 100644 return is_vmalloc_addr(x); } -@@ -217,8 +253,14 @@ struct page *vmalloc_to_page(const void *vmalloc_addr) +@@ -217,8 +252,14 @@ struct page *vmalloc_to_page(const void *vmalloc_addr) if (!pgd_none(*pgd)) { pud_t *pud = pud_offset(pgd, addr); @@ -110660,7 +110709,7 @@ index f34ffd0..4b76d56 100644 if (!pmd_none(*pmd)) { pte_t *ptep, pte; -@@ -292,13 +334,13 @@ static void __insert_vmap_area(struct vmap_area *va) +@@ -292,13 +333,13 @@ static void __insert_vmap_area(struct vmap_area *va) struct rb_node *tmp; while (*p) { @@ -110678,7 +110727,7 @@ index f34ffd0..4b76d56 100644 p = &(*p)->rb_right; else BUG(); -@@ -323,7 +365,7 @@ static void purge_vmap_area_lazy(void); +@@ -323,7 +364,7 @@ static void purge_vmap_area_lazy(void); * Allocate a region of KVA of the specified size and alignment, within the * vstart and vend. */ @@ -110687,7 +110736,7 @@ index f34ffd0..4b76d56 100644 unsigned long align, unsigned long vstart, unsigned long vend, int node, gfp_t gfp_mask) -@@ -1245,6 +1287,16 @@ static struct vm_struct *__get_vm_area_node(unsigned long size, +@@ -1245,6 +1286,16 @@ static struct vm_struct *__get_vm_area_node(unsigned long size, struct vm_struct *area; BUG_ON(in_interrupt()); @@ -110704,7 +110753,7 @@ index f34ffd0..4b76d56 100644 if (flags & VM_IOREMAP) { int bit = fls(size); -@@ -1484,6 +1536,11 @@ void *vmap(struct page **pages, unsigned int count, +@@ -1484,6 +1535,11 @@ void *vmap(struct page **pages, unsigned int count, if (count > totalram_pages) return NULL; @@ -110716,7 +110765,7 @@ index f34ffd0..4b76d56 100644 area = get_vm_area_caller((count << PAGE_SHIFT), flags, __builtin_return_address(0)); if (!area) -@@ -1594,6 +1651,14 @@ static void *__vmalloc_node(unsigned long size, unsigned long align, +@@ -1594,6 +1650,14 @@ static void *__vmalloc_node(unsigned long size, unsigned long align, if (!size || (size >> PAGE_SHIFT) > totalram_pages) return NULL; @@ -110731,7 +110780,7 @@ index f34ffd0..4b76d56 100644 area = __get_vm_area_node(size, align, VM_ALLOC | VM_UNLIST, VMALLOC_START, VMALLOC_END, node, gfp_mask, caller); -@@ -1698,10 +1763,9 @@ EXPORT_SYMBOL(vmalloc_node); +@@ -1698,10 +1762,9 @@ EXPORT_SYMBOL(vmalloc_node); * For tight control over page level allocator and protection flags * use __vmalloc() instead. */ @@ -110743,7 +110792,7 @@ index f34ffd0..4b76d56 100644 -1, __builtin_return_address(0)); } -@@ -1998,6 +2062,8 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr, +@@ -1998,6 +2061,8 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr, unsigned long uaddr = vma->vm_start; unsigned long usize = vma->vm_end - vma->vm_start; @@ -110752,7 +110801,7 @@ index f34ffd0..4b76d56 100644 if ((PAGE_SIZE-1) & (unsigned long)addr) return -EINVAL; -@@ -2250,8 +2316,8 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets, +@@ -2250,8 +2315,8 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets, return NULL; } @@ -110763,7 +110812,7 @@ index f34ffd0..4b76d56 100644 if (!vas || !vms) goto err_free; -@@ -2433,7 +2499,7 @@ static int s_show(struct seq_file *m, void *p) +@@ -2433,7 +2498,7 @@ static int s_show(struct seq_file *m, void *p) { struct vm_struct *v = p; @@ -110772,6 +110821,19 @@ index f34ffd0..4b76d56 100644 v->addr, v->addr + v->size, v->size); if (v->caller) { +diff --git a/mm/vmscan.c b/mm/vmscan.c +index 4649929..738db2b 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -2241,6 +2241,8 @@ static int kswapd(void *p) + balance_pgdat(pgdat, order); + } + } ++ ++ current->reclaim_state = NULL; + return 0; + } + diff --git a/mm/vmstat.c b/mm/vmstat.c index 42d76c6..5643dc4 100644 --- a/mm/vmstat.c @@ -122086,10 +122148,10 @@ index 0000000..ab28d46 +_002742_hash cciss_allocate_sg_chain_blocks 3-2 5368 _002742_hash NULL diff --git a/tools/gcc/size_overflow_plugin.c b/tools/gcc/size_overflow_plugin.c new file mode 100644 -index 0000000..244559e +index 0000000..1aa0dce --- /dev/null +++ b/tools/gcc/size_overflow_plugin.c -@@ -0,0 +1,1879 @@ +@@ -0,0 +1,1865 @@ +/* + * Copyright 2011, 2012 by Emese Revfy <re.emese@gmail.com> + * Licensed under the GPL v2, or (at your option) v3 @@ -122167,10 +122229,10 @@ index 0000000..244559e +static unsigned int handle_function(void); +static void check_size_overflow(gimple stmt, tree size_overflow_type, tree cast_rhs, tree rhs, bool before); +static tree get_size_overflow_type(gimple stmt, const_tree node); -+static tree dup_assign(struct pointer_set_t *visited, gimple oldstmt, tree size_overflow_type, tree rhs1, tree rhs2, tree __unused rhs3); ++static tree dup_assign(struct pointer_set_t *visited, gimple oldstmt, const_tree node, tree rhs1, tree rhs2, tree __unused rhs3); + +static struct plugin_info size_overflow_plugin_info = { -+ .version = "20120930beta", ++ .version = "20121113beta", + .help = "no-size-overflow\tturn off size overflow checking\n", +}; + @@ -122489,6 +122551,7 @@ index 0000000..244559e + tree type = TREE_TYPE(rhs1); + tree lhs = create_new_var(type); + ++ gcc_assert(types_compatible_p(type, TREE_TYPE(rhs2))); + assign = gimple_build_assign_with_ops(code, lhs, rhs1, rhs2); + gimple_set_lhs(assign, make_ssa_name(lhs, assign)); + @@ -122554,42 +122617,41 @@ index 0000000..244559e + return assign; +} + -+static tree cast_to_new_size_overflow_type(gimple stmt, tree new_rhs1, tree size_overflow_type, bool before) ++static tree cast_to_new_size_overflow_type(gimple stmt, tree rhs, tree size_overflow_type, bool before) +{ -+ const_gimple assign; ++ gimple assign; + gimple_stmt_iterator gsi; + -+ if (new_rhs1 == NULL_TREE) ++ if (rhs == NULL_TREE) + return NULL_TREE; + -+ if (!useless_type_conversion_p(TREE_TYPE(new_rhs1), size_overflow_type)) { -+ gsi = gsi_for_stmt(stmt); -+ assign = build_cast_stmt(size_overflow_type, new_rhs1, CREATE_NEW_VAR, &gsi, before); -+ return gimple_get_lhs(assign); -+ } -+ return new_rhs1; ++ if (types_compatible_p(TREE_TYPE(rhs), size_overflow_type) && gimple_plf(stmt, MY_STMT)) ++ return rhs; ++ ++ gsi = gsi_for_stmt(stmt); ++ assign = build_cast_stmt(size_overflow_type, rhs, CREATE_NEW_VAR, &gsi, before); ++ gimple_set_plf(assign, MY_STMT, true); ++ return gimple_get_lhs(assign); +} + -+static tree follow_overflow_type_and_dup(struct pointer_set_t *visited, gimple stmt, const_tree node, tree new_rhs1, tree new_rhs2, tree new_rhs3) ++static tree cast_to_TI_type(gimple stmt, tree node) +{ -+ tree size_overflow_type = get_size_overflow_type(stmt, node); -+ -+ new_rhs1 = cast_to_new_size_overflow_type(stmt, new_rhs1, size_overflow_type, BEFORE_STMT); -+ -+ if (new_rhs2 != NULL_TREE) -+ new_rhs2 = cast_to_new_size_overflow_type(stmt, new_rhs2, size_overflow_type, BEFORE_STMT); ++ gimple_stmt_iterator gsi; ++ gimple cast_stmt; ++ tree type = TREE_TYPE(node); + -+ if (new_rhs3 != NULL_TREE) -+ new_rhs3 = cast_to_new_size_overflow_type(stmt, new_rhs3, size_overflow_type, BEFORE_STMT); ++ if (types_compatible_p(type, intTI_type_node)) ++ return node; + -+ return dup_assign(visited, stmt, size_overflow_type, new_rhs1, new_rhs2, new_rhs3); ++ gsi = gsi_for_stmt(stmt); ++ cast_stmt = build_cast_stmt(intTI_type_node, node, CREATE_NEW_VAR, &gsi, BEFORE_STMT); ++ gimple_set_plf(cast_stmt, MY_STMT, true); ++ return gimple_get_lhs(cast_stmt); +} + -+ +static tree create_assign(struct pointer_set_t *visited, gimple oldstmt, tree rhs1, bool before) +{ -+ tree size_overflow_type, lhs; -+ gimple stmt; ++ tree lhs; + gimple_stmt_iterator gsi; + + if (rhs1 == NULL_TREE) { @@ -122627,18 +122689,14 @@ index 0000000..244559e + oldstmt = gsi_stmt(gsi); + } + -+ size_overflow_type = get_size_overflow_type(oldstmt, lhs); -+ -+ stmt = build_cast_stmt(size_overflow_type, rhs1, CREATE_NEW_VAR, &gsi, before); -+ gimple_set_plf(stmt, MY_STMT, true); -+ return gimple_get_lhs(stmt); ++ return cast_to_new_size_overflow_type(oldstmt, rhs1, get_size_overflow_type(oldstmt, lhs), before); +} + -+static tree dup_assign(struct pointer_set_t *visited, gimple oldstmt, tree size_overflow_type, tree rhs1, tree rhs2, tree __unused rhs3) ++static tree dup_assign(struct pointer_set_t *visited, gimple oldstmt, const_tree node, tree rhs1, tree rhs2, tree __unused rhs3) +{ + gimple stmt; + gimple_stmt_iterator gsi; -+ tree new_var, lhs = gimple_get_lhs(oldstmt); ++ tree size_overflow_type, new_var, lhs = gimple_get_lhs(oldstmt); + + if (gimple_plf(oldstmt, MY_STMT)) + return lhs; @@ -122659,6 +122717,8 @@ index 0000000..244559e + if (gimple_assign_rhs_code(oldstmt) == WIDEN_MULT_EXPR) + gimple_assign_set_rhs_code(stmt, MULT_EXPR); + ++ size_overflow_type = get_size_overflow_type(oldstmt, node); ++ + if (is_bool(lhs)) + new_var = SSA_NAME_VAR(lhs); + else @@ -122667,7 +122727,7 @@ index 0000000..244559e + gimple_set_lhs(stmt, new_var); + + if (rhs1 != NULL_TREE) { -+ if (!gimple_assign_cast_p(oldstmt)) ++ if (!gimple_assign_cast_p(oldstmt) && TREE_CODE_CLASS(gimple_assign_rhs_code(oldstmt)) != tcc_comparison) + rhs1 = cast_a_tree(size_overflow_type, rhs1); + gimple_assign_set_rhs1(stmt, rhs1); + } @@ -122919,7 +122979,7 @@ index 0000000..244559e + return lhs; + + if (gimple_plf(stmt, NO_CAST_CHECK)) -+ return follow_overflow_type_and_dup(visited, stmt, rhs1, new_rhs1, NULL_TREE, NULL_TREE); ++ return dup_assign(visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); + + if (gimple_assign_rhs_code(stmt) == BIT_NOT_EXPR) { + size_overflow_type = get_size_overflow_type(stmt, rhs1); @@ -122929,7 +122989,7 @@ index 0000000..244559e + } + + if (!gimple_assign_cast_p(stmt) || check_undefined_integer_operation(stmt)) -+ return follow_overflow_type_and_dup(visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); ++ return dup_assign(visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); + + size_overflow_type = get_size_overflow_type(stmt, rhs1); + new_rhs1 = cast_to_new_size_overflow_type(stmt, new_rhs1, size_overflow_type, BEFORE_STMT); @@ -123114,8 +123174,8 @@ index 0000000..244559e + cast_rhs_type = TREE_TYPE(cast_rhs); + type_max_type = TREE_TYPE(type_max); + type_min_type = TREE_TYPE(type_min); -+ gcc_assert(useless_type_conversion_p(cast_rhs_type, type_max_type)); -+ gcc_assert(useless_type_conversion_p(type_max_type, type_min_type)); ++ gcc_assert(types_compatible_p(cast_rhs_type, type_max_type)); ++ gcc_assert(types_compatible_p(type_max_type, type_min_type)); + + insert_check_size_overflow(stmt, GT_EXPR, cast_rhs, type_max, before, false); + insert_check_size_overflow(stmt, LT_EXPR, cast_rhs, type_min, before, true); @@ -123143,7 +123203,7 @@ index 0000000..244559e + if (gimple_assign_rhs_code(def_stmt) == RSHIFT_EXPR) + return get_size_overflow_type(change_rhs_def_stmt, change_rhs); + -+ if (!useless_type_conversion_p(lhs_type, rhs1_type) || !useless_type_conversion_p(rhs1_type, rhs2_type)) { ++ if (!types_compatible_p(lhs_type, rhs1_type) || !useless_type_conversion_p(rhs1_type, rhs2_type)) { + debug_gimple_stmt(def_stmt); + gcc_unreachable(); + } @@ -123160,64 +123220,20 @@ index 0000000..244559e + return true; +} + -+static tree get_cast_def_stmt_rhs(const_tree new_rhs) -+{ -+ gimple def_stmt; -+ -+ def_stmt = get_def_stmt(new_rhs); -+ // get_size_overflow_type -+ if (LONG_TYPE_SIZE != GET_MODE_BITSIZE(SImode)) -+ gcc_assert(gimple_assign_cast_p(def_stmt)); -+ return gimple_assign_rhs1(def_stmt); -+} -+ -+static tree cast_to_int_TI_type_and_check(gimple stmt, tree new_rhs) -+{ -+ gimple_stmt_iterator gsi; -+ const_gimple cast_stmt; -+ gimple def_stmt; -+ enum machine_mode mode = TYPE_MODE(TREE_TYPE(new_rhs)); -+ -+ if (mode != TImode && mode != DImode) { -+ def_stmt = get_def_stmt(new_rhs); -+ gcc_assert(gimple_assign_cast_p(def_stmt)); -+ new_rhs = gimple_assign_rhs1(def_stmt); -+ mode = TYPE_MODE(TREE_TYPE(new_rhs)); -+ } -+ -+ gcc_assert(mode == TImode || mode == DImode); -+ -+ if (mode == TYPE_MODE(intTI_type_node) && useless_type_conversion_p(TREE_TYPE(new_rhs), intTI_type_node)) -+ return new_rhs; -+ -+ gsi = gsi_for_stmt(stmt); -+ cast_stmt = build_cast_stmt(intTI_type_node, new_rhs, CREATE_NEW_VAR, &gsi, BEFORE_STMT); -+ new_rhs = gimple_get_lhs(cast_stmt); -+ -+ if (mode == DImode) -+ return new_rhs; -+ -+ check_size_overflow(stmt, intTI_type_node, new_rhs, new_rhs, BEFORE_STMT); -+ -+ return new_rhs; -+} -+ -+static bool is_an_integer_trunction(const_gimple stmt) ++static bool is_subtraction_special(const_gimple stmt) +{ + gimple rhs1_def_stmt, rhs2_def_stmt; -+ const_tree rhs1_def_stmt_rhs1, rhs2_def_stmt_rhs1; -+ enum machine_mode rhs1_def_stmt_rhs1_mode, rhs2_def_stmt_rhs1_mode; ++ const_tree rhs1_def_stmt_rhs1, rhs2_def_stmt_rhs1, rhs1_def_stmt_lhs, rhs2_def_stmt_lhs; ++ enum machine_mode rhs1_def_stmt_rhs1_mode, rhs2_def_stmt_rhs1_mode, rhs1_def_stmt_lhs_mode, rhs2_def_stmt_lhs_mode; + const_tree rhs1 = gimple_assign_rhs1(stmt); + const_tree rhs2 = gimple_assign_rhs2(stmt); -+ enum machine_mode rhs1_mode = TYPE_MODE(TREE_TYPE(rhs1)); -+ enum machine_mode rhs2_mode = TYPE_MODE(TREE_TYPE(rhs2)); + + if (is_gimple_constant(rhs1) || is_gimple_constant(rhs2)) + return false; + + gcc_assert(TREE_CODE(rhs1) == SSA_NAME && TREE_CODE(rhs2) == SSA_NAME); + -+ if (gimple_assign_rhs_code(stmt) != MINUS_EXPR || rhs1_mode != SImode || rhs2_mode != SImode) ++ if (gimple_assign_rhs_code(stmt) != MINUS_EXPR) + return false; + + rhs1_def_stmt = get_def_stmt(rhs1); @@ -123227,9 +123243,15 @@ index 0000000..244559e + + rhs1_def_stmt_rhs1 = gimple_assign_rhs1(rhs1_def_stmt); + rhs2_def_stmt_rhs1 = gimple_assign_rhs1(rhs2_def_stmt); ++ rhs1_def_stmt_lhs = gimple_get_lhs(rhs1_def_stmt); ++ rhs2_def_stmt_lhs = gimple_get_lhs(rhs2_def_stmt); + rhs1_def_stmt_rhs1_mode = TYPE_MODE(TREE_TYPE(rhs1_def_stmt_rhs1)); + rhs2_def_stmt_rhs1_mode = TYPE_MODE(TREE_TYPE(rhs2_def_stmt_rhs1)); -+ if (rhs1_def_stmt_rhs1_mode != DImode || rhs2_def_stmt_rhs1_mode != DImode) ++ rhs1_def_stmt_lhs_mode = TYPE_MODE(TREE_TYPE(rhs1_def_stmt_lhs)); ++ rhs2_def_stmt_lhs_mode = TYPE_MODE(TREE_TYPE(rhs2_def_stmt_lhs)); ++ if (GET_MODE_BITSIZE(rhs1_def_stmt_rhs1_mode) <= GET_MODE_BITSIZE(rhs1_def_stmt_lhs_mode)) ++ return false; ++ if (GET_MODE_BITSIZE(rhs2_def_stmt_rhs1_mode) <= GET_MODE_BITSIZE(rhs2_def_stmt_lhs_mode)) + return false; + + gimple_set_plf(rhs1_def_stmt, NO_CAST_CHECK, true); @@ -123237,37 +123259,63 @@ index 0000000..244559e + return true; +} + ++static tree get_def_stmt_rhs(const_tree var) ++{ ++ tree rhs1, def_stmt_rhs1; ++ gimple rhs1_def_stmt, def_stmt_rhs1_def_stmt, def_stmt; ++ ++ def_stmt = get_def_stmt(var); ++ gcc_assert(gimple_code(def_stmt) != GIMPLE_NOP && gimple_plf(def_stmt, MY_STMT) && gimple_assign_cast_p(def_stmt)); ++ ++ rhs1 = gimple_assign_rhs1(def_stmt); ++ rhs1_def_stmt = get_def_stmt(rhs1); ++ gcc_assert(gimple_code(rhs1_def_stmt) != GIMPLE_NOP); ++ if (!gimple_assign_cast_p(rhs1_def_stmt)) ++ return rhs1; ++ ++ def_stmt_rhs1 = gimple_assign_rhs1(rhs1_def_stmt); ++ def_stmt_rhs1_def_stmt = get_def_stmt(def_stmt_rhs1); ++ ++ switch (gimple_code(def_stmt_rhs1_def_stmt)) { ++ case GIMPLE_CALL: ++ case GIMPLE_NOP: ++ case GIMPLE_ASM: ++ return def_stmt_rhs1; ++ case GIMPLE_ASSIGN: ++ return rhs1; ++ default: ++ debug_gimple_stmt(def_stmt_rhs1_def_stmt); ++ gcc_unreachable(); ++ } ++} ++ +static tree handle_integer_truncation(struct pointer_set_t *visited, const_tree lhs) +{ + tree new_rhs1, new_rhs2; + tree new_rhs1_def_stmt_rhs1, new_rhs2_def_stmt_rhs1, new_lhs; -+ tree new_rhs1_def_stmt_rhs1_type, new_rhs2_def_stmt_rhs1_type; + gimple assign, stmt = get_def_stmt(lhs); + tree rhs1 = gimple_assign_rhs1(stmt); + tree rhs2 = gimple_assign_rhs2(stmt); + -+ if (!is_an_integer_trunction(stmt)) ++ if (!is_subtraction_special(stmt)) + return NULL_TREE; + + new_rhs1 = expand(visited, rhs1); + new_rhs2 = expand(visited, rhs2); + -+ new_rhs1_def_stmt_rhs1 = get_cast_def_stmt_rhs(new_rhs1); -+ new_rhs2_def_stmt_rhs1 = get_cast_def_stmt_rhs(new_rhs2); -+ -+ new_rhs1_def_stmt_rhs1_type = TREE_TYPE(new_rhs1_def_stmt_rhs1); -+ new_rhs2_def_stmt_rhs1_type = TREE_TYPE(new_rhs2_def_stmt_rhs1); ++ new_rhs1_def_stmt_rhs1 = get_def_stmt_rhs(new_rhs1); ++ new_rhs2_def_stmt_rhs1 = get_def_stmt_rhs(new_rhs2); + -+ if (!useless_type_conversion_p(new_rhs1_def_stmt_rhs1_type, new_rhs2_def_stmt_rhs1_type)) { -+ new_rhs1_def_stmt_rhs1 = cast_to_int_TI_type_and_check(stmt, new_rhs1_def_stmt_rhs1); -+ new_rhs2_def_stmt_rhs1 = cast_to_int_TI_type_and_check(stmt, new_rhs2_def_stmt_rhs1); ++ if (!types_compatible_p(TREE_TYPE(new_rhs1_def_stmt_rhs1), TREE_TYPE(new_rhs2_def_stmt_rhs1))) { ++ new_rhs1_def_stmt_rhs1 = cast_to_TI_type(stmt, new_rhs1_def_stmt_rhs1); ++ new_rhs2_def_stmt_rhs1 = cast_to_TI_type(stmt, new_rhs2_def_stmt_rhs1); + } + + assign = create_binary_assign(MINUS_EXPR, stmt, new_rhs1_def_stmt_rhs1, new_rhs2_def_stmt_rhs1); + new_lhs = gimple_get_lhs(assign); + check_size_overflow(assign, TREE_TYPE(new_lhs), new_lhs, rhs1, AFTER_STMT); + -+ return follow_overflow_type_and_dup(visited, stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); ++ return dup_assign(visited, stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); +} + +static bool is_a_neg_overflow(const_gimple stmt, const_tree rhs) @@ -123370,7 +123418,7 @@ index 0000000..244559e + if (is_a_constant_overflow(def_stmt, rhs1)) + return handle_intentional_overflow(visited, !is_a_cast_and_const_overflow(rhs2), def_stmt, new_rhs2, NULL_TREE, new_rhs2); + -+ return follow_overflow_type_and_dup(visited, def_stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); ++ return dup_assign(visited, def_stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); +} + +#if BUILDING_GCC_VERSION >= 4007 @@ -123397,7 +123445,7 @@ index 0000000..244559e + new_rhs2 = get_new_rhs(visited, size_overflow_type, rhs2); + new_rhs3 = get_new_rhs(visited, size_overflow_type, rhs3); + -+ return follow_overflow_type_and_dup(visited, def_stmt, lhs, new_rhs1, new_rhs2, new_rhs3); ++ return dup_assign(visited, def_stmt, lhs, new_rhs1, new_rhs2, new_rhs3); +} +#endif + diff --git a/3.2.33/0000_README b/3.2.34/0000_README index c03c7c6..0896e71 100644 --- a/3.2.33/0000_README +++ b/3.2.34/0000_README @@ -50,7 +50,11 @@ Patch: 1032_linux-3.2.33.patch From: http://www.kernel.org Desc: Linux 3.2.33 -Patch: 4420_grsecurity-2.9.1-3.2.33-201211122213.patch +Patch: 1033_linux-3.2.34.patch +From: http://www.kernel.org +Desc: Linux 3.2.34 + +Patch: 4420_grsecurity-2.9.1-3.2.34-201211181104.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.2.33/1021_linux-3.2.22.patch b/3.2.34/1021_linux-3.2.22.patch index e6ad93a..e6ad93a 100644 --- a/3.2.33/1021_linux-3.2.22.patch +++ b/3.2.34/1021_linux-3.2.22.patch diff --git a/3.2.33/1022_linux-3.2.23.patch b/3.2.34/1022_linux-3.2.23.patch index 3d796d0..3d796d0 100644 --- a/3.2.33/1022_linux-3.2.23.patch +++ b/3.2.34/1022_linux-3.2.23.patch diff --git a/3.2.33/1023_linux-3.2.24.patch b/3.2.34/1023_linux-3.2.24.patch index 4692eb4..4692eb4 100644 --- a/3.2.33/1023_linux-3.2.24.patch +++ b/3.2.34/1023_linux-3.2.24.patch diff --git a/3.2.33/1024_linux-3.2.25.patch b/3.2.34/1024_linux-3.2.25.patch index e95c213..e95c213 100644 --- a/3.2.33/1024_linux-3.2.25.patch +++ b/3.2.34/1024_linux-3.2.25.patch diff --git a/3.2.33/1025_linux-3.2.26.patch b/3.2.34/1025_linux-3.2.26.patch index 44065b9..44065b9 100644 --- a/3.2.33/1025_linux-3.2.26.patch +++ b/3.2.34/1025_linux-3.2.26.patch diff --git a/3.2.33/1026_linux-3.2.27.patch b/3.2.34/1026_linux-3.2.27.patch index 5878eb4..5878eb4 100644 --- a/3.2.33/1026_linux-3.2.27.patch +++ b/3.2.34/1026_linux-3.2.27.patch diff --git a/3.2.33/1027_linux-3.2.28.patch b/3.2.34/1027_linux-3.2.28.patch index 4dbba4b..4dbba4b 100644 --- a/3.2.33/1027_linux-3.2.28.patch +++ b/3.2.34/1027_linux-3.2.28.patch diff --git a/3.2.33/1028_linux-3.2.29.patch b/3.2.34/1028_linux-3.2.29.patch index 3c65179..3c65179 100644 --- a/3.2.33/1028_linux-3.2.29.patch +++ b/3.2.34/1028_linux-3.2.29.patch diff --git a/3.2.33/1029_linux-3.2.30.patch b/3.2.34/1029_linux-3.2.30.patch index 86aea4b..86aea4b 100644 --- a/3.2.33/1029_linux-3.2.30.patch +++ b/3.2.34/1029_linux-3.2.30.patch diff --git a/3.2.33/1030_linux-3.2.31.patch b/3.2.34/1030_linux-3.2.31.patch index c6accf5..c6accf5 100644 --- a/3.2.33/1030_linux-3.2.31.patch +++ b/3.2.34/1030_linux-3.2.31.patch diff --git a/3.2.33/1031_linux-3.2.32.patch b/3.2.34/1031_linux-3.2.32.patch index 247fc0b..247fc0b 100644 --- a/3.2.33/1031_linux-3.2.32.patch +++ b/3.2.34/1031_linux-3.2.32.patch diff --git a/3.2.33/1032_linux-3.2.33.patch b/3.2.34/1032_linux-3.2.33.patch index c32fb75..c32fb75 100644 --- a/3.2.33/1032_linux-3.2.33.patch +++ b/3.2.34/1032_linux-3.2.33.patch diff --git a/3.2.34/1033_linux-3.2.34.patch b/3.2.34/1033_linux-3.2.34.patch new file mode 100644 index 0000000..d647b38 --- /dev/null +++ b/3.2.34/1033_linux-3.2.34.patch @@ -0,0 +1,3678 @@ +diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt +index 3d84912..47c4ec2 100644 +--- a/Documentation/feature-removal-schedule.txt ++++ b/Documentation/feature-removal-schedule.txt +@@ -6,14 +6,6 @@ be removed from this file. + + --------------------------- + +-What: x86 floppy disable_hlt +-When: 2012 +-Why: ancient workaround of dubious utility clutters the +- code used by everybody else. +-Who: Len Brown <len.brown@intel.com> +- +---------------------------- +- + What: CONFIG_APM_CPU_IDLE, and its ability to call APM BIOS in idle + When: 2012 + Why: This optional sub-feature of APM is of dubious reliability, +diff --git a/Makefile b/Makefile +index 63ca1ea2..14ebacf 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 2 +-SUBLEVEL = 33 ++SUBLEVEL = 34 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c +index 143eebb..929fd91 100644 +--- a/arch/arm/mach-at91/at91rm9200_devices.c ++++ b/arch/arm/mach-at91/at91rm9200_devices.c +@@ -462,7 +462,7 @@ static struct i2c_gpio_platform_data pdata = { + + static struct platform_device at91rm9200_twi_device = { + .name = "i2c-gpio", +- .id = -1, ++ .id = 0, + .dev.platform_data = &pdata, + }; + +diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c +index 2590988..465e026 100644 +--- a/arch/arm/mach-at91/at91sam9260_devices.c ++++ b/arch/arm/mach-at91/at91sam9260_devices.c +@@ -467,7 +467,7 @@ static struct i2c_gpio_platform_data pdata = { + + static struct platform_device at91sam9260_twi_device = { + .name = "i2c-gpio", +- .id = -1, ++ .id = 0, + .dev.platform_data = &pdata, + }; + +diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c +index daf3e66..d6d1e76 100644 +--- a/arch/arm/mach-at91/at91sam9261_devices.c ++++ b/arch/arm/mach-at91/at91sam9261_devices.c +@@ -284,7 +284,7 @@ static struct i2c_gpio_platform_data pdata = { + + static struct platform_device at91sam9261_twi_device = { + .name = "i2c-gpio", +- .id = -1, ++ .id = 0, + .dev.platform_data = &pdata, + }; + +diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c +index 32a7e43..e051376e 100644 +--- a/arch/arm/mach-at91/at91sam9263_devices.c ++++ b/arch/arm/mach-at91/at91sam9263_devices.c +@@ -540,7 +540,7 @@ static struct i2c_gpio_platform_data pdata = { + + static struct platform_device at91sam9263_twi_device = { + .name = "i2c-gpio", +- .id = -1, ++ .id = 0, + .dev.platform_data = &pdata, + }; + +diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c +index 628eb56..4862b23 100644 +--- a/arch/arm/mach-at91/at91sam9rl_devices.c ++++ b/arch/arm/mach-at91/at91sam9rl_devices.c +@@ -319,7 +319,7 @@ static struct i2c_gpio_platform_data pdata = { + + static struct platform_device at91sam9rl_twi_device = { + .name = "i2c-gpio", +- .id = -1, ++ .id = 0, + .dev.platform_data = &pdata, + }; + +diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c +index f5bbe0ef..0d264bf 100644 +--- a/arch/arm/mach-at91/setup.c ++++ b/arch/arm/mach-at91/setup.c +@@ -163,7 +163,7 @@ static void __init soc_detect(u32 dbgu_base) + } + + /* at91sam9g10 */ +- if ((cidr & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) { ++ if ((socid & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) { + at91_soc_initdata.type = AT91_SOC_SAM9G10; + at91_boot_soc = at91sam9261_soc; + } +diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h +index 2d2f01c..d75adff 100644 +--- a/arch/x86/include/asm/system.h ++++ b/arch/x86/include/asm/system.h +@@ -93,10 +93,6 @@ do { \ + "memory"); \ + } while (0) + +-/* +- * disable hlt during certain critical i/o operations +- */ +-#define HAVE_DISABLE_HLT + #else + + /* frame pointer must be last for get_wchan */ +@@ -392,9 +388,6 @@ static inline void clflush(volatile void *__p) + + #define nop() asm volatile ("nop") + +-void disable_hlt(void); +-void enable_hlt(void); +- + void cpu_idle_wait(void); + + extern unsigned long arch_align_stack(unsigned long sp); +diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c +index ee5d4fb..59b9b37 100644 +--- a/arch/x86/kernel/process.c ++++ b/arch/x86/kernel/process.c +@@ -341,34 +341,10 @@ void (*pm_idle)(void); + EXPORT_SYMBOL(pm_idle); + #endif + +-#ifdef CONFIG_X86_32 +-/* +- * This halt magic was a workaround for ancient floppy DMA +- * wreckage. It should be safe to remove. +- */ +-static int hlt_counter; +-void disable_hlt(void) +-{ +- hlt_counter++; +-} +-EXPORT_SYMBOL(disable_hlt); +- +-void enable_hlt(void) +-{ +- hlt_counter--; +-} +-EXPORT_SYMBOL(enable_hlt); +- +-static inline int hlt_use_halt(void) +-{ +- return (!hlt_counter && boot_cpu_data.hlt_works_ok); +-} +-#else + static inline int hlt_use_halt(void) + { + return 1; + } +-#endif + + /* + * We use this if we don't have any better +diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c +index ec3d603..2b8b0de 100644 +--- a/arch/x86/xen/mmu.c ++++ b/arch/x86/xen/mmu.c +@@ -1203,6 +1203,25 @@ unsigned long xen_read_cr2_direct(void) + return percpu_read(xen_vcpu_info.arch.cr2); + } + ++void xen_flush_tlb_all(void) ++{ ++ struct mmuext_op *op; ++ struct multicall_space mcs; ++ ++ trace_xen_mmu_flush_tlb_all(0); ++ ++ preempt_disable(); ++ ++ mcs = xen_mc_entry(sizeof(*op)); ++ ++ op = mcs.args; ++ op->cmd = MMUEXT_TLB_FLUSH_ALL; ++ MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); ++ ++ xen_mc_issue(PARAVIRT_LAZY_MMU); ++ ++ preempt_enable(); ++} + static void xen_flush_tlb(void) + { + struct mmuext_op *op; +@@ -2366,7 +2385,7 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma, + err = 0; + out: + +- flush_tlb_all(); ++ xen_flush_tlb_all(); + + return err; + } +diff --git a/crypto/cryptd.c b/crypto/cryptd.c +index 671d4d6..7bdd61b 100644 +--- a/crypto/cryptd.c ++++ b/crypto/cryptd.c +@@ -137,13 +137,18 @@ static void cryptd_queue_worker(struct work_struct *work) + struct crypto_async_request *req, *backlog; + + cpu_queue = container_of(work, struct cryptd_cpu_queue, work); +- /* Only handle one request at a time to avoid hogging crypto +- * workqueue. preempt_disable/enable is used to prevent +- * being preempted by cryptd_enqueue_request() */ ++ /* ++ * Only handle one request at a time to avoid hogging crypto workqueue. ++ * preempt_disable/enable is used to prevent being preempted by ++ * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent ++ * cryptd_enqueue_request() being accessed from software interrupts. ++ */ ++ local_bh_disable(); + preempt_disable(); + backlog = crypto_get_backlog(&cpu_queue->queue); + req = crypto_dequeue_request(&cpu_queue->queue); + preempt_enable(); ++ local_bh_enable(); + + if (!req) + return; +diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c +index c864add..7a90d4a 100644 +--- a/drivers/block/floppy.c ++++ b/drivers/block/floppy.c +@@ -1032,37 +1032,6 @@ static int fd_wait_for_completion(unsigned long delay, timeout_fn function) + return 0; + } + +-static DEFINE_SPINLOCK(floppy_hlt_lock); +-static int hlt_disabled; +-static void floppy_disable_hlt(void) +-{ +- unsigned long flags; +- +- WARN_ONCE(1, "floppy_disable_hlt() scheduled for removal in 2012"); +- spin_lock_irqsave(&floppy_hlt_lock, flags); +- if (!hlt_disabled) { +- hlt_disabled = 1; +-#ifdef HAVE_DISABLE_HLT +- disable_hlt(); +-#endif +- } +- spin_unlock_irqrestore(&floppy_hlt_lock, flags); +-} +- +-static void floppy_enable_hlt(void) +-{ +- unsigned long flags; +- +- spin_lock_irqsave(&floppy_hlt_lock, flags); +- if (hlt_disabled) { +- hlt_disabled = 0; +-#ifdef HAVE_DISABLE_HLT +- enable_hlt(); +-#endif +- } +- spin_unlock_irqrestore(&floppy_hlt_lock, flags); +-} +- + static void setup_DMA(void) + { + unsigned long f; +@@ -1107,7 +1076,6 @@ static void setup_DMA(void) + fd_enable_dma(); + release_dma_lock(f); + #endif +- floppy_disable_hlt(); + } + + static void show_floppy(void); +@@ -1709,7 +1677,6 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id) + fd_disable_dma(); + release_dma_lock(f); + +- floppy_enable_hlt(); + do_floppy = NULL; + if (fdc >= N_FDC || FDCS->address == -1) { + /* we don't even know which FDC is the culprit */ +@@ -1858,8 +1825,6 @@ static void floppy_shutdown(unsigned long data) + show_floppy(); + cancel_activity(); + +- floppy_enable_hlt(); +- + flags = claim_dma_lock(); + fd_disable_dma(); + release_dma_lock(flags); +@@ -4198,6 +4163,7 @@ static int __init floppy_init(void) + + disks[dr]->queue = blk_init_queue(do_fd_request, &floppy_lock); + if (!disks[dr]->queue) { ++ put_disk(disks[dr]); + err = -ENOMEM; + goto out_put_disk; + } +@@ -4339,7 +4305,7 @@ static int __init floppy_init(void) + + err = platform_device_register(&floppy_device[drive]); + if (err) +- goto out_flush_work; ++ goto out_remove_drives; + + err = device_create_file(&floppy_device[drive].dev, + &dev_attr_cmos); +@@ -4357,6 +4323,15 @@ static int __init floppy_init(void) + + out_unreg_platform_dev: + platform_device_unregister(&floppy_device[drive]); ++out_remove_drives: ++ while (drive--) { ++ if ((allowed_drive_mask & (1 << drive)) && ++ fdc_state[FDC(drive)].version != FDC_NONE) { ++ del_gendisk(disks[drive]); ++ device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); ++ platform_device_unregister(&floppy_device[drive]); ++ } ++ } + out_flush_work: + flush_work_sync(&floppy_work); + if (atomic_read(&usage_count)) +@@ -4510,7 +4485,6 @@ static void floppy_release_irq_and_dma(void) + #if N_FDC > 1 + set_dor(1, ~8, 0); + #endif +- floppy_enable_hlt(); + + if (floppy_track_buffer && max_buffer_sectors) { + tmpsize = max_buffer_sectors * 1024; +diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c +index c593bd4..edff410 100644 +--- a/drivers/gpio/gpio-timberdale.c ++++ b/drivers/gpio/gpio-timberdale.c +@@ -116,7 +116,7 @@ static void timbgpio_irq_disable(struct irq_data *d) + unsigned long flags; + + spin_lock_irqsave(&tgpio->lock, flags); +- tgpio->last_ier &= ~(1 << offset); ++ tgpio->last_ier &= ~(1UL << offset); + iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); + spin_unlock_irqrestore(&tgpio->lock, flags); + } +@@ -128,7 +128,7 @@ static void timbgpio_irq_enable(struct irq_data *d) + unsigned long flags; + + spin_lock_irqsave(&tgpio->lock, flags); +- tgpio->last_ier |= 1 << offset; ++ tgpio->last_ier |= 1UL << offset; + iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); + spin_unlock_irqrestore(&tgpio->lock, flags); + } +diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c +index 828bf65..020b103 100644 +--- a/drivers/gpu/drm/drm_fops.c ++++ b/drivers/gpu/drm/drm_fops.c +@@ -136,8 +136,11 @@ int drm_open(struct inode *inode, struct file *filp) + retcode = drm_open_helper(inode, filp, dev); + if (!retcode) { + atomic_inc(&dev->counts[_DRM_STAT_OPENS]); +- if (!dev->open_count++) ++ if (!dev->open_count++) { + retcode = drm_setup(dev); ++ if (retcode) ++ dev->open_count--; ++ } + } + if (!retcode) { + mutex_lock(&dev->struct_mutex); +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 83e820e..bcadf74 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -227,12 +227,12 @@ struct dip_infoframe { + uint16_t bottom_bar_start; + uint16_t left_bar_end; + uint16_t right_bar_start; +- } avi; ++ } __attribute__ ((packed)) avi; + struct { + uint8_t vn[8]; + uint8_t pd[16]; + uint8_t sdi; +- } spd; ++ } __attribute__ ((packed)) spd; + uint8_t payload[27]; + } __attribute__ ((packed)) body; + } __attribute__((packed)); +diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c +index cdf17d4..478b51f 100644 +--- a/drivers/gpu/drm/i915/intel_overlay.c ++++ b/drivers/gpu/drm/i915/intel_overlay.c +@@ -428,9 +428,17 @@ static int intel_overlay_off(struct intel_overlay *overlay) + OUT_RING(flip_addr); + OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); + /* turn overlay off */ +- OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF); +- OUT_RING(flip_addr); +- OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); ++ if (IS_I830(dev)) { ++ /* Workaround: Don't disable the overlay fully, since otherwise ++ * it dies on the next OVERLAY_ON cmd. */ ++ OUT_RING(MI_NOOP); ++ OUT_RING(MI_NOOP); ++ OUT_RING(MI_NOOP); ++ } else { ++ OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF); ++ OUT_RING(flip_addr); ++ OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); ++ } + ADVANCE_LP_RING(); + + return intel_overlay_do_wait_request(overlay, request, +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index bbf247c..3f4afba 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -868,31 +868,38 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) + } + #endif + +-static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) ++static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, ++ unsigned if_index, uint8_t tx_rate, ++ uint8_t *data, unsigned length) + { +- struct dip_infoframe avi_if = { +- .type = DIP_TYPE_AVI, +- .ver = DIP_VERSION_AVI, +- .len = DIP_LEN_AVI, +- }; +- uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; +- uint8_t set_buf_index[2] = { 1, 0 }; +- uint64_t *data = (uint64_t *)&avi_if; +- unsigned i; +- +- intel_dip_infoframe_csum(&avi_if); ++ uint8_t set_buf_index[2] = { if_index, 0 }; ++ uint8_t hbuf_size, tmp[8]; ++ int i; + + if (!intel_sdvo_set_value(intel_sdvo, + SDVO_CMD_SET_HBUF_INDEX, + set_buf_index, 2)) + return false; + +- for (i = 0; i < sizeof(avi_if); i += 8) { ++ if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO, ++ &hbuf_size, 1)) ++ return false; ++ ++ /* Buffer size is 0 based, hooray! */ ++ hbuf_size++; ++ ++ DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n", ++ if_index, length, hbuf_size); ++ ++ for (i = 0; i < hbuf_size; i += 8) { ++ memset(tmp, 0, 8); ++ if (i < length) ++ memcpy(tmp, data + i, min_t(unsigned, 8, length - i)); ++ + if (!intel_sdvo_set_value(intel_sdvo, + SDVO_CMD_SET_HBUF_DATA, +- data, 8)) ++ tmp, 8)) + return false; +- data++; + } + + return intel_sdvo_set_value(intel_sdvo, +@@ -900,6 +907,28 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) + &tx_rate, 1); + } + ++static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) ++{ ++ struct dip_infoframe avi_if = { ++ .type = DIP_TYPE_AVI, ++ .ver = DIP_VERSION_AVI, ++ .len = DIP_LEN_AVI, ++ }; ++ uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; ++ ++ intel_dip_infoframe_csum(&avi_if); ++ ++ /* sdvo spec says that the ecc is handled by the hw, and it looks like ++ * we must not send the ecc field, either. */ ++ memcpy(sdvo_data, &avi_if, 3); ++ sdvo_data[3] = avi_if.checksum; ++ memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); ++ ++ return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, ++ SDVO_HBUF_TX_VSYNC, ++ sdvo_data, sizeof(sdvo_data)); ++} ++ + static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) + { + struct intel_sdvo_tv_format format; +diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h +index 372f33b..4193c54 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo_regs.h ++++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h +@@ -708,6 +708,8 @@ struct intel_sdvo_enhancements_arg { + #define SDVO_CMD_SET_AUDIO_STAT 0x91 + #define SDVO_CMD_GET_AUDIO_STAT 0x92 + #define SDVO_CMD_SET_HBUF_INDEX 0x93 ++ #define SDVO_HBUF_INDEX_ELD 0 ++ #define SDVO_HBUF_INDEX_AVI_IF 1 + #define SDVO_CMD_GET_HBUF_INDEX 0x94 + #define SDVO_CMD_GET_HBUF_INFO 0x95 + #define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 +diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c +index 9791d13..8c084c0 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_drv.c ++++ b/drivers/gpu/drm/nouveau/nouveau_drv.c +@@ -178,8 +178,10 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) + if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) + return 0; + +- NV_INFO(dev, "Disabling fbcon acceleration...\n"); +- nouveau_fbcon_save_disable_accel(dev); ++ if (dev->mode_config.num_crtc) { ++ NV_INFO(dev, "Disabling fbcon acceleration...\n"); ++ nouveau_fbcon_save_disable_accel(dev); ++ } + + NV_INFO(dev, "Unpinning framebuffer(s)...\n"); + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { +@@ -246,10 +248,12 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) + pci_set_power_state(pdev, PCI_D3hot); + } + +- console_lock(); +- nouveau_fbcon_set_suspend(dev, 1); +- console_unlock(); +- nouveau_fbcon_restore_accel(dev); ++ if (dev->mode_config.num_crtc) { ++ console_lock(); ++ nouveau_fbcon_set_suspend(dev, 1); ++ console_unlock(); ++ nouveau_fbcon_restore_accel(dev); ++ } + return 0; + + out_abort: +@@ -275,7 +279,8 @@ nouveau_pci_resume(struct pci_dev *pdev) + if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) + return 0; + +- nouveau_fbcon_save_disable_accel(dev); ++ if (dev->mode_config.num_crtc) ++ nouveau_fbcon_save_disable_accel(dev); + + NV_INFO(dev, "We're back, enabling device...\n"); + pci_set_power_state(pdev, PCI_D0); +@@ -376,15 +381,18 @@ nouveau_pci_resume(struct pci_dev *pdev) + nv_crtc->lut.depth = 0; + } + +- console_lock(); +- nouveau_fbcon_set_suspend(dev, 0); +- console_unlock(); ++ if (dev->mode_config.num_crtc) { ++ console_lock(); ++ nouveau_fbcon_set_suspend(dev, 0); ++ console_unlock(); + +- nouveau_fbcon_zfill_all(dev); ++ nouveau_fbcon_zfill_all(dev); ++ } + + drm_helper_resume_force_mode(dev); + +- nouveau_fbcon_restore_accel(dev); ++ if (dev->mode_config.num_crtc) ++ nouveau_fbcon_restore_accel(dev); + return 0; + } + +@@ -466,9 +474,7 @@ static int __init nouveau_init(void) + #ifdef CONFIG_VGA_CONSOLE + if (vgacon_text_force()) + nouveau_modeset = 0; +- else + #endif +- nouveau_modeset = 1; + } + + if (!nouveau_modeset) +diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c +index d8831ab..01adcfb 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_state.c ++++ b/drivers/gpu/drm/nouveau/nouveau_state.c +@@ -46,6 +46,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->engine; ++ u32 pclass = dev->pdev->class >> 8; + + switch (dev_priv->chipset & 0xf0) { + case 0x00: +@@ -481,7 +482,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) + } + + /* headless mode */ +- if (nouveau_modeset == 2) { ++ if (nouveau_modeset == 2 || ++ (nouveau_modeset < 0 && pclass != PCI_CLASS_DISPLAY_VGA)) { + engine->display.early_init = nouveau_stub_init; + engine->display.late_takedown = nouveau_stub_takedown; + engine->display.create = nouveau_stub_init; +diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c +index e000455..2d6bfd0 100644 +--- a/drivers/gpu/drm/nouveau/nv04_dac.c ++++ b/drivers/gpu/drm/nouveau/nv04_dac.c +@@ -209,7 +209,7 @@ out: + NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode); + + if (blue == 0x18) { +- NV_INFO(dev, "Load detected on head A\n"); ++ NV_DEBUG(dev, "Load detected on head A\n"); + return connector_status_connected; + } + +@@ -323,7 +323,7 @@ nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) + + if (nv17_dac_sample_load(encoder) & + NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { +- NV_INFO(dev, "Load detected on output %c\n", ++ NV_DEBUG(dev, "Load detected on output %c\n", + '@' + ffs(dcb->or)); + return connector_status_connected; + } else { +@@ -398,7 +398,7 @@ static void nv04_dac_commit(struct drm_encoder *encoder) + + helper->dpms(encoder, DRM_MODE_DPMS_ON); + +- NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", ++ NV_DEBUG(dev, "Output %s is running on CRTC %d using output %c\n", + drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), + nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); + } +@@ -447,7 +447,7 @@ static void nv04_dac_dpms(struct drm_encoder *encoder, int mode) + return; + nv_encoder->last_dpms = mode; + +- NV_INFO(dev, "Setting dpms mode %d on vga encoder (output %d)\n", ++ NV_DEBUG(dev, "Setting dpms mode %d on vga encoder (output %d)\n", + mode, nv_encoder->dcb->index); + + nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); +diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c +index 12098bf..752440c 100644 +--- a/drivers/gpu/drm/nouveau/nv04_dfp.c ++++ b/drivers/gpu/drm/nouveau/nv04_dfp.c +@@ -468,7 +468,7 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) + + helper->dpms(encoder, DRM_MODE_DPMS_ON); + +- NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", ++ NV_DEBUG(dev, "Output %s is running on CRTC %d using output %c\n", + drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), + nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); + } +@@ -511,7 +511,7 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) + return; + nv_encoder->last_dpms = mode; + +- NV_INFO(dev, "Setting dpms mode %d on lvds encoder (output %d)\n", ++ NV_DEBUG(dev, "Setting dpms mode %d on lvds encoder (output %d)\n", + mode, nv_encoder->dcb->index); + + if (was_powersaving && is_powersaving_dpms(mode)) +@@ -556,7 +556,7 @@ static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode) + return; + nv_encoder->last_dpms = mode; + +- NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n", ++ NV_DEBUG(dev, "Setting dpms mode %d on tmds encoder (output %d)\n", + mode, nv_encoder->dcb->index); + + nv04_dfp_update_backlight(encoder, mode); +diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c +index 3eb605d..4de1fbe 100644 +--- a/drivers/gpu/drm/nouveau/nv04_tv.c ++++ b/drivers/gpu/drm/nouveau/nv04_tv.c +@@ -69,7 +69,7 @@ static void nv04_tv_dpms(struct drm_encoder *encoder, int mode) + struct nv04_mode_state *state = &dev_priv->mode_reg; + uint8_t crtc1A; + +- NV_INFO(dev, "Setting dpms mode %d on TV encoder (output %d)\n", ++ NV_DEBUG(dev, "Setting dpms mode %d on TV encoder (output %d)\n", + mode, nv_encoder->dcb->index); + + state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK); +@@ -162,7 +162,7 @@ static void nv04_tv_commit(struct drm_encoder *encoder) + + helper->dpms(encoder, DRM_MODE_DPMS_ON); + +- NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", ++ NV_DEBUG(dev, "Output %s is running on CRTC %d using output %c\n", + drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, + '@' + ffs(nv_encoder->dcb->or)); + } +diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c +index b61f490..ca94e23 100644 +--- a/drivers/gpu/drm/radeon/evergreen.c ++++ b/drivers/gpu/drm/radeon/evergreen.c +@@ -1164,7 +1164,7 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s + WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN); + + for (i = 0; i < rdev->num_crtc; i++) { +- if (save->crtc_enabled) { ++ if (save->crtc_enabled[i]) { + tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); + tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; + WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp); +diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +index 3ad3cc6..8165953 100644 +--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c ++++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +@@ -650,6 +650,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc + tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN; + WREG32(RADEON_DAC_CNTL, tmp); + ++ tmp = dac_macro_cntl; + tmp &= ~(RADEON_DAC_PDWN_R | + RADEON_DAC_PDWN_G | + RADEON_DAC_PDWN_B); +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c +index 3fa884d..27151f7 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c +@@ -306,7 +306,7 @@ void vmw_bo_pin(struct ttm_buffer_object *bo, bool pin) + + BUG_ON(!atomic_read(&bo->reserved)); + BUG_ON(old_mem_type != TTM_PL_VRAM && +- old_mem_type != VMW_PL_FLAG_GMR); ++ old_mem_type != VMW_PL_GMR); + + pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED; + if (pin) +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +index 033fc96..b639536 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +@@ -1048,6 +1048,11 @@ static void vmw_pm_complete(struct device *kdev) + struct drm_device *dev = pci_get_drvdata(pdev); + struct vmw_private *dev_priv = vmw_priv(dev); + ++ mutex_lock(&dev_priv->hw_mutex); ++ vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); ++ (void) vmw_read(dev_priv, SVGA_REG_ID); ++ mutex_unlock(&dev_priv->hw_mutex); ++ + /** + * Reclaim 3d reference held by fbdev and potentially + * start fifo. +diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c +index e5c699b..3899989 100644 +--- a/drivers/hid/hid-microsoft.c ++++ b/drivers/hid/hid-microsoft.c +@@ -29,22 +29,30 @@ + #define MS_RDESC 0x08 + #define MS_NOGET 0x10 + #define MS_DUPLICATE_USAGES 0x20 ++#define MS_RDESC_3K 0x40 + +-/* +- * Microsoft Wireless Desktop Receiver (Model 1028) has +- * 'Usage Min/Max' where it ought to have 'Physical Min/Max' +- */ + static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, + unsigned int *rsize) + { + unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); + ++ /* ++ * Microsoft Wireless Desktop Receiver (Model 1028) has ++ * 'Usage Min/Max' where it ought to have 'Physical Min/Max' ++ */ + if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 && + rdesc[559] == 0x29) { + hid_info(hdev, "fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n"); + rdesc[557] = 0x35; + rdesc[559] = 0x45; + } ++ /* the same as above (s/usage/physical/) */ ++ if ((quirks & MS_RDESC_3K) && *rsize == 106 && ++ !memcmp((char []){ 0x19, 0x00, 0x29, 0xff }, ++ &rdesc[94], 4)) { ++ rdesc[94] = 0x35; ++ rdesc[96] = 0x45; ++ } + return rdesc; + } + +@@ -193,7 +201,7 @@ static const struct hid_device_id ms_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB), + .driver_data = MS_PRESENTER }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K), +- .driver_data = MS_ERGONOMY }, ++ .driver_data = MS_ERGONOMY | MS_RDESC_3K }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0), + .driver_data = MS_NOGET }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), +diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c +index ceaec92..b6a3ce3 100644 +--- a/drivers/hwmon/w83627ehf.c ++++ b/drivers/hwmon/w83627ehf.c +@@ -2015,6 +2015,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) + mutex_init(&data->lock); + mutex_init(&data->update_lock); + data->name = w83627ehf_device_names[sio_data->kind]; ++ data->bank = 0xff; /* Force initial bank selection */ + platform_set_drvdata(pdev, data); + + /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */ +diff --git a/drivers/input/touchscreen/tsc40.c b/drivers/input/touchscreen/tsc40.c +index 29d5ed4..80d4610 100644 +--- a/drivers/input/touchscreen/tsc40.c ++++ b/drivers/input/touchscreen/tsc40.c +@@ -107,7 +107,6 @@ static int tsc_connect(struct serio *serio, struct serio_driver *drv) + __set_bit(BTN_TOUCH, input_dev->keybit); + input_set_abs_params(ptsc->dev, ABS_X, 0, 0x3ff, 0, 0); + input_set_abs_params(ptsc->dev, ABS_Y, 0, 0x3ff, 0, 0); +- input_set_abs_params(ptsc->dev, ABS_PRESSURE, 0, 0, 0, 0); + + serio_set_drvdata(serio, ptsc); + +diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c +index 11ddd838..69fc888 100644 +--- a/drivers/net/ethernet/marvell/sky2.c ++++ b/drivers/net/ethernet/marvell/sky2.c +@@ -3060,8 +3060,10 @@ static irqreturn_t sky2_intr(int irq, void *dev_id) + + /* Reading this mask interrupts as side effect */ + status = sky2_read32(hw, B0_Y2_SP_ISRC2); +- if (status == 0 || status == ~0) ++ if (status == 0 || status == ~0) { ++ sky2_write32(hw, B0_Y2_SP_ICR, 2); + return IRQ_NONE; ++ } + + prefetch(&hw->st_le[hw->st_idx]); + +diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c +index 4b43bc5..b8db4cd 100644 +--- a/drivers/net/ethernet/realtek/r8169.c ++++ b/drivers/net/ethernet/realtek/r8169.c +@@ -77,7 +77,7 @@ static const int multicast_filter_limit = 32; + #define MAC_ADDR_LEN 6 + + #define MAX_READ_REQUEST_SHIFT 12 +-#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ ++#define TX_DMA_BURST 7 /* Maximum PCI burst, '7' is unlimited */ + #define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */ + #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ + +@@ -3521,6 +3521,8 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) + void __iomem *ioaddr = tp->mmio_addr; + + switch (tp->mac_version) { ++ case RTL_GIGA_MAC_VER_25: ++ case RTL_GIGA_MAC_VER_26: + case RTL_GIGA_MAC_VER_29: + case RTL_GIGA_MAC_VER_30: + case RTL_GIGA_MAC_VER_32: +@@ -6064,6 +6066,9 @@ static void rtl_set_rx_mode(struct net_device *dev) + mc_filter[1] = swab32(data); + } + ++ if (tp->mac_version == RTL_GIGA_MAC_VER_35) ++ mc_filter[1] = mc_filter[0] = 0xffffffff; ++ + RTL_W32(MAR0 + 4, mc_filter[1]); + RTL_W32(MAR0 + 0, mc_filter[0]); + +diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c +index b873b5d..dc53a8f 100644 +--- a/drivers/net/usb/usbnet.c ++++ b/drivers/net/usb/usbnet.c +@@ -1156,6 +1156,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, + usb_anchor_urb(urb, &dev->deferred); + /* no use to process more packets */ + netif_stop_queue(net); ++ usb_put_urb(urb); + spin_unlock_irqrestore(&dev->txq.lock, flags); + netdev_dbg(dev->net, "Delaying transmission for resumption\n"); + goto deferred; +@@ -1297,6 +1298,8 @@ void usbnet_disconnect (struct usb_interface *intf) + + cancel_work_sync(&dev->kevent); + ++ usb_scuttle_anchored_urbs(&dev->deferred); ++ + if (dev->driver_info->unbind) + dev->driver_info->unbind (dev, intf); + +diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c +index c59c592..18da100 100644 +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -288,6 +288,7 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) + } + + bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); ++ bf->bf_next = NULL; + list_del(&bf->list); + + spin_unlock_bh(&sc->tx.txbuflock); +@@ -369,7 +370,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, + u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0; + u32 ba[WME_BA_BMP_SIZE >> 5]; + int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; +- bool rc_update = true; ++ bool rc_update = true, isba; + struct ieee80211_tx_rate rates[4]; + struct ath_frame_info *fi; + int nframes; +@@ -407,13 +408,17 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, + an = (struct ath_node *)sta->drv_priv; + tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; + tid = ATH_AN_2_TID(an, tidno); ++ isba = ts->ts_flags & ATH9K_TX_BA; + + /* + * The hardware occasionally sends a tx status for the wrong TID. + * In this case, the BA status cannot be considered valid and all + * subframes need to be retransmitted ++ * ++ * Only BlockAcks have a TID and therefore normal Acks cannot be ++ * checked + */ +- if (tidno != ts->tid) ++ if (isba && tidno != ts->tid) + txok = false; + + isaggr = bf_isaggr(bf); +@@ -1710,6 +1715,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, + if (tid) + INCR(tid->seq_start, IEEE80211_SEQ_MAX); + ++ bf->bf_next = NULL; + bf->bf_lastbf = bf; + ath_tx_fill_desc(sc, bf, txq, fi->framelen); + ath_tx_txqaddbuf(sc, txq, &bf_head, false); +diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c +index 1ba079d..fb19447 100644 +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c +@@ -2141,7 +2141,7 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev) + /* + * Check if temperature compensation is supported. + */ +- if (tssi_bounds[4] == 0xff) ++ if (tssi_bounds[4] == 0xff || step == 0xff) + return 0; + + /* +diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c +index f35cb10..6fa7222 100644 +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -3523,7 +3523,9 @@ restart: + */ + iscsit_thread_check_cpumask(conn, current, 1); + +- schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT); ++ wait_event_interruptible(conn->queues_wq, ++ !iscsit_conn_all_queues_empty(conn) || ++ ts->status == ISCSI_THREAD_SET_RESET); + + if ((ts->status == ISCSI_THREAD_SET_RESET) || + signal_pending(current)) +diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h +index dae283f..bd8ce01 100644 +--- a/drivers/target/iscsi/iscsi_target_core.h ++++ b/drivers/target/iscsi/iscsi_target_core.h +@@ -491,6 +491,7 @@ struct iscsi_tmr_req { + }; + + struct iscsi_conn { ++ wait_queue_head_t queues_wq; + /* Authentication Successful for this connection */ + u8 auth_complete; + /* State connection is currently in */ +diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c +index 2ec5339..eb0c9fe 100644 +--- a/drivers/target/iscsi/iscsi_target_login.c ++++ b/drivers/target/iscsi/iscsi_target_login.c +@@ -44,6 +44,7 @@ extern spinlock_t sess_idr_lock; + + static int iscsi_login_init_conn(struct iscsi_conn *conn) + { ++ init_waitqueue_head(&conn->queues_wq); + INIT_LIST_HEAD(&conn->conn_list); + INIT_LIST_HEAD(&conn->conn_cmd_list); + INIT_LIST_HEAD(&conn->immed_queue_list); +diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c +index 99f2af3..e612722 100644 +--- a/drivers/target/iscsi/iscsi_target_util.c ++++ b/drivers/target/iscsi/iscsi_target_util.c +@@ -659,7 +659,7 @@ void iscsit_add_cmd_to_immediate_queue( + atomic_set(&conn->check_immediate_queue, 1); + spin_unlock_bh(&conn->immed_queue_lock); + +- wake_up_process(conn->thread_set->tx_thread); ++ wake_up(&conn->queues_wq); + } + + struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *conn) +@@ -733,7 +733,7 @@ void iscsit_add_cmd_to_response_queue( + atomic_inc(&cmd->response_queue_count); + spin_unlock_bh(&conn->response_queue_lock); + +- wake_up_process(conn->thread_set->tx_thread); ++ wake_up(&conn->queues_wq); + } + + struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *conn) +@@ -787,6 +787,24 @@ static void iscsit_remove_cmd_from_response_queue( + } + } + ++bool iscsit_conn_all_queues_empty(struct iscsi_conn *conn) ++{ ++ bool empty; ++ ++ spin_lock_bh(&conn->immed_queue_lock); ++ empty = list_empty(&conn->immed_queue_list); ++ spin_unlock_bh(&conn->immed_queue_lock); ++ ++ if (!empty) ++ return empty; ++ ++ spin_lock_bh(&conn->response_queue_lock); ++ empty = list_empty(&conn->response_queue_list); ++ spin_unlock_bh(&conn->response_queue_lock); ++ ++ return empty; ++} ++ + void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn) + { + struct iscsi_queue_req *qr, *qr_tmp; +diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h +index 835bf7d..cfac698 100644 +--- a/drivers/target/iscsi/iscsi_target_util.h ++++ b/drivers/target/iscsi/iscsi_target_util.h +@@ -28,6 +28,7 @@ extern struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_ + extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8); + extern struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *); + extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_conn *); ++extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *); + extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *); + extern void iscsit_release_cmd(struct iscsi_cmd *); + extern void iscsit_free_cmd(struct iscsi_cmd *); +diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c +index 0b01bfc..013b133 100644 +--- a/drivers/target/target_core_configfs.c ++++ b/drivers/target/target_core_configfs.c +@@ -3205,7 +3205,8 @@ static int __init target_core_init_configfs(void) + if (ret < 0) + goto out; + +- if (core_dev_setup_virtual_lun0() < 0) ++ ret = core_dev_setup_virtual_lun0(); ++ if (ret < 0) + goto out; + + return 0; +diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c +index f8773ae..a0143a0 100644 +--- a/drivers/target/target_core_device.c ++++ b/drivers/target/target_core_device.c +@@ -835,20 +835,20 @@ int se_dev_check_shutdown(struct se_device *dev) + + u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) + { +- u32 tmp, aligned_max_sectors; ++ u32 aligned_max_sectors; ++ u32 alignment; + /* + * Limit max_sectors to a PAGE_SIZE aligned value for modern + * transport_allocate_data_tasks() operation. + */ +- tmp = rounddown((max_sectors * block_size), PAGE_SIZE); +- aligned_max_sectors = (tmp / block_size); +- if (max_sectors != aligned_max_sectors) { +- printk(KERN_INFO "Rounding down aligned max_sectors from %u" +- " to %u\n", max_sectors, aligned_max_sectors); +- return aligned_max_sectors; +- } ++ alignment = max(1ul, PAGE_SIZE / block_size); ++ aligned_max_sectors = rounddown(max_sectors, alignment); ++ ++ if (max_sectors != aligned_max_sectors) ++ pr_info("Rounding down aligned max_sectors from %u to %u\n", ++ max_sectors, aligned_max_sectors); + +- return max_sectors; ++ return aligned_max_sectors; + } + + void se_dev_set_default_attribs( +diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c +index d481f80..43a38aa 100644 +--- a/drivers/usb/serial/mos7840.c ++++ b/drivers/usb/serial/mos7840.c +@@ -2585,7 +2585,6 @@ error: + static void mos7840_disconnect(struct usb_serial *serial) + { + int i; +- unsigned long flags; + struct moschip_port *mos7840_port; + dbg("%s", " disconnect :entering.........."); + +diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c +index 625890c..080b186 100644 +--- a/drivers/xen/gntdev.c ++++ b/drivers/xen/gntdev.c +@@ -105,6 +105,21 @@ static void gntdev_print_maps(struct gntdev_priv *priv, + #endif + } + ++static void gntdev_free_map(struct grant_map *map) ++{ ++ if (map == NULL) ++ return; ++ ++ if (map->pages) ++ free_xenballooned_pages(map->count, map->pages); ++ kfree(map->pages); ++ kfree(map->grants); ++ kfree(map->map_ops); ++ kfree(map->unmap_ops); ++ kfree(map->kmap_ops); ++ kfree(map); ++} ++ + static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) + { + struct grant_map *add; +@@ -142,12 +157,7 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) + return add; + + err: +- kfree(add->pages); +- kfree(add->grants); +- kfree(add->map_ops); +- kfree(add->unmap_ops); +- kfree(add->kmap_ops); +- kfree(add); ++ gntdev_free_map(add); + return NULL; + } + +@@ -196,17 +206,9 @@ static void gntdev_put_map(struct grant_map *map) + if (map->notify.flags & UNMAP_NOTIFY_SEND_EVENT) + notify_remote_via_evtchn(map->notify.event); + +- if (map->pages) { +- if (!use_ptemod) +- unmap_grant_pages(map, 0, map->count); +- +- free_xenballooned_pages(map->count, map->pages); +- } +- kfree(map->pages); +- kfree(map->grants); +- kfree(map->map_ops); +- kfree(map->unmap_ops); +- kfree(map); ++ if (map->pages && !use_ptemod) ++ unmap_grant_pages(map, 0, map->count); ++ gntdev_free_map(map); + } + + /* ------------------------------------------------------------------ */ +diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c +index 72ddf23..b3522af 100644 +--- a/fs/cifs/cifsacl.c ++++ b/fs/cifs/cifsacl.c +@@ -225,6 +225,13 @@ sid_to_str(struct cifs_sid *sidptr, char *sidstr) + } + + static void ++cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src) ++{ ++ memcpy(dst, src, sizeof(*dst)); ++ dst->num_subauth = min_t(u8, src->num_subauth, NUM_SUBAUTHS); ++} ++ ++static void + id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr, + struct cifs_sid_id **psidid, char *typestr) + { +@@ -248,7 +255,7 @@ id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr, + } + } + +- memcpy(&(*psidid)->sid, sidptr, sizeof(struct cifs_sid)); ++ cifs_copy_sid(&(*psidid)->sid, sidptr); + (*psidid)->time = jiffies - (SID_MAP_RETRY + 1); + (*psidid)->refcount = 0; + +@@ -354,7 +361,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) + * any fields of the node after a reference is put . + */ + if (test_bit(SID_ID_MAPPED, &psidid->state)) { +- memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid)); ++ cifs_copy_sid(ssid, &psidid->sid); + psidid->time = jiffies; /* update ts for accessing */ + goto id_sid_out; + } +@@ -370,14 +377,14 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) + if (IS_ERR(sidkey)) { + rc = -EINVAL; + cFYI(1, "%s: Can't map and id to a SID", __func__); ++ } else if (sidkey->datalen < sizeof(struct cifs_sid)) { ++ rc = -EIO; ++ cFYI(1, "%s: Downcall contained malformed key " ++ "(datalen=%hu)", __func__, sidkey->datalen); + } else { + lsid = (struct cifs_sid *)sidkey->payload.data; +- memcpy(&psidid->sid, lsid, +- sidkey->datalen < sizeof(struct cifs_sid) ? +- sidkey->datalen : sizeof(struct cifs_sid)); +- memcpy(ssid, &psidid->sid, +- sidkey->datalen < sizeof(struct cifs_sid) ? +- sidkey->datalen : sizeof(struct cifs_sid)); ++ cifs_copy_sid(&psidid->sid, lsid); ++ cifs_copy_sid(ssid, &psidid->sid); + set_bit(SID_ID_MAPPED, &psidid->state); + key_put(sidkey); + kfree(psidid->sidstr); +@@ -396,7 +403,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) + return rc; + } + if (test_bit(SID_ID_MAPPED, &psidid->state)) +- memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid)); ++ cifs_copy_sid(ssid, &psidid->sid); + else + rc = -EINVAL; + } +@@ -674,8 +681,6 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) + static void copy_sec_desc(const struct cifs_ntsd *pntsd, + struct cifs_ntsd *pnntsd, __u32 sidsoffset) + { +- int i; +- + struct cifs_sid *owner_sid_ptr, *group_sid_ptr; + struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr; + +@@ -691,26 +696,14 @@ static void copy_sec_desc(const struct cifs_ntsd *pntsd, + owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + + le32_to_cpu(pntsd->osidoffset)); + nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset); +- +- nowner_sid_ptr->revision = owner_sid_ptr->revision; +- nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth; +- for (i = 0; i < 6; i++) +- nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i]; +- for (i = 0; i < 5; i++) +- nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i]; ++ cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr); + + /* copy group sid */ + group_sid_ptr = (struct cifs_sid *)((char *)pntsd + + le32_to_cpu(pntsd->gsidoffset)); + ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset + + sizeof(struct cifs_sid)); +- +- ngroup_sid_ptr->revision = group_sid_ptr->revision; +- ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth; +- for (i = 0; i < 6; i++) +- ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i]; +- for (i = 0; i < 5; i++) +- ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i]; ++ cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr); + + return; + } +@@ -1117,8 +1110,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, + kfree(nowner_sid_ptr); + return rc; + } +- memcpy(owner_sid_ptr, nowner_sid_ptr, +- sizeof(struct cifs_sid)); ++ cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr); + kfree(nowner_sid_ptr); + *aclflag = CIFS_ACL_OWNER; + } +@@ -1136,8 +1128,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, + kfree(ngroup_sid_ptr); + return rc; + } +- memcpy(group_sid_ptr, ngroup_sid_ptr, +- sizeof(struct cifs_sid)); ++ cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr); + kfree(ngroup_sid_ptr); + *aclflag = CIFS_ACL_GROUP; + } +diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c +index 1cfef9f..94afdfd 100644 +--- a/fs/ecryptfs/main.c ++++ b/fs/ecryptfs/main.c +@@ -280,6 +280,7 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, + char *fnek_src; + char *cipher_key_bytes_src; + char *fn_cipher_key_bytes_src; ++ u8 cipher_code; + + *check_ruid = 0; + +@@ -421,6 +422,18 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, + && !fn_cipher_key_bytes_set) + mount_crypt_stat->global_default_fn_cipher_key_bytes = + mount_crypt_stat->global_default_cipher_key_size; ++ ++ cipher_code = ecryptfs_code_for_cipher_string( ++ mount_crypt_stat->global_default_cipher_name, ++ mount_crypt_stat->global_default_cipher_key_size); ++ if (!cipher_code) { ++ ecryptfs_printk(KERN_ERR, ++ "eCryptfs doesn't support cipher: %s", ++ mount_crypt_stat->global_default_cipher_name); ++ rc = -EINVAL; ++ goto out; ++ } ++ + mutex_lock(&key_tfm_list_mutex); + if (!ecryptfs_tfm_exists(mount_crypt_stat->global_default_cipher_name, + NULL)) { +@@ -506,7 +519,6 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags + goto out; + } + +- s->s_flags = flags; + rc = bdi_setup_and_register(&sbi->bdi, "ecryptfs", BDI_CAP_MAP_COPY); + if (rc) + goto out1; +@@ -542,6 +554,15 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags + } + + ecryptfs_set_superblock_lower(s, path.dentry->d_sb); ++ ++ /** ++ * Set the POSIX ACL flag based on whether they're enabled in the lower ++ * mount. Force a read-only eCryptfs mount if the lower mount is ro. ++ * Allow a ro eCryptfs mount even when the lower mount is rw. ++ */ ++ s->s_flags = flags & ~MS_POSIXACL; ++ s->s_flags |= path.dentry->d_sb->s_flags & (MS_RDONLY | MS_POSIXACL); ++ + s->s_maxbytes = path.dentry->d_sb->s_maxbytes; + s->s_blocksize = path.dentry->d_sb->s_blocksize; + s->s_magic = ECRYPTFS_SUPER_MAGIC; +diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c +index a6e711a..ee02db5 100644 +--- a/fs/nfs/dns_resolve.c ++++ b/fs/nfs/dns_resolve.c +@@ -213,7 +213,7 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen) + { + char buf1[NFS_DNS_HOSTNAME_MAXLEN+1]; + struct nfs_dns_ent key, *item; +- unsigned long ttl; ++ unsigned int ttl; + ssize_t len; + int ret = -EINVAL; + +@@ -236,7 +236,8 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen) + key.namelen = len; + memset(&key.h, 0, sizeof(key.h)); + +- ttl = get_expiry(&buf); ++ if (get_uint(&buf, &ttl) < 0) ++ goto out; + if (ttl == 0) + goto out; + key.h.expiry_time = ttl + seconds_since_boot(); +diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h +index 68b3f20..c5af878 100644 +--- a/fs/nfs/internal.h ++++ b/fs/nfs/internal.h +@@ -274,8 +274,9 @@ extern void nfs_sb_active(struct super_block *sb); + extern void nfs_sb_deactive(struct super_block *sb); + + /* namespace.c */ ++#define NFS_PATH_CANONICAL 1 + extern char *nfs_path(char **p, struct dentry *dentry, +- char *buffer, ssize_t buflen); ++ char *buffer, ssize_t buflen, unsigned flags); + extern struct vfsmount *nfs_d_automount(struct path *path); + #ifdef CONFIG_NFS_V4 + rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *); +@@ -364,7 +365,7 @@ static inline char *nfs_devname(struct dentry *dentry, + char *buffer, ssize_t buflen) + { + char *dummy; +- return nfs_path(&dummy, dentry, buffer, buflen); ++ return nfs_path(&dummy, dentry, buffer, buflen, NFS_PATH_CANONICAL); + } + + /* +diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c +index d4c2d6b..3d93216 100644 +--- a/fs/nfs/mount_clnt.c ++++ b/fs/nfs/mount_clnt.c +@@ -181,7 +181,7 @@ int nfs_mount(struct nfs_mount_request *info) + else + msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC_MNT]; + +- status = rpc_call_sync(mnt_clnt, &msg, 0); ++ status = rpc_call_sync(mnt_clnt, &msg, RPC_TASK_SOFT|RPC_TASK_TIMEOUT); + rpc_shutdown_client(mnt_clnt); + + if (status < 0) +diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c +index 8102391..a86873e 100644 +--- a/fs/nfs/namespace.c ++++ b/fs/nfs/namespace.c +@@ -37,6 +37,7 @@ static struct vfsmount *nfs_do_submount(struct dentry *dentry, + * @dentry - pointer to dentry + * @buffer - result buffer + * @buflen - length of buffer ++ * @flags - options (see below) + * + * Helper function for constructing the server pathname + * by arbitrary hashed dentry. +@@ -44,8 +45,14 @@ static struct vfsmount *nfs_do_submount(struct dentry *dentry, + * This is mainly for use in figuring out the path on the + * server side when automounting on top of an existing partition + * and in generating /proc/mounts and friends. ++ * ++ * Supported flags: ++ * NFS_PATH_CANONICAL: ensure there is exactly one slash after ++ * the original device (export) name ++ * (if unset, the original name is returned verbatim) + */ +-char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen) ++char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen, ++ unsigned flags) + { + char *end; + int namelen; +@@ -78,7 +85,7 @@ rename_retry: + rcu_read_unlock(); + goto rename_retry; + } +- if (*end != '/') { ++ if ((flags & NFS_PATH_CANONICAL) && *end != '/') { + if (--buflen < 0) { + spin_unlock(&dentry->d_lock); + rcu_read_unlock(); +@@ -95,9 +102,11 @@ rename_retry: + return end; + } + namelen = strlen(base); +- /* Strip off excess slashes in base string */ +- while (namelen > 0 && base[namelen - 1] == '/') +- namelen--; ++ if (flags & NFS_PATH_CANONICAL) { ++ /* Strip off excess slashes in base string */ ++ while (namelen > 0 && base[namelen - 1] == '/') ++ namelen--; ++ } + buflen -= namelen; + if (buflen < 0) { + spin_unlock(&dentry->d_lock); +diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c +index bb80c49..96f2b67 100644 +--- a/fs/nfs/nfs4namespace.c ++++ b/fs/nfs/nfs4namespace.c +@@ -57,7 +57,8 @@ Elong: + static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen) + { + char *limit; +- char *path = nfs_path(&limit, dentry, buffer, buflen); ++ char *path = nfs_path(&limit, dentry, buffer, buflen, ++ NFS_PATH_CANONICAL); + if (!IS_ERR(path)) { + char *colon = strchr(path, ':'); + if (colon && colon < limit) +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 61796a40..864b831 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -303,8 +303,7 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc + dprintk("%s ERROR: %d Reset session\n", __func__, + errorcode); + nfs4_schedule_session_recovery(clp->cl_session); +- exception->retry = 1; +- break; ++ goto wait_on_recovery; + #endif /* defined(CONFIG_NFS_V4_1) */ + case -NFS4ERR_FILE_OPEN: + if (exception->timeout > HZ) { +@@ -1464,9 +1463,11 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) + data->timestamp = jiffies; + if (nfs4_setup_sequence(data->o_arg.server, + &data->o_arg.seq_args, +- &data->o_res.seq_res, 1, task)) +- return; +- rpc_call_start(task); ++ &data->o_res.seq_res, ++ 1, task) != 0) ++ nfs_release_seqid(data->o_arg.seqid); ++ else ++ rpc_call_start(task); + return; + unlock_no_action: + rcu_read_unlock(); +@@ -2046,9 +2047,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) + calldata->timestamp = jiffies; + if (nfs4_setup_sequence(NFS_SERVER(calldata->inode), + &calldata->arg.seq_args, &calldata->res.seq_res, +- 1, task)) +- return; +- rpc_call_start(task); ++ 1, task) != 0) ++ nfs_release_seqid(calldata->arg.seqid); ++ else ++ rpc_call_start(task); + } + + static const struct rpc_call_ops nfs4_close_ops = { +@@ -4148,6 +4150,7 @@ static void nfs4_locku_done(struct rpc_task *task, void *data) + if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN) + rpc_restart_call_prepare(task); + } ++ nfs_release_seqid(calldata->arg.seqid); + } + + static void nfs4_locku_prepare(struct rpc_task *task, void *data) +@@ -4164,9 +4167,11 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data) + calldata->timestamp = jiffies; + if (nfs4_setup_sequence(calldata->server, + &calldata->arg.seq_args, +- &calldata->res.seq_res, 1, task)) +- return; +- rpc_call_start(task); ++ &calldata->res.seq_res, ++ 1, task) != 0) ++ nfs_release_seqid(calldata->arg.seqid); ++ else ++ rpc_call_start(task); + } + + static const struct rpc_call_ops nfs4_locku_ops = { +@@ -4310,7 +4315,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) + /* Do we need to do an open_to_lock_owner? */ + if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) { + if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0) +- return; ++ goto out_release_lock_seqid; + data->arg.open_stateid = &state->stateid; + data->arg.new_lock_owner = 1; + data->res.open_seqid = data->arg.open_seqid; +@@ -4319,10 +4324,15 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) + data->timestamp = jiffies; + if (nfs4_setup_sequence(data->server, + &data->arg.seq_args, +- &data->res.seq_res, 1, task)) ++ &data->res.seq_res, ++ 1, task) == 0) { ++ rpc_call_start(task); + return; +- rpc_call_start(task); +- dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status); ++ } ++ nfs_release_seqid(data->arg.open_seqid); ++out_release_lock_seqid: ++ nfs_release_seqid(data->arg.lock_seqid); ++ dprintk("%s: done!, ret = %d\n", __func__, task->tk_status); + } + + static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata) +diff --git a/fs/nfs/super.c b/fs/nfs/super.c +index e42d6f6..8150344 100644 +--- a/fs/nfs/super.c ++++ b/fs/nfs/super.c +@@ -768,7 +768,7 @@ static int nfs_show_devname(struct seq_file *m, struct vfsmount *mnt) + int err = 0; + if (!page) + return -ENOMEM; +- devname = nfs_path(&dummy, mnt->mnt_root, page, PAGE_SIZE); ++ devname = nfs_path(&dummy, mnt->mnt_root, page, PAGE_SIZE, 0); + if (IS_ERR(devname)) + err = PTR_ERR(devname); + else +diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c +index 5f312ab..a0205fc 100644 +--- a/fs/nfsd/export.c ++++ b/fs/nfsd/export.c +@@ -401,7 +401,7 @@ fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc) + int migrated, i, err; + + /* listsize */ +- err = get_int(mesg, &fsloc->locations_count); ++ err = get_uint(mesg, &fsloc->locations_count); + if (err) + return err; + if (fsloc->locations_count > MAX_FS_LOCATIONS) +@@ -459,7 +459,7 @@ static int secinfo_parse(char **mesg, char *buf, struct svc_export *exp) + return -EINVAL; + + for (f = exp->ex_flavors; f < exp->ex_flavors + listsize; f++) { +- err = get_int(mesg, &f->pseudoflavor); ++ err = get_uint(mesg, &f->pseudoflavor); + if (err) + return err; + /* +@@ -468,7 +468,7 @@ static int secinfo_parse(char **mesg, char *buf, struct svc_export *exp) + * problem at export time instead of when a client fails + * to authenticate. + */ +- err = get_int(mesg, &f->flags); ++ err = get_uint(mesg, &f->flags); + if (err) + return err; + /* Only some flags are allowed to differ between flavors: */ +diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c +index f35794b..a506360 100644 +--- a/fs/notify/fanotify/fanotify.c ++++ b/fs/notify/fanotify/fanotify.c +@@ -21,6 +21,7 @@ static bool should_merge(struct fsnotify_event *old, struct fsnotify_event *new) + if ((old->path.mnt == new->path.mnt) && + (old->path.dentry == new->path.dentry)) + return true; ++ break; + case (FSNOTIFY_EVENT_NONE): + return true; + default: +diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c +index 4f5d0ce..86ca506 100644 +--- a/fs/xfs/xfs_log_recover.c ++++ b/fs/xfs/xfs_log_recover.c +@@ -3514,7 +3514,7 @@ xlog_do_recovery_pass( + * - order is important. + */ + error = xlog_bread_offset(log, 0, +- bblks - split_bblks, hbp, ++ bblks - split_bblks, dbp, + offset + BBTOB(split_bblks)); + if (error) + goto bread_err2; +diff --git a/include/linux/if_link.h b/include/linux/if_link.h +index c52d4b5..4b24ff4 100644 +--- a/include/linux/if_link.h ++++ b/include/linux/if_link.h +@@ -137,6 +137,7 @@ enum { + IFLA_AF_SPEC, + IFLA_GROUP, /* Group the device belongs to */ + IFLA_NET_NS_FD, ++ IFLA_EXT_MASK, /* Extended info mask, VFs, etc */ + __IFLA_MAX + }; + +diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h +index 8e872ea..577592e 100644 +--- a/include/linux/rtnetlink.h ++++ b/include/linux/rtnetlink.h +@@ -602,6 +602,9 @@ struct tcamsg { + #define TCA_ACT_TAB 1 /* attr type must be >=1 */ + #define TCAA_MAX 1 + ++/* New extended info filters for IFLA_EXT_MASK */ ++#define RTEXT_FILTER_VF (1 << 0) ++ + /* End of information exported to user level */ + + #ifdef __KERNEL__ +diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h +index 5efd8ce..f0c6ab5 100644 +--- a/include/linux/sunrpc/cache.h ++++ b/include/linux/sunrpc/cache.h +@@ -224,6 +224,22 @@ static inline int get_int(char **bpp, int *anint) + return 0; + } + ++static inline int get_uint(char **bpp, unsigned int *anint) ++{ ++ char buf[50]; ++ int len = qword_get(bpp, buf, sizeof(buf)); ++ ++ if (len < 0) ++ return -EINVAL; ++ if (len == 0) ++ return -ENOENT; ++ ++ if (kstrtouint(buf, 0, anint)) ++ return -EINVAL; ++ ++ return 0; ++} ++ + /* + * timestamps kept in the cache are expressed in seconds + * since boot. This is the best for measuring differences in +diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h +index 95852e3..19d632d 100644 +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -2431,6 +2431,15 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); + unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc); + + /** ++ * ieee80211_get_mesh_hdrlen - get mesh extension header length ++ * @meshhdr: the mesh extension header, only the flags field ++ * (first byte) will be accessed ++ * Returns the length of the extension header, which is always at ++ * least 6 bytes and at most 18 if address 5 and 6 are present. ++ */ ++unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); ++ ++/** + * DOC: Data path helpers + * + * In addition to generic utilities, cfg80211 also offers +diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h +index 678f1ff..3702939 100644 +--- a/include/net/rtnetlink.h ++++ b/include/net/rtnetlink.h +@@ -6,7 +6,7 @@ + + typedef int (*rtnl_doit_func)(struct sk_buff *, struct nlmsghdr *, void *); + typedef int (*rtnl_dumpit_func)(struct sk_buff *, struct netlink_callback *); +-typedef u16 (*rtnl_calcit_func)(struct sk_buff *); ++typedef u16 (*rtnl_calcit_func)(struct sk_buff *, struct nlmsghdr *); + + extern int __rtnl_register(int protocol, int msgtype, + rtnl_doit_func, rtnl_dumpit_func, +diff --git a/include/sound/core.h b/include/sound/core.h +index 3be5ab7..222f11e 100644 +--- a/include/sound/core.h ++++ b/include/sound/core.h +@@ -132,6 +132,7 @@ struct snd_card { + int shutdown; /* this card is going down */ + int free_on_last_close; /* free in context of file_release */ + wait_queue_head_t shutdown_sleep; ++ atomic_t refcount; /* refcount for disconnection */ + struct device *dev; /* device assigned to this card */ + struct device *card_dev; /* cardX object for sysfs */ + +@@ -189,6 +190,7 @@ struct snd_minor { + const struct file_operations *f_ops; /* file operations */ + void *private_data; /* private data for f_ops->open */ + struct device *dev; /* device for sysfs */ ++ struct snd_card *card_ptr; /* assigned card instance */ + }; + + /* return a device pointer linked to each sound device as a parent */ +@@ -295,6 +297,7 @@ int snd_card_info_done(void); + int snd_component_add(struct snd_card *card, const char *component); + int snd_card_file_add(struct snd_card *card, struct file *file); + int snd_card_file_remove(struct snd_card *card, struct file *file); ++void snd_card_unref(struct snd_card *card); + + #define snd_card_set_dev(card, devptr) ((card)->dev = (devptr)) + +diff --git a/include/trace/events/xen.h b/include/trace/events/xen.h +index 92f1a79..348c4fe 100644 +--- a/include/trace/events/xen.h ++++ b/include/trace/events/xen.h +@@ -377,6 +377,14 @@ DECLARE_EVENT_CLASS(xen_mmu_pgd, + DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_pin); + DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_unpin); + ++TRACE_EVENT(xen_mmu_flush_tlb_all, ++ TP_PROTO(int x), ++ TP_ARGS(x), ++ TP_STRUCT__entry(__array(char, x, 0)), ++ TP_fast_assign((void)x), ++ TP_printk("%s", "") ++ ); ++ + TRACE_EVENT(xen_mmu_flush_tlb, + TP_PROTO(int x), + TP_ARGS(x), +diff --git a/kernel/module.c b/kernel/module.c +index 6c8fa34..65362d9 100644 +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -2193,15 +2193,17 @@ static void layout_symtab(struct module *mod, struct load_info *info) + + src = (void *)info->hdr + symsect->sh_offset; + nsrc = symsect->sh_size / sizeof(*src); +- for (ndst = i = 1; i < nsrc; ++i, ++src) +- if (is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) { +- unsigned int j = src->st_name; ++ for (ndst = i = 0; i < nsrc; i++) { ++ if (i == 0 || ++ is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { ++ unsigned int j = src[i].st_name; + + while (!__test_and_set_bit(j, info->strmap) + && info->strtab[j]) + ++j; + ++ndst; + } ++ } + + /* Append room for core symbols at end of core part. */ + info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1); +@@ -2238,14 +2240,14 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) + + mod->core_symtab = dst = mod->module_core + info->symoffs; + src = mod->symtab; +- *dst = *src; +- for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) { +- if (!is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) +- continue; +- dst[ndst] = *src; +- dst[ndst].st_name = bitmap_weight(info->strmap, +- dst[ndst].st_name); +- ++ndst; ++ for (ndst = i = 0; i < mod->num_symtab; i++) { ++ if (i == 0 || ++ is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { ++ dst[ndst] = src[i]; ++ dst[ndst].st_name = bitmap_weight(info->strmap, ++ dst[ndst].st_name); ++ ++ndst; ++ } + } + mod->core_num_syms = ndst; + +diff --git a/mm/vmscan.c b/mm/vmscan.c +index 86eb848..313381c 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -3015,6 +3015,8 @@ static int kswapd(void *p) + &balanced_classzone_idx); + } + } ++ ++ current->reclaim_state = NULL; + return 0; + } + +diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c +index 1fb1aec..aa12649 100644 +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -642,8 +642,10 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) + { + BT_DBG("conn %p", conn); + ++#ifdef CONFIG_BT_L2CAP + if (conn->type == LE_LINK) + return smp_conn_security(conn, sec_level); ++#endif + + /* For sdp we don't need the link key. */ + if (sec_level == BT_SECURITY_SDP) +diff --git a/net/core/dev.c b/net/core/dev.c +index f500a69..480be72 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1633,7 +1633,7 @@ static inline int deliver_skb(struct sk_buff *skb, + + static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb) + { +- if (ptype->af_packet_priv == NULL) ++ if (!ptype->af_packet_priv || !skb->sk) + return false; + + if (ptype->id_match) +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index 0cf604b..5229c7f 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -60,7 +60,6 @@ struct rtnl_link { + }; + + static DEFINE_MUTEX(rtnl_mutex); +-static u16 min_ifinfo_dump_size; + + void rtnl_lock(void) + { +@@ -727,10 +726,11 @@ static void copy_rtnl_link_stats64(void *v, const struct rtnl_link_stats64 *b) + } + + /* All VF info */ +-static inline int rtnl_vfinfo_size(const struct net_device *dev) ++static inline int rtnl_vfinfo_size(const struct net_device *dev, ++ u32 ext_filter_mask) + { +- if (dev->dev.parent && dev_is_pci(dev->dev.parent)) { +- ++ if (dev->dev.parent && dev_is_pci(dev->dev.parent) && ++ (ext_filter_mask & RTEXT_FILTER_VF)) { + int num_vfs = dev_num_vf(dev->dev.parent); + size_t size = nla_total_size(sizeof(struct nlattr)); + size += nla_total_size(num_vfs * sizeof(struct nlattr)); +@@ -769,7 +769,8 @@ static size_t rtnl_port_size(const struct net_device *dev) + return port_self_size; + } + +-static noinline size_t if_nlmsg_size(const struct net_device *dev) ++static noinline size_t if_nlmsg_size(const struct net_device *dev, ++ u32 ext_filter_mask) + { + return NLMSG_ALIGN(sizeof(struct ifinfomsg)) + + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ +@@ -787,8 +788,9 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev) + + nla_total_size(4) /* IFLA_MASTER */ + + nla_total_size(1) /* IFLA_OPERSTATE */ + + nla_total_size(1) /* IFLA_LINKMODE */ +- + nla_total_size(4) /* IFLA_NUM_VF */ +- + rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */ ++ + nla_total_size(ext_filter_mask ++ & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */ ++ + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */ + + rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */ + + rtnl_link_get_size(dev) /* IFLA_LINKINFO */ + + rtnl_link_get_af_size(dev); /* IFLA_AF_SPEC */ +@@ -871,7 +873,7 @@ static int rtnl_port_fill(struct sk_buff *skb, struct net_device *dev) + + static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, + int type, u32 pid, u32 seq, u32 change, +- unsigned int flags) ++ unsigned int flags, u32 ext_filter_mask) + { + struct ifinfomsg *ifm; + struct nlmsghdr *nlh; +@@ -944,10 +946,11 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, + goto nla_put_failure; + copy_rtnl_link_stats64(nla_data(attr), stats); + +- if (dev->dev.parent) ++ if (dev->dev.parent && (ext_filter_mask & RTEXT_FILTER_VF)) + NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent)); + +- if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) { ++ if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent ++ && (ext_filter_mask & RTEXT_FILTER_VF)) { + int i; + + struct nlattr *vfinfo, *vf; +@@ -1051,6 +1054,8 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) + struct net_device *dev; + struct hlist_head *head; + struct hlist_node *node; ++ struct nlattr *tb[IFLA_MAX+1]; ++ u32 ext_filter_mask = 0; + + s_h = cb->args[0]; + s_idx = cb->args[1]; +@@ -1058,6 +1063,13 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) + rcu_read_lock(); + cb->seq = net->dev_base_seq; + ++ if (nlmsg_parse(cb->nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX, ++ ifla_policy) >= 0) { ++ ++ if (tb[IFLA_EXT_MASK]) ++ ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); ++ } ++ + for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { + idx = 0; + head = &net->dev_index_head[h]; +@@ -1067,7 +1079,8 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) + if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, + NETLINK_CB(cb->skb).pid, + cb->nlh->nlmsg_seq, 0, +- NLM_F_MULTI) <= 0) ++ NLM_F_MULTI, ++ ext_filter_mask) <= 0) + goto out; + + nl_dump_check_consistent(cb, nlmsg_hdr(skb)); +@@ -1103,6 +1116,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = { + [IFLA_VF_PORTS] = { .type = NLA_NESTED }, + [IFLA_PORT_SELF] = { .type = NLA_NESTED }, + [IFLA_AF_SPEC] = { .type = NLA_NESTED }, ++ [IFLA_EXT_MASK] = { .type = NLA_U32 }, + }; + EXPORT_SYMBOL(ifla_policy); + +@@ -1845,6 +1859,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) + struct net_device *dev = NULL; + struct sk_buff *nskb; + int err; ++ u32 ext_filter_mask = 0; + + err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); + if (err < 0) +@@ -1853,6 +1868,9 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) + if (tb[IFLA_IFNAME]) + nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); + ++ if (tb[IFLA_EXT_MASK]) ++ ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); ++ + ifm = nlmsg_data(nlh); + if (ifm->ifi_index > 0) + dev = __dev_get_by_index(net, ifm->ifi_index); +@@ -1864,12 +1882,12 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) + if (dev == NULL) + return -ENODEV; + +- nskb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL); ++ nskb = nlmsg_new(if_nlmsg_size(dev, ext_filter_mask), GFP_KERNEL); + if (nskb == NULL) + return -ENOBUFS; + + err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).pid, +- nlh->nlmsg_seq, 0, 0); ++ nlh->nlmsg_seq, 0, 0, ext_filter_mask); + if (err < 0) { + /* -EMSGSIZE implies BUG in if_nlmsg_size */ + WARN_ON(err == -EMSGSIZE); +@@ -1880,8 +1898,32 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) + return err; + } + +-static u16 rtnl_calcit(struct sk_buff *skb) ++static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh) + { ++ struct net *net = sock_net(skb->sk); ++ struct net_device *dev; ++ struct nlattr *tb[IFLA_MAX+1]; ++ u32 ext_filter_mask = 0; ++ u16 min_ifinfo_dump_size = 0; ++ ++ if (nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX, ++ ifla_policy) >= 0) { ++ if (tb[IFLA_EXT_MASK]) ++ ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); ++ } ++ ++ if (!ext_filter_mask) ++ return NLMSG_GOODSIZE; ++ /* ++ * traverse the list of net devices and compute the minimum ++ * buffer size based upon the filter mask. ++ */ ++ list_for_each_entry(dev, &net->dev_base_head, dev_list) { ++ min_ifinfo_dump_size = max_t(u16, min_ifinfo_dump_size, ++ if_nlmsg_size(dev, ++ ext_filter_mask)); ++ } ++ + return min_ifinfo_dump_size; + } + +@@ -1916,13 +1958,11 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) + int err = -ENOBUFS; + size_t if_info_size; + +- skb = nlmsg_new((if_info_size = if_nlmsg_size(dev)), GFP_KERNEL); ++ skb = nlmsg_new((if_info_size = if_nlmsg_size(dev, 0)), GFP_KERNEL); + if (skb == NULL) + goto errout; + +- min_ifinfo_dump_size = max_t(u16, if_info_size, min_ifinfo_dump_size); +- +- err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0); ++ err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0, 0); + if (err < 0) { + /* -EMSGSIZE implies BUG in if_nlmsg_size() */ + WARN_ON(err == -EMSGSIZE); +@@ -1980,7 +2020,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + return -EOPNOTSUPP; + calcit = rtnl_get_calcit(family, type); + if (calcit) +- min_dump_alloc = calcit(skb); ++ min_dump_alloc = calcit(skb, nlh); + + __rtnl_unlock(); + rtnl = net->rtnl; +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 7397ad8..52edbb8 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -481,14 +481,12 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) + !tp->urg_data || + before(tp->urg_seq, tp->copied_seq) || + !before(tp->urg_seq, tp->rcv_nxt)) { +- struct sk_buff *skb; + + answ = tp->rcv_nxt - tp->copied_seq; + +- /* Subtract 1, if FIN is in queue. */ +- skb = skb_peek_tail(&sk->sk_receive_queue); +- if (answ && skb) +- answ -= tcp_hdr(skb)->fin; ++ /* Subtract 1, if FIN was received */ ++ if (answ && sock_flag(sk, SOCK_DONE)) ++ answ--; + } else + answ = tp->urg_seq - tp->copied_seq; + release_sock(sk); +diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c +index 813b43a..834857f 100644 +--- a/net/ipv4/tcp_illinois.c ++++ b/net/ipv4/tcp_illinois.c +@@ -313,11 +313,13 @@ static void tcp_illinois_info(struct sock *sk, u32 ext, + .tcpv_rttcnt = ca->cnt_rtt, + .tcpv_minrtt = ca->base_rtt, + }; +- u64 t = ca->sum_rtt; + +- do_div(t, ca->cnt_rtt); +- info.tcpv_rtt = t; ++ if (info.tcpv_rttcnt > 0) { ++ u64 t = ca->sum_rtt; + ++ do_div(t, info.tcpv_rttcnt); ++ info.tcpv_rtt = t; ++ } + nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info); + } + } +diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c +index 0cb78d7..9ffc37f 100644 +--- a/net/ipv6/ndisc.c ++++ b/net/ipv6/ndisc.c +@@ -606,7 +606,7 @@ static void ndisc_send_unsol_na(struct net_device *dev) + { + struct inet6_dev *idev; + struct inet6_ifaddr *ifa; +- struct in6_addr mcaddr; ++ struct in6_addr mcaddr = IN6ADDR_LINKLOCAL_ALLNODES_INIT; + + idev = in6_dev_get(dev); + if (!idev) +@@ -614,7 +614,6 @@ static void ndisc_send_unsol_na(struct net_device *dev) + + read_lock_bh(&idev->lock); + list_for_each_entry(ifa, &idev->addr_list, if_list) { +- addrconf_addr_solict_mult(&ifa->addr, &mcaddr); + ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr, + /*router=*/ !!idev->cnf.forwarding, + /*solicited=*/ false, /*override=*/ true, +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 488a1b7..19724bd 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -185,7 +185,7 @@ static struct dst_ops ip6_dst_blackhole_ops = { + }; + + static const u32 ip6_template_metrics[RTAX_MAX] = { +- [RTAX_HOPLIMIT - 1] = 255, ++ [RTAX_HOPLIMIT - 1] = 0, + }; + + static struct rt6_info ip6_null_entry_template = { +@@ -1097,7 +1097,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, + ipv6_addr_copy(&rt->rt6i_dst.addr, addr); + rt->rt6i_dst.plen = 128; + rt->rt6i_idev = idev; +- dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); ++ dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 0); + + spin_lock_bh(&icmp6_dst_lock); + rt->dst.next = icmp6_dst_gc_list; +diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c +index 2cef50b..64164fb 100644 +--- a/net/l2tp/l2tp_eth.c ++++ b/net/l2tp/l2tp_eth.c +@@ -269,6 +269,7 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p + + out_del_dev: + free_netdev(dev); ++ spriv->dev = NULL; + out_del_session: + l2tp_session_delete(session); + out: +diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c +index 3ece106..8c7364b 100644 +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -940,7 +940,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, + sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; + sdata->u.ibss.ibss_join_req = jiffies; + +- memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); ++ memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); + sdata->u.ibss.ssid_len = params->ssid_len; + + mutex_unlock(&sdata->u.ibss.mtx); +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index cda4875..cd6cbdb 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -515,6 +515,11 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) + + if (ieee80211_is_action(hdr->frame_control)) { + u8 category; ++ ++ /* make sure category field is present */ ++ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE) ++ return RX_DROP_MONITOR; ++ + mgmt = (struct ieee80211_mgmt *)hdr; + category = mgmt->u.action.category; + if (category != WLAN_CATEGORY_MESH_ACTION && +@@ -854,14 +859,16 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) + (!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC)))) { + if (rx->sta && rx->sta->dummy && + ieee80211_is_data_present(hdr->frame_control)) { +- u16 ethertype; +- u8 *payload; +- +- payload = rx->skb->data + +- ieee80211_hdrlen(hdr->frame_control); +- ethertype = (payload[6] << 8) | payload[7]; +- if (cpu_to_be16(ethertype) == +- rx->sdata->control_port_protocol) ++ unsigned int hdrlen; ++ __be16 ethertype; ++ ++ hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ ++ if (rx->skb->len < hdrlen + 8) ++ return RX_DROP_MONITOR; ++ ++ skb_copy_bits(rx->skb, hdrlen + 6, ðertype, 2); ++ if (ethertype == rx->sdata->control_port_protocol) + return RX_CONTINUE; + } + return RX_DROP_MONITOR; +@@ -1449,11 +1456,14 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + + hdr = (struct ieee80211_hdr *)rx->skb->data; + fc = hdr->frame_control; ++ ++ if (ieee80211_is_ctl(fc)) ++ return RX_CONTINUE; ++ + sc = le16_to_cpu(hdr->seq_ctrl); + frag = sc & IEEE80211_SCTL_FRAG; + + if (likely((!ieee80211_has_morefrags(fc) && frag == 0) || +- (rx->skb)->len < 24 || + is_multicast_ether_addr(hdr->addr1))) { + /* not fragmented */ + goto out; +@@ -1887,6 +1897,20 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) + + hdr = (struct ieee80211_hdr *) skb->data; + hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ ++ /* make sure fixed part of mesh header is there, also checks skb len */ ++ if (!pskb_may_pull(rx->skb, hdrlen + 6)) ++ return RX_DROP_MONITOR; ++ ++ mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); ++ ++ /* make sure full mesh header is there, also checks skb len */ ++ if (!pskb_may_pull(rx->skb, ++ hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr))) ++ return RX_DROP_MONITOR; ++ ++ /* reload pointers */ ++ hdr = (struct ieee80211_hdr *) skb->data; + mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); + + /* frame is in RMC, don't forward */ +@@ -1895,7 +1919,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) + mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata)) + return RX_DROP_MONITOR; + +- if (!ieee80211_is_data(hdr->frame_control)) ++ if (!ieee80211_is_data(hdr->frame_control) || ++ !(status->rx_flags & IEEE80211_RX_RA_MATCH)) + return RX_CONTINUE; + + if (!mesh_hdr->ttl) +@@ -1916,9 +1941,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) + if (is_multicast_ether_addr(hdr->addr1)) { + mpp_addr = hdr->addr3; + proxied_addr = mesh_hdr->eaddr1; +- } else { ++ } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) { ++ /* has_a4 already checked in ieee80211_rx_mesh_check */ + mpp_addr = hdr->addr4; + proxied_addr = mesh_hdr->eaddr2; ++ } else { ++ return RX_DROP_MONITOR; + } + + rcu_read_lock(); +@@ -1941,7 +1969,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) + + mesh_hdr->ttl--; + +- if (status->rx_flags & IEEE80211_RX_RA_MATCH) { ++ { + if (!mesh_hdr->ttl) + IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh, + dropped_frames_ttl); +@@ -2295,6 +2323,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) + } + break; + case WLAN_CATEGORY_SELF_PROTECTED: ++ if (len < (IEEE80211_MIN_ACTION_SIZE + ++ sizeof(mgmt->u.action.u.self_prot.action_code))) ++ break; ++ + switch (mgmt->u.action.u.self_prot.action_code) { + case WLAN_SP_MESH_PEERING_OPEN: + case WLAN_SP_MESH_PEERING_CLOSE: +@@ -2313,6 +2345,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) + } + break; + case WLAN_CATEGORY_MESH_ACTION: ++ if (len < (IEEE80211_MIN_ACTION_SIZE + ++ sizeof(mgmt->u.action.u.mesh_action.action_code))) ++ break; ++ + if (!ieee80211_vif_is_mesh(&sdata->vif)) + break; + if (mesh_action_is_path_sel(mgmt) && +@@ -2870,10 +2906,15 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, + test_bit(SCAN_OFF_CHANNEL, &local->scanning))) + status->rx_flags |= IEEE80211_RX_IN_SCAN; + +- if (ieee80211_is_mgmt(fc)) +- err = skb_linearize(skb); +- else ++ if (ieee80211_is_mgmt(fc)) { ++ /* drop frame if too short for header */ ++ if (skb->len < ieee80211_hdrlen(fc)) ++ err = -ENOBUFS; ++ else ++ err = skb_linearize(skb); ++ } else { + err = !pskb_may_pull(skb, ieee80211_hdrlen(fc)); ++ } + + if (err) { + dev_kfree_skb(skb); +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 38b78b9..3d1d55d 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -137,6 +137,8 @@ static void netlink_destroy_callback(struct netlink_callback *cb); + static DEFINE_RWLOCK(nl_table_lock); + static atomic_t nl_table_users = ATOMIC_INIT(0); + ++#define nl_deref_protected(X) rcu_dereference_protected(X, lockdep_is_held(&nl_table_lock)); ++ + static ATOMIC_NOTIFIER_HEAD(netlink_chain); + + static u32 netlink_group_mask(u32 group) +@@ -331,6 +333,11 @@ netlink_update_listeners(struct sock *sk) + struct hlist_node *node; + unsigned long mask; + unsigned int i; ++ struct listeners *listeners; ++ ++ listeners = nl_deref_protected(tbl->listeners); ++ if (!listeners) ++ return; + + for (i = 0; i < NLGRPLONGS(tbl->groups); i++) { + mask = 0; +@@ -338,7 +345,7 @@ netlink_update_listeners(struct sock *sk) + if (i < NLGRPLONGS(nlk_sk(sk)->ngroups)) + mask |= nlk_sk(sk)->groups[i]; + } +- tbl->listeners->masks[i] = mask; ++ listeners->masks[i] = mask; + } + /* this function is only called with the netlink table "grabbed", which + * makes sure updates are visible before bind or setsockopt return. */ +@@ -519,7 +526,11 @@ static int netlink_release(struct socket *sock) + if (netlink_is_kernel(sk)) { + BUG_ON(nl_table[sk->sk_protocol].registered == 0); + if (--nl_table[sk->sk_protocol].registered == 0) { +- kfree(nl_table[sk->sk_protocol].listeners); ++ struct listeners *old; ++ ++ old = nl_deref_protected(nl_table[sk->sk_protocol].listeners); ++ RCU_INIT_POINTER(nl_table[sk->sk_protocol].listeners, NULL); ++ kfree_rcu(old, rcu); + nl_table[sk->sk_protocol].module = NULL; + nl_table[sk->sk_protocol].registered = 0; + } +@@ -950,7 +961,7 @@ int netlink_has_listeners(struct sock *sk, unsigned int group) + rcu_read_lock(); + listeners = rcu_dereference(nl_table[sk->sk_protocol].listeners); + +- if (group - 1 < nl_table[sk->sk_protocol].groups) ++ if (listeners && group - 1 < nl_table[sk->sk_protocol].groups) + res = test_bit(group - 1, listeners->masks); + + rcu_read_unlock(); +@@ -1584,7 +1595,7 @@ int __netlink_change_ngroups(struct sock *sk, unsigned int groups) + new = kzalloc(sizeof(*new) + NLGRPSZ(groups), GFP_ATOMIC); + if (!new) + return -ENOMEM; +- old = rcu_dereference_protected(tbl->listeners, 1); ++ old = nl_deref_protected(tbl->listeners); + memcpy(new->masks, old->masks, NLGRPSZ(tbl->groups)); + rcu_assign_pointer(tbl->listeners, new); + +diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c +index 76388b0..9032d50 100644 +--- a/net/sctp/sm_sideeffect.c ++++ b/net/sctp/sm_sideeffect.c +@@ -1604,8 +1604,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, + asoc->outqueue.outstanding_bytes; + sackh.num_gap_ack_blocks = 0; + sackh.num_dup_tsns = 0; ++ chunk->subh.sack_hdr = &sackh; + sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, +- SCTP_SACKH(&sackh)); ++ SCTP_CHUNK(chunk)); + break; + + case SCTP_CMD_DISCARD_PACKET: +diff --git a/net/wireless/core.c b/net/wireless/core.c +index 8f5042d..ea93f4b 100644 +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -548,8 +548,7 @@ int wiphy_register(struct wiphy *wiphy) + for (i = 0; i < sband->n_channels; i++) { + sband->channels[i].orig_flags = + sband->channels[i].flags; +- sband->channels[i].orig_mag = +- sband->channels[i].max_antenna_gain; ++ sband->channels[i].orig_mag = INT_MAX; + sband->channels[i].orig_mpwr = + sband->channels[i].max_power; + sband->channels[i].band = band; +diff --git a/net/wireless/util.c b/net/wireless/util.c +index 22fb802..5fba039 100644 +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -301,23 +301,21 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) + } + EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); + +-static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) ++unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) + { + int ae = meshhdr->flags & MESH_FLAGS_AE; +- /* 7.1.3.5a.2 */ ++ /* 802.11-2012, 8.2.4.7.3 */ + switch (ae) { ++ default: + case 0: + return 6; + case MESH_FLAGS_AE_A4: + return 12; + case MESH_FLAGS_AE_A5_A6: + return 18; +- case (MESH_FLAGS_AE_A4 | MESH_FLAGS_AE_A5_A6): +- return 24; +- default: +- return 6; + } + } ++EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); + + int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, + enum nl80211_iftype iftype) +@@ -365,6 +363,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, + /* make sure meshdr->flags is on the linear part */ + if (!pskb_may_pull(skb, hdrlen + 1)) + return -1; ++ if (meshdr->flags & MESH_FLAGS_AE_A4) ++ return -1; + if (meshdr->flags & MESH_FLAGS_AE_A5_A6) { + skb_copy_bits(skb, hdrlen + + offsetof(struct ieee80211s_hdr, eaddr1), +@@ -389,6 +389,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, + /* make sure meshdr->flags is on the linear part */ + if (!pskb_may_pull(skb, hdrlen + 1)) + return -1; ++ if (meshdr->flags & MESH_FLAGS_AE_A5_A6) ++ return -1; + if (meshdr->flags & MESH_FLAGS_AE_A4) + skb_copy_bits(skb, hdrlen + + offsetof(struct ieee80211s_hdr, eaddr1), +diff --git a/sound/core/control.c b/sound/core/control.c +index 819a5c5..5511307 100644 +--- a/sound/core/control.c ++++ b/sound/core/control.c +@@ -86,6 +86,7 @@ static int snd_ctl_open(struct inode *inode, struct file *file) + write_lock_irqsave(&card->ctl_files_rwlock, flags); + list_add_tail(&ctl->list, &card->ctl_files); + write_unlock_irqrestore(&card->ctl_files_rwlock, flags); ++ snd_card_unref(card); + return 0; + + __error: +@@ -93,6 +94,8 @@ static int snd_ctl_open(struct inode *inode, struct file *file) + __error2: + snd_card_file_remove(card, file); + __error1: ++ if (card) ++ snd_card_unref(card); + return err; + } + +@@ -1433,6 +1436,8 @@ static ssize_t snd_ctl_read(struct file *file, char __user *buffer, + spin_unlock_irq(&ctl->read_lock); + schedule(); + remove_wait_queue(&ctl->change_sleep, &wait); ++ if (ctl->card->shutdown) ++ return -ENODEV; + if (signal_pending(current)) + return -ERESTARTSYS; + spin_lock_irq(&ctl->read_lock); +diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c +index 75ea16f..3f7f662 100644 +--- a/sound/core/hwdep.c ++++ b/sound/core/hwdep.c +@@ -100,8 +100,10 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) + if (hw == NULL) + return -ENODEV; + +- if (!try_module_get(hw->card->module)) ++ if (!try_module_get(hw->card->module)) { ++ snd_card_unref(hw->card); + return -EFAULT; ++ } + + init_waitqueue_entry(&wait, current); + add_wait_queue(&hw->open_wait, &wait); +@@ -129,6 +131,10 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) + mutex_unlock(&hw->open_mutex); + schedule(); + mutex_lock(&hw->open_mutex); ++ if (hw->card->shutdown) { ++ err = -ENODEV; ++ break; ++ } + if (signal_pending(current)) { + err = -ERESTARTSYS; + break; +@@ -148,6 +154,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) + mutex_unlock(&hw->open_mutex); + if (err < 0) + module_put(hw->card->module); ++ snd_card_unref(hw->card); + return err; + } + +@@ -459,12 +466,15 @@ static int snd_hwdep_dev_disconnect(struct snd_device *device) + mutex_unlock(®ister_mutex); + return -EINVAL; + } ++ mutex_lock(&hwdep->open_mutex); ++ wake_up(&hwdep->open_wait); + #ifdef CONFIG_SND_OSSEMUL + if (hwdep->ossreg) + snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device); + #endif + snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device); + list_del_init(&hwdep->list); ++ mutex_unlock(&hwdep->open_mutex); + mutex_unlock(®ister_mutex); + return 0; + } +diff --git a/sound/core/init.c b/sound/core/init.c +index 3ac49b1..fa0f35b 100644 +--- a/sound/core/init.c ++++ b/sound/core/init.c +@@ -212,6 +212,7 @@ int snd_card_create(int idx, const char *xid, + spin_lock_init(&card->files_lock); + INIT_LIST_HEAD(&card->files_list); + init_waitqueue_head(&card->shutdown_sleep); ++ atomic_set(&card->refcount, 0); + #ifdef CONFIG_PM + mutex_init(&card->power_lock); + init_waitqueue_head(&card->power_sleep); +@@ -445,21 +446,36 @@ static int snd_card_do_free(struct snd_card *card) + return 0; + } + ++/** ++ * snd_card_unref - release the reference counter ++ * @card: the card instance ++ * ++ * Decrements the reference counter. When it reaches to zero, wake up ++ * the sleeper and call the destructor if needed. ++ */ ++void snd_card_unref(struct snd_card *card) ++{ ++ if (atomic_dec_and_test(&card->refcount)) { ++ wake_up(&card->shutdown_sleep); ++ if (card->free_on_last_close) ++ snd_card_do_free(card); ++ } ++} ++EXPORT_SYMBOL(snd_card_unref); ++ + int snd_card_free_when_closed(struct snd_card *card) + { +- int free_now = 0; +- int ret = snd_card_disconnect(card); +- if (ret) +- return ret; ++ int ret; + +- spin_lock(&card->files_lock); +- if (list_empty(&card->files_list)) +- free_now = 1; +- else +- card->free_on_last_close = 1; +- spin_unlock(&card->files_lock); ++ atomic_inc(&card->refcount); ++ ret = snd_card_disconnect(card); ++ if (ret) { ++ atomic_dec(&card->refcount); ++ return ret; ++ } + +- if (free_now) ++ card->free_on_last_close = 1; ++ if (atomic_dec_and_test(&card->refcount)) + snd_card_do_free(card); + return 0; + } +@@ -473,7 +489,7 @@ int snd_card_free(struct snd_card *card) + return ret; + + /* wait, until all devices are ready for the free operation */ +- wait_event(card->shutdown_sleep, list_empty(&card->files_list)); ++ wait_event(card->shutdown_sleep, !atomic_read(&card->refcount)); + snd_card_do_free(card); + return 0; + } +@@ -854,6 +870,7 @@ int snd_card_file_add(struct snd_card *card, struct file *file) + return -ENODEV; + } + list_add(&mfile->list, &card->files_list); ++ atomic_inc(&card->refcount); + spin_unlock(&card->files_lock); + return 0; + } +@@ -876,7 +893,6 @@ EXPORT_SYMBOL(snd_card_file_add); + int snd_card_file_remove(struct snd_card *card, struct file *file) + { + struct snd_monitor_file *mfile, *found = NULL; +- int last_close = 0; + + spin_lock(&card->files_lock); + list_for_each_entry(mfile, &card->files_list, list) { +@@ -891,19 +907,13 @@ int snd_card_file_remove(struct snd_card *card, struct file *file) + break; + } + } +- if (list_empty(&card->files_list)) +- last_close = 1; + spin_unlock(&card->files_lock); +- if (last_close) { +- wake_up(&card->shutdown_sleep); +- if (card->free_on_last_close) +- snd_card_do_free(card); +- } + if (!found) { + snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file); + return -ENOENT; + } + kfree(found); ++ snd_card_unref(card); + return 0; + } + +diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c +index 18297f7..c353768 100644 +--- a/sound/core/oss/mixer_oss.c ++++ b/sound/core/oss/mixer_oss.c +@@ -52,14 +52,19 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file) + SNDRV_OSS_DEVICE_TYPE_MIXER); + if (card == NULL) + return -ENODEV; +- if (card->mixer_oss == NULL) ++ if (card->mixer_oss == NULL) { ++ snd_card_unref(card); + return -ENODEV; ++ } + err = snd_card_file_add(card, file); +- if (err < 0) ++ if (err < 0) { ++ snd_card_unref(card); + return err; ++ } + fmixer = kzalloc(sizeof(*fmixer), GFP_KERNEL); + if (fmixer == NULL) { + snd_card_file_remove(card, file); ++ snd_card_unref(card); + return -ENOMEM; + } + fmixer->card = card; +@@ -68,8 +73,10 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file) + if (!try_module_get(card->module)) { + kfree(fmixer); + snd_card_file_remove(card, file); ++ snd_card_unref(card); + return -EFAULT; + } ++ snd_card_unref(card); + return 0; + } + +diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c +index 3cc4b86..542f69e 100644 +--- a/sound/core/oss/pcm_oss.c ++++ b/sound/core/oss/pcm_oss.c +@@ -2441,6 +2441,10 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) + mutex_unlock(&pcm->open_mutex); + schedule(); + mutex_lock(&pcm->open_mutex); ++ if (pcm->card->shutdown) { ++ err = -ENODEV; ++ break; ++ } + if (signal_pending(current)) { + err = -ERESTARTSYS; + break; +@@ -2450,6 +2454,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) + mutex_unlock(&pcm->open_mutex); + if (err < 0) + goto __error; ++ snd_card_unref(pcm->card); + return err; + + __error: +@@ -2457,6 +2462,8 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) + __error2: + snd_card_file_remove(pcm->card, file); + __error1: ++ if (pcm) ++ snd_card_unref(pcm->card); + return err; + } + +diff --git a/sound/core/pcm.c b/sound/core/pcm.c +index 8928ca87..13eaeb3 100644 +--- a/sound/core/pcm.c ++++ b/sound/core/pcm.c +@@ -1046,11 +1046,19 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) + if (list_empty(&pcm->list)) + goto unlock; + ++ mutex_lock(&pcm->open_mutex); ++ wake_up(&pcm->open_wait); + list_del_init(&pcm->list); + for (cidx = 0; cidx < 2; cidx++) +- for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) +- if (substream->runtime) ++ for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) { ++ snd_pcm_stream_lock_irq(substream); ++ if (substream->runtime) { + substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED; ++ wake_up(&substream->runtime->sleep); ++ wake_up(&substream->runtime->tsleep); ++ } ++ snd_pcm_stream_unlock_irq(substream); ++ } + list_for_each_entry(notify, &snd_pcm_notify_list, list) { + notify->n_disconnect(pcm); + } +@@ -1066,6 +1074,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) + } + snd_unregister_device(devtype, pcm->card, pcm->device); + } ++ mutex_unlock(&pcm->open_mutex); + unlock: + mutex_unlock(®ister_mutex); + return 0; +diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c +index 25ed9fe..7ada40e 100644 +--- a/sound/core/pcm_native.c ++++ b/sound/core/pcm_native.c +@@ -369,6 +369,14 @@ static int period_to_usecs(struct snd_pcm_runtime *runtime) + return usecs; + } + ++static void snd_pcm_set_state(struct snd_pcm_substream *substream, int state) ++{ ++ snd_pcm_stream_lock_irq(substream); ++ if (substream->runtime->status->state != SNDRV_PCM_STATE_DISCONNECTED) ++ substream->runtime->status->state = state; ++ snd_pcm_stream_unlock_irq(substream); ++} ++ + static int snd_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) + { +@@ -452,7 +460,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, + runtime->boundary *= 2; + + snd_pcm_timer_resolution_change(substream); +- runtime->status->state = SNDRV_PCM_STATE_SETUP; ++ snd_pcm_set_state(substream, SNDRV_PCM_STATE_SETUP); + + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); +@@ -464,7 +472,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, + /* hardware might be unusable from this time, + so we force application to retry to set + the correct hardware parameter settings */ +- runtime->status->state = SNDRV_PCM_STATE_OPEN; ++ snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); + if (substream->ops->hw_free != NULL) + substream->ops->hw_free(substream); + return err; +@@ -512,7 +520,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream) + return -EBADFD; + if (substream->ops->hw_free) + result = substream->ops->hw_free(substream); +- runtime->status->state = SNDRV_PCM_STATE_OPEN; ++ snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); + pm_qos_remove_request(&substream->latency_pm_qos_req); + return result; + } +@@ -1320,7 +1328,7 @@ static void snd_pcm_post_prepare(struct snd_pcm_substream *substream, int state) + { + struct snd_pcm_runtime *runtime = substream->runtime; + runtime->control->appl_ptr = runtime->status->hw_ptr; +- runtime->status->state = SNDRV_PCM_STATE_PREPARED; ++ snd_pcm_set_state(substream, SNDRV_PCM_STATE_PREPARED); + } + + static struct action_ops snd_pcm_action_prepare = { +@@ -1500,6 +1508,10 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, + down_read(&snd_pcm_link_rwsem); + snd_pcm_stream_lock_irq(substream); + remove_wait_queue(&to_check->sleep, &wait); ++ if (card->shutdown) { ++ result = -ENODEV; ++ break; ++ } + if (tout == 0) { + if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) + result = -ESTRPIPE; +@@ -1620,6 +1632,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) + _end: + write_unlock_irq(&snd_pcm_link_rwlock); + up_write(&snd_pcm_link_rwsem); ++ snd_card_unref(substream1->pcm->card); + fput(file); + return res; + } +@@ -2092,7 +2105,10 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file) + return err; + pcm = snd_lookup_minor_data(iminor(inode), + SNDRV_DEVICE_TYPE_PCM_PLAYBACK); +- return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); ++ err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); ++ if (pcm) ++ snd_card_unref(pcm->card); ++ return err; + } + + static int snd_pcm_capture_open(struct inode *inode, struct file *file) +@@ -2103,7 +2119,10 @@ static int snd_pcm_capture_open(struct inode *inode, struct file *file) + return err; + pcm = snd_lookup_minor_data(iminor(inode), + SNDRV_DEVICE_TYPE_PCM_CAPTURE); +- return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); ++ err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); ++ if (pcm) ++ snd_card_unref(pcm->card); ++ return err; + } + + static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) +@@ -2140,6 +2159,10 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) + mutex_unlock(&pcm->open_mutex); + schedule(); + mutex_lock(&pcm->open_mutex); ++ if (pcm->card->shutdown) { ++ err = -ENODEV; ++ break; ++ } + if (signal_pending(current)) { + err = -ERESTARTSYS; + break; +diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c +index ebf6e49..1bb95ae 100644 +--- a/sound/core/rawmidi.c ++++ b/sound/core/rawmidi.c +@@ -379,8 +379,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) + if (rmidi == NULL) + return -ENODEV; + +- if (!try_module_get(rmidi->card->module)) ++ if (!try_module_get(rmidi->card->module)) { ++ snd_card_unref(rmidi->card); + return -ENXIO; ++ } + + mutex_lock(&rmidi->open_mutex); + card = rmidi->card; +@@ -422,6 +424,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) + mutex_unlock(&rmidi->open_mutex); + schedule(); + mutex_lock(&rmidi->open_mutex); ++ if (rmidi->card->shutdown) { ++ err = -ENODEV; ++ break; ++ } + if (signal_pending(current)) { + err = -ERESTARTSYS; + break; +@@ -440,6 +446,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) + #endif + file->private_data = rawmidi_file; + mutex_unlock(&rmidi->open_mutex); ++ snd_card_unref(rmidi->card); + return 0; + + __error: +@@ -447,6 +454,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) + __error_card: + mutex_unlock(&rmidi->open_mutex); + module_put(rmidi->card->module); ++ snd_card_unref(rmidi->card); + return err; + } + +@@ -991,6 +999,8 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun + spin_unlock_irq(&runtime->lock); + schedule(); + remove_wait_queue(&runtime->sleep, &wait); ++ if (rfile->rmidi->card->shutdown) ++ return -ENODEV; + if (signal_pending(current)) + return result > 0 ? result : -ERESTARTSYS; + if (!runtime->avail) +@@ -1234,6 +1244,8 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, + spin_unlock_irq(&runtime->lock); + timeout = schedule_timeout(30 * HZ); + remove_wait_queue(&runtime->sleep, &wait); ++ if (rfile->rmidi->card->shutdown) ++ return -ENODEV; + if (signal_pending(current)) + return result > 0 ? result : -ERESTARTSYS; + if (!runtime->avail && !timeout) +@@ -1609,9 +1621,20 @@ static int snd_rawmidi_dev_register(struct snd_device *device) + static int snd_rawmidi_dev_disconnect(struct snd_device *device) + { + struct snd_rawmidi *rmidi = device->device_data; ++ int dir; + + mutex_lock(®ister_mutex); ++ mutex_lock(&rmidi->open_mutex); ++ wake_up(&rmidi->open_wait); + list_del_init(&rmidi->list); ++ for (dir = 0; dir < 2; dir++) { ++ struct snd_rawmidi_substream *s; ++ list_for_each_entry(s, &rmidi->streams[dir].substreams, list) { ++ if (s->runtime) ++ wake_up(&s->runtime->sleep); ++ } ++ } ++ + #ifdef CONFIG_SND_OSSEMUL + if (rmidi->ossreg) { + if ((int)rmidi->device == midi_map[rmidi->card->number]) { +@@ -1626,6 +1649,7 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device) + } + #endif /* CONFIG_SND_OSSEMUL */ + snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); ++ mutex_unlock(&rmidi->open_mutex); + mutex_unlock(®ister_mutex); + return 0; + } +diff --git a/sound/core/sound.c b/sound/core/sound.c +index 828af35..8e17b4d 100644 +--- a/sound/core/sound.c ++++ b/sound/core/sound.c +@@ -99,6 +99,10 @@ static void snd_request_other(int minor) + * + * Checks that a minor device with the specified type is registered, and returns + * its user data pointer. ++ * ++ * This function increments the reference counter of the card instance ++ * if an associated instance with the given minor number and type is found. ++ * The caller must call snd_card_unref() appropriately later. + */ + void *snd_lookup_minor_data(unsigned int minor, int type) + { +@@ -109,9 +113,11 @@ void *snd_lookup_minor_data(unsigned int minor, int type) + return NULL; + mutex_lock(&sound_mutex); + mreg = snd_minors[minor]; +- if (mreg && mreg->type == type) ++ if (mreg && mreg->type == type) { + private_data = mreg->private_data; +- else ++ if (private_data && mreg->card_ptr) ++ atomic_inc(&mreg->card_ptr->refcount); ++ } else + private_data = NULL; + mutex_unlock(&sound_mutex); + return private_data; +@@ -275,6 +281,7 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev, + preg->device = dev; + preg->f_ops = f_ops; + preg->private_data = private_data; ++ preg->card_ptr = card; + mutex_lock(&sound_mutex); + #ifdef CONFIG_SND_DYNAMIC_MINORS + minor = snd_find_free_minor(type); +diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c +index c700920..ec86009 100644 +--- a/sound/core/sound_oss.c ++++ b/sound/core/sound_oss.c +@@ -40,6 +40,9 @@ + static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS]; + static DEFINE_MUTEX(sound_oss_mutex); + ++/* NOTE: This function increments the refcount of the associated card like ++ * snd_lookup_minor_data(); the caller must call snd_card_unref() appropriately ++ */ + void *snd_lookup_oss_minor_data(unsigned int minor, int type) + { + struct snd_minor *mreg; +@@ -49,9 +52,11 @@ void *snd_lookup_oss_minor_data(unsigned int minor, int type) + return NULL; + mutex_lock(&sound_oss_mutex); + mreg = snd_oss_minors[minor]; +- if (mreg && mreg->type == type) ++ if (mreg && mreg->type == type) { + private_data = mreg->private_data; +- else ++ if (private_data && mreg->card_ptr) ++ atomic_inc(&mreg->card_ptr->refcount); ++ } else + private_data = NULL; + mutex_unlock(&sound_oss_mutex); + return private_data; +@@ -123,6 +128,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, + preg->device = dev; + preg->f_ops = f_ops; + preg->private_data = private_data; ++ preg->card_ptr = card; + mutex_lock(&sound_oss_mutex); + snd_oss_minors[minor] = preg; + minor_unit = SNDRV_MINOR_OSS_DEVICE(minor); +diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c +index bcb3310..b4890f9 100644 +--- a/sound/pci/hda/patch_analog.c ++++ b/sound/pci/hda/patch_analog.c +@@ -573,6 +573,7 @@ static int ad198x_build_pcms(struct hda_codec *codec) + if (spec->multiout.dig_out_nid) { + info++; + codec->num_pcms++; ++ codec->spdif_status_reset = 1; + info->name = "AD198x Digital"; + info->pcm_type = HDA_PCM_TYPE_SPDIF; + info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback; +diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c +index e449278..0ed6867 100644 +--- a/sound/pci/hda/patch_cirrus.c ++++ b/sound/pci/hda/patch_cirrus.c +@@ -93,8 +93,8 @@ enum { + #define CS420X_VENDOR_NID 0x11 + #define CS_DIG_OUT1_PIN_NID 0x10 + #define CS_DIG_OUT2_PIN_NID 0x15 +-#define CS_DMIC1_PIN_NID 0x12 +-#define CS_DMIC2_PIN_NID 0x0e ++#define CS_DMIC1_PIN_NID 0x0e ++#define CS_DMIC2_PIN_NID 0x12 + + /* coef indices */ + #define IDX_SPDIF_STAT 0x0000 +@@ -1088,14 +1088,18 @@ static void init_input(struct hda_codec *codec) + cs_automic(codec); + + coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */ ++ cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); ++ ++ coef = cs_vendor_coef_get(codec, IDX_BEEP_CFG); + if (is_active_pin(codec, CS_DMIC2_PIN_NID)) +- coef |= 0x0500; /* DMIC2 2 chan on, GPIO1 off */ ++ coef |= 1 << 4; /* DMIC2 2 chan on, GPIO1 off */ + if (is_active_pin(codec, CS_DMIC1_PIN_NID)) +- coef |= 0x1800; /* DMIC1 2 chan on, GPIO0 off ++ coef |= 1 << 3; /* DMIC1 2 chan on, GPIO0 off + * No effect if SPDIF_OUT2 is + * selected in IDX_SPDIF_CTL. + */ +- cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); ++ ++ cs_vendor_coef_set(codec, IDX_BEEP_CFG, coef); + } + } + +@@ -1109,7 +1113,7 @@ static const struct hda_verb cs_coef_init_verbs[] = { + | 0x0400 /* Disable Coefficient Auto increment */ + )}, + /* Beep */ +- {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG}, ++ {0x11, AC_VERB_SET_COEF_INDEX, IDX_BEEP_CFG}, + {0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */ + + {} /* terminator */ +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index c2c7f90..3ce2da2 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -6039,6 +6039,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { + .patch = patch_alc662 }, + { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, + { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, ++ { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, + { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, + { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, + { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, +@@ -6056,6 +6057,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { + { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, + { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, + { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 }, ++ { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 }, + {} /* terminator */ + }; + +diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c +index 7160ff2..9e0c889 100644 +--- a/sound/pci/hda/patch_via.c ++++ b/sound/pci/hda/patch_via.c +@@ -1856,11 +1856,11 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec) + { + struct via_spec *spec = codec->spec; + const struct auto_pin_cfg *cfg = &spec->autocfg; +- int i, dac_num; ++ int i; + hda_nid_t nid; + ++ spec->multiout.num_dacs = 0; + spec->multiout.dac_nids = spec->private_dac_nids; +- dac_num = 0; + for (i = 0; i < cfg->line_outs; i++) { + hda_nid_t dac = 0; + nid = cfg->line_out_pins[i]; +@@ -1871,16 +1871,13 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec) + if (!i && parse_output_path(codec, nid, dac, 1, + &spec->out_mix_path)) + dac = spec->out_mix_path.path[0]; +- if (dac) { +- spec->private_dac_nids[i] = dac; +- dac_num++; +- } ++ if (dac) ++ spec->private_dac_nids[spec->multiout.num_dacs++] = dac; + } + if (!spec->out_path[0].depth && spec->out_mix_path.depth) { + spec->out_path[0] = spec->out_mix_path; + spec->out_mix_path.depth = 0; + } +- spec->multiout.num_dacs = dac_num; + return 0; + } + +@@ -3689,6 +3686,18 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + } + ++/* NIDs 0x24 and 0x33 on VT1802 have connections to non-existing NID 0x3e ++ * Replace this with mixer NID 0x1c ++ */ ++static void fix_vt1802_connections(struct hda_codec *codec) ++{ ++ static hda_nid_t conn_24[] = { 0x14, 0x1c }; ++ static hda_nid_t conn_33[] = { 0x1c }; ++ ++ snd_hda_override_conn_list(codec, 0x24, ARRAY_SIZE(conn_24), conn_24); ++ snd_hda_override_conn_list(codec, 0x33, ARRAY_SIZE(conn_33), conn_33); ++} ++ + /* patch for vt2002P */ + static int patch_vt2002P(struct hda_codec *codec) + { +@@ -3703,6 +3712,8 @@ static int patch_vt2002P(struct hda_codec *codec) + spec->aa_mix_nid = 0x21; + override_mic_boost(codec, 0x2b, 0, 3, 40); + override_mic_boost(codec, 0x29, 0, 3, 40); ++ if (spec->codec_type == VT1802) ++ fix_vt1802_connections(codec); + add_secret_dac_path(codec); + + /* automatic parse from the BIOS config */ +diff --git a/sound/usb/card.c b/sound/usb/card.c +index 0f6dc0d..566acb3 100644 +--- a/sound/usb/card.c ++++ b/sound/usb/card.c +@@ -336,7 +336,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx, + return -ENOMEM; + } + +- mutex_init(&chip->shutdown_mutex); ++ init_rwsem(&chip->shutdown_rwsem); + chip->index = idx; + chip->dev = dev; + chip->card = card; +@@ -555,9 +555,11 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, + return; + + card = chip->card; +- mutex_lock(®ister_mutex); +- mutex_lock(&chip->shutdown_mutex); ++ down_write(&chip->shutdown_rwsem); + chip->shutdown = 1; ++ up_write(&chip->shutdown_rwsem); ++ ++ mutex_lock(®ister_mutex); + chip->num_interfaces--; + if (chip->num_interfaces <= 0) { + snd_card_disconnect(card); +@@ -574,11 +576,9 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, + snd_usb_mixer_disconnect(p); + } + usb_chip[chip->index] = NULL; +- mutex_unlock(&chip->shutdown_mutex); + mutex_unlock(®ister_mutex); + snd_card_free_when_closed(card); + } else { +- mutex_unlock(&chip->shutdown_mutex); + mutex_unlock(®ister_mutex); + } + } +@@ -610,16 +610,20 @@ int snd_usb_autoresume(struct snd_usb_audio *chip) + { + int err = -ENODEV; + ++ down_read(&chip->shutdown_rwsem); + if (!chip->shutdown && !chip->probing) + err = usb_autopm_get_interface(chip->pm_intf); ++ up_read(&chip->shutdown_rwsem); + + return err; + } + + void snd_usb_autosuspend(struct snd_usb_audio *chip) + { ++ down_read(&chip->shutdown_rwsem); + if (!chip->shutdown && !chip->probing) + usb_autopm_put_interface(chip->pm_intf); ++ up_read(&chip->shutdown_rwsem); + } + + static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) +diff --git a/sound/usb/card.h b/sound/usb/card.h +index a39edcc..665e297 100644 +--- a/sound/usb/card.h ++++ b/sound/usb/card.h +@@ -86,6 +86,7 @@ struct snd_usb_substream { + struct snd_urb_ctx syncurb[SYNC_URBS]; /* sync urb table */ + char *syncbuf; /* sync buffer for all sync URBs */ + dma_addr_t sync_dma; /* DMA address of syncbuf */ ++ unsigned int speed; /* USB_SPEED_XXX */ + + u64 formats; /* format bitmasks (all or'ed) */ + unsigned int num_formats; /* number of supported audio formats (list) */ +diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c +index 08dcce5..24c5114 100644 +--- a/sound/usb/endpoint.c ++++ b/sound/usb/endpoint.c +@@ -148,8 +148,10 @@ void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force) + int i; + + /* stop urbs (to be sure) */ +- deactivate_urbs(subs, force, 1); +- wait_clear_urbs(subs); ++ if (!subs->stream->chip->shutdown) { ++ deactivate_urbs(subs, force, 1); ++ wait_clear_urbs(subs); ++ } + + for (i = 0; i < MAX_URBS; i++) + release_urb_ctx(&subs->dataurb[i]); +@@ -895,7 +897,8 @@ void snd_usb_init_substream(struct snd_usb_stream *as, + subs->dev = as->chip->dev; + subs->txfr_quirk = as->chip->txfr_quirk; + subs->ops = audio_urb_ops[stream]; +- if (snd_usb_get_speed(subs->dev) >= USB_SPEED_HIGH) ++ subs->speed = snd_usb_get_speed(subs->dev); ++ if (subs->speed >= USB_SPEED_HIGH) + subs->ops.prepare_sync = prepare_capture_sync_urb_hs; + + snd_usb_set_pcm_ops(as->pcm, stream); +diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c +index ab23869..6730a33 100644 +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -287,25 +287,32 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v + unsigned char buf[2]; + int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; + int timeout = 10; +- int err; ++ int idx = 0, err; + + err = snd_usb_autoresume(cval->mixer->chip); + if (err < 0) + return -EIO; ++ down_read(&chip->shutdown_rwsem); + while (timeout-- > 0) { ++ if (chip->shutdown) ++ break; ++ idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); + if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, +- validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), +- buf, val_len) >= val_len) { ++ validx, idx, buf, val_len) >= val_len) { + *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); +- snd_usb_autosuspend(cval->mixer->chip); +- return 0; ++ err = 0; ++ goto out; + } + } +- snd_usb_autosuspend(cval->mixer->chip); + snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", +- request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type); +- return -EINVAL; ++ request, validx, idx, cval->val_type); ++ err = -EINVAL; ++ ++ out: ++ up_read(&chip->shutdown_rwsem); ++ snd_usb_autosuspend(cval->mixer->chip); ++ return err; + } + + static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) +@@ -313,7 +320,7 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v + struct snd_usb_audio *chip = cval->mixer->chip; + unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */ + unsigned char *val; +- int ret, size; ++ int idx = 0, ret, size; + __u8 bRequest; + + if (request == UAC_GET_CUR) { +@@ -330,16 +337,22 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v + if (ret) + goto error; + +- ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, ++ down_read(&chip->shutdown_rwsem); ++ if (chip->shutdown) ++ ret = -ENODEV; ++ else { ++ idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); ++ ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, +- validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), +- buf, size); ++ validx, idx, buf, size); ++ } ++ up_read(&chip->shutdown_rwsem); + snd_usb_autosuspend(chip); + + if (ret < 0) { + error: + snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", +- request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type); ++ request, validx, idx, cval->val_type); + return ret; + } + +@@ -417,7 +430,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, + { + struct snd_usb_audio *chip = cval->mixer->chip; + unsigned char buf[2]; +- int val_len, err, timeout = 10; ++ int idx = 0, val_len, err, timeout = 10; + + if (cval->mixer->protocol == UAC_VERSION_1) { + val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; +@@ -440,19 +453,27 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, + err = snd_usb_autoresume(chip); + if (err < 0) + return -EIO; +- while (timeout-- > 0) ++ down_read(&chip->shutdown_rwsem); ++ while (timeout-- > 0) { ++ if (chip->shutdown) ++ break; ++ idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); + if (snd_usb_ctl_msg(chip->dev, + usb_sndctrlpipe(chip->dev, 0), request, + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, +- validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), +- buf, val_len) >= 0) { +- snd_usb_autosuspend(chip); +- return 0; ++ validx, idx, buf, val_len) >= 0) { ++ err = 0; ++ goto out; + } +- snd_usb_autosuspend(chip); ++ } + snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", +- request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]); +- return -EINVAL; ++ request, validx, idx, cval->val_type, buf[0], buf[1]); ++ err = -EINVAL; ++ ++ out: ++ up_read(&chip->shutdown_rwsem); ++ snd_usb_autosuspend(chip); ++ return err; + } + + static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value) +diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c +index ab125ee..38a607a 100644 +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -186,6 +186,11 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e + if (value > 1) + return -EINVAL; + changed = value != mixer->audigy2nx_leds[index]; ++ down_read(&mixer->chip->shutdown_rwsem); ++ if (mixer->chip->shutdown) { ++ err = -ENODEV; ++ goto out; ++ } + if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) + err = snd_usb_ctl_msg(mixer->chip->dev, + usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, +@@ -202,6 +207,8 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e + usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, + value, index + 2, NULL, 0); ++ out: ++ up_read(&mixer->chip->shutdown_rwsem); + if (err < 0) + return err; + mixer->audigy2nx_leds[index] = value; +@@ -295,11 +302,16 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry, + + for (i = 0; jacks[i].name; ++i) { + snd_iprintf(buffer, "%s: ", jacks[i].name); +- err = snd_usb_ctl_msg(mixer->chip->dev, ++ down_read(&mixer->chip->shutdown_rwsem); ++ if (mixer->chip->shutdown) ++ err = 0; ++ else ++ err = snd_usb_ctl_msg(mixer->chip->dev, + usb_rcvctrlpipe(mixer->chip->dev, 0), + UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS | + USB_RECIP_INTERFACE, 0, + jacks[i].unitid << 8, buf, 3); ++ up_read(&mixer->chip->shutdown_rwsem); + if (err == 3 && (buf[0] == 3 || buf[0] == 6)) + snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]); + else +@@ -329,10 +341,15 @@ static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol, + else + new_status = old_status & ~0x02; + changed = new_status != old_status; +- err = snd_usb_ctl_msg(mixer->chip->dev, ++ down_read(&mixer->chip->shutdown_rwsem); ++ if (mixer->chip->shutdown) ++ err = -ENODEV; ++ else ++ err = snd_usb_ctl_msg(mixer->chip->dev, + usb_sndctrlpipe(mixer->chip->dev, 0), 0x08, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, + 50, 0, &new_status, 1); ++ up_read(&mixer->chip->shutdown_rwsem); + if (err < 0) + return err; + mixer->xonar_u1_status = new_status; +@@ -371,11 +388,17 @@ static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol, + u8 bRequest = (kcontrol->private_value >> 16) & 0xff; + u16 wIndex = kcontrol->private_value & 0xffff; + u8 tmp; ++ int ret; + +- int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest, ++ down_read(&mixer->chip->shutdown_rwsem); ++ if (mixer->chip->shutdown) ++ ret = -ENODEV; ++ else ++ ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + 0, cpu_to_le16(wIndex), + &tmp, sizeof(tmp), 1000); ++ up_read(&mixer->chip->shutdown_rwsem); + + if (ret < 0) { + snd_printk(KERN_ERR +@@ -396,11 +419,17 @@ static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol, + u8 bRequest = (kcontrol->private_value >> 16) & 0xff; + u16 wIndex = kcontrol->private_value & 0xffff; + u16 wValue = ucontrol->value.integer.value[0]; ++ int ret; + +- int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest, ++ down_read(&mixer->chip->shutdown_rwsem); ++ if (mixer->chip->shutdown) ++ ret = -ENODEV; ++ else ++ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, + cpu_to_le16(wValue), cpu_to_le16(wIndex), + NULL, 0, 1000); ++ up_read(&mixer->chip->shutdown_rwsem); + + if (ret < 0) { + snd_printk(KERN_ERR +diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c +index 839165f..983e071 100644 +--- a/sound/usb/pcm.c ++++ b/sound/usb/pcm.c +@@ -67,6 +67,8 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream + unsigned int hwptr_done; + + subs = (struct snd_usb_substream *)substream->runtime->private_data; ++ if (subs->stream->chip->shutdown) ++ return SNDRV_PCM_POS_XRUN; + spin_lock(&subs->lock); + hwptr_done = subs->hwptr_done; + substream->runtime->delay = snd_usb_pcm_delay(subs, +@@ -373,8 +375,14 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, + changed = subs->cur_audiofmt != fmt || + subs->period_bytes != params_period_bytes(hw_params) || + subs->cur_rate != rate; ++ ++ down_read(&subs->stream->chip->shutdown_rwsem); ++ if (subs->stream->chip->shutdown) { ++ ret = -ENODEV; ++ goto unlock; ++ } + if ((ret = set_format(subs, fmt)) < 0) +- return ret; ++ goto unlock; + + if (subs->cur_rate != rate) { + struct usb_host_interface *alts; +@@ -383,12 +391,11 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, + alts = &iface->altsetting[fmt->altset_idx]; + ret = snd_usb_init_sample_rate(subs->stream->chip, subs->interface, alts, fmt, rate); + if (ret < 0) +- return ret; ++ goto unlock; + subs->cur_rate = rate; + } + + if (changed) { +- mutex_lock(&subs->stream->chip->shutdown_mutex); + /* format changed */ + snd_usb_release_substream_urbs(subs, 0); + /* influenced: period_bytes, channels, rate, format, */ +@@ -396,9 +403,10 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, + params_rate(hw_params), + snd_pcm_format_physical_width(params_format(hw_params)) * + params_channels(hw_params)); +- mutex_unlock(&subs->stream->chip->shutdown_mutex); + } + ++unlock: ++ up_read(&subs->stream->chip->shutdown_rwsem); + return ret; + } + +@@ -414,9 +422,9 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream) + subs->cur_audiofmt = NULL; + subs->cur_rate = 0; + subs->period_bytes = 0; +- mutex_lock(&subs->stream->chip->shutdown_mutex); ++ down_read(&subs->stream->chip->shutdown_rwsem); + snd_usb_release_substream_urbs(subs, 0); +- mutex_unlock(&subs->stream->chip->shutdown_mutex); ++ up_read(&subs->stream->chip->shutdown_rwsem); + return snd_pcm_lib_free_vmalloc_buffer(substream); + } + +@@ -429,12 +437,18 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) + { + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_usb_substream *subs = runtime->private_data; ++ int ret = 0; + + if (! subs->cur_audiofmt) { + snd_printk(KERN_ERR "usbaudio: no format is specified!\n"); + return -ENXIO; + } + ++ down_read(&subs->stream->chip->shutdown_rwsem); ++ if (subs->stream->chip->shutdown) { ++ ret = -ENODEV; ++ goto unlock; ++ } + /* some unit conversions in runtime */ + subs->maxframesize = bytes_to_frames(runtime, subs->maxpacksize); + subs->curframesize = bytes_to_frames(runtime, subs->curpacksize); +@@ -447,7 +461,10 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) + subs->last_frame_number = 0; + runtime->delay = 0; + +- return snd_usb_substream_prepare(subs, runtime); ++ ret = snd_usb_substream_prepare(subs, runtime); ++ unlock: ++ up_read(&subs->stream->chip->shutdown_rwsem); ++ return ret; + } + + static struct snd_pcm_hardware snd_usb_hardware = +@@ -500,7 +517,7 @@ static int hw_check_valid_format(struct snd_usb_substream *subs, + return 0; + } + /* check whether the period time is >= the data packet interval */ +- if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) { ++ if (subs->speed != USB_SPEED_FULL) { + ptime = 125 * (1 << fp->datainterval); + if (ptime > pt->max || (ptime == pt->max && pt->openmax)) { + hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max); +@@ -776,7 +793,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre + return err; + + param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME; +- if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) ++ if (subs->speed == USB_SPEED_FULL) + /* full speed devices have fixed data packet interval */ + ptmin = 1000; + if (ptmin == 1000) +diff --git a/sound/usb/proc.c b/sound/usb/proc.c +index 961c9a2..aef03db 100644 +--- a/sound/usb/proc.c ++++ b/sound/usb/proc.c +@@ -107,7 +107,7 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s + } + snd_iprintf(buffer, "\n"); + } +- if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) ++ if (subs->speed != USB_SPEED_FULL) + snd_iprintf(buffer, " Data packet interval: %d us\n", + 125 * (1 << fp->datainterval)); + // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize); +@@ -128,7 +128,7 @@ static void proc_dump_substream_status(struct snd_usb_substream *subs, struct sn + snd_iprintf(buffer, "]\n"); + snd_iprintf(buffer, " Packet Size = %d\n", subs->curpacksize); + snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n", +- snd_usb_get_speed(subs->dev) == USB_SPEED_FULL ++ subs->speed == USB_SPEED_FULL + ? get_full_speed_hz(subs->freqm) + : get_high_speed_hz(subs->freqm), + subs->freqm >> 16, subs->freqm & 0xffff); +diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h +index 3e2b035..6c805a5 100644 +--- a/sound/usb/usbaudio.h ++++ b/sound/usb/usbaudio.h +@@ -36,7 +36,7 @@ struct snd_usb_audio { + struct snd_card *card; + struct usb_interface *pm_intf; + u32 usb_id; +- struct mutex shutdown_mutex; ++ struct rw_semaphore shutdown_rwsem; + unsigned int shutdown:1; + unsigned int probing:1; + unsigned int autosuspended:1; diff --git a/3.2.33/4420_grsecurity-2.9.1-3.2.33-201211122213.patch b/3.2.34/4420_grsecurity-2.9.1-3.2.34-201211181104.patch index 7a220ce..08bfa63 100644 --- a/3.2.33/4420_grsecurity-2.9.1-3.2.33-201211122213.patch +++ b/3.2.34/4420_grsecurity-2.9.1-3.2.34-201211181104.patch @@ -255,7 +255,7 @@ index 88fd7f5..b318a78 100644 ============================================================== diff --git a/Makefile b/Makefile -index 63ca1ea2..811946a 100644 +index 14ebacf..f7e0add 100644 --- a/Makefile +++ b/Makefile @@ -245,8 +245,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ @@ -5856,6 +5856,26 @@ index cb85458..e063f17 100644 extra-y := head_$(BITS).o extra-y += init_task.o +diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c +index a19c8a0..d04a60b 100644 +--- a/arch/sparc/kernel/leon_kernel.c ++++ b/arch/sparc/kernel/leon_kernel.c +@@ -53,11 +53,13 @@ static inline unsigned int leon_eirq_get(int cpu) + static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc) + { + unsigned int eirq; ++ struct irq_bucket *p; + int cpu = sparc_leon3_cpuid(); + + eirq = leon_eirq_get(cpu); +- if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */ +- generic_handle_irq(irq_map[eirq]->irq); ++ p = irq_map[eirq]; ++ if ((eirq & 0x10) && p && p->irq) /* bit4 tells if IRQ happened */ ++ generic_handle_irq(p->irq); + } + + /* The extended IRQ controller has been found, this function registers it */ diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index f793742..4d880af 100644 --- a/arch/sparc/kernel/process_32.c @@ -12505,10 +12525,10 @@ index cb23852..2dde194 100644 asmlinkage long sys32_sched_rr_get_interval(compat_pid_t, diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h -index 2d2f01c..f985723 100644 +index d75adff..c0cc78b 100644 --- a/arch/x86/include/asm/system.h +++ b/arch/x86/include/asm/system.h -@@ -129,7 +129,7 @@ do { \ +@@ -125,7 +125,7 @@ do { \ "call __switch_to\n\t" \ "movq "__percpu_arg([current_task])",%%rsi\n\t" \ __switch_canary \ @@ -12517,7 +12537,7 @@ index 2d2f01c..f985723 100644 "movq %%rax,%%rdi\n\t" \ "testl %[_tif_fork],%P[ti_flags](%%r8)\n\t" \ "jnz ret_from_fork\n\t" \ -@@ -140,7 +140,7 @@ do { \ +@@ -136,7 +136,7 @@ do { \ [threadrsp] "i" (offsetof(struct task_struct, thread.sp)), \ [ti_flags] "i" (offsetof(struct thread_info, flags)), \ [_tif_fork] "i" (_TIF_FORK), \ @@ -12526,7 +12546,7 @@ index 2d2f01c..f985723 100644 [current_task] "m" (current_task) \ __switch_canary_iparam \ : "memory", "cc" __EXTRA_CLOBBER) -@@ -200,7 +200,7 @@ static inline unsigned long get_limit(unsigned long segment) +@@ -196,7 +196,7 @@ static inline unsigned long get_limit(unsigned long segment) { unsigned long __limit; asm("lsll %1,%0" : "=r" (__limit) : "r" (segment)); @@ -12535,7 +12555,7 @@ index 2d2f01c..f985723 100644 } static inline void native_clts(void) -@@ -397,13 +397,13 @@ void enable_hlt(void); +@@ -390,13 +390,13 @@ static inline void clflush(volatile void *__p) void cpu_idle_wait(void); @@ -15804,7 +15824,7 @@ index 4893d58..0152a42 100644 /* diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S -index 6274f5f..b451ef1 100644 +index 6274f5f..c1b617b 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -55,6 +55,8 @@ @@ -15880,7 +15900,7 @@ index 6274f5f..b451ef1 100644 jmp *%rdi #endif -@@ -178,6 +186,280 @@ ENTRY(native_usergs_sysret64) +@@ -178,6 +186,273 @@ ENTRY(native_usergs_sysret64) ENDPROC(native_usergs_sysret64) #endif /* CONFIG_PARAVIRT */ @@ -15966,13 +15986,6 @@ index 6274f5f..b451ef1 100644 + ljmpq __KERNEL_CS,3f +3: SET_RDI_INTO_CR0 + jmp 1b -+#ifdef CONFIG_PARAVIRT -+ PV_RESTORE_REGS(CLBR_RDI); -+#endif -+ -+ popq %rdi -+ pax_force_retaddr -+ retq +ENDPROC(pax_exit_kernel) +#endif + @@ -16161,7 +16174,7 @@ index 6274f5f..b451ef1 100644 .macro TRACE_IRQS_IRETQ offset=ARGOFFSET #ifdef CONFIG_TRACE_IRQFLAGS -@@ -231,8 +513,8 @@ ENDPROC(native_usergs_sysret64) +@@ -231,8 +506,8 @@ ENDPROC(native_usergs_sysret64) .endm .macro UNFAKE_STACK_FRAME @@ -16172,7 +16185,7 @@ index 6274f5f..b451ef1 100644 .endm /* -@@ -319,7 +601,7 @@ ENDPROC(native_usergs_sysret64) +@@ -319,7 +594,7 @@ ENDPROC(native_usergs_sysret64) movq %rsp, %rsi leaq -RBP(%rsp),%rdi /* arg1 for handler */ @@ -16181,7 +16194,7 @@ index 6274f5f..b451ef1 100644 je 1f SWAPGS /* -@@ -355,9 +637,10 @@ ENTRY(save_rest) +@@ -355,9 +630,10 @@ ENTRY(save_rest) movq_cfi r15, R15+16 movq %r11, 8(%rsp) /* return address */ FIXUP_TOP_OF_STACK %r11, 16 @@ -16193,7 +16206,7 @@ index 6274f5f..b451ef1 100644 /* save complete stack frame */ .pushsection .kprobes.text, "ax" -@@ -386,9 +669,10 @@ ENTRY(save_paranoid) +@@ -386,9 +662,10 @@ ENTRY(save_paranoid) js 1f /* negative -> in kernel */ SWAPGS xorl %ebx,%ebx @@ -16206,7 +16219,7 @@ index 6274f5f..b451ef1 100644 .popsection /* -@@ -410,7 +694,7 @@ ENTRY(ret_from_fork) +@@ -410,7 +687,7 @@ ENTRY(ret_from_fork) RESTORE_REST @@ -16215,7 +16228,7 @@ index 6274f5f..b451ef1 100644 je int_ret_from_sys_call testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET -@@ -420,7 +704,7 @@ ENTRY(ret_from_fork) +@@ -420,7 +697,7 @@ ENTRY(ret_from_fork) jmp ret_from_sys_call # go to the SYSRET fastpath CFI_ENDPROC @@ -16224,7 +16237,7 @@ index 6274f5f..b451ef1 100644 /* * System call entry. Up to 6 arguments in registers are supported. -@@ -456,7 +740,7 @@ END(ret_from_fork) +@@ -456,7 +733,7 @@ END(ret_from_fork) ENTRY(system_call) CFI_STARTPROC simple CFI_SIGNAL_FRAME @@ -16233,7 +16246,7 @@ index 6274f5f..b451ef1 100644 CFI_REGISTER rip,rcx /*CFI_REGISTER rflags,r11*/ SWAPGS_UNSAFE_STACK -@@ -469,12 +753,18 @@ ENTRY(system_call_after_swapgs) +@@ -469,12 +746,18 @@ ENTRY(system_call_after_swapgs) movq %rsp,PER_CPU_VAR(old_rsp) movq PER_CPU_VAR(kernel_stack),%rsp @@ -16253,7 +16266,7 @@ index 6274f5f..b451ef1 100644 movq %rax,ORIG_RAX-ARGOFFSET(%rsp) movq %rcx,RIP-ARGOFFSET(%rsp) CFI_REL_OFFSET rip,RIP-ARGOFFSET -@@ -484,7 +774,7 @@ ENTRY(system_call_after_swapgs) +@@ -484,7 +767,7 @@ ENTRY(system_call_after_swapgs) system_call_fastpath: cmpq $__NR_syscall_max,%rax ja badsys @@ -16262,7 +16275,7 @@ index 6274f5f..b451ef1 100644 call *sys_call_table(,%rax,8) # XXX: rip relative movq %rax,RAX-ARGOFFSET(%rsp) /* -@@ -503,6 +793,8 @@ sysret_check: +@@ -503,6 +786,8 @@ sysret_check: andl %edi,%edx jnz sysret_careful CFI_REMEMBER_STATE @@ -16271,7 +16284,7 @@ index 6274f5f..b451ef1 100644 /* * sysretq will re-enable interrupts: */ -@@ -554,14 +846,18 @@ badsys: +@@ -554,14 +839,18 @@ badsys: * jump back to the normal fast path. */ auditsys: @@ -16291,7 +16304,7 @@ index 6274f5f..b451ef1 100644 jmp system_call_fastpath /* -@@ -591,16 +887,20 @@ tracesys: +@@ -591,16 +880,20 @@ tracesys: FIXUP_TOP_OF_STACK %rdi movq %rsp,%rdi call syscall_trace_enter @@ -16313,7 +16326,7 @@ index 6274f5f..b451ef1 100644 call *sys_call_table(,%rax,8) movq %rax,RAX-ARGOFFSET(%rsp) /* Use IRET because user could have changed frame */ -@@ -612,7 +912,7 @@ tracesys: +@@ -612,7 +905,7 @@ tracesys: GLOBAL(int_ret_from_sys_call) DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF @@ -16322,7 +16335,7 @@ index 6274f5f..b451ef1 100644 je retint_restore_args movl $_TIF_ALLWORK_MASK,%edi /* edi: mask to check */ -@@ -623,7 +923,9 @@ GLOBAL(int_with_check) +@@ -623,7 +916,9 @@ GLOBAL(int_with_check) andl %edi,%edx jnz int_careful andl $~TS_COMPAT,TI_status(%rcx) @@ -16333,7 +16346,7 @@ index 6274f5f..b451ef1 100644 /* Either reschedule or signal or syscall exit tracking needed. */ /* First do a reschedule test. */ -@@ -669,7 +971,7 @@ int_restore_rest: +@@ -669,7 +964,7 @@ int_restore_rest: TRACE_IRQS_OFF jmp int_with_check CFI_ENDPROC @@ -16342,7 +16355,7 @@ index 6274f5f..b451ef1 100644 /* * Certain special system calls that need to save a complete full stack frame. -@@ -685,7 +987,7 @@ ENTRY(\label) +@@ -685,7 +980,7 @@ ENTRY(\label) call \func jmp ptregscall_common CFI_ENDPROC @@ -16351,7 +16364,7 @@ index 6274f5f..b451ef1 100644 .endm PTREGSCALL stub_clone, sys_clone, %r8 -@@ -703,9 +1005,10 @@ ENTRY(ptregscall_common) +@@ -703,9 +998,10 @@ ENTRY(ptregscall_common) movq_cfi_restore R12+8, r12 movq_cfi_restore RBP+8, rbp movq_cfi_restore RBX+8, rbx @@ -16363,7 +16376,7 @@ index 6274f5f..b451ef1 100644 ENTRY(stub_execve) CFI_STARTPROC -@@ -720,7 +1023,7 @@ ENTRY(stub_execve) +@@ -720,7 +1016,7 @@ ENTRY(stub_execve) RESTORE_REST jmp int_ret_from_sys_call CFI_ENDPROC @@ -16372,7 +16385,7 @@ index 6274f5f..b451ef1 100644 /* * sigreturn is special because it needs to restore all registers on return. -@@ -738,7 +1041,7 @@ ENTRY(stub_rt_sigreturn) +@@ -738,7 +1034,7 @@ ENTRY(stub_rt_sigreturn) RESTORE_REST jmp int_ret_from_sys_call CFI_ENDPROC @@ -16381,7 +16394,7 @@ index 6274f5f..b451ef1 100644 /* * Build the entry stubs and pointer table with some assembler magic. -@@ -773,7 +1076,7 @@ vector=vector+1 +@@ -773,7 +1069,7 @@ vector=vector+1 2: jmp common_interrupt .endr CFI_ENDPROC @@ -16390,7 +16403,7 @@ index 6274f5f..b451ef1 100644 .previous END(interrupt) -@@ -793,6 +1096,16 @@ END(interrupt) +@@ -793,6 +1089,16 @@ END(interrupt) subq $ORIG_RAX-RBP, %rsp CFI_ADJUST_CFA_OFFSET ORIG_RAX-RBP SAVE_ARGS_IRQ @@ -16407,7 +16420,7 @@ index 6274f5f..b451ef1 100644 call \func .endm -@@ -824,7 +1137,7 @@ ret_from_intr: +@@ -824,7 +1130,7 @@ ret_from_intr: exit_intr: GET_THREAD_INFO(%rcx) @@ -16416,7 +16429,7 @@ index 6274f5f..b451ef1 100644 je retint_kernel /* Interrupt came from user space */ -@@ -846,12 +1159,16 @@ retint_swapgs: /* return to user-space */ +@@ -846,12 +1152,16 @@ retint_swapgs: /* return to user-space */ * The iretq could re-enable interrupts: */ DISABLE_INTERRUPTS(CLBR_ANY) @@ -16433,7 +16446,7 @@ index 6274f5f..b451ef1 100644 /* * The iretq could re-enable interrupts: */ -@@ -940,7 +1257,7 @@ ENTRY(retint_kernel) +@@ -940,7 +1250,7 @@ ENTRY(retint_kernel) #endif CFI_ENDPROC @@ -16442,7 +16455,7 @@ index 6274f5f..b451ef1 100644 /* * End of kprobes section */ -@@ -956,7 +1273,7 @@ ENTRY(\sym) +@@ -956,7 +1266,7 @@ ENTRY(\sym) interrupt \do_sym jmp ret_from_intr CFI_ENDPROC @@ -16451,7 +16464,7 @@ index 6274f5f..b451ef1 100644 .endm #ifdef CONFIG_SMP -@@ -1021,12 +1338,22 @@ ENTRY(\sym) +@@ -1021,12 +1331,22 @@ ENTRY(\sym) CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 call error_entry DEFAULT_FRAME 0 @@ -16475,7 +16488,7 @@ index 6274f5f..b451ef1 100644 .endm .macro paranoidzeroentry sym do_sym -@@ -1038,15 +1365,25 @@ ENTRY(\sym) +@@ -1038,15 +1358,25 @@ ENTRY(\sym) CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 call save_paranoid TRACE_IRQS_OFF @@ -16503,7 +16516,7 @@ index 6274f5f..b451ef1 100644 .macro paranoidzeroentry_ist sym do_sym ist ENTRY(\sym) INTR_FRAME -@@ -1056,14 +1393,30 @@ ENTRY(\sym) +@@ -1056,14 +1386,30 @@ ENTRY(\sym) CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 call save_paranoid TRACE_IRQS_OFF @@ -16535,7 +16548,7 @@ index 6274f5f..b451ef1 100644 .endm .macro errorentry sym do_sym -@@ -1074,13 +1427,23 @@ ENTRY(\sym) +@@ -1074,13 +1420,23 @@ ENTRY(\sym) CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 call error_entry DEFAULT_FRAME 0 @@ -16560,7 +16573,7 @@ index 6274f5f..b451ef1 100644 .endm /* error code is on the stack already */ -@@ -1093,13 +1456,23 @@ ENTRY(\sym) +@@ -1093,13 +1449,23 @@ ENTRY(\sym) call save_paranoid DEFAULT_FRAME 0 TRACE_IRQS_OFF @@ -16585,7 +16598,7 @@ index 6274f5f..b451ef1 100644 .endm zeroentry divide_error do_divide_error -@@ -1129,9 +1502,10 @@ gs_change: +@@ -1129,9 +1495,10 @@ gs_change: 2: mfence /* workaround */ SWAPGS popfq_cfi @@ -16597,7 +16610,7 @@ index 6274f5f..b451ef1 100644 .section __ex_table,"a" .align 8 -@@ -1153,13 +1527,14 @@ ENTRY(kernel_thread_helper) +@@ -1153,13 +1520,14 @@ ENTRY(kernel_thread_helper) * Here we are in the child and the registers are set as they were * at kernel_thread() invocation in the parent. */ @@ -16613,7 +16626,7 @@ index 6274f5f..b451ef1 100644 /* * execve(). This function needs to use IRET, not SYSRET, to set up all state properly. -@@ -1186,11 +1561,11 @@ ENTRY(kernel_execve) +@@ -1186,11 +1554,11 @@ ENTRY(kernel_execve) RESTORE_REST testq %rax,%rax je int_ret_from_sys_call @@ -16627,7 +16640,7 @@ index 6274f5f..b451ef1 100644 /* Call softirq on interrupt stack. Interrupts are off. */ ENTRY(call_softirq) -@@ -1208,9 +1583,10 @@ ENTRY(call_softirq) +@@ -1208,9 +1576,10 @@ ENTRY(call_softirq) CFI_DEF_CFA_REGISTER rsp CFI_ADJUST_CFA_OFFSET -8 decl PER_CPU_VAR(irq_count) @@ -16639,7 +16652,7 @@ index 6274f5f..b451ef1 100644 #ifdef CONFIG_XEN zeroentry xen_hypervisor_callback xen_do_hypervisor_callback -@@ -1248,7 +1624,7 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) +@@ -1248,7 +1617,7 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) decl PER_CPU_VAR(irq_count) jmp error_exit CFI_ENDPROC @@ -16648,7 +16661,7 @@ index 6274f5f..b451ef1 100644 /* * Hypervisor uses this for application faults while it executes. -@@ -1307,7 +1683,7 @@ ENTRY(xen_failsafe_callback) +@@ -1307,7 +1676,7 @@ ENTRY(xen_failsafe_callback) SAVE_ALL jmp error_exit CFI_ENDPROC @@ -16657,7 +16670,7 @@ index 6274f5f..b451ef1 100644 apicinterrupt XEN_HVM_EVTCHN_CALLBACK \ xen_hvm_callback_vector xen_evtchn_do_upcall -@@ -1356,16 +1732,31 @@ ENTRY(paranoid_exit) +@@ -1356,16 +1725,31 @@ ENTRY(paranoid_exit) TRACE_IRQS_OFF testl %ebx,%ebx /* swapgs needed? */ jnz paranoid_restore @@ -16690,7 +16703,7 @@ index 6274f5f..b451ef1 100644 jmp irq_return paranoid_userspace: GET_THREAD_INFO(%rcx) -@@ -1394,7 +1785,7 @@ paranoid_schedule: +@@ -1394,7 +1778,7 @@ paranoid_schedule: TRACE_IRQS_OFF jmp paranoid_userspace CFI_ENDPROC @@ -16699,7 +16712,7 @@ index 6274f5f..b451ef1 100644 /* * Exception entry point. This expects an error code/orig_rax on the stack. -@@ -1421,12 +1812,13 @@ ENTRY(error_entry) +@@ -1421,12 +1805,13 @@ ENTRY(error_entry) movq_cfi r14, R14+8 movq_cfi r15, R15+8 xorl %ebx,%ebx @@ -16714,7 +16727,7 @@ index 6274f5f..b451ef1 100644 ret /* -@@ -1453,7 +1845,7 @@ bstep_iret: +@@ -1453,7 +1838,7 @@ bstep_iret: movq %rcx,RIP+8(%rsp) jmp error_swapgs CFI_ENDPROC @@ -16723,7 +16736,7 @@ index 6274f5f..b451ef1 100644 /* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */ -@@ -1473,7 +1865,7 @@ ENTRY(error_exit) +@@ -1473,7 +1858,7 @@ ENTRY(error_exit) jnz retint_careful jmp retint_swapgs CFI_ENDPROC @@ -16732,7 +16745,7 @@ index 6274f5f..b451ef1 100644 /* runs on exception stack */ -@@ -1485,6 +1877,16 @@ ENTRY(nmi) +@@ -1485,6 +1870,16 @@ ENTRY(nmi) CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 call save_paranoid DEFAULT_FRAME 0 @@ -16749,7 +16762,7 @@ index 6274f5f..b451ef1 100644 /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */ movq %rsp,%rdi movq $-1,%rsi -@@ -1495,12 +1897,28 @@ ENTRY(nmi) +@@ -1495,12 +1890,28 @@ ENTRY(nmi) DISABLE_INTERRUPTS(CLBR_NONE) testl %ebx,%ebx /* swapgs needed? */ jnz nmi_restore @@ -16779,7 +16792,7 @@ index 6274f5f..b451ef1 100644 jmp irq_return nmi_userspace: GET_THREAD_INFO(%rcx) -@@ -1529,14 +1947,14 @@ nmi_schedule: +@@ -1529,14 +1940,14 @@ nmi_schedule: jmp paranoid_exit CFI_ENDPROC #endif @@ -18569,7 +18582,7 @@ index 35ccf75..7a15747 100644 #define DEBUG 1 diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c -index ee5d4fb..426649b 100644 +index 59b9b37..f02ee42 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -48,16 +48,33 @@ void free_thread_xstate(struct task_struct *tsk) @@ -18652,7 +18665,7 @@ index ee5d4fb..426649b 100644 #else regs.ss = __KERNEL_DS; #endif -@@ -411,7 +431,7 @@ bool set_pm_idle_to_default(void) +@@ -387,7 +407,7 @@ bool set_pm_idle_to_default(void) return ret; } @@ -18661,7 +18674,7 @@ index ee5d4fb..426649b 100644 { local_irq_disable(); /* -@@ -653,16 +673,37 @@ static int __init idle_setup(char *str) +@@ -629,16 +649,37 @@ static int __init idle_setup(char *str) } early_param("idle", idle_setup); @@ -27533,10 +27546,10 @@ index 69b9ef6..cbe5f3a 100644 #ifdef CONFIG_ACPI_NUMA diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c -index ec3d603..fa4ed1b 100644 +index 2b8b0de..0787f8a 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c -@@ -1738,6 +1738,9 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, +@@ -1757,6 +1757,9 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, convert_pfn_mfn(init_level4_pgt); convert_pfn_mfn(level3_ident_pgt); convert_pfn_mfn(level3_kernel_pgt); @@ -27546,7 +27559,7 @@ index ec3d603..fa4ed1b 100644 l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd); l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud); -@@ -1756,7 +1759,11 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, +@@ -1775,7 +1778,11 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, set_page_prot(init_level4_pgt, PAGE_KERNEL_RO); set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO); set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO); @@ -27558,7 +27571,7 @@ index ec3d603..fa4ed1b 100644 set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO); set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO); -@@ -1967,6 +1974,7 @@ static void __init xen_post_allocator_init(void) +@@ -1986,6 +1993,7 @@ static void __init xen_post_allocator_init(void) pv_mmu_ops.set_pud = xen_set_pud; #if PAGETABLE_LEVELS == 4 pv_mmu_ops.set_pgd = xen_set_pgd; @@ -27566,7 +27579,7 @@ index ec3d603..fa4ed1b 100644 #endif /* This will work as long as patching hasn't happened yet -@@ -2048,6 +2056,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = { +@@ -2067,6 +2075,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = { .pud_val = PV_CALLEE_SAVE(xen_pud_val), .make_pud = PV_CALLEE_SAVE(xen_make_pud), .set_pgd = xen_set_pgd_hyper, @@ -27882,7 +27895,7 @@ index 9e76a32..48d7145 100644 goto error; diff --git a/crypto/cryptd.c b/crypto/cryptd.c -index 671d4d6..5f24030 100644 +index 7bdd61b..afec999 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c @@ -63,7 +63,7 @@ struct cryptd_blkcipher_ctx { @@ -30806,7 +30819,7 @@ index 40c187c..5746164 100644 DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c -index 828bf65..cdaa0e9 100644 +index 020b103..68ae292 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -71,7 +71,7 @@ static int drm_setup(struct drm_device * dev) @@ -30818,18 +30831,22 @@ index 828bf65..cdaa0e9 100644 dev->sigdata.lock = NULL; -@@ -135,8 +135,8 @@ int drm_open(struct inode *inode, struct file *filp) +@@ -135,11 +135,11 @@ int drm_open(struct inode *inode, struct file *filp) retcode = drm_open_helper(inode, filp, dev); if (!retcode) { - atomic_inc(&dev->counts[_DRM_STAT_OPENS]); -- if (!dev->open_count++) +- if (!dev->open_count++) { + atomic_inc_unchecked(&dev->counts[_DRM_STAT_OPENS]); -+ if (local_inc_return(&dev->open_count) == 1) ++ if (local_inc_return(&dev->open_count) == 1) { retcode = drm_setup(dev); + if (retcode) +- dev->open_count--; ++ local_dec(&dev->open_count); + } } if (!retcode) { -@@ -473,7 +473,7 @@ int drm_release(struct inode *inode, struct file *filp) +@@ -476,7 +476,7 @@ int drm_release(struct inode *inode, struct file *filp) mutex_lock(&drm_global_mutex); @@ -30838,7 +30855,7 @@ index 828bf65..cdaa0e9 100644 if (dev->driver->preclose) dev->driver->preclose(dev, file_priv); -@@ -485,7 +485,7 @@ int drm_release(struct inode *inode, struct file *filp) +@@ -488,7 +488,7 @@ int drm_release(struct inode *inode, struct file *filp) DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", task_pid_nr(current), (long)old_encode_dev(file_priv->minor->device), @@ -30847,7 +30864,7 @@ index 828bf65..cdaa0e9 100644 /* Release any auth tokens that might point to this file_priv, (do that under the drm_global_mutex) */ -@@ -571,8 +571,8 @@ int drm_release(struct inode *inode, struct file *filp) +@@ -574,8 +574,8 @@ int drm_release(struct inode *inode, struct file *filp) * End inline drm_release */ @@ -31211,7 +31228,7 @@ index 2812d7b..c35ade7 100644 INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); INIT_WORK(&dev_priv->error_work, i915_error_work_func); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c -index adac0dd..65f8049 100644 +index adac0dd..bb551dd 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2196,7 +2196,7 @@ intel_finish_fb(struct drm_framebuffer *old_fb) @@ -31223,16 +31240,17 @@ index adac0dd..65f8049 100644 /* Big Hammer, we also need to ensure that any pending * MI_WAIT_FOR_EVENT inside a user batch buffer on the -@@ -6971,7 +6971,7 @@ static void do_intel_finish_page_flip(struct drm_device *dev, +@@ -6971,8 +6971,7 @@ static void do_intel_finish_page_flip(struct drm_device *dev, obj = work->old_fb_obj; - atomic_clear_mask(1 << intel_crtc->plane, -+ atomic_clear_mask_unchecked(1 << intel_crtc->plane, - &obj->pending_flip.counter); +- &obj->pending_flip.counter); ++ atomic_clear_mask_unchecked(1 << intel_crtc->plane, &obj->pending_flip); wake_up(&dev_priv->pending_flip_queue); -@@ -7167,7 +7167,13 @@ static int intel_gen6_queue_flip(struct drm_device *dev, + schedule_work(&work->work); +@@ -7167,7 +7166,13 @@ static int intel_gen6_queue_flip(struct drm_device *dev, OUT_RING(fb->pitch | obj->tiling_mode); OUT_RING(obj->gtt_offset); @@ -31247,7 +31265,7 @@ index adac0dd..65f8049 100644 pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; OUT_RING(pf | pipesrc); ADVANCE_LP_RING(); -@@ -7299,7 +7305,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, +@@ -7299,7 +7304,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, /* Block clients from rendering to the new back buffer until * the flip occurs and the object is no longer visible. */ @@ -31256,7 +31274,7 @@ index adac0dd..65f8049 100644 ret = dev_priv->display.queue_flip(dev, crtc, fb, obj); if (ret) -@@ -7313,7 +7319,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, +@@ -7313,7 +7318,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, return 0; cleanup_pending: @@ -31435,10 +31453,10 @@ index 7ce3fde..cb3ea04 100644 if (++trycnt > 100000) { NV_ERROR(dev, "%s failed and gave up.\n", __func__); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c -index d8831ab..0ba8356 100644 +index 01adcfb..c6726fe 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c -@@ -542,7 +542,7 @@ static bool nouveau_switcheroo_can_switch(struct pci_dev *pdev) +@@ -544,7 +544,7 @@ static bool nouveau_switcheroo_can_switch(struct pci_dev *pdev) bool can_switch; spin_lock(&dev->count_lock); @@ -35304,7 +35322,7 @@ index 8d082b4..aa749ae 100644 /* * Timer function to enforce the timelimit on the partition disengage. diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c -index ba168a7..399925d 100644 +index ba168a7..399925d6 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -347,6 +347,11 @@ void st_int_recv(void *disc_data, @@ -36042,7 +36060,7 @@ index 49b549f..13d648c 100644 mac->phydev = phydev; diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c -index 4b43bc5..32d9a1b 100644 +index b8db4cd..41bf50c 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -704,17 +704,17 @@ struct rtl8169_private { @@ -38845,7 +38863,7 @@ index ed147c4..94fc3c6 100644 /* core tmem accessor functions */ diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c -index f35cb10..187b92a 100644 +index 6fa7222..6c7cfc2 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -1351,7 +1351,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) @@ -38857,40 +38875,6 @@ index f35cb10..187b92a 100644 if (hdr->flags & ISCSI_FLAG_CMD_FINAL) if (--cmd->outstanding_r2ts < 1) { iscsit_stop_dataout_timer(cmd); -diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c -index f8773ae..a0143a0 100644 ---- a/drivers/target/target_core_device.c -+++ b/drivers/target/target_core_device.c -@@ -835,20 +835,20 @@ int se_dev_check_shutdown(struct se_device *dev) - - u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) - { -- u32 tmp, aligned_max_sectors; -+ u32 aligned_max_sectors; -+ u32 alignment; - /* - * Limit max_sectors to a PAGE_SIZE aligned value for modern - * transport_allocate_data_tasks() operation. - */ -- tmp = rounddown((max_sectors * block_size), PAGE_SIZE); -- aligned_max_sectors = (tmp / block_size); -- if (max_sectors != aligned_max_sectors) { -- printk(KERN_INFO "Rounding down aligned max_sectors from %u" -- " to %u\n", max_sectors, aligned_max_sectors); -- return aligned_max_sectors; -- } -+ alignment = max(1ul, PAGE_SIZE / block_size); -+ aligned_max_sectors = rounddown(max_sectors, alignment); - -- return max_sectors; -+ if (max_sectors != aligned_max_sectors) -+ pr_info("Rounding down aligned max_sectors from %u to %u\n", -+ max_sectors, aligned_max_sectors); -+ -+ return aligned_max_sectors; - } - - void se_dev_set_default_attribs( diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 6845228..df77141 100644 --- a/drivers/target/target_core_tmr.c @@ -43295,7 +43279,7 @@ index a6395bd..f1e376a 100644 (unsigned long) create_aout_tables((char __user *) bprm->p, bprm); #ifdef __alpha__ diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c -index 8dd615c..4b512f5 100644 +index 8dd615c..e65f3cf 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -32,6 +32,7 @@ @@ -43441,7 +43425,7 @@ index 8dd615c..4b512f5 100644 error = -ENOMEM; goto out_close; } -@@ -528,6 +549,311 @@ out: +@@ -528,6 +549,315 @@ out: return error; } @@ -43675,7 +43659,7 @@ index 8dd615c..4b512f5 100644 + unsigned long pax_flags_hardmode = 0UL, pax_flags_softmode = 0UL; + + xattr_size = vfs_getxattr(file->f_path.dentry, XATTR_NAME_PAX_FLAGS, xattr_value, sizeof xattr_value); -+ if (xattr_size <= 0) ++ if (xattr_size <= 0 || xattr_size > 5) + return ~0UL; + + for (i = 0; i < xattr_size; i++) @@ -43685,9 +43669,13 @@ index 8dd615c..4b512f5 100644 + +#define parse_flag(option1, option2, flag) \ + case option1: \ ++ if (pax_flags_hardmode & MF_PAX_##flag) \ ++ return ~0UL; \ + pax_flags_hardmode |= MF_PAX_##flag; \ + break; \ + case option2: \ ++ if (pax_flags_softmode & MF_PAX_##flag) \ ++ return ~0UL; \ + pax_flags_softmode |= MF_PAX_##flag; \ + break; + @@ -43753,7 +43741,7 @@ index 8dd615c..4b512f5 100644 /* * These are the functions used to load ELF style executables and shared * libraries. There is no binary dependent code anywhere else. -@@ -544,6 +870,11 @@ static unsigned long randomize_stack_top(unsigned long stack_top) +@@ -544,6 +874,11 @@ static unsigned long randomize_stack_top(unsigned long stack_top) { unsigned int random_variable = 0; @@ -43765,7 +43753,7 @@ index 8dd615c..4b512f5 100644 if ((current->flags & PF_RANDOMIZE) && !(current->personality & ADDR_NO_RANDOMIZE)) { random_variable = get_random_int() & STACK_RND_MASK; -@@ -562,7 +893,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +@@ -562,7 +897,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) unsigned long load_addr = 0, load_bias = 0; int load_addr_set = 0; char * elf_interpreter = NULL; @@ -43774,7 +43762,7 @@ index 8dd615c..4b512f5 100644 struct elf_phdr *elf_ppnt, *elf_phdata; unsigned long elf_bss, elf_brk; int retval, i; -@@ -572,11 +903,11 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +@@ -572,11 +907,11 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) unsigned long start_code, end_code, start_data, end_data; unsigned long reloc_func_desc __maybe_unused = 0; int executable_stack = EXSTACK_DEFAULT; @@ -43787,7 +43775,7 @@ index 8dd615c..4b512f5 100644 loc = kmalloc(sizeof(*loc), GFP_KERNEL); if (!loc) { -@@ -713,11 +1044,81 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +@@ -713,11 +1048,81 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) /* OK, This is the point of no return */ current->flags &= ~PF_FORKNOEXEC; @@ -43870,7 +43858,7 @@ index 8dd615c..4b512f5 100644 if (elf_read_implies_exec(loc->elf_ex, executable_stack)) current->personality |= READ_IMPLIES_EXEC; -@@ -808,6 +1209,20 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +@@ -808,6 +1213,20 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) #else load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); #endif @@ -43891,7 +43879,7 @@ index 8dd615c..4b512f5 100644 } error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, -@@ -840,9 +1255,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +@@ -840,9 +1259,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) * allowed task size. Note that p_filesz must always be * <= p_memsz so it is only necessary to check p_memsz. */ @@ -43904,7 +43892,7 @@ index 8dd615c..4b512f5 100644 /* set_brk can never work. Avoid overflows. */ send_sig(SIGKILL, current, 0); retval = -EINVAL; -@@ -881,17 +1296,43 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +@@ -881,17 +1300,43 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) goto out_free_dentry; } if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) { @@ -43954,7 +43942,7 @@ index 8dd615c..4b512f5 100644 load_bias); if (!IS_ERR((void *)elf_entry)) { /* -@@ -1098,7 +1539,7 @@ out: +@@ -1098,7 +1543,7 @@ out: * Decide what to dump of a segment, part, all or none. */ static unsigned long vma_dump_size(struct vm_area_struct *vma, @@ -43963,7 +43951,7 @@ index 8dd615c..4b512f5 100644 { #define FILTER(type) (mm_flags & (1UL << MMF_DUMP_##type)) -@@ -1132,7 +1573,7 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma, +@@ -1132,7 +1577,7 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma, if (vma->vm_file == NULL) return 0; @@ -43972,7 +43960,7 @@ index 8dd615c..4b512f5 100644 goto whole; /* -@@ -1354,9 +1795,9 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm) +@@ -1354,9 +1799,9 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm) { elf_addr_t *auxv = (elf_addr_t *) mm->saved_auxv; int i = 0; @@ -43984,7 +43972,7 @@ index 8dd615c..4b512f5 100644 fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv); } -@@ -1851,14 +2292,14 @@ static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum, +@@ -1851,14 +2296,14 @@ static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum, } static size_t elf_core_vma_data_size(struct vm_area_struct *gate_vma, @@ -44001,7 +43989,7 @@ index 8dd615c..4b512f5 100644 return size; } -@@ -1952,7 +2393,7 @@ static int elf_core_dump(struct coredump_params *cprm) +@@ -1952,7 +2397,7 @@ static int elf_core_dump(struct coredump_params *cprm) dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); @@ -44010,7 +43998,7 @@ index 8dd615c..4b512f5 100644 offset += elf_core_extra_data_size(); e_shoff = offset; -@@ -1966,10 +2407,12 @@ static int elf_core_dump(struct coredump_params *cprm) +@@ -1966,10 +2411,12 @@ static int elf_core_dump(struct coredump_params *cprm) offset = dataoff; size += sizeof(*elf); @@ -44023,7 +44011,7 @@ index 8dd615c..4b512f5 100644 if (size > cprm->limit || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note))) goto end_coredump; -@@ -1983,7 +2426,7 @@ static int elf_core_dump(struct coredump_params *cprm) +@@ -1983,7 +2430,7 @@ static int elf_core_dump(struct coredump_params *cprm) phdr.p_offset = offset; phdr.p_vaddr = vma->vm_start; phdr.p_paddr = 0; @@ -44032,7 +44020,7 @@ index 8dd615c..4b512f5 100644 phdr.p_memsz = vma->vm_end - vma->vm_start; offset += phdr.p_filesz; phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; -@@ -1994,6 +2437,7 @@ static int elf_core_dump(struct coredump_params *cprm) +@@ -1994,6 +2441,7 @@ static int elf_core_dump(struct coredump_params *cprm) phdr.p_align = ELF_EXEC_PAGESIZE; size += sizeof(phdr); @@ -44040,7 +44028,7 @@ index 8dd615c..4b512f5 100644 if (size > cprm->limit || !dump_write(cprm->file, &phdr, sizeof(phdr))) goto end_coredump; -@@ -2018,7 +2462,7 @@ static int elf_core_dump(struct coredump_params *cprm) +@@ -2018,7 +2466,7 @@ static int elf_core_dump(struct coredump_params *cprm) unsigned long addr; unsigned long end; @@ -44049,7 +44037,7 @@ index 8dd615c..4b512f5 100644 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) { struct page *page; -@@ -2027,6 +2471,7 @@ static int elf_core_dump(struct coredump_params *cprm) +@@ -2027,6 +2475,7 @@ static int elf_core_dump(struct coredump_params *cprm) page = get_dump_page(addr); if (page) { void *kaddr = kmap(page); @@ -44057,7 +44045,7 @@ index 8dd615c..4b512f5 100644 stop = ((size += PAGE_SIZE) > cprm->limit) || !dump_write(cprm->file, kaddr, PAGE_SIZE); -@@ -2044,6 +2489,7 @@ static int elf_core_dump(struct coredump_params *cprm) +@@ -2044,6 +2493,7 @@ static int elf_core_dump(struct coredump_params *cprm) if (e_phnum == PN_XNUM) { size += sizeof(*shdr4extnum); @@ -44065,7 +44053,7 @@ index 8dd615c..4b512f5 100644 if (size > cprm->limit || !dump_write(cprm->file, shdr4extnum, sizeof(*shdr4extnum))) -@@ -2064,6 +2510,97 @@ out: +@@ -2064,6 +2514,97 @@ out: #endif /* CONFIG_ELF_CORE */ @@ -66192,26 +66180,6 @@ index 9e5425b..8136ffc 100644 struct list_head list; /* Protects from simultaneous access to first_req list */ spinlock_t info_list_lock; -diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h -index 95852e3..19d632d 100644 ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -2431,6 +2431,15 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); - unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc); - - /** -+ * ieee80211_get_mesh_hdrlen - get mesh extension header length -+ * @meshhdr: the mesh extension header, only the flags field -+ * (first byte) will be accessed -+ * Returns the length of the extension header, which is always at -+ * least 6 bytes and at most 18 if address 5 and 6 are present. -+ */ -+unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); -+ -+/** - * DOC: Data path helpers - * - * In addition to generic utilities, cfg80211 also offers diff --git a/include/net/flow.h b/include/net/flow.h index 2a7eefd..3250f3b 100644 --- a/include/net/flow.h @@ -69098,7 +69066,7 @@ index 91c32a0..7b88d63 100644 seq_printf(m, "%40s %14lu %29s %pS\n", name, stats->contending_point[i], diff --git a/kernel/module.c b/kernel/module.c -index 6c8fa34..b289138 100644 +index 65362d9..51930e1 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -58,6 +58,7 @@ @@ -69378,8 +69346,8 @@ index 6c8fa34..b289138 100644 info->index.sym) | INIT_OFFSET_MASK; DEBUGP("\t%s\n", info->secstrings + symsect->sh_name); -@@ -2204,19 +2221,19 @@ static void layout_symtab(struct module *mod, struct load_info *info) - } +@@ -2206,19 +2223,19 @@ static void layout_symtab(struct module *mod, struct load_info *info) + } /* Append room for core symbols at end of core part. */ - info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1); @@ -69403,7 +69371,7 @@ index 6c8fa34..b289138 100644 } static void add_kallsyms(struct module *mod, const struct load_info *info) -@@ -2232,11 +2249,13 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) +@@ -2234,11 +2251,13 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) /* Make sure we get permanent strtab: don't use info->strtab. */ mod->strtab = (void *)info->sechdrs[info->index.str].sh_addr; @@ -69416,9 +69384,9 @@ index 6c8fa34..b289138 100644 - mod->core_symtab = dst = mod->module_core + info->symoffs; + mod->core_symtab = dst = mod->module_core_rx + info->symoffs; src = mod->symtab; - *dst = *src; - for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) { -@@ -2249,10 +2268,12 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) + for (ndst = i = 0; i < mod->num_symtab; i++) { + if (i == 0 || +@@ -2251,10 +2270,12 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) } mod->core_num_syms = ndst; @@ -69432,7 +69400,7 @@ index 6c8fa34..b289138 100644 } #else static inline void layout_symtab(struct module *mod, struct load_info *info) -@@ -2286,17 +2307,33 @@ void * __weak module_alloc(unsigned long size) +@@ -2288,17 +2309,33 @@ void * __weak module_alloc(unsigned long size) return size == 0 ? NULL : vmalloc_exec(size); } @@ -69471,7 +69439,7 @@ index 6c8fa34..b289138 100644 mutex_unlock(&module_mutex); } return ret; -@@ -2473,8 +2510,14 @@ static struct module *setup_load_info(struct load_info *info) +@@ -2475,8 +2512,14 @@ static struct module *setup_load_info(struct load_info *info) static int check_modinfo(struct module *mod, struct load_info *info) { const char *modmagic = get_modinfo(info, "vermagic"); @@ -69486,7 +69454,7 @@ index 6c8fa34..b289138 100644 /* This is allowed: modprobe --force will invalidate it. */ if (!modmagic) { err = try_to_force_load(mod, "bad vermagic"); -@@ -2497,7 +2540,7 @@ static int check_modinfo(struct module *mod, struct load_info *info) +@@ -2499,7 +2542,7 @@ static int check_modinfo(struct module *mod, struct load_info *info) } /* Set up license info based on the info section */ @@ -69495,7 +69463,7 @@ index 6c8fa34..b289138 100644 return 0; } -@@ -2591,7 +2634,7 @@ static int move_module(struct module *mod, struct load_info *info) +@@ -2593,7 +2636,7 @@ static int move_module(struct module *mod, struct load_info *info) void *ptr; /* Do the allocs. */ @@ -69504,7 +69472,7 @@ index 6c8fa34..b289138 100644 /* * The pointer to this block is stored in the module structure * which is inside the block. Just mark it as not being a -@@ -2601,23 +2644,50 @@ static int move_module(struct module *mod, struct load_info *info) +@@ -2603,23 +2646,50 @@ static int move_module(struct module *mod, struct load_info *info) if (!ptr) return -ENOMEM; @@ -69563,7 +69531,7 @@ index 6c8fa34..b289138 100644 /* Transfer each section which specifies SHF_ALLOC */ DEBUGP("final section addresses:\n"); -@@ -2628,16 +2698,45 @@ static int move_module(struct module *mod, struct load_info *info) +@@ -2630,16 +2700,45 @@ static int move_module(struct module *mod, struct load_info *info) if (!(shdr->sh_flags & SHF_ALLOC)) continue; @@ -69616,7 +69584,7 @@ index 6c8fa34..b289138 100644 DEBUGP("\t0x%lx %s\n", shdr->sh_addr, info->secstrings + shdr->sh_name); } -@@ -2692,12 +2791,12 @@ static void flush_module_icache(const struct module *mod) +@@ -2694,12 +2793,12 @@ static void flush_module_icache(const struct module *mod) * Do it before processing of module parameters, so the module * can provide parameter accessor functions of its own. */ @@ -69635,7 +69603,7 @@ index 6c8fa34..b289138 100644 set_fs(old_fs); } -@@ -2777,8 +2876,10 @@ static void module_deallocate(struct module *mod, struct load_info *info) +@@ -2779,8 +2878,10 @@ static void module_deallocate(struct module *mod, struct load_info *info) { kfree(info->strmap); percpu_modfree(mod); @@ -69648,7 +69616,7 @@ index 6c8fa34..b289138 100644 } int __weak module_finalize(const Elf_Ehdr *hdr, -@@ -2842,9 +2943,38 @@ static struct module *load_module(void __user *umod, +@@ -2844,9 +2945,38 @@ static struct module *load_module(void __user *umod, if (err) goto free_unload; @@ -69687,7 +69655,7 @@ index 6c8fa34..b289138 100644 /* Fix up syms, so that st_value is a pointer to location. */ err = simplify_symbols(mod, &info); if (err < 0) -@@ -2860,13 +2990,6 @@ static struct module *load_module(void __user *umod, +@@ -2862,13 +2992,6 @@ static struct module *load_module(void __user *umod, flush_module_icache(mod); @@ -69701,7 +69669,7 @@ index 6c8fa34..b289138 100644 /* Mark state as coming so strong_try_module_get() ignores us. */ mod->state = MODULE_STATE_COMING; -@@ -2924,11 +3047,10 @@ static struct module *load_module(void __user *umod, +@@ -2926,11 +3049,10 @@ static struct module *load_module(void __user *umod, unlock: mutex_unlock(&module_mutex); synchronize_sched(); @@ -69714,7 +69682,7 @@ index 6c8fa34..b289138 100644 free_unload: module_unload_free(mod); free_module: -@@ -2969,16 +3091,16 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, +@@ -2971,16 +3093,16 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, MODULE_STATE_COMING, mod); /* Set RO and NX regions for core */ @@ -69739,7 +69707,7 @@ index 6c8fa34..b289138 100644 do_mod_ctors(mod); /* Start the module */ -@@ -3024,11 +3146,12 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, +@@ -3026,11 +3148,12 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, mod->strtab = mod->core_strtab; #endif unset_module_init_ro_nx(mod); @@ -69757,7 +69725,7 @@ index 6c8fa34..b289138 100644 mutex_unlock(&module_mutex); return 0; -@@ -3059,10 +3182,16 @@ static const char *get_ksymbol(struct module *mod, +@@ -3061,10 +3184,16 @@ static const char *get_ksymbol(struct module *mod, unsigned long nextval; /* At worse, next value is at end of module */ @@ -69777,7 +69745,7 @@ index 6c8fa34..b289138 100644 /* Scan for closest preceding symbol, and next symbol. (ELF starts real symbols at 1). */ -@@ -3310,7 +3439,7 @@ static int m_show(struct seq_file *m, void *p) +@@ -3312,7 +3441,7 @@ static int m_show(struct seq_file *m, void *p) char buf[8]; seq_printf(m, "%s %u", @@ -69786,7 +69754,7 @@ index 6c8fa34..b289138 100644 print_unload_info(m, mod); /* Informative for users. */ -@@ -3319,7 +3448,7 @@ static int m_show(struct seq_file *m, void *p) +@@ -3321,7 +3450,7 @@ static int m_show(struct seq_file *m, void *p) mod->state == MODULE_STATE_COMING ? "Loading": "Live"); /* Used by oprofile and other similar tools. */ @@ -69795,7 +69763,7 @@ index 6c8fa34..b289138 100644 /* Taints info */ if (mod->taints) -@@ -3355,7 +3484,17 @@ static const struct file_operations proc_modules_operations = { +@@ -3357,7 +3486,17 @@ static const struct file_operations proc_modules_operations = { static int __init proc_modules_init(void) { @@ -69813,7 +69781,7 @@ index 6c8fa34..b289138 100644 return 0; } module_init(proc_modules_init); -@@ -3414,12 +3553,12 @@ struct module *__module_address(unsigned long addr) +@@ -3416,12 +3555,12 @@ struct module *__module_address(unsigned long addr) { struct module *mod; @@ -69829,7 +69797,7 @@ index 6c8fa34..b289138 100644 return mod; return NULL; } -@@ -3453,11 +3592,20 @@ bool is_module_text_address(unsigned long addr) +@@ -3455,11 +3594,20 @@ bool is_module_text_address(unsigned long addr) */ struct module *__module_text_address(unsigned long addr) { @@ -72514,6 +72482,33 @@ index 3efb882..8492f4c 100644 WARN_ON(release == (void (*)(struct kref *))kfree); if (atomic_dec_and_test(&kref->refcount)) { +diff --git a/lib/list_debug.c b/lib/list_debug.c +index b8029a5..1fa8092 100644 +--- a/lib/list_debug.c ++++ b/lib/list_debug.c +@@ -20,14 +20,18 @@ void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) + { +- WARN(next->prev != prev, ++ if (WARN(next->prev != prev, + "list_add corruption. next->prev should be " + "prev (%p), but was %p. (next=%p).\n", +- prev, next->prev, next); +- WARN(prev->next != next, ++ prev, next->prev, next) || ++ WARN(prev->next != next, + "list_add corruption. prev->next should be " + "next (%p), but was %p. (prev=%p).\n", +- next, prev->next, prev); ++ next, prev->next, prev) || ++ WARN(new == prev || new == next, ++ "list_add double add: new=%p, prev=%p, next=%p.\n", ++ new, prev, next)) ++ return; + next->prev = new; + new->next = next; + new->prev = prev; diff --git a/lib/radix-tree.c b/lib/radix-tree.c index d9df745..e73c2fe 100644 --- a/lib/radix-tree.c @@ -73729,8 +73724,44 @@ index 70f5daf..0964853 100644 /* * Make sure the vDSO gets into every core dump. * Dumping its contents makes post-mortem fully interpretable later +diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c +index 9ad7d1e..09d87b7 100644 +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -515,20 +515,21 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages) + + zone->present_pages += onlined_pages; + zone->zone_pgdat->node_present_pages += onlined_pages; +- if (need_zonelists_rebuild) +- build_all_zonelists(zone); +- else +- zone_pcp_update(zone); +- +- mutex_unlock(&zonelists_mutex); +- +- init_per_zone_wmark_min(); +- + if (onlined_pages) { +- kswapd_run(zone_to_nid(zone)); + node_set_state(zone_to_nid(zone), N_HIGH_MEMORY); ++ if (need_zonelists_rebuild) ++ build_all_zonelists(zone); ++ else ++ zone_pcp_update(zone); + } + ++ mutex_unlock(&zonelists_mutex); ++ ++ init_per_zone_wmark_min(); ++ ++ if (onlined_pages) ++ kswapd_run(zone_to_nid(zone)); ++ + vm_total_pages = nr_free_pagecache_pages(); + + writeback_set_ratelimit(); diff --git a/mm/mempolicy.c b/mm/mempolicy.c -index 4c82c21..f0fb9eb 100644 +index 4c82c21..d7fdbbd 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -655,6 +655,10 @@ static int mbind_range(struct mm_struct *mm, unsigned long start, @@ -73752,7 +73783,7 @@ index 4c82c21..f0fb9eb 100644 +#ifdef CONFIG_PAX_SEGMEXEC + vma_m = pax_find_mirror_vma(vma); + if (vma_m) { -+ err = policy_vma(vma_m, new_pol); ++ err = vma_replace_policy(vma_m, new_pol); + if (err) + goto out; + } @@ -75905,7 +75936,7 @@ index 8685697..b490361 100644 struct anon_vma_chain *avc; struct anon_vma *anon_vma; diff --git a/mm/shmem.c b/mm/shmem.c -index 126ca35..77e6609 100644 +index 126ca35..a89cd4c 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -31,7 +31,7 @@ @@ -75926,7 +75957,35 @@ index 126ca35..77e6609 100644 struct shmem_xattr { struct list_head list; /* anchored by shmem_inode_info->xattr_list */ -@@ -2183,8 +2183,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) +@@ -1803,6 +1803,11 @@ static const struct xattr_handler *shmem_xattr_handlers[] = { + static int shmem_xattr_validate(const char *name) + { + struct { const char *prefix; size_t len; } arr[] = { ++ ++#ifdef CONFIG_PAX_XATTR_PAX_FLAGS ++ { XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN}, ++#endif ++ + { XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN }, + { XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN } + }; +@@ -1856,6 +1861,15 @@ static int shmem_setxattr(struct dentry *dentry, const char *name, + if (err) + return err; + ++#ifdef CONFIG_PAX_XATTR_PAX_FLAGS ++ if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { ++ if (strcmp(name, XATTR_NAME_PAX_FLAGS)) ++ return -EOPNOTSUPP; ++ if (size > 8) ++ return -EINVAL; ++ } ++#endif ++ + if (size == 0) + value = ""; /* empty EA, do not remove */ + +@@ -2183,8 +2197,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) int err = -ENOMEM; /* Round up to L1_CACHE_BYTES to resist false sharing */ @@ -76906,7 +76965,7 @@ index 136ac4f..f917fa9 100644 mm->unmap_area = arch_unmap_area; } diff --git a/mm/vmalloc.c b/mm/vmalloc.c -index eeba3bb..1828c9e 100644 +index eeba3bb..dc333fa 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -39,8 +39,19 @@ static void vunmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end) @@ -76931,15 +76990,7 @@ index eeba3bb..1828c9e 100644 } while (pte++, addr += PAGE_SIZE, addr != end); } -@@ -91,6 +102,7 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, - unsigned long end, pgprot_t prot, struct page **pages, int *nr) - { - pte_t *pte; -+ int ret = -ENOMEM; - - /* - * nr is a running index into the array which helps higher level -@@ -100,17 +112,30 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, +@@ -100,16 +111,29 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, pte = pte_alloc_kernel(pmd, addr); if (!pte) return -ENOMEM; @@ -76949,33 +77000,29 @@ index eeba3bb..1828c9e 100644 struct page *page = pages[*nr]; - if (WARN_ON(!pte_none(*pte))) -- return -EBUSY; -- if (WARN_ON(!page)) -- return -ENOMEM; +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) + if (pgprot_val(prot) & _PAGE_NX) +#endif + -+ if (WARN_ON(!pte_none(*pte))) { -+ ret = -EBUSY; -+ goto out; ++ if (!pte_none(*pte)) { ++ pax_close_kernel(); ++ WARN_ON(1); + return -EBUSY; +- if (WARN_ON(!page)) + } -+ if (WARN_ON(!page)) { -+ ret = -ENOMEM; -+ goto out; ++ if (!page) { ++ pax_close_kernel(); ++ WARN_ON(1); + return -ENOMEM; + } set_pte_at(&init_mm, addr, pte, mk_pte(page, prot)); (*nr)++; } while (pte++, addr += PAGE_SIZE, addr != end); -- return 0; -+ ret = 0; -+out: + pax_close_kernel(); -+ return ret; + return 0; } - static int vmap_pmd_range(pud_t *pud, unsigned long addr, -@@ -119,7 +144,7 @@ static int vmap_pmd_range(pud_t *pud, unsigned long addr, +@@ -119,7 +143,7 @@ static int vmap_pmd_range(pud_t *pud, unsigned long addr, pmd_t *pmd; unsigned long next; @@ -76984,7 +77031,7 @@ index eeba3bb..1828c9e 100644 if (!pmd) return -ENOMEM; do { -@@ -136,7 +161,7 @@ static int vmap_pud_range(pgd_t *pgd, unsigned long addr, +@@ -136,7 +160,7 @@ static int vmap_pud_range(pgd_t *pgd, unsigned long addr, pud_t *pud; unsigned long next; @@ -76993,7 +77040,7 @@ index eeba3bb..1828c9e 100644 if (!pud) return -ENOMEM; do { -@@ -191,11 +216,20 @@ int is_vmalloc_or_module_addr(const void *x) +@@ -191,11 +215,20 @@ int is_vmalloc_or_module_addr(const void *x) * and fall back on vmalloc() if that fails. Others * just put it in the vmalloc space. */ @@ -77015,7 +77062,7 @@ index eeba3bb..1828c9e 100644 return is_vmalloc_addr(x); } -@@ -216,8 +250,14 @@ struct page *vmalloc_to_page(const void *vmalloc_addr) +@@ -216,8 +249,14 @@ struct page *vmalloc_to_page(const void *vmalloc_addr) if (!pgd_none(*pgd)) { pud_t *pud = pud_offset(pgd, addr); @@ -77030,7 +77077,7 @@ index eeba3bb..1828c9e 100644 if (!pmd_none(*pmd)) { pte_t *ptep, pte; -@@ -329,7 +369,7 @@ static void purge_vmap_area_lazy(void); +@@ -329,7 +368,7 @@ static void purge_vmap_area_lazy(void); * Allocate a region of KVA of the specified size and alignment, within the * vstart and vend. */ @@ -77039,7 +77086,7 @@ index eeba3bb..1828c9e 100644 unsigned long align, unsigned long vstart, unsigned long vend, int node, gfp_t gfp_mask) -@@ -1295,6 +1335,16 @@ static struct vm_struct *__get_vm_area_node(unsigned long size, +@@ -1295,6 +1334,16 @@ static struct vm_struct *__get_vm_area_node(unsigned long size, struct vm_struct *area; BUG_ON(in_interrupt()); @@ -77056,7 +77103,7 @@ index eeba3bb..1828c9e 100644 if (flags & VM_IOREMAP) { int bit = fls(size); -@@ -1527,6 +1577,11 @@ void *vmap(struct page **pages, unsigned int count, +@@ -1527,6 +1576,11 @@ void *vmap(struct page **pages, unsigned int count, if (count > totalram_pages) return NULL; @@ -77068,7 +77115,7 @@ index eeba3bb..1828c9e 100644 area = get_vm_area_caller((count << PAGE_SHIFT), flags, __builtin_return_address(0)); if (!area) -@@ -1628,6 +1683,13 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align, +@@ -1628,6 +1682,13 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align, if (!size || (size >> PAGE_SHIFT) > totalram_pages) goto fail; @@ -77082,7 +77129,7 @@ index eeba3bb..1828c9e 100644 area = __get_vm_area_node(size, align, VM_ALLOC | VM_UNLIST, start, end, node, gfp_mask, caller); if (!area) -@@ -1801,10 +1863,9 @@ EXPORT_SYMBOL(vzalloc_node); +@@ -1801,10 +1862,9 @@ EXPORT_SYMBOL(vzalloc_node); * For tight control over page level allocator and protection flags * use __vmalloc() instead. */ @@ -77094,7 +77141,7 @@ index eeba3bb..1828c9e 100644 -1, __builtin_return_address(0)); } -@@ -2099,6 +2160,8 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr, +@@ -2099,6 +2159,8 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr, unsigned long uaddr = vma->vm_start; unsigned long usize = vma->vm_end - vma->vm_start; @@ -77103,7 +77150,7 @@ index eeba3bb..1828c9e 100644 if ((PAGE_SIZE-1) & (unsigned long)addr) return -EINVAL; -@@ -2351,8 +2414,8 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets, +@@ -2351,8 +2413,8 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets, return NULL; } @@ -77114,7 +77161,7 @@ index eeba3bb..1828c9e 100644 if (!vas || !vms) goto err_free; -@@ -2536,7 +2599,7 @@ static int s_show(struct seq_file *m, void *p) +@@ -2536,7 +2598,7 @@ static int s_show(struct seq_file *m, void *p) { struct vm_struct *v = p; @@ -77416,8 +77463,21 @@ index 07d1c1d..7e9bea9 100644 frag1->seqno = htons(seqno - 1); frag2->seqno = htons(seqno); +diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile +index 9b67f3d..f6d7e5c 100644 +--- a/net/bluetooth/Makefile ++++ b/net/bluetooth/Makefile +@@ -8,6 +8,6 @@ obj-$(CONFIG_BT_BNEP) += bnep/ + obj-$(CONFIG_BT_CMTP) += cmtp/ + obj-$(CONFIG_BT_HIDP) += hidp/ + +-bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o +-bluetooth-$(CONFIG_BT_L2CAP) += l2cap_core.o l2cap_sock.o smp.o ++bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o smp.o ++bluetooth-$(CONFIG_BT_L2CAP) += l2cap_core.o l2cap_sock.o + bluetooth-$(CONFIG_BT_SCO) += sco.o diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c -index 1fb1aec..7438254 100644 +index aa12649..a22d595 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -235,7 +235,7 @@ void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16]) @@ -77993,7 +78053,7 @@ index 68bbf9f..5ef0d12 100644 return err; diff --git a/net/core/dev.c b/net/core/dev.c -index f500a69..94fbae3 100644 +index 480be72..cd4758c 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1142,10 +1142,14 @@ void dev_load(struct net *net, const char *name) @@ -78160,7 +78220,7 @@ index c40f27e..7f49254 100644 m->msg_iov = iov; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index 0cf604b..8d4b86f 100644 +index 5229c7f..6cb13fa 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -57,7 +57,7 @@ struct rtnl_link { @@ -78171,7 +78231,7 @@ index 0cf604b..8d4b86f 100644 +} __no_const; static DEFINE_MUTEX(rtnl_mutex); - static u16 min_ifinfo_dump_size; + diff --git a/net/core/scm.c b/net/core/scm.c index ff52ad0..aff1c0f 100644 --- a/net/core/scm.c @@ -78772,27 +78832,6 @@ index 94cdbc5..0cb0063 100644 if (peer->tcp_ts_stamp) { ts = peer->tcp_ts; tsage = get_seconds() - peer->tcp_ts_stamp; -diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c -index 813b43a..834857f 100644 ---- a/net/ipv4/tcp_illinois.c -+++ b/net/ipv4/tcp_illinois.c -@@ -313,11 +313,13 @@ static void tcp_illinois_info(struct sock *sk, u32 ext, - .tcpv_rttcnt = ca->cnt_rtt, - .tcpv_minrtt = ca->base_rtt, - }; -- u64 t = ca->sum_rtt; - -- do_div(t, ca->cnt_rtt); -- info.tcpv_rtt = t; -+ if (info.tcpv_rttcnt > 0) { -+ u64 t = ca->sum_rtt; - -+ do_div(t, info.tcpv_rttcnt); -+ info.tcpv_rtt = t; -+ } - nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info); - } - } diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index a08a621..a1ca37e 100644 --- a/net/ipv4/tcp_input.c @@ -79641,18 +79680,6 @@ index 1e733e9..3d73c9f 100644 } while (!res); return res; } -diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c -index 2cef50b..64164fb 100644 ---- a/net/l2tp/l2tp_eth.c -+++ b/net/l2tp/l2tp_eth.c -@@ -269,6 +269,7 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p - - out_del_dev: - free_netdev(dev); -+ spriv->dev = NULL; - out_del_session: - l2tp_session_delete(session); - out: diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index 93a41a0..d4b4edb 100644 --- a/net/l2tp/l2tp_netlink.c @@ -79690,19 +79717,6 @@ index 93a41a0..d4b4edb 100644 NLA_PUT_U32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id); NLA_PUT_U32(skb, L2TP_ATTR_SESSION_ID, session->session_id); -diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c -index 3ece106..8c7364b 100644 ---- a/net/mac80211/ibss.c -+++ b/net/mac80211/ibss.c -@@ -940,7 +940,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, - sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; - sdata->u.ibss.ibss_join_req = jiffies; - -- memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); -+ memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); - sdata->u.ibss.ssid_len = params->ssid_len; - - mutex_unlock(&sdata->u.ibss.mtx); diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 73495f1..ad51356 100644 --- a/net/mac80211/ieee80211_i.h @@ -79852,79 +79866,6 @@ index c97a065..ff61928 100644 return -EFAULT; return p; -diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c -index cda4875..223aad9 100644 ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -515,6 +515,11 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) - - if (ieee80211_is_action(hdr->frame_control)) { - u8 category; -+ -+ /* make sure category field is present */ -+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE) -+ return RX_DROP_MONITOR; -+ - mgmt = (struct ieee80211_mgmt *)hdr; - category = mgmt->u.action.category; - if (category != WLAN_CATEGORY_MESH_ACTION && -@@ -1887,6 +1892,20 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) - - hdr = (struct ieee80211_hdr *) skb->data; - hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ -+ /* make sure fixed part of mesh header is there, also checks skb len */ -+ if (!pskb_may_pull(rx->skb, hdrlen + 6)) -+ return RX_DROP_MONITOR; -+ -+ mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); -+ -+ /* make sure full mesh header is there, also checks skb len */ -+ if (!pskb_may_pull(rx->skb, -+ hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr))) -+ return RX_DROP_MONITOR; -+ -+ /* reload pointers */ -+ hdr = (struct ieee80211_hdr *) skb->data; - mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); - - /* frame is in RMC, don't forward */ -@@ -1916,9 +1935,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) - if (is_multicast_ether_addr(hdr->addr1)) { - mpp_addr = hdr->addr3; - proxied_addr = mesh_hdr->eaddr1; -- } else { -+ } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) { -+ /* has_a4 already checked in ieee80211_rx_mesh_check */ - mpp_addr = hdr->addr4; - proxied_addr = mesh_hdr->eaddr2; -+ } else { -+ return RX_DROP_MONITOR; - } - - rcu_read_lock(); -@@ -2295,6 +2317,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) - } - break; - case WLAN_CATEGORY_SELF_PROTECTED: -+ if (len < (IEEE80211_MIN_ACTION_SIZE + -+ sizeof(mgmt->u.action.u.self_prot.action_code))) -+ break; -+ - switch (mgmt->u.action.u.self_prot.action_code) { - case WLAN_SP_MESH_PEERING_OPEN: - case WLAN_SP_MESH_PEERING_CLOSE: -@@ -2313,6 +2339,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) - } - break; - case WLAN_CATEGORY_MESH_ACTION: -+ if (len < (IEEE80211_MIN_ACTION_SIZE + -+ sizeof(mgmt->u.action.u.mesh_action.action_code))) -+ break; -+ - if (!ieee80211_vif_is_mesh(&sdata->vif)) - break; - if (mesh_action_is_path_sel(mgmt) && diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 7095ae5..85ba5e9 100644 --- a/net/mac80211/util.c @@ -80258,10 +80199,10 @@ index 4fe4fb4..87a89e5 100644 return 0; } diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c -index 38b78b9..7a58852 100644 +index 3d1d55d..2a0b8cc 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c -@@ -742,7 +742,7 @@ static void netlink_overrun(struct sock *sk) +@@ -753,7 +753,7 @@ static void netlink_overrun(struct sock *sk) sk->sk_error_report(sk); } } @@ -80270,7 +80211,7 @@ index 38b78b9..7a58852 100644 } static struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid) -@@ -2002,7 +2002,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v) +@@ -2013,7 +2013,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v) sk_wmem_alloc_get(s), nlk->cb, atomic_read(&s->sk_refcnt), @@ -81503,27 +81444,6 @@ index 02c3be3..e022efa 100644 struct rfkill *rfkill; struct work_struct rfkill_sync; -diff --git a/net/wireless/util.c b/net/wireless/util.c -index 22fb802..74d064c 100644 ---- a/net/wireless/util.c -+++ b/net/wireless/util.c -@@ -301,7 +301,7 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) - } - EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); - --static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) -+unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) - { - int ae = meshhdr->flags & MESH_FLAGS_AE; - /* 7.1.3.5a.2 */ -@@ -318,6 +318,7 @@ static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) - return 6; - } - } -+EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); - - int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, - enum nl80211_iftype iftype) diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index 0af7f54..c916d2f 100644 --- a/net/wireless/wext-core.c @@ -83443,7 +83363,7 @@ index ffd2025..df062c9 100644 /* PCM3052 register definitions */ diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c -index 3cc4b86..af0a951 100644 +index 542f69e..fe6e8c3 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -1189,10 +1189,10 @@ snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, const @@ -83531,10 +83451,10 @@ index 91cdf94..4085161 100644 if (err < 0) return err; diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c -index 25ed9fe..24c46e9 100644 +index 7ada40e..8c53bfe 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c -@@ -2765,11 +2765,11 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, +@@ -2788,11 +2788,11 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, switch (substream->stream) { case SNDRV_PCM_STREAM_PLAYBACK: result = snd_pcm_playback_ioctl1(NULL, substream, cmd, @@ -83944,7 +83864,7 @@ index ee15337..e2187a6 100644 .close = soc_pcm_close, .hw_params = soc_pcm_hw_params, diff --git a/sound/usb/card.h b/sound/usb/card.h -index a39edcc..1014050 100644 +index 665e297..ed6b31c 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h @@ -44,6 +44,7 @@ struct snd_urb_ops { @@ -83955,7 +83875,7 @@ index a39edcc..1014050 100644 struct snd_usb_substream { struct snd_usb_stream *stream; -@@ -93,7 +94,7 @@ struct snd_usb_substream { +@@ -94,7 +95,7 @@ struct snd_usb_substream { struct snd_pcm_hw_constraint_list rate_list; /* limited rates */ spinlock_t lock; @@ -85697,10 +85617,10 @@ index 0000000..b8008f7 +} diff --git a/tools/gcc/size_overflow_hash.data b/tools/gcc/size_overflow_hash.data new file mode 100644 -index 0000000..ea65f09 +index 0000000..7020cf0 --- /dev/null +++ b/tools/gcc/size_overflow_hash.data -@@ -0,0 +1,3380 @@ +@@ -0,0 +1,3382 @@ +_000001_hash alloc_dr 2 65495 _000001_hash NULL +_000002_hash __copy_from_user 3 10918 _000002_hash NULL +_000003_hash __copy_from_user_inatomic 3 4365 _000003_hash NULL @@ -89081,12 +89001,14 @@ index 0000000..ea65f09 +_003653_hash __kmalloc_section_memmap 1 32651 _003653_hash NULL +_003654_hash kmalloc_section_memmap 3 46168 _003654_hash NULL +_003655_hash sparse_add_one_section 3 41778 _003655_hash NULL ++_003656_hash hidraw_report_event 3 20503 _003656_hash NULL ++_003657_hash hid_report_raw_event 4 2762 _003657_hash NULL diff --git a/tools/gcc/size_overflow_plugin.c b/tools/gcc/size_overflow_plugin.c new file mode 100644 -index 0000000..244559e +index 0000000..1aa0dce --- /dev/null +++ b/tools/gcc/size_overflow_plugin.c -@@ -0,0 +1,1879 @@ +@@ -0,0 +1,1865 @@ +/* + * Copyright 2011, 2012 by Emese Revfy <re.emese@gmail.com> + * Licensed under the GPL v2, or (at your option) v3 @@ -89164,10 +89086,10 @@ index 0000000..244559e +static unsigned int handle_function(void); +static void check_size_overflow(gimple stmt, tree size_overflow_type, tree cast_rhs, tree rhs, bool before); +static tree get_size_overflow_type(gimple stmt, const_tree node); -+static tree dup_assign(struct pointer_set_t *visited, gimple oldstmt, tree size_overflow_type, tree rhs1, tree rhs2, tree __unused rhs3); ++static tree dup_assign(struct pointer_set_t *visited, gimple oldstmt, const_tree node, tree rhs1, tree rhs2, tree __unused rhs3); + +static struct plugin_info size_overflow_plugin_info = { -+ .version = "20120930beta", ++ .version = "20121113beta", + .help = "no-size-overflow\tturn off size overflow checking\n", +}; + @@ -89486,6 +89408,7 @@ index 0000000..244559e + tree type = TREE_TYPE(rhs1); + tree lhs = create_new_var(type); + ++ gcc_assert(types_compatible_p(type, TREE_TYPE(rhs2))); + assign = gimple_build_assign_with_ops(code, lhs, rhs1, rhs2); + gimple_set_lhs(assign, make_ssa_name(lhs, assign)); + @@ -89551,42 +89474,41 @@ index 0000000..244559e + return assign; +} + -+static tree cast_to_new_size_overflow_type(gimple stmt, tree new_rhs1, tree size_overflow_type, bool before) ++static tree cast_to_new_size_overflow_type(gimple stmt, tree rhs, tree size_overflow_type, bool before) +{ -+ const_gimple assign; ++ gimple assign; + gimple_stmt_iterator gsi; + -+ if (new_rhs1 == NULL_TREE) ++ if (rhs == NULL_TREE) + return NULL_TREE; + -+ if (!useless_type_conversion_p(TREE_TYPE(new_rhs1), size_overflow_type)) { -+ gsi = gsi_for_stmt(stmt); -+ assign = build_cast_stmt(size_overflow_type, new_rhs1, CREATE_NEW_VAR, &gsi, before); -+ return gimple_get_lhs(assign); -+ } -+ return new_rhs1; ++ if (types_compatible_p(TREE_TYPE(rhs), size_overflow_type) && gimple_plf(stmt, MY_STMT)) ++ return rhs; ++ ++ gsi = gsi_for_stmt(stmt); ++ assign = build_cast_stmt(size_overflow_type, rhs, CREATE_NEW_VAR, &gsi, before); ++ gimple_set_plf(assign, MY_STMT, true); ++ return gimple_get_lhs(assign); +} + -+static tree follow_overflow_type_and_dup(struct pointer_set_t *visited, gimple stmt, const_tree node, tree new_rhs1, tree new_rhs2, tree new_rhs3) ++static tree cast_to_TI_type(gimple stmt, tree node) +{ -+ tree size_overflow_type = get_size_overflow_type(stmt, node); -+ -+ new_rhs1 = cast_to_new_size_overflow_type(stmt, new_rhs1, size_overflow_type, BEFORE_STMT); -+ -+ if (new_rhs2 != NULL_TREE) -+ new_rhs2 = cast_to_new_size_overflow_type(stmt, new_rhs2, size_overflow_type, BEFORE_STMT); ++ gimple_stmt_iterator gsi; ++ gimple cast_stmt; ++ tree type = TREE_TYPE(node); + -+ if (new_rhs3 != NULL_TREE) -+ new_rhs3 = cast_to_new_size_overflow_type(stmt, new_rhs3, size_overflow_type, BEFORE_STMT); ++ if (types_compatible_p(type, intTI_type_node)) ++ return node; + -+ return dup_assign(visited, stmt, size_overflow_type, new_rhs1, new_rhs2, new_rhs3); ++ gsi = gsi_for_stmt(stmt); ++ cast_stmt = build_cast_stmt(intTI_type_node, node, CREATE_NEW_VAR, &gsi, BEFORE_STMT); ++ gimple_set_plf(cast_stmt, MY_STMT, true); ++ return gimple_get_lhs(cast_stmt); +} + -+ +static tree create_assign(struct pointer_set_t *visited, gimple oldstmt, tree rhs1, bool before) +{ -+ tree size_overflow_type, lhs; -+ gimple stmt; ++ tree lhs; + gimple_stmt_iterator gsi; + + if (rhs1 == NULL_TREE) { @@ -89624,18 +89546,14 @@ index 0000000..244559e + oldstmt = gsi_stmt(gsi); + } + -+ size_overflow_type = get_size_overflow_type(oldstmt, lhs); -+ -+ stmt = build_cast_stmt(size_overflow_type, rhs1, CREATE_NEW_VAR, &gsi, before); -+ gimple_set_plf(stmt, MY_STMT, true); -+ return gimple_get_lhs(stmt); ++ return cast_to_new_size_overflow_type(oldstmt, rhs1, get_size_overflow_type(oldstmt, lhs), before); +} + -+static tree dup_assign(struct pointer_set_t *visited, gimple oldstmt, tree size_overflow_type, tree rhs1, tree rhs2, tree __unused rhs3) ++static tree dup_assign(struct pointer_set_t *visited, gimple oldstmt, const_tree node, tree rhs1, tree rhs2, tree __unused rhs3) +{ + gimple stmt; + gimple_stmt_iterator gsi; -+ tree new_var, lhs = gimple_get_lhs(oldstmt); ++ tree size_overflow_type, new_var, lhs = gimple_get_lhs(oldstmt); + + if (gimple_plf(oldstmt, MY_STMT)) + return lhs; @@ -89656,6 +89574,8 @@ index 0000000..244559e + if (gimple_assign_rhs_code(oldstmt) == WIDEN_MULT_EXPR) + gimple_assign_set_rhs_code(stmt, MULT_EXPR); + ++ size_overflow_type = get_size_overflow_type(oldstmt, node); ++ + if (is_bool(lhs)) + new_var = SSA_NAME_VAR(lhs); + else @@ -89664,7 +89584,7 @@ index 0000000..244559e + gimple_set_lhs(stmt, new_var); + + if (rhs1 != NULL_TREE) { -+ if (!gimple_assign_cast_p(oldstmt)) ++ if (!gimple_assign_cast_p(oldstmt) && TREE_CODE_CLASS(gimple_assign_rhs_code(oldstmt)) != tcc_comparison) + rhs1 = cast_a_tree(size_overflow_type, rhs1); + gimple_assign_set_rhs1(stmt, rhs1); + } @@ -89916,7 +89836,7 @@ index 0000000..244559e + return lhs; + + if (gimple_plf(stmt, NO_CAST_CHECK)) -+ return follow_overflow_type_and_dup(visited, stmt, rhs1, new_rhs1, NULL_TREE, NULL_TREE); ++ return dup_assign(visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); + + if (gimple_assign_rhs_code(stmt) == BIT_NOT_EXPR) { + size_overflow_type = get_size_overflow_type(stmt, rhs1); @@ -89926,7 +89846,7 @@ index 0000000..244559e + } + + if (!gimple_assign_cast_p(stmt) || check_undefined_integer_operation(stmt)) -+ return follow_overflow_type_and_dup(visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); ++ return dup_assign(visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); + + size_overflow_type = get_size_overflow_type(stmt, rhs1); + new_rhs1 = cast_to_new_size_overflow_type(stmt, new_rhs1, size_overflow_type, BEFORE_STMT); @@ -90111,8 +90031,8 @@ index 0000000..244559e + cast_rhs_type = TREE_TYPE(cast_rhs); + type_max_type = TREE_TYPE(type_max); + type_min_type = TREE_TYPE(type_min); -+ gcc_assert(useless_type_conversion_p(cast_rhs_type, type_max_type)); -+ gcc_assert(useless_type_conversion_p(type_max_type, type_min_type)); ++ gcc_assert(types_compatible_p(cast_rhs_type, type_max_type)); ++ gcc_assert(types_compatible_p(type_max_type, type_min_type)); + + insert_check_size_overflow(stmt, GT_EXPR, cast_rhs, type_max, before, false); + insert_check_size_overflow(stmt, LT_EXPR, cast_rhs, type_min, before, true); @@ -90140,7 +90060,7 @@ index 0000000..244559e + if (gimple_assign_rhs_code(def_stmt) == RSHIFT_EXPR) + return get_size_overflow_type(change_rhs_def_stmt, change_rhs); + -+ if (!useless_type_conversion_p(lhs_type, rhs1_type) || !useless_type_conversion_p(rhs1_type, rhs2_type)) { ++ if (!types_compatible_p(lhs_type, rhs1_type) || !useless_type_conversion_p(rhs1_type, rhs2_type)) { + debug_gimple_stmt(def_stmt); + gcc_unreachable(); + } @@ -90157,64 +90077,20 @@ index 0000000..244559e + return true; +} + -+static tree get_cast_def_stmt_rhs(const_tree new_rhs) -+{ -+ gimple def_stmt; -+ -+ def_stmt = get_def_stmt(new_rhs); -+ // get_size_overflow_type -+ if (LONG_TYPE_SIZE != GET_MODE_BITSIZE(SImode)) -+ gcc_assert(gimple_assign_cast_p(def_stmt)); -+ return gimple_assign_rhs1(def_stmt); -+} -+ -+static tree cast_to_int_TI_type_and_check(gimple stmt, tree new_rhs) -+{ -+ gimple_stmt_iterator gsi; -+ const_gimple cast_stmt; -+ gimple def_stmt; -+ enum machine_mode mode = TYPE_MODE(TREE_TYPE(new_rhs)); -+ -+ if (mode != TImode && mode != DImode) { -+ def_stmt = get_def_stmt(new_rhs); -+ gcc_assert(gimple_assign_cast_p(def_stmt)); -+ new_rhs = gimple_assign_rhs1(def_stmt); -+ mode = TYPE_MODE(TREE_TYPE(new_rhs)); -+ } -+ -+ gcc_assert(mode == TImode || mode == DImode); -+ -+ if (mode == TYPE_MODE(intTI_type_node) && useless_type_conversion_p(TREE_TYPE(new_rhs), intTI_type_node)) -+ return new_rhs; -+ -+ gsi = gsi_for_stmt(stmt); -+ cast_stmt = build_cast_stmt(intTI_type_node, new_rhs, CREATE_NEW_VAR, &gsi, BEFORE_STMT); -+ new_rhs = gimple_get_lhs(cast_stmt); -+ -+ if (mode == DImode) -+ return new_rhs; -+ -+ check_size_overflow(stmt, intTI_type_node, new_rhs, new_rhs, BEFORE_STMT); -+ -+ return new_rhs; -+} -+ -+static bool is_an_integer_trunction(const_gimple stmt) ++static bool is_subtraction_special(const_gimple stmt) +{ + gimple rhs1_def_stmt, rhs2_def_stmt; -+ const_tree rhs1_def_stmt_rhs1, rhs2_def_stmt_rhs1; -+ enum machine_mode rhs1_def_stmt_rhs1_mode, rhs2_def_stmt_rhs1_mode; ++ const_tree rhs1_def_stmt_rhs1, rhs2_def_stmt_rhs1, rhs1_def_stmt_lhs, rhs2_def_stmt_lhs; ++ enum machine_mode rhs1_def_stmt_rhs1_mode, rhs2_def_stmt_rhs1_mode, rhs1_def_stmt_lhs_mode, rhs2_def_stmt_lhs_mode; + const_tree rhs1 = gimple_assign_rhs1(stmt); + const_tree rhs2 = gimple_assign_rhs2(stmt); -+ enum machine_mode rhs1_mode = TYPE_MODE(TREE_TYPE(rhs1)); -+ enum machine_mode rhs2_mode = TYPE_MODE(TREE_TYPE(rhs2)); + + if (is_gimple_constant(rhs1) || is_gimple_constant(rhs2)) + return false; + + gcc_assert(TREE_CODE(rhs1) == SSA_NAME && TREE_CODE(rhs2) == SSA_NAME); + -+ if (gimple_assign_rhs_code(stmt) != MINUS_EXPR || rhs1_mode != SImode || rhs2_mode != SImode) ++ if (gimple_assign_rhs_code(stmt) != MINUS_EXPR) + return false; + + rhs1_def_stmt = get_def_stmt(rhs1); @@ -90224,9 +90100,15 @@ index 0000000..244559e + + rhs1_def_stmt_rhs1 = gimple_assign_rhs1(rhs1_def_stmt); + rhs2_def_stmt_rhs1 = gimple_assign_rhs1(rhs2_def_stmt); ++ rhs1_def_stmt_lhs = gimple_get_lhs(rhs1_def_stmt); ++ rhs2_def_stmt_lhs = gimple_get_lhs(rhs2_def_stmt); + rhs1_def_stmt_rhs1_mode = TYPE_MODE(TREE_TYPE(rhs1_def_stmt_rhs1)); + rhs2_def_stmt_rhs1_mode = TYPE_MODE(TREE_TYPE(rhs2_def_stmt_rhs1)); -+ if (rhs1_def_stmt_rhs1_mode != DImode || rhs2_def_stmt_rhs1_mode != DImode) ++ rhs1_def_stmt_lhs_mode = TYPE_MODE(TREE_TYPE(rhs1_def_stmt_lhs)); ++ rhs2_def_stmt_lhs_mode = TYPE_MODE(TREE_TYPE(rhs2_def_stmt_lhs)); ++ if (GET_MODE_BITSIZE(rhs1_def_stmt_rhs1_mode) <= GET_MODE_BITSIZE(rhs1_def_stmt_lhs_mode)) ++ return false; ++ if (GET_MODE_BITSIZE(rhs2_def_stmt_rhs1_mode) <= GET_MODE_BITSIZE(rhs2_def_stmt_lhs_mode)) + return false; + + gimple_set_plf(rhs1_def_stmt, NO_CAST_CHECK, true); @@ -90234,37 +90116,63 @@ index 0000000..244559e + return true; +} + ++static tree get_def_stmt_rhs(const_tree var) ++{ ++ tree rhs1, def_stmt_rhs1; ++ gimple rhs1_def_stmt, def_stmt_rhs1_def_stmt, def_stmt; ++ ++ def_stmt = get_def_stmt(var); ++ gcc_assert(gimple_code(def_stmt) != GIMPLE_NOP && gimple_plf(def_stmt, MY_STMT) && gimple_assign_cast_p(def_stmt)); ++ ++ rhs1 = gimple_assign_rhs1(def_stmt); ++ rhs1_def_stmt = get_def_stmt(rhs1); ++ gcc_assert(gimple_code(rhs1_def_stmt) != GIMPLE_NOP); ++ if (!gimple_assign_cast_p(rhs1_def_stmt)) ++ return rhs1; ++ ++ def_stmt_rhs1 = gimple_assign_rhs1(rhs1_def_stmt); ++ def_stmt_rhs1_def_stmt = get_def_stmt(def_stmt_rhs1); ++ ++ switch (gimple_code(def_stmt_rhs1_def_stmt)) { ++ case GIMPLE_CALL: ++ case GIMPLE_NOP: ++ case GIMPLE_ASM: ++ return def_stmt_rhs1; ++ case GIMPLE_ASSIGN: ++ return rhs1; ++ default: ++ debug_gimple_stmt(def_stmt_rhs1_def_stmt); ++ gcc_unreachable(); ++ } ++} ++ +static tree handle_integer_truncation(struct pointer_set_t *visited, const_tree lhs) +{ + tree new_rhs1, new_rhs2; + tree new_rhs1_def_stmt_rhs1, new_rhs2_def_stmt_rhs1, new_lhs; -+ tree new_rhs1_def_stmt_rhs1_type, new_rhs2_def_stmt_rhs1_type; + gimple assign, stmt = get_def_stmt(lhs); + tree rhs1 = gimple_assign_rhs1(stmt); + tree rhs2 = gimple_assign_rhs2(stmt); + -+ if (!is_an_integer_trunction(stmt)) ++ if (!is_subtraction_special(stmt)) + return NULL_TREE; + + new_rhs1 = expand(visited, rhs1); + new_rhs2 = expand(visited, rhs2); + -+ new_rhs1_def_stmt_rhs1 = get_cast_def_stmt_rhs(new_rhs1); -+ new_rhs2_def_stmt_rhs1 = get_cast_def_stmt_rhs(new_rhs2); -+ -+ new_rhs1_def_stmt_rhs1_type = TREE_TYPE(new_rhs1_def_stmt_rhs1); -+ new_rhs2_def_stmt_rhs1_type = TREE_TYPE(new_rhs2_def_stmt_rhs1); ++ new_rhs1_def_stmt_rhs1 = get_def_stmt_rhs(new_rhs1); ++ new_rhs2_def_stmt_rhs1 = get_def_stmt_rhs(new_rhs2); + -+ if (!useless_type_conversion_p(new_rhs1_def_stmt_rhs1_type, new_rhs2_def_stmt_rhs1_type)) { -+ new_rhs1_def_stmt_rhs1 = cast_to_int_TI_type_and_check(stmt, new_rhs1_def_stmt_rhs1); -+ new_rhs2_def_stmt_rhs1 = cast_to_int_TI_type_and_check(stmt, new_rhs2_def_stmt_rhs1); ++ if (!types_compatible_p(TREE_TYPE(new_rhs1_def_stmt_rhs1), TREE_TYPE(new_rhs2_def_stmt_rhs1))) { ++ new_rhs1_def_stmt_rhs1 = cast_to_TI_type(stmt, new_rhs1_def_stmt_rhs1); ++ new_rhs2_def_stmt_rhs1 = cast_to_TI_type(stmt, new_rhs2_def_stmt_rhs1); + } + + assign = create_binary_assign(MINUS_EXPR, stmt, new_rhs1_def_stmt_rhs1, new_rhs2_def_stmt_rhs1); + new_lhs = gimple_get_lhs(assign); + check_size_overflow(assign, TREE_TYPE(new_lhs), new_lhs, rhs1, AFTER_STMT); + -+ return follow_overflow_type_and_dup(visited, stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); ++ return dup_assign(visited, stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); +} + +static bool is_a_neg_overflow(const_gimple stmt, const_tree rhs) @@ -90367,7 +90275,7 @@ index 0000000..244559e + if (is_a_constant_overflow(def_stmt, rhs1)) + return handle_intentional_overflow(visited, !is_a_cast_and_const_overflow(rhs2), def_stmt, new_rhs2, NULL_TREE, new_rhs2); + -+ return follow_overflow_type_and_dup(visited, def_stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); ++ return dup_assign(visited, def_stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); +} + +#if BUILDING_GCC_VERSION >= 4007 @@ -90394,7 +90302,7 @@ index 0000000..244559e + new_rhs2 = get_new_rhs(visited, size_overflow_type, rhs2); + new_rhs3 = get_new_rhs(visited, size_overflow_type, rhs3); + -+ return follow_overflow_type_and_dup(visited, def_stmt, lhs, new_rhs1, new_rhs2, new_rhs3); ++ return dup_assign(visited, def_stmt, lhs, new_rhs1, new_rhs2, new_rhs3); +} +#endif + diff --git a/3.2.33/4425-tmpfs-user-namespace.patch b/3.2.34/4425-tmpfs-user-namespace.patch index a7d2649..a7d2649 100644 --- a/3.2.33/4425-tmpfs-user-namespace.patch +++ b/3.2.34/4425-tmpfs-user-namespace.patch diff --git a/3.2.33/4430_grsec-remove-localversion-grsec.patch b/3.2.34/4430_grsec-remove-localversion-grsec.patch index 31cf878..31cf878 100644 --- a/3.2.33/4430_grsec-remove-localversion-grsec.patch +++ b/3.2.34/4430_grsec-remove-localversion-grsec.patch diff --git a/3.2.33/4435_grsec-mute-warnings.patch b/3.2.34/4435_grsec-mute-warnings.patch index e85abd6..e85abd6 100644 --- a/3.2.33/4435_grsec-mute-warnings.patch +++ b/3.2.34/4435_grsec-mute-warnings.patch diff --git a/3.2.33/4440_grsec-remove-protected-paths.patch b/3.2.34/4440_grsec-remove-protected-paths.patch index 637934a..637934a 100644 --- a/3.2.33/4440_grsec-remove-protected-paths.patch +++ b/3.2.34/4440_grsec-remove-protected-paths.patch diff --git a/3.2.33/4450_grsec-kconfig-default-gids.patch b/3.2.34/4450_grsec-kconfig-default-gids.patch index d4b0b7e..d4b0b7e 100644 --- a/3.2.33/4450_grsec-kconfig-default-gids.patch +++ b/3.2.34/4450_grsec-kconfig-default-gids.patch diff --git a/3.2.33/4465_selinux-avc_audit-log-curr_ip.patch b/3.2.34/4465_selinux-avc_audit-log-curr_ip.patch index 3ea7bcc..3ea7bcc 100644 --- a/3.2.33/4465_selinux-avc_audit-log-curr_ip.patch +++ b/3.2.34/4465_selinux-avc_audit-log-curr_ip.patch diff --git a/3.2.33/4470_disable-compat_vdso.patch b/3.2.34/4470_disable-compat_vdso.patch index 4742d01..4742d01 100644 --- a/3.2.33/4470_disable-compat_vdso.patch +++ b/3.2.34/4470_disable-compat_vdso.patch diff --git a/3.6.6/0000_README b/3.6.7/0000_README index 306bcfd..8b389a1 100644 --- a/3.6.6/0000_README +++ b/3.6.7/0000_README @@ -2,7 +2,11 @@ README ----------------------------------------------------------------------------- Individual Patch Descriptions: ----------------------------------------------------------------------------- -Patch: 4420_grsecurity-2.9.1-3.6.6-201211122213.patch +Patch: 1006_linux-3.6.7.patch +From: http://www.kernel.org +Desc: Linux 3.6.7 + +Patch: 4420_grsecurity-2.9.1-3.6.7-201211181105.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.6.7/1006_linux-3.6.7.patch b/3.6.7/1006_linux-3.6.7.patch new file mode 100644 index 0000000..4b496eb --- /dev/null +++ b/3.6.7/1006_linux-3.6.7.patch @@ -0,0 +1,3082 @@ +diff --git a/Makefile b/Makefile +index 471b83c..07f2308 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 6 +-SUBLEVEL = 6 ++SUBLEVEL = 7 + EXTRAVERSION = + NAME = Terrified Chipmunk + +diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c +index 5141d80..dde1a3f 100644 +--- a/arch/x86/xen/mmu.c ++++ b/arch/x86/xen/mmu.c +@@ -1215,6 +1215,25 @@ unsigned long xen_read_cr2_direct(void) + return this_cpu_read(xen_vcpu_info.arch.cr2); + } + ++void xen_flush_tlb_all(void) ++{ ++ struct mmuext_op *op; ++ struct multicall_space mcs; ++ ++ trace_xen_mmu_flush_tlb_all(0); ++ ++ preempt_disable(); ++ ++ mcs = xen_mc_entry(sizeof(*op)); ++ ++ op = mcs.args; ++ op->cmd = MMUEXT_TLB_FLUSH_ALL; ++ MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); ++ ++ xen_mc_issue(PARAVIRT_LAZY_MMU); ++ ++ preempt_enable(); ++} + static void xen_flush_tlb(void) + { + struct mmuext_op *op; +@@ -2366,7 +2385,7 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma, + err = 0; + out: + +- flush_tlb_all(); ++ xen_flush_tlb_all(); + + return err; + } +diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c +index 5062eec..7aff5c7 100644 +--- a/drivers/gpu/drm/drm_fops.c ++++ b/drivers/gpu/drm/drm_fops.c +@@ -121,6 +121,8 @@ int drm_open(struct inode *inode, struct file *filp) + int minor_id = iminor(inode); + struct drm_minor *minor; + int retcode = 0; ++ int need_setup = 0; ++ struct address_space *old_mapping; + + minor = idr_find(&drm_minors_idr, minor_id); + if (!minor) +@@ -132,23 +134,37 @@ int drm_open(struct inode *inode, struct file *filp) + if (drm_device_is_unplugged(dev)) + return -ENODEV; + ++ if (!dev->open_count++) ++ need_setup = 1; ++ mutex_lock(&dev->struct_mutex); ++ old_mapping = dev->dev_mapping; ++ if (old_mapping == NULL) ++ dev->dev_mapping = &inode->i_data; ++ /* ihold ensures nobody can remove inode with our i_data */ ++ ihold(container_of(dev->dev_mapping, struct inode, i_data)); ++ inode->i_mapping = dev->dev_mapping; ++ filp->f_mapping = dev->dev_mapping; ++ mutex_unlock(&dev->struct_mutex); ++ + retcode = drm_open_helper(inode, filp, dev); +- if (!retcode) { +- atomic_inc(&dev->counts[_DRM_STAT_OPENS]); +- if (!dev->open_count++) +- retcode = drm_setup(dev); +- } +- if (!retcode) { +- mutex_lock(&dev->struct_mutex); +- if (dev->dev_mapping == NULL) +- dev->dev_mapping = &inode->i_data; +- /* ihold ensures nobody can remove inode with our i_data */ +- ihold(container_of(dev->dev_mapping, struct inode, i_data)); +- inode->i_mapping = dev->dev_mapping; +- filp->f_mapping = dev->dev_mapping; +- mutex_unlock(&dev->struct_mutex); ++ if (retcode) ++ goto err_undo; ++ atomic_inc(&dev->counts[_DRM_STAT_OPENS]); ++ if (need_setup) { ++ retcode = drm_setup(dev); ++ if (retcode) ++ goto err_undo; + } ++ return 0; + ++err_undo: ++ mutex_lock(&dev->struct_mutex); ++ filp->f_mapping = old_mapping; ++ inode->i_mapping = old_mapping; ++ iput(container_of(dev->dev_mapping, struct inode, i_data)); ++ dev->dev_mapping = old_mapping; ++ mutex_unlock(&dev->struct_mutex); ++ dev->open_count--; + return retcode; + } + EXPORT_SYMBOL(drm_open); +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 914c0df..0969a7c 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1484,7 +1484,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + goto put_gmch; + } + +- i915_kick_out_firmware_fb(dev_priv); ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ i915_kick_out_firmware_fb(dev_priv); + + pci_set_master(dev->pdev); + +diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c +index 830d0dd..cf49a57 100644 +--- a/drivers/gpu/drm/i915/intel_overlay.c ++++ b/drivers/gpu/drm/i915/intel_overlay.c +@@ -431,9 +431,17 @@ static int intel_overlay_off(struct intel_overlay *overlay) + intel_ring_emit(ring, flip_addr); + intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); + /* turn overlay off */ +- intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); +- intel_ring_emit(ring, flip_addr); +- intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); ++ if (IS_I830(dev)) { ++ /* Workaround: Don't disable the overlay fully, since otherwise ++ * it dies on the next OVERLAY_ON cmd. */ ++ intel_ring_emit(ring, MI_NOOP); ++ intel_ring_emit(ring, MI_NOOP); ++ intel_ring_emit(ring, MI_NOOP); ++ } else { ++ intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); ++ intel_ring_emit(ring, flip_addr); ++ intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); ++ } + intel_ring_advance(ring); + + return intel_overlay_do_wait_request(overlay, request, +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index 123afd3..20cb52d 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -882,6 +882,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) + } + #endif + ++static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, ++ unsigned if_index, uint8_t tx_rate, ++ uint8_t *data, unsigned length) ++{ ++ uint8_t set_buf_index[2] = { if_index, 0 }; ++ uint8_t hbuf_size, tmp[8]; ++ int i; ++ ++ if (!intel_sdvo_set_value(intel_sdvo, ++ SDVO_CMD_SET_HBUF_INDEX, ++ set_buf_index, 2)) ++ return false; ++ ++ if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO, ++ &hbuf_size, 1)) ++ return false; ++ ++ /* Buffer size is 0 based, hooray! */ ++ hbuf_size++; ++ ++ DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n", ++ if_index, length, hbuf_size); ++ ++ for (i = 0; i < hbuf_size; i += 8) { ++ memset(tmp, 0, 8); ++ if (i < length) ++ memcpy(tmp, data + i, min_t(unsigned, 8, length - i)); ++ ++ if (!intel_sdvo_set_value(intel_sdvo, ++ SDVO_CMD_SET_HBUF_DATA, ++ tmp, 8)) ++ return false; ++ } ++ ++ return intel_sdvo_set_value(intel_sdvo, ++ SDVO_CMD_SET_HBUF_TXRATE, ++ &tx_rate, 1); ++} ++ + static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) + { + struct dip_infoframe avi_if = { +@@ -889,11 +928,7 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) + .ver = DIP_VERSION_AVI, + .len = DIP_LEN_AVI, + }; +- uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; +- uint8_t set_buf_index[2] = { 1, 0 }; + uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; +- uint64_t *data = (uint64_t *)sdvo_data; +- unsigned i; + + intel_dip_infoframe_csum(&avi_if); + +@@ -903,22 +938,9 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) + sdvo_data[3] = avi_if.checksum; + memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); + +- if (!intel_sdvo_set_value(intel_sdvo, +- SDVO_CMD_SET_HBUF_INDEX, +- set_buf_index, 2)) +- return false; +- +- for (i = 0; i < sizeof(sdvo_data); i += 8) { +- if (!intel_sdvo_set_value(intel_sdvo, +- SDVO_CMD_SET_HBUF_DATA, +- data, 8)) +- return false; +- data++; +- } +- +- return intel_sdvo_set_value(intel_sdvo, +- SDVO_CMD_SET_HBUF_TXRATE, +- &tx_rate, 1); ++ return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, ++ SDVO_HBUF_TX_VSYNC, ++ sdvo_data, sizeof(sdvo_data)); + } + + static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) +diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h +index 9d03014..770bdd6 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo_regs.h ++++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h +@@ -708,6 +708,8 @@ struct intel_sdvo_enhancements_arg { + #define SDVO_CMD_SET_AUDIO_STAT 0x91 + #define SDVO_CMD_GET_AUDIO_STAT 0x92 + #define SDVO_CMD_SET_HBUF_INDEX 0x93 ++ #define SDVO_HBUF_INDEX_ELD 0 ++ #define SDVO_HBUF_INDEX_AVI_IF 1 + #define SDVO_CMD_GET_HBUF_INDEX 0x94 + #define SDVO_CMD_GET_HBUF_INFO 0x95 + #define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 +diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c +index e932810..4a33cdc 100644 +--- a/drivers/gpu/drm/radeon/evergreen_cs.c ++++ b/drivers/gpu/drm/radeon/evergreen_cs.c +@@ -2725,6 +2725,9 @@ static bool evergreen_vm_reg_valid(u32 reg) + /* check config regs */ + switch (reg) { + case GRBM_GFX_INDEX: ++ case CP_STRMOUT_CNTL: ++ case CP_COHER_CNTL: ++ case CP_COHER_SIZE: + case VGT_VTX_VECT_EJECT_REG: + case VGT_CACHE_INVALIDATION: + case VGT_GS_VERTEX_REUSE: +diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h +index 7934785..302af4f 100644 +--- a/drivers/gpu/drm/radeon/evergreend.h ++++ b/drivers/gpu/drm/radeon/evergreend.h +@@ -87,6 +87,10 @@ + + #define CONFIG_MEMSIZE 0x5428 + ++#define CP_STRMOUT_CNTL 0x84FC ++ ++#define CP_COHER_CNTL 0x85F0 ++#define CP_COHER_SIZE 0x85F4 + #define CP_COHER_BASE 0x85F8 + #define CP_STALLED_STAT1 0x8674 + #define CP_STALLED_STAT2 0x8678 +diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +index d16f50f..dd402bb 100644 +--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c ++++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +@@ -651,6 +651,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc + tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN; + WREG32(RADEON_DAC_CNTL, tmp); + ++ tmp = dac_macro_cntl; + tmp &= ~(RADEON_DAC_PDWN_R | + RADEON_DAC_PDWN_G | + RADEON_DAC_PDWN_B); +diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c +index 0139e22..6ab4a90 100644 +--- a/drivers/gpu/drm/radeon/si.c ++++ b/drivers/gpu/drm/radeon/si.c +@@ -2472,6 +2472,7 @@ static bool si_vm_reg_valid(u32 reg) + /* check config regs */ + switch (reg) { + case GRBM_GFX_INDEX: ++ case CP_STRMOUT_CNTL: + case VGT_VTX_VECT_EJECT_REG: + case VGT_CACHE_INVALIDATION: + case VGT_ESGS_RING_SIZE: +diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h +index ef4815c..6f0083a 100644 +--- a/drivers/gpu/drm/radeon/sid.h ++++ b/drivers/gpu/drm/radeon/sid.h +@@ -424,6 +424,7 @@ + # define RDERR_INT_ENABLE (1 << 0) + # define GUI_IDLE_INT_ENABLE (1 << 19) + ++#define CP_STRMOUT_CNTL 0x84FC + #define SCRATCH_REG0 0x8500 + #define SCRATCH_REG1 0x8504 + #define SCRATCH_REG2 0x8508 +diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h +index fccd361..87aa5f5 100644 +--- a/drivers/gpu/drm/udl/udl_drv.h ++++ b/drivers/gpu/drm/udl/udl_drv.h +@@ -104,7 +104,7 @@ udl_fb_user_fb_create(struct drm_device *dev, + + int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, + const char *front, char **urb_buf_ptr, +- u32 byte_offset, u32 byte_width, ++ u32 byte_offset, u32 device_byte_offset, u32 byte_width, + int *ident_ptr, int *sent_ptr); + + int udl_dumb_create(struct drm_file *file_priv, +diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c +index ce9a611..6f6ca50 100644 +--- a/drivers/gpu/drm/udl/udl_fb.c ++++ b/drivers/gpu/drm/udl/udl_fb.c +@@ -114,9 +114,10 @@ static void udlfb_dpy_deferred_io(struct fb_info *info, + list_for_each_entry(cur, &fbdefio->pagelist, lru) { + + if (udl_render_hline(dev, (ufbdev->ufb.base.bits_per_pixel / 8), +- &urb, (char *) info->fix.smem_start, +- &cmd, cur->index << PAGE_SHIFT, +- PAGE_SIZE, &bytes_identical, &bytes_sent)) ++ &urb, (char *) info->fix.smem_start, ++ &cmd, cur->index << PAGE_SHIFT, ++ cur->index << PAGE_SHIFT, ++ PAGE_SIZE, &bytes_identical, &bytes_sent)) + goto error; + bytes_rendered += PAGE_SIZE; + } +@@ -187,10 +188,11 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, + for (i = y; i < y + height ; i++) { + const int line_offset = fb->base.pitches[0] * i; + const int byte_offset = line_offset + (x * bpp); +- ++ const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp); + if (udl_render_hline(dev, bpp, &urb, + (char *) fb->obj->vmapping, +- &cmd, byte_offset, width * bpp, ++ &cmd, byte_offset, dev_byte_offset, ++ width * bpp, + &bytes_identical, &bytes_sent)) + goto error; + } +diff --git a/drivers/gpu/drm/udl/udl_transfer.c b/drivers/gpu/drm/udl/udl_transfer.c +index b9320e2..fc11344 100644 +--- a/drivers/gpu/drm/udl/udl_transfer.c ++++ b/drivers/gpu/drm/udl/udl_transfer.c +@@ -213,11 +213,12 @@ static void udl_compress_hline16( + */ + int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, + const char *front, char **urb_buf_ptr, +- u32 byte_offset, u32 byte_width, ++ u32 byte_offset, u32 device_byte_offset, ++ u32 byte_width, + int *ident_ptr, int *sent_ptr) + { + const u8 *line_start, *line_end, *next_pixel; +- u32 base16 = 0 + (byte_offset / bpp) * 2; ++ u32 base16 = 0 + (device_byte_offset / bpp) * 2; + struct urb *urb = *urb_ptr; + u8 *cmd = *urb_buf_ptr; + u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length; +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c +index 3fa884d..27151f7 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c +@@ -306,7 +306,7 @@ void vmw_bo_pin(struct ttm_buffer_object *bo, bool pin) + + BUG_ON(!atomic_read(&bo->reserved)); + BUG_ON(old_mem_type != TTM_PL_VRAM && +- old_mem_type != VMW_PL_FLAG_GMR); ++ old_mem_type != VMW_PL_GMR); + + pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED; + if (pin) +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +index ba2c35d..4a04ae0 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +@@ -1099,6 +1099,11 @@ static void vmw_pm_complete(struct device *kdev) + struct drm_device *dev = pci_get_drvdata(pdev); + struct vmw_private *dev_priv = vmw_priv(dev); + ++ mutex_lock(&dev_priv->hw_mutex); ++ vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); ++ (void) vmw_read(dev_priv, SVGA_REG_ID); ++ mutex_unlock(&dev_priv->hw_mutex); ++ + /** + * Reclaim 3d reference held by fbdev and potentially + * start fifo. +diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c +index 1821b74..de3c7e0 100644 +--- a/drivers/hwmon/w83627ehf.c ++++ b/drivers/hwmon/w83627ehf.c +@@ -2083,6 +2083,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) + mutex_init(&data->lock); + mutex_init(&data->update_lock); + data->name = w83627ehf_device_names[sio_data->kind]; ++ data->bank = 0xff; /* Force initial bank selection */ + platform_set_drvdata(pdev, data); + + /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */ +diff --git a/drivers/input/touchscreen/tsc40.c b/drivers/input/touchscreen/tsc40.c +index 63209aa..eb96f16 100644 +--- a/drivers/input/touchscreen/tsc40.c ++++ b/drivers/input/touchscreen/tsc40.c +@@ -107,7 +107,6 @@ static int tsc_connect(struct serio *serio, struct serio_driver *drv) + __set_bit(BTN_TOUCH, input_dev->keybit); + input_set_abs_params(ptsc->dev, ABS_X, 0, 0x3ff, 0, 0); + input_set_abs_params(ptsc->dev, ABS_Y, 0, 0x3ff, 0, 0); +- input_set_abs_params(ptsc->dev, ABS_PRESSURE, 0, 0, 0, 0); + + serio_set_drvdata(serio, ptsc); + +diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c +index 9a11dc3..b1facf9 100644 +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -1307,16 +1307,19 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) + */ + if ((host->flags & SDHCI_NEEDS_RETUNING) && + !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { +- /* eMMC uses cmd21 while sd and sdio use cmd19 */ +- tuning_opcode = mmc->card->type == MMC_TYPE_MMC ? +- MMC_SEND_TUNING_BLOCK_HS200 : +- MMC_SEND_TUNING_BLOCK; +- spin_unlock_irqrestore(&host->lock, flags); +- sdhci_execute_tuning(mmc, tuning_opcode); +- spin_lock_irqsave(&host->lock, flags); +- +- /* Restore original mmc_request structure */ +- host->mrq = mrq; ++ if (mmc->card) { ++ /* eMMC uses cmd21 but sd and sdio use cmd19 */ ++ tuning_opcode = ++ mmc->card->type == MMC_TYPE_MMC ? ++ MMC_SEND_TUNING_BLOCK_HS200 : ++ MMC_SEND_TUNING_BLOCK; ++ spin_unlock_irqrestore(&host->lock, flags); ++ sdhci_execute_tuning(mmc, tuning_opcode); ++ spin_lock_irqsave(&host->lock, flags); ++ ++ /* Restore original mmc_request structure */ ++ host->mrq = mrq; ++ } + } + + if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23)) +diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c +index ba0e493..9058d21 100644 +--- a/drivers/mmc/host/sh_mmcif.c ++++ b/drivers/mmc/host/sh_mmcif.c +@@ -1464,9 +1464,9 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev) + + platform_set_drvdata(pdev, NULL); + ++ clk_disable(host->hclk); + mmc_free_host(host->mmc); + pm_runtime_put_sync(&pdev->dev); +- clk_disable(host->hclk); + pm_runtime_disable(&pdev->dev); + + return 0; +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +index 56b20d1..116f0e9 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +@@ -2673,6 +2673,9 @@ static int ixgbe_get_ts_info(struct net_device *dev, + case ixgbe_mac_X540: + case ixgbe_mac_82599EB: + info->so_timestamping = ++ SOF_TIMESTAMPING_TX_SOFTWARE | ++ SOF_TIMESTAMPING_RX_SOFTWARE | ++ SOF_TIMESTAMPING_SOFTWARE | + SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_RAW_HARDWARE; +diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c +index 53743f7..af8b414 100644 +--- a/drivers/net/ethernet/nxp/lpc_eth.c ++++ b/drivers/net/ethernet/nxp/lpc_eth.c +@@ -1524,6 +1524,7 @@ static int lpc_eth_drv_remove(struct platform_device *pdev) + pldat->dma_buff_base_p); + free_irq(ndev->irq, ndev); + iounmap(pldat->net_base); ++ mdiobus_unregister(pldat->mii_bus); + mdiobus_free(pldat->mii_bus); + clk_disable(pldat->clk); + clk_put(pldat->clk); +diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c +index fc9f578..9c382b5 100644 +--- a/drivers/net/usb/usbnet.c ++++ b/drivers/net/usb/usbnet.c +@@ -1158,6 +1158,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, + usb_anchor_urb(urb, &dev->deferred); + /* no use to process more packets */ + netif_stop_queue(net); ++ usb_put_urb(urb); + spin_unlock_irqrestore(&dev->txq.lock, flags); + netdev_dbg(dev->net, "Delaying transmission for resumption\n"); + goto deferred; +@@ -1310,6 +1311,8 @@ void usbnet_disconnect (struct usb_interface *intf) + + cancel_work_sync(&dev->kevent); + ++ usb_scuttle_anchored_urbs(&dev->deferred); ++ + if (dev->driver_info->unbind) + dev->driver_info->unbind (dev, intf); + +diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c +index 423a9f3..88b6acc 100644 +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -312,6 +312,7 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) + } + + bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); ++ bf->bf_next = NULL; + list_del(&bf->list); + + spin_unlock_bh(&sc->tx.txbuflock); +@@ -393,7 +394,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, + u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first; + u32 ba[WME_BA_BMP_SIZE >> 5]; + int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; +- bool rc_update = true; ++ bool rc_update = true, isba; + struct ieee80211_tx_rate rates[4]; + struct ath_frame_info *fi; + int nframes; +@@ -437,13 +438,17 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, + tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; + tid = ATH_AN_2_TID(an, tidno); + seq_first = tid->seq_start; ++ isba = ts->ts_flags & ATH9K_TX_BA; + + /* + * The hardware occasionally sends a tx status for the wrong TID. + * In this case, the BA status cannot be considered valid and all + * subframes need to be retransmitted ++ * ++ * Only BlockAcks have a TID and therefore normal Acks cannot be ++ * checked + */ +- if (tidno != ts->tid) ++ if (isba && tidno != ts->tid) + txok = false; + + isaggr = bf_isaggr(bf); +@@ -1774,6 +1779,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, + list_add_tail(&bf->list, &bf_head); + bf->bf_state.bf_type = 0; + ++ bf->bf_next = NULL; + bf->bf_lastbf = bf; + ath_tx_fill_desc(sc, bf, txq, fi->framelen); + ath_tx_txqaddbuf(sc, txq, &bf_head, false); +diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c +index b93516d..1345bdd 100644 +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c +@@ -2395,7 +2395,7 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev) + /* + * Check if temperature compensation is supported. + */ +- if (tssi_bounds[4] == 0xff) ++ if (tssi_bounds[4] == 0xff || step == 0xff) + return 0; + + /* +diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c +index dd4fce2..6b6f50a 100644 +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -3735,7 +3735,9 @@ restart: + */ + iscsit_thread_check_cpumask(conn, current, 1); + +- schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT); ++ wait_event_interruptible(conn->queues_wq, ++ !iscsit_conn_all_queues_empty(conn) || ++ ts->status == ISCSI_THREAD_SET_RESET); + + if ((ts->status == ISCSI_THREAD_SET_RESET) || + signal_pending(current)) +diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h +index a90294f..1d63d56 100644 +--- a/drivers/target/iscsi/iscsi_target_core.h ++++ b/drivers/target/iscsi/iscsi_target_core.h +@@ -486,6 +486,7 @@ struct iscsi_tmr_req { + }; + + struct iscsi_conn { ++ wait_queue_head_t queues_wq; + /* Authentication Successful for this connection */ + u8 auth_complete; + /* State connection is currently in */ +diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c +index 6aba439..7b643ab 100644 +--- a/drivers/target/iscsi/iscsi_target_login.c ++++ b/drivers/target/iscsi/iscsi_target_login.c +@@ -45,6 +45,7 @@ extern spinlock_t sess_idr_lock; + + static int iscsi_login_init_conn(struct iscsi_conn *conn) + { ++ init_waitqueue_head(&conn->queues_wq); + INIT_LIST_HEAD(&conn->conn_list); + INIT_LIST_HEAD(&conn->conn_cmd_list); + INIT_LIST_HEAD(&conn->immed_queue_list); +diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c +index b42cdeb..552f45a 100644 +--- a/drivers/target/iscsi/iscsi_target_util.c ++++ b/drivers/target/iscsi/iscsi_target_util.c +@@ -488,7 +488,7 @@ void iscsit_add_cmd_to_immediate_queue( + atomic_set(&conn->check_immediate_queue, 1); + spin_unlock_bh(&conn->immed_queue_lock); + +- wake_up_process(conn->thread_set->tx_thread); ++ wake_up(&conn->queues_wq); + } + + struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *conn) +@@ -562,7 +562,7 @@ void iscsit_add_cmd_to_response_queue( + atomic_inc(&cmd->response_queue_count); + spin_unlock_bh(&conn->response_queue_lock); + +- wake_up_process(conn->thread_set->tx_thread); ++ wake_up(&conn->queues_wq); + } + + struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *conn) +@@ -616,6 +616,24 @@ static void iscsit_remove_cmd_from_response_queue( + } + } + ++bool iscsit_conn_all_queues_empty(struct iscsi_conn *conn) ++{ ++ bool empty; ++ ++ spin_lock_bh(&conn->immed_queue_lock); ++ empty = list_empty(&conn->immed_queue_list); ++ spin_unlock_bh(&conn->immed_queue_lock); ++ ++ if (!empty) ++ return empty; ++ ++ spin_lock_bh(&conn->response_queue_lock); ++ empty = list_empty(&conn->response_queue_list); ++ spin_unlock_bh(&conn->response_queue_lock); ++ ++ return empty; ++} ++ + void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn) + { + struct iscsi_queue_req *qr, *qr_tmp; +diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h +index e1c729b..2ff9bbc 100644 +--- a/drivers/target/iscsi/iscsi_target_util.h ++++ b/drivers/target/iscsi/iscsi_target_util.h +@@ -25,6 +25,7 @@ extern struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_ + extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8); + extern struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *); + extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_conn *); ++extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *); + extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *); + extern void iscsit_release_cmd(struct iscsi_cmd *); + extern void iscsit_free_cmd(struct iscsi_cmd *); +diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c +index 06aca11..ac0b69f 100644 +--- a/drivers/target/target_core_configfs.c ++++ b/drivers/target/target_core_configfs.c +@@ -3214,7 +3214,8 @@ static int __init target_core_init_configfs(void) + if (ret < 0) + goto out; + +- if (core_dev_setup_virtual_lun0() < 0) ++ ret = core_dev_setup_virtual_lun0(); ++ if (ret < 0) + goto out; + + return 0; +diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c +index 9fc9a60..68d4c10 100644 +--- a/drivers/target/target_core_device.c ++++ b/drivers/target/target_core_device.c +@@ -850,20 +850,20 @@ int se_dev_check_shutdown(struct se_device *dev) + + static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) + { +- u32 tmp, aligned_max_sectors; ++ u32 aligned_max_sectors; ++ u32 alignment; + /* + * Limit max_sectors to a PAGE_SIZE aligned value for modern + * transport_allocate_data_tasks() operation. + */ +- tmp = rounddown((max_sectors * block_size), PAGE_SIZE); +- aligned_max_sectors = (tmp / block_size); +- if (max_sectors != aligned_max_sectors) { +- printk(KERN_INFO "Rounding down aligned max_sectors from %u" +- " to %u\n", max_sectors, aligned_max_sectors); +- return aligned_max_sectors; +- } ++ alignment = max(1ul, PAGE_SIZE / block_size); ++ aligned_max_sectors = rounddown(max_sectors, alignment); ++ ++ if (max_sectors != aligned_max_sectors) ++ pr_info("Rounding down aligned max_sectors from %u to %u\n", ++ max_sectors, aligned_max_sectors); + +- return max_sectors; ++ return aligned_max_sectors; + } + + void se_dev_set_default_attribs( +diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c +index 9229bd9..6fd434d 100644 +--- a/drivers/target/target_core_spc.c ++++ b/drivers/target/target_core_spc.c +@@ -605,6 +605,8 @@ static int spc_emulate_inquiry(struct se_cmd *cmd) + unsigned char buf[SE_INQUIRY_BUF]; + int p, ret; + ++ memset(buf, 0, SE_INQUIRY_BUF); ++ + if (dev == tpg->tpg_virt_lun0.lun_se_dev) + buf[0] = 0x3f; /* Not connected */ + else +diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c +index 1c59a3c..be75c43 100644 +--- a/drivers/target/target_core_tmr.c ++++ b/drivers/target/target_core_tmr.c +@@ -140,15 +140,15 @@ void core_tmr_abort_task( + printk("ABORT_TASK: Found referenced %s task_tag: %u\n", + se_cmd->se_tfo->get_fabric_name(), ref_tag); + +- spin_lock_irq(&se_cmd->t_state_lock); ++ spin_lock(&se_cmd->t_state_lock); + if (se_cmd->transport_state & CMD_T_COMPLETE) { + printk("ABORT_TASK: ref_tag: %u already complete, skipping\n", ref_tag); +- spin_unlock_irq(&se_cmd->t_state_lock); ++ spin_unlock(&se_cmd->t_state_lock); + spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); + goto out; + } + se_cmd->transport_state |= CMD_T_ABORTED; +- spin_unlock_irq(&se_cmd->t_state_lock); ++ spin_unlock(&se_cmd->t_state_lock); + + list_del_init(&se_cmd->se_cmd_list); + kref_get(&se_cmd->cmd_kref); +diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c +index 7f12416..9a113b7 100644 +--- a/drivers/xen/gntdev.c ++++ b/drivers/xen/gntdev.c +@@ -105,6 +105,21 @@ static void gntdev_print_maps(struct gntdev_priv *priv, + #endif + } + ++static void gntdev_free_map(struct grant_map *map) ++{ ++ if (map == NULL) ++ return; ++ ++ if (map->pages) ++ free_xenballooned_pages(map->count, map->pages); ++ kfree(map->pages); ++ kfree(map->grants); ++ kfree(map->map_ops); ++ kfree(map->unmap_ops); ++ kfree(map->kmap_ops); ++ kfree(map); ++} ++ + static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) + { + struct grant_map *add; +@@ -142,12 +157,7 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) + return add; + + err: +- kfree(add->pages); +- kfree(add->grants); +- kfree(add->map_ops); +- kfree(add->unmap_ops); +- kfree(add->kmap_ops); +- kfree(add); ++ gntdev_free_map(add); + return NULL; + } + +@@ -198,17 +208,9 @@ static void gntdev_put_map(struct grant_map *map) + evtchn_put(map->notify.event); + } + +- if (map->pages) { +- if (!use_ptemod) +- unmap_grant_pages(map, 0, map->count); +- +- free_xenballooned_pages(map->count, map->pages); +- } +- kfree(map->pages); +- kfree(map->grants); +- kfree(map->map_ops); +- kfree(map->unmap_ops); +- kfree(map); ++ if (map->pages && !use_ptemod) ++ unmap_grant_pages(map, 0, map->count); ++ gntdev_free_map(map); + } + + /* ------------------------------------------------------------------ */ +diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c +index 8ff95a2..0967d0c 100644 +--- a/fs/gfs2/lops.c ++++ b/fs/gfs2/lops.c +@@ -393,12 +393,10 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) + struct gfs2_meta_header *mh; + struct gfs2_trans *tr; + +- lock_buffer(bd->bd_bh); +- gfs2_log_lock(sdp); + tr = current->journal_info; + tr->tr_touched = 1; + if (!list_empty(&bd->bd_list)) +- goto out; ++ return; + set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); + set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); + mh = (struct gfs2_meta_header *)bd->bd_bh->b_data; +@@ -414,9 +412,6 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) + sdp->sd_log_num_buf++; + list_add(&bd->bd_list, &sdp->sd_log_le_buf); + tr->tr_num_buf_new++; +-out: +- gfs2_log_unlock(sdp); +- unlock_buffer(bd->bd_bh); + } + + static void gfs2_check_magic(struct buffer_head *bh) +@@ -777,12 +772,10 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) + struct address_space *mapping = bd->bd_bh->b_page->mapping; + struct gfs2_inode *ip = GFS2_I(mapping->host); + +- lock_buffer(bd->bd_bh); +- gfs2_log_lock(sdp); + if (tr) + tr->tr_touched = 1; + if (!list_empty(&bd->bd_list)) +- goto out; ++ return; + set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); + set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); + if (gfs2_is_jdata(ip)) { +@@ -793,9 +786,6 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) + } else { + list_add_tail(&bd->bd_list, &sdp->sd_log_le_ordered); + } +-out: +- gfs2_log_unlock(sdp); +- unlock_buffer(bd->bd_bh); + } + + /** +diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c +index adbd278..4136270 100644 +--- a/fs/gfs2/trans.c ++++ b/fs/gfs2/trans.c +@@ -155,14 +155,22 @@ void gfs2_trans_add_bh(struct gfs2_glock *gl, struct buffer_head *bh, int meta) + struct gfs2_sbd *sdp = gl->gl_sbd; + struct gfs2_bufdata *bd; + ++ lock_buffer(bh); ++ gfs2_log_lock(sdp); + bd = bh->b_private; + if (bd) + gfs2_assert(sdp, bd->bd_gl == gl); + else { ++ gfs2_log_unlock(sdp); ++ unlock_buffer(bh); + gfs2_attach_bufdata(gl, bh, meta); + bd = bh->b_private; ++ lock_buffer(bh); ++ gfs2_log_lock(sdp); + } + lops_add(sdp, bd); ++ gfs2_log_unlock(sdp); ++ unlock_buffer(bh); + } + + void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) +diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c +index 31c26c4..ca4b11e 100644 +--- a/fs/nfs/dns_resolve.c ++++ b/fs/nfs/dns_resolve.c +@@ -217,7 +217,7 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen) + { + char buf1[NFS_DNS_HOSTNAME_MAXLEN+1]; + struct nfs_dns_ent key, *item; +- unsigned long ttl; ++ unsigned int ttl; + ssize_t len; + int ret = -EINVAL; + +@@ -240,7 +240,8 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen) + key.namelen = len; + memset(&key.h, 0, sizeof(key.h)); + +- ttl = get_expiry(&buf); ++ if (get_uint(&buf, &ttl) < 0) ++ goto out; + if (ttl == 0) + goto out; + key.h.expiry_time = ttl + seconds_since_boot(); +diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h +index 31fdb03..e794dee 100644 +--- a/fs/nfs/internal.h ++++ b/fs/nfs/internal.h +@@ -353,8 +353,9 @@ extern void nfs_sb_active(struct super_block *sb); + extern void nfs_sb_deactive(struct super_block *sb); + + /* namespace.c */ ++#define NFS_PATH_CANONICAL 1 + extern char *nfs_path(char **p, struct dentry *dentry, +- char *buffer, ssize_t buflen); ++ char *buffer, ssize_t buflen, unsigned flags); + extern struct vfsmount *nfs_d_automount(struct path *path); + struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *, + struct nfs_fh *, struct nfs_fattr *); +@@ -491,7 +492,7 @@ static inline char *nfs_devname(struct dentry *dentry, + char *buffer, ssize_t buflen) + { + char *dummy; +- return nfs_path(&dummy, dentry, buffer, buflen); ++ return nfs_path(&dummy, dentry, buffer, buflen, NFS_PATH_CANONICAL); + } + + /* +diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c +index 8e65c7f..015f71f 100644 +--- a/fs/nfs/mount_clnt.c ++++ b/fs/nfs/mount_clnt.c +@@ -181,7 +181,7 @@ int nfs_mount(struct nfs_mount_request *info) + else + msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC_MNT]; + +- status = rpc_call_sync(mnt_clnt, &msg, 0); ++ status = rpc_call_sync(mnt_clnt, &msg, RPC_TASK_SOFT|RPC_TASK_TIMEOUT); + rpc_shutdown_client(mnt_clnt); + + if (status < 0) +diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c +index 6559253..dd057bc 100644 +--- a/fs/nfs/namespace.c ++++ b/fs/nfs/namespace.c +@@ -33,6 +33,7 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ; + * @dentry - pointer to dentry + * @buffer - result buffer + * @buflen - length of buffer ++ * @flags - options (see below) + * + * Helper function for constructing the server pathname + * by arbitrary hashed dentry. +@@ -40,8 +41,14 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ; + * This is mainly for use in figuring out the path on the + * server side when automounting on top of an existing partition + * and in generating /proc/mounts and friends. ++ * ++ * Supported flags: ++ * NFS_PATH_CANONICAL: ensure there is exactly one slash after ++ * the original device (export) name ++ * (if unset, the original name is returned verbatim) + */ +-char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen) ++char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen, ++ unsigned flags) + { + char *end; + int namelen; +@@ -74,7 +81,7 @@ rename_retry: + rcu_read_unlock(); + goto rename_retry; + } +- if (*end != '/') { ++ if ((flags & NFS_PATH_CANONICAL) && *end != '/') { + if (--buflen < 0) { + spin_unlock(&dentry->d_lock); + rcu_read_unlock(); +@@ -91,9 +98,11 @@ rename_retry: + return end; + } + namelen = strlen(base); +- /* Strip off excess slashes in base string */ +- while (namelen > 0 && base[namelen - 1] == '/') +- namelen--; ++ if (flags & NFS_PATH_CANONICAL) { ++ /* Strip off excess slashes in base string */ ++ while (namelen > 0 && base[namelen - 1] == '/') ++ namelen--; ++ } + buflen -= namelen; + if (buflen < 0) { + spin_unlock(&dentry->d_lock); +diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c +index 017b4b0..c077b25 100644 +--- a/fs/nfs/nfs4namespace.c ++++ b/fs/nfs/nfs4namespace.c +@@ -81,7 +81,8 @@ static char *nfs_path_component(const char *nfspath, const char *end) + static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen) + { + char *limit; +- char *path = nfs_path(&limit, dentry, buffer, buflen); ++ char *path = nfs_path(&limit, dentry, buffer, buflen, ++ NFS_PATH_CANONICAL); + if (!IS_ERR(path)) { + char *path_component = nfs_path_component(path, limit); + if (path_component) +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index d5a0cf1..7bff871 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -331,8 +331,7 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc + dprintk("%s ERROR: %d Reset session\n", __func__, + errorcode); + nfs4_schedule_session_recovery(clp->cl_session, errorcode); +- exception->retry = 1; +- break; ++ goto wait_on_recovery; + #endif /* defined(CONFIG_NFS_V4_1) */ + case -NFS4ERR_FILE_OPEN: + if (exception->timeout > HZ) { +@@ -1499,9 +1498,11 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) + data->timestamp = jiffies; + if (nfs4_setup_sequence(data->o_arg.server, + &data->o_arg.seq_args, +- &data->o_res.seq_res, task)) +- return; +- rpc_call_start(task); ++ &data->o_res.seq_res, ++ task) != 0) ++ nfs_release_seqid(data->o_arg.seqid); ++ else ++ rpc_call_start(task); + return; + unlock_no_action: + rcu_read_unlock(); +@@ -2182,9 +2183,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) + if (nfs4_setup_sequence(NFS_SERVER(calldata->inode), + &calldata->arg.seq_args, + &calldata->res.seq_res, +- task)) +- goto out; +- rpc_call_start(task); ++ task) != 0) ++ nfs_release_seqid(calldata->arg.seqid); ++ else ++ rpc_call_start(task); + out: + dprintk("%s: done!\n", __func__); + } +@@ -4390,6 +4392,7 @@ static void nfs4_locku_done(struct rpc_task *task, void *data) + if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN) + rpc_restart_call_prepare(task); + } ++ nfs_release_seqid(calldata->arg.seqid); + } + + static void nfs4_locku_prepare(struct rpc_task *task, void *data) +@@ -4406,9 +4409,11 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data) + calldata->timestamp = jiffies; + if (nfs4_setup_sequence(calldata->server, + &calldata->arg.seq_args, +- &calldata->res.seq_res, task)) +- return; +- rpc_call_start(task); ++ &calldata->res.seq_res, ++ task) != 0) ++ nfs_release_seqid(calldata->arg.seqid); ++ else ++ rpc_call_start(task); + } + + static const struct rpc_call_ops nfs4_locku_ops = { +@@ -4553,7 +4558,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) + /* Do we need to do an open_to_lock_owner? */ + if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) { + if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0) +- return; ++ goto out_release_lock_seqid; + data->arg.open_stateid = &state->stateid; + data->arg.new_lock_owner = 1; + data->res.open_seqid = data->arg.open_seqid; +@@ -4562,10 +4567,15 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) + data->timestamp = jiffies; + if (nfs4_setup_sequence(data->server, + &data->arg.seq_args, +- &data->res.seq_res, task)) ++ &data->res.seq_res, ++ task) == 0) { ++ rpc_call_start(task); + return; +- rpc_call_start(task); +- dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status); ++ } ++ nfs_release_seqid(data->arg.open_seqid); ++out_release_lock_seqid: ++ nfs_release_seqid(data->arg.lock_seqid); ++ dprintk("%s: done!, ret = %d\n", __func__, task->tk_status); + } + + static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata) +diff --git a/fs/nfs/super.c b/fs/nfs/super.c +index b8eda70..d8d7396 100644 +--- a/fs/nfs/super.c ++++ b/fs/nfs/super.c +@@ -765,7 +765,7 @@ int nfs_show_devname(struct seq_file *m, struct dentry *root) + int err = 0; + if (!page) + return -ENOMEM; +- devname = nfs_path(&dummy, root, page, PAGE_SIZE); ++ devname = nfs_path(&dummy, root, page, PAGE_SIZE, 0); + if (IS_ERR(devname)) + err = PTR_ERR(devname); + else +diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c +index a8d0ed9..becf4a9 100644 +--- a/fs/xfs/xfs_buf_item.c ++++ b/fs/xfs/xfs_buf_item.c +@@ -526,7 +526,25 @@ xfs_buf_item_unpin( + } + xfs_buf_relse(bp); + } else if (freed && remove) { ++ /* ++ * There are currently two references to the buffer - the active ++ * LRU reference and the buf log item. What we are about to do ++ * here - simulate a failed IO completion - requires 3 ++ * references. ++ * ++ * The LRU reference is removed by the xfs_buf_stale() call. The ++ * buf item reference is removed by the xfs_buf_iodone() ++ * callback that is run by xfs_buf_do_callbacks() during ioend ++ * processing (via the bp->b_iodone callback), and then finally ++ * the ioend processing will drop the IO reference if the buffer ++ * is marked XBF_ASYNC. ++ * ++ * Hence we need to take an additional reference here so that IO ++ * completion processing doesn't free the buffer prematurely. ++ */ + xfs_buf_lock(bp); ++ xfs_buf_hold(bp); ++ bp->b_flags |= XBF_ASYNC; + xfs_buf_ioerror(bp, EIO); + XFS_BUF_UNDONE(bp); + xfs_buf_stale(bp); +diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c +index 5da3ace..d308749 100644 +--- a/fs/xfs/xfs_log_recover.c ++++ b/fs/xfs/xfs_log_recover.c +@@ -3541,7 +3541,7 @@ xlog_do_recovery_pass( + * - order is important. + */ + error = xlog_bread_offset(log, 0, +- bblks - split_bblks, hbp, ++ bblks - split_bblks, dbp, + offset + BBTOB(split_bblks)); + if (error) + goto bread_err2; +diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h +index f10553c..fb5204b 100644 +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -2633,6 +2633,15 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); + unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc); + + /** ++ * ieee80211_get_mesh_hdrlen - get mesh extension header length ++ * @meshhdr: the mesh extension header, only the flags field ++ * (first byte) will be accessed ++ * Returns the length of the extension header, which is always at ++ * least 6 bytes and at most 18 if address 5 and 6 are present. ++ */ ++unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); ++ ++/** + * DOC: Data path helpers + * + * In addition to generic utilities, cfg80211 also offers +diff --git a/include/sound/core.h b/include/sound/core.h +index bc05668..93896ad 100644 +--- a/include/sound/core.h ++++ b/include/sound/core.h +@@ -132,6 +132,7 @@ struct snd_card { + int shutdown; /* this card is going down */ + int free_on_last_close; /* free in context of file_release */ + wait_queue_head_t shutdown_sleep; ++ atomic_t refcount; /* refcount for disconnection */ + struct device *dev; /* device assigned to this card */ + struct device *card_dev; /* cardX object for sysfs */ + +@@ -189,6 +190,7 @@ struct snd_minor { + const struct file_operations *f_ops; /* file operations */ + void *private_data; /* private data for f_ops->open */ + struct device *dev; /* device for sysfs */ ++ struct snd_card *card_ptr; /* assigned card instance */ + }; + + /* return a device pointer linked to each sound device as a parent */ +@@ -295,6 +297,7 @@ int snd_card_info_done(void); + int snd_component_add(struct snd_card *card, const char *component); + int snd_card_file_add(struct snd_card *card, struct file *file); + int snd_card_file_remove(struct snd_card *card, struct file *file); ++void snd_card_unref(struct snd_card *card); + + #define snd_card_set_dev(card, devptr) ((card)->dev = (devptr)) + +diff --git a/include/trace/events/xen.h b/include/trace/events/xen.h +index 15ba03b..d06b6da 100644 +--- a/include/trace/events/xen.h ++++ b/include/trace/events/xen.h +@@ -377,6 +377,14 @@ DECLARE_EVENT_CLASS(xen_mmu_pgd, + DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_pin); + DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_unpin); + ++TRACE_EVENT(xen_mmu_flush_tlb_all, ++ TP_PROTO(int x), ++ TP_ARGS(x), ++ TP_STRUCT__entry(__array(char, x, 0)), ++ TP_fast_assign((void)x), ++ TP_printk("%s", "") ++ ); ++ + TRACE_EVENT(xen_mmu_flush_tlb, + TP_PROTO(int x), + TP_ARGS(x), +diff --git a/kernel/futex.c b/kernel/futex.c +index 3717e7b..20ef219 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -716,7 +716,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, + struct futex_pi_state **ps, + struct task_struct *task, int set_waiters) + { +- int lock_taken, ret, ownerdied = 0; ++ int lock_taken, ret, force_take = 0; + u32 uval, newval, curval, vpid = task_pid_vnr(task); + + retry: +@@ -755,17 +755,15 @@ retry: + newval = curval | FUTEX_WAITERS; + + /* +- * There are two cases, where a futex might have no owner (the +- * owner TID is 0): OWNER_DIED. We take over the futex in this +- * case. We also do an unconditional take over, when the owner +- * of the futex died. +- * +- * This is safe as we are protected by the hash bucket lock ! ++ * Should we force take the futex? See below. + */ +- if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) { +- /* Keep the OWNER_DIED bit */ ++ if (unlikely(force_take)) { ++ /* ++ * Keep the OWNER_DIED and the WAITERS bit and set the ++ * new TID value. ++ */ + newval = (curval & ~FUTEX_TID_MASK) | vpid; +- ownerdied = 0; ++ force_take = 0; + lock_taken = 1; + } + +@@ -775,7 +773,7 @@ retry: + goto retry; + + /* +- * We took the lock due to owner died take over. ++ * We took the lock due to forced take over. + */ + if (unlikely(lock_taken)) + return 1; +@@ -790,20 +788,25 @@ retry: + switch (ret) { + case -ESRCH: + /* +- * No owner found for this futex. Check if the +- * OWNER_DIED bit is set to figure out whether +- * this is a robust futex or not. ++ * We failed to find an owner for this ++ * futex. So we have no pi_state to block ++ * on. This can happen in two cases: ++ * ++ * 1) The owner died ++ * 2) A stale FUTEX_WAITERS bit ++ * ++ * Re-read the futex value. + */ + if (get_futex_value_locked(&curval, uaddr)) + return -EFAULT; + + /* +- * We simply start over in case of a robust +- * futex. The code above will take the futex +- * and return happy. ++ * If the owner died or we have a stale ++ * WAITERS bit the owner TID in the user space ++ * futex is 0. + */ +- if (curval & FUTEX_OWNER_DIED) { +- ownerdied = 1; ++ if (!(curval & FUTEX_TID_MASK)) { ++ force_take = 1; + goto retry; + } + default: +diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c +index 6705d35..e7b5777 100644 +--- a/net/batman-adv/bridge_loop_avoidance.c ++++ b/net/batman-adv/bridge_loop_avoidance.c +@@ -1205,8 +1205,8 @@ int batadv_bla_init(struct batadv_priv *bat_priv) + /** + * batadv_bla_check_bcast_duplist + * @bat_priv: the bat priv with all the soft interface information +- * @bcast_packet: originator mac address +- * @hdr_size: maximum length of the frame ++ * @bcast_packet: encapsulated broadcast frame plus batman header ++ * @bcast_packet_len: length of encapsulated broadcast frame plus batman header + * + * check if it is on our broadcast list. Another gateway might + * have sent the same packet because it is connected to the same backbone, +@@ -1219,14 +1219,14 @@ int batadv_bla_init(struct batadv_priv *bat_priv) + */ + int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, + struct batadv_bcast_packet *bcast_packet, +- int hdr_size) ++ int bcast_packet_len) + { + int i, length, curr; + uint8_t *content; + uint16_t crc; + struct batadv_bcast_duplist_entry *entry; + +- length = hdr_size - sizeof(*bcast_packet); ++ length = bcast_packet_len - sizeof(*bcast_packet); + content = (uint8_t *)bcast_packet; + content += sizeof(*bcast_packet); + +diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c +index bc2b88b..f861b7c 100644 +--- a/net/batman-adv/routing.c ++++ b/net/batman-adv/routing.c +@@ -1136,8 +1136,14 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, + + spin_unlock_bh(&orig_node->bcast_seqno_lock); + ++ /* keep skb linear for crc calculation */ ++ if (skb_linearize(skb) < 0) ++ goto out; ++ ++ bcast_packet = (struct batadv_bcast_packet *)skb->data; ++ + /* check whether this has been sent by another originator before */ +- if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, hdr_size)) ++ if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, skb->len)) + goto out; + + /* rebroadcast packet */ +diff --git a/net/core/dev.c b/net/core/dev.c +index 2fb9f59..aed87a4 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1644,7 +1644,7 @@ static inline int deliver_skb(struct sk_buff *skb, + + static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb) + { +- if (ptype->af_packet_priv == NULL) ++ if (!ptype->af_packet_priv || !skb->sk) + return false; + + if (ptype->id_match) +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index ef172af..9708777 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -3384,10 +3384,12 @@ EXPORT_SYMBOL(__skb_warn_lro_forwarding); + + void kfree_skb_partial(struct sk_buff *skb, bool head_stolen) + { +- if (head_stolen) ++ if (head_stolen) { ++ skb_release_head_state(skb); + kmem_cache_free(skbuff_head_cache, skb); +- else ++ } else { + __kfree_skb(skb); ++ } + } + EXPORT_SYMBOL(kfree_skb_partial); + +diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c +index 570e61f..6405a44 100644 +--- a/net/ipv4/inet_diag.c ++++ b/net/ipv4/inet_diag.c +@@ -883,13 +883,16 @@ static int __inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, + struct inet_diag_req_v2 *r, struct nlattr *bc) + { + const struct inet_diag_handler *handler; ++ int err = 0; + + handler = inet_diag_lock_handler(r->sdiag_protocol); + if (!IS_ERR(handler)) + handler->dump(skb, cb, r, bc); ++ else ++ err = PTR_ERR(handler); + inet_diag_unlock_handler(handler); + +- return skb->len; ++ return err ? : skb->len; + } + + static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index 2a1383c..c017cb1 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -1166,8 +1166,12 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe, + spin_lock_bh(&fnhe_lock); + + if (daddr == fnhe->fnhe_daddr) { +- struct rtable *orig; +- ++ struct rtable *orig = rcu_dereference(fnhe->fnhe_rth); ++ if (orig && rt_is_expired(orig)) { ++ fnhe->fnhe_gw = 0; ++ fnhe->fnhe_pmtu = 0; ++ fnhe->fnhe_expires = 0; ++ } + if (fnhe->fnhe_pmtu) { + unsigned long expires = fnhe->fnhe_expires; + unsigned long diff = expires - jiffies; +@@ -1184,7 +1188,6 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe, + } else if (!rt->rt_gateway) + rt->rt_gateway = daddr; + +- orig = rcu_dereference(fnhe->fnhe_rth); + rcu_assign_pointer(fnhe->fnhe_rth, rt); + if (orig) + rt_free(orig); +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 5f64193..49dd993 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -548,14 +548,12 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) + !tp->urg_data || + before(tp->urg_seq, tp->copied_seq) || + !before(tp->urg_seq, tp->rcv_nxt)) { +- struct sk_buff *skb; + + answ = tp->rcv_nxt - tp->copied_seq; + +- /* Subtract 1, if FIN is in queue. */ +- skb = skb_peek_tail(&sk->sk_receive_queue); +- if (answ && skb) +- answ -= tcp_hdr(skb)->fin; ++ /* Subtract 1, if FIN was received */ ++ if (answ && sock_flag(sk, SOCK_DONE)) ++ answ--; + } else + answ = tp->urg_seq - tp->copied_seq; + release_sock(sk); +diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c +index 813b43a..834857f 100644 +--- a/net/ipv4/tcp_illinois.c ++++ b/net/ipv4/tcp_illinois.c +@@ -313,11 +313,13 @@ static void tcp_illinois_info(struct sock *sk, u32 ext, + .tcpv_rttcnt = ca->cnt_rtt, + .tcpv_minrtt = ca->base_rtt, + }; +- u64 t = ca->sum_rtt; + +- do_div(t, ca->cnt_rtt); +- info.tcpv_rtt = t; ++ if (info.tcpv_rttcnt > 0) { ++ u64 t = ca->sum_rtt; + ++ do_div(t, info.tcpv_rttcnt); ++ info.tcpv_rtt = t; ++ } + nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info); + } + } +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index d377f48..c92c4da 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -4556,6 +4556,9 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) + struct tcphdr *th; + bool fragstolen; + ++ if (size == 0) ++ return 0; ++ + skb = alloc_skb(size + sizeof(*th), sk->sk_allocation); + if (!skb) + goto err; +diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c +index ff36194..2edce30 100644 +--- a/net/ipv6/ndisc.c ++++ b/net/ipv6/ndisc.c +@@ -535,7 +535,7 @@ static void ndisc_send_unsol_na(struct net_device *dev) + { + struct inet6_dev *idev; + struct inet6_ifaddr *ifa; +- struct in6_addr mcaddr; ++ struct in6_addr mcaddr = IN6ADDR_LINKLOCAL_ALLNODES_INIT; + + idev = in6_dev_get(dev); + if (!idev) +@@ -543,7 +543,6 @@ static void ndisc_send_unsol_na(struct net_device *dev) + + read_lock_bh(&idev->lock); + list_for_each_entry(ifa, &idev->addr_list, if_list) { +- addrconf_addr_solict_mult(&ifa->addr, &mcaddr); + ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr, + /*router=*/ !!idev->cnf.forwarding, + /*solicited=*/ false, /*override=*/ true, +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 46eff42..070a3ce 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -219,7 +219,7 @@ static struct dst_ops ip6_dst_blackhole_ops = { + }; + + static const u32 ip6_template_metrics[RTAX_MAX] = { +- [RTAX_HOPLIMIT - 1] = 255, ++ [RTAX_HOPLIMIT - 1] = 0, + }; + + static struct rt6_info ip6_null_entry_template = { +@@ -1241,7 +1241,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, + rt->rt6i_dst.addr = fl6->daddr; + rt->rt6i_dst.plen = 128; + rt->rt6i_idev = idev; +- dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); ++ dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 0); + + spin_lock_bh(&icmp6_dst_lock); + rt->dst.next = icmp6_dst_gc_list; +diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c +index 3bfb34a..69bf48d 100644 +--- a/net/l2tp/l2tp_eth.c ++++ b/net/l2tp/l2tp_eth.c +@@ -290,6 +290,7 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p + + out_del_dev: + free_netdev(dev); ++ spriv->dev = NULL; + out_del_session: + l2tp_session_delete(session); + out: +diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c +index 5746d62..327aa07 100644 +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -1074,7 +1074,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, + sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; + sdata->u.ibss.ibss_join_req = jiffies; + +- memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); ++ memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); + sdata->u.ibss.ssid_len = params->ssid_len; + + mutex_unlock(&sdata->u.ibss.mtx); +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 0cb4ede..37fe5ce 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -491,6 +491,11 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) + + if (ieee80211_is_action(hdr->frame_control)) { + u8 category; ++ ++ /* make sure category field is present */ ++ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE) ++ return RX_DROP_MONITOR; ++ + mgmt = (struct ieee80211_mgmt *)hdr; + category = mgmt->u.action.category; + if (category != WLAN_CATEGORY_MESH_ACTION && +@@ -843,14 +848,16 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) + */ + if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION && + ieee80211_is_data_present(hdr->frame_control)) { +- u16 ethertype; +- u8 *payload; +- +- payload = rx->skb->data + +- ieee80211_hdrlen(hdr->frame_control); +- ethertype = (payload[6] << 8) | payload[7]; +- if (cpu_to_be16(ethertype) == +- rx->sdata->control_port_protocol) ++ unsigned int hdrlen; ++ __be16 ethertype; ++ ++ hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ ++ if (rx->skb->len < hdrlen + 8) ++ return RX_DROP_MONITOR; ++ ++ skb_copy_bits(rx->skb, hdrlen + 6, ðertype, 2); ++ if (ethertype == rx->sdata->control_port_protocol) + return RX_CONTINUE; + } + +@@ -1422,11 +1429,14 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + + hdr = (struct ieee80211_hdr *)rx->skb->data; + fc = hdr->frame_control; ++ ++ if (ieee80211_is_ctl(fc)) ++ return RX_CONTINUE; ++ + sc = le16_to_cpu(hdr->seq_ctrl); + frag = sc & IEEE80211_SCTL_FRAG; + + if (likely((!ieee80211_has_morefrags(fc) && frag == 0) || +- (rx->skb)->len < 24 || + is_multicast_ether_addr(hdr->addr1))) { + /* not fragmented */ + goto out; +@@ -1849,6 +1859,20 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) + + hdr = (struct ieee80211_hdr *) skb->data; + hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ ++ /* make sure fixed part of mesh header is there, also checks skb len */ ++ if (!pskb_may_pull(rx->skb, hdrlen + 6)) ++ return RX_DROP_MONITOR; ++ ++ mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); ++ ++ /* make sure full mesh header is there, also checks skb len */ ++ if (!pskb_may_pull(rx->skb, ++ hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr))) ++ return RX_DROP_MONITOR; ++ ++ /* reload pointers */ ++ hdr = (struct ieee80211_hdr *) skb->data; + mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); + + /* frame is in RMC, don't forward */ +@@ -1857,7 +1881,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) + mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata)) + return RX_DROP_MONITOR; + +- if (!ieee80211_is_data(hdr->frame_control)) ++ if (!ieee80211_is_data(hdr->frame_control) || ++ !(status->rx_flags & IEEE80211_RX_RA_MATCH)) + return RX_CONTINUE; + + if (!mesh_hdr->ttl) +@@ -1871,9 +1896,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) + if (is_multicast_ether_addr(hdr->addr1)) { + mpp_addr = hdr->addr3; + proxied_addr = mesh_hdr->eaddr1; +- } else { ++ } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) { ++ /* has_a4 already checked in ieee80211_rx_mesh_check */ + mpp_addr = hdr->addr4; + proxied_addr = mesh_hdr->eaddr2; ++ } else { ++ return RX_DROP_MONITOR; + } + + rcu_read_lock(); +@@ -1901,9 +1929,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) + } + skb_set_queue_mapping(skb, q); + +- if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) +- goto out; +- + if (!--mesh_hdr->ttl) { + IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); + return RX_DROP_MONITOR; +@@ -2313,6 +2338,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) + } + break; + case WLAN_CATEGORY_SELF_PROTECTED: ++ if (len < (IEEE80211_MIN_ACTION_SIZE + ++ sizeof(mgmt->u.action.u.self_prot.action_code))) ++ break; ++ + switch (mgmt->u.action.u.self_prot.action_code) { + case WLAN_SP_MESH_PEERING_OPEN: + case WLAN_SP_MESH_PEERING_CLOSE: +@@ -2331,6 +2360,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) + } + break; + case WLAN_CATEGORY_MESH_ACTION: ++ if (len < (IEEE80211_MIN_ACTION_SIZE + ++ sizeof(mgmt->u.action.u.mesh_action.action_code))) ++ break; ++ + if (!ieee80211_vif_is_mesh(&sdata->vif)) + break; + if (mesh_action_is_path_sel(mgmt) && +@@ -2865,10 +2898,15 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, + if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) + local->dot11ReceivedFragmentCount++; + +- if (ieee80211_is_mgmt(fc)) +- err = skb_linearize(skb); +- else ++ if (ieee80211_is_mgmt(fc)) { ++ /* drop frame if too short for header */ ++ if (skb->len < ieee80211_hdrlen(fc)) ++ err = -ENOBUFS; ++ else ++ err = skb_linearize(skb); ++ } else { + err = !pskb_may_pull(skb, ieee80211_hdrlen(fc)); ++ } + + if (err) { + dev_kfree_skb(skb); +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index c9b52f7..1cfe6d5 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -637,13 +637,41 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, + break; + } + +- if (id != WLAN_EID_VENDOR_SPECIFIC && +- id != WLAN_EID_QUIET && +- test_bit(id, seen_elems)) { +- elems->parse_error = true; +- left -= elen; +- pos += elen; +- continue; ++ switch (id) { ++ case WLAN_EID_SSID: ++ case WLAN_EID_SUPP_RATES: ++ case WLAN_EID_FH_PARAMS: ++ case WLAN_EID_DS_PARAMS: ++ case WLAN_EID_CF_PARAMS: ++ case WLAN_EID_TIM: ++ case WLAN_EID_IBSS_PARAMS: ++ case WLAN_EID_CHALLENGE: ++ case WLAN_EID_RSN: ++ case WLAN_EID_ERP_INFO: ++ case WLAN_EID_EXT_SUPP_RATES: ++ case WLAN_EID_HT_CAPABILITY: ++ case WLAN_EID_HT_OPERATION: ++ case WLAN_EID_VHT_CAPABILITY: ++ case WLAN_EID_VHT_OPERATION: ++ case WLAN_EID_MESH_ID: ++ case WLAN_EID_MESH_CONFIG: ++ case WLAN_EID_PEER_MGMT: ++ case WLAN_EID_PREQ: ++ case WLAN_EID_PREP: ++ case WLAN_EID_PERR: ++ case WLAN_EID_RANN: ++ case WLAN_EID_CHANNEL_SWITCH: ++ case WLAN_EID_EXT_CHANSWITCH_ANN: ++ case WLAN_EID_COUNTRY: ++ case WLAN_EID_PWR_CONSTRAINT: ++ case WLAN_EID_TIMEOUT_INTERVAL: ++ if (test_bit(id, seen_elems)) { ++ elems->parse_error = true; ++ left -= elen; ++ pos += elen; ++ continue; ++ } ++ break; + } + + if (calc_crc && id < 64 && (filter & (1ULL << id))) +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 9172179..0426b67 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -138,6 +138,8 @@ static int netlink_dump(struct sock *sk); + static DEFINE_RWLOCK(nl_table_lock); + static atomic_t nl_table_users = ATOMIC_INIT(0); + ++#define nl_deref_protected(X) rcu_dereference_protected(X, lockdep_is_held(&nl_table_lock)); ++ + static ATOMIC_NOTIFIER_HEAD(netlink_chain); + + static inline u32 netlink_group_mask(u32 group) +@@ -345,6 +347,11 @@ netlink_update_listeners(struct sock *sk) + struct hlist_node *node; + unsigned long mask; + unsigned int i; ++ struct listeners *listeners; ++ ++ listeners = nl_deref_protected(tbl->listeners); ++ if (!listeners) ++ return; + + for (i = 0; i < NLGRPLONGS(tbl->groups); i++) { + mask = 0; +@@ -352,7 +359,7 @@ netlink_update_listeners(struct sock *sk) + if (i < NLGRPLONGS(nlk_sk(sk)->ngroups)) + mask |= nlk_sk(sk)->groups[i]; + } +- tbl->listeners->masks[i] = mask; ++ listeners->masks[i] = mask; + } + /* this function is only called with the netlink table "grabbed", which + * makes sure updates are visible before bind or setsockopt return. */ +@@ -536,7 +543,11 @@ static int netlink_release(struct socket *sock) + if (netlink_is_kernel(sk)) { + BUG_ON(nl_table[sk->sk_protocol].registered == 0); + if (--nl_table[sk->sk_protocol].registered == 0) { +- kfree(nl_table[sk->sk_protocol].listeners); ++ struct listeners *old; ++ ++ old = nl_deref_protected(nl_table[sk->sk_protocol].listeners); ++ RCU_INIT_POINTER(nl_table[sk->sk_protocol].listeners, NULL); ++ kfree_rcu(old, rcu); + nl_table[sk->sk_protocol].module = NULL; + nl_table[sk->sk_protocol].registered = 0; + } +@@ -978,7 +989,7 @@ int netlink_has_listeners(struct sock *sk, unsigned int group) + rcu_read_lock(); + listeners = rcu_dereference(nl_table[sk->sk_protocol].listeners); + +- if (group - 1 < nl_table[sk->sk_protocol].groups) ++ if (listeners && group - 1 < nl_table[sk->sk_protocol].groups) + res = test_bit(group - 1, listeners->masks); + + rcu_read_unlock(); +@@ -1620,7 +1631,7 @@ int __netlink_change_ngroups(struct sock *sk, unsigned int groups) + new = kzalloc(sizeof(*new) + NLGRPSZ(groups), GFP_ATOMIC); + if (!new) + return -ENOMEM; +- old = rcu_dereference_protected(tbl->listeners, 1); ++ old = nl_deref_protected(tbl->listeners); + memcpy(new->masks, old->masks, NLGRPSZ(tbl->groups)); + rcu_assign_pointer(tbl->listeners, new); + +diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c +index fe99628..b1c5be3 100644 +--- a/net/sctp/sm_sideeffect.c ++++ b/net/sctp/sm_sideeffect.c +@@ -1634,8 +1634,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, + asoc->outqueue.outstanding_bytes; + sackh.num_gap_ack_blocks = 0; + sackh.num_dup_tsns = 0; ++ chunk->subh.sack_hdr = &sackh; + sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, +- SCTP_SACKH(&sackh)); ++ SCTP_CHUNK(chunk)); + break; + + case SCTP_CMD_DISCARD_PACKET: +diff --git a/net/wireless/core.c b/net/wireless/core.c +index dcd64d5..5797032 100644 +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -506,8 +506,7 @@ int wiphy_register(struct wiphy *wiphy) + for (i = 0; i < sband->n_channels; i++) { + sband->channels[i].orig_flags = + sband->channels[i].flags; +- sband->channels[i].orig_mag = +- sband->channels[i].max_antenna_gain; ++ sband->channels[i].orig_mag = INT_MAX; + sband->channels[i].orig_mpwr = + sband->channels[i].max_power; + sband->channels[i].band = band; +diff --git a/net/wireless/util.c b/net/wireless/util.c +index 994e2f0..09afde7 100644 +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -309,23 +309,21 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) + } + EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); + +-static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) ++unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) + { + int ae = meshhdr->flags & MESH_FLAGS_AE; +- /* 7.1.3.5a.2 */ ++ /* 802.11-2012, 8.2.4.7.3 */ + switch (ae) { ++ default: + case 0: + return 6; + case MESH_FLAGS_AE_A4: + return 12; + case MESH_FLAGS_AE_A5_A6: + return 18; +- case (MESH_FLAGS_AE_A4 | MESH_FLAGS_AE_A5_A6): +- return 24; +- default: +- return 6; + } + } ++EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); + + int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, + enum nl80211_iftype iftype) +@@ -373,6 +371,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, + /* make sure meshdr->flags is on the linear part */ + if (!pskb_may_pull(skb, hdrlen + 1)) + return -1; ++ if (meshdr->flags & MESH_FLAGS_AE_A4) ++ return -1; + if (meshdr->flags & MESH_FLAGS_AE_A5_A6) { + skb_copy_bits(skb, hdrlen + + offsetof(struct ieee80211s_hdr, eaddr1), +@@ -397,6 +397,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, + /* make sure meshdr->flags is on the linear part */ + if (!pskb_may_pull(skb, hdrlen + 1)) + return -1; ++ if (meshdr->flags & MESH_FLAGS_AE_A5_A6) ++ return -1; + if (meshdr->flags & MESH_FLAGS_AE_A4) + skb_copy_bits(skb, hdrlen + + offsetof(struct ieee80211s_hdr, eaddr1), +diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c +index eb60cb8..d5103f7 100644 +--- a/sound/core/compress_offload.c ++++ b/sound/core/compress_offload.c +@@ -100,12 +100,15 @@ static int snd_compr_open(struct inode *inode, struct file *f) + + if (dirn != compr->direction) { + pr_err("this device doesn't support this direction\n"); ++ snd_card_unref(compr->card); + return -EINVAL; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); +- if (!data) ++ if (!data) { ++ snd_card_unref(compr->card); + return -ENOMEM; ++ } + data->stream.ops = compr->ops; + data->stream.direction = dirn; + data->stream.private_data = compr->private_data; +@@ -113,6 +116,7 @@ static int snd_compr_open(struct inode *inode, struct file *f) + runtime = kzalloc(sizeof(*runtime), GFP_KERNEL); + if (!runtime) { + kfree(data); ++ snd_card_unref(compr->card); + return -ENOMEM; + } + runtime->state = SNDRV_PCM_STATE_OPEN; +@@ -126,7 +130,8 @@ static int snd_compr_open(struct inode *inode, struct file *f) + kfree(runtime); + kfree(data); + } +- return ret; ++ snd_card_unref(compr->card); ++ return 0; + } + + static int snd_compr_free(struct inode *inode, struct file *f) +diff --git a/sound/core/control.c b/sound/core/control.c +index 2487a6b..daa4fc8 100644 +--- a/sound/core/control.c ++++ b/sound/core/control.c +@@ -86,6 +86,7 @@ static int snd_ctl_open(struct inode *inode, struct file *file) + write_lock_irqsave(&card->ctl_files_rwlock, flags); + list_add_tail(&ctl->list, &card->ctl_files); + write_unlock_irqrestore(&card->ctl_files_rwlock, flags); ++ snd_card_unref(card); + return 0; + + __error: +@@ -93,6 +94,8 @@ static int snd_ctl_open(struct inode *inode, struct file *file) + __error2: + snd_card_file_remove(card, file); + __error1: ++ if (card) ++ snd_card_unref(card); + return err; + } + +@@ -1433,6 +1436,8 @@ static ssize_t snd_ctl_read(struct file *file, char __user *buffer, + spin_unlock_irq(&ctl->read_lock); + schedule(); + remove_wait_queue(&ctl->change_sleep, &wait); ++ if (ctl->card->shutdown) ++ return -ENODEV; + if (signal_pending(current)) + return -ERESTARTSYS; + spin_lock_irq(&ctl->read_lock); +diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c +index 75ea16f..3f7f662 100644 +--- a/sound/core/hwdep.c ++++ b/sound/core/hwdep.c +@@ -100,8 +100,10 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) + if (hw == NULL) + return -ENODEV; + +- if (!try_module_get(hw->card->module)) ++ if (!try_module_get(hw->card->module)) { ++ snd_card_unref(hw->card); + return -EFAULT; ++ } + + init_waitqueue_entry(&wait, current); + add_wait_queue(&hw->open_wait, &wait); +@@ -129,6 +131,10 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) + mutex_unlock(&hw->open_mutex); + schedule(); + mutex_lock(&hw->open_mutex); ++ if (hw->card->shutdown) { ++ err = -ENODEV; ++ break; ++ } + if (signal_pending(current)) { + err = -ERESTARTSYS; + break; +@@ -148,6 +154,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) + mutex_unlock(&hw->open_mutex); + if (err < 0) + module_put(hw->card->module); ++ snd_card_unref(hw->card); + return err; + } + +@@ -459,12 +466,15 @@ static int snd_hwdep_dev_disconnect(struct snd_device *device) + mutex_unlock(®ister_mutex); + return -EINVAL; + } ++ mutex_lock(&hwdep->open_mutex); ++ wake_up(&hwdep->open_wait); + #ifdef CONFIG_SND_OSSEMUL + if (hwdep->ossreg) + snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device); + #endif + snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device); + list_del_init(&hwdep->list); ++ mutex_unlock(&hwdep->open_mutex); + mutex_unlock(®ister_mutex); + return 0; + } +diff --git a/sound/core/init.c b/sound/core/init.c +index d8ec849..7b012d1 100644 +--- a/sound/core/init.c ++++ b/sound/core/init.c +@@ -213,6 +213,7 @@ int snd_card_create(int idx, const char *xid, + spin_lock_init(&card->files_lock); + INIT_LIST_HEAD(&card->files_list); + init_waitqueue_head(&card->shutdown_sleep); ++ atomic_set(&card->refcount, 0); + #ifdef CONFIG_PM + mutex_init(&card->power_lock); + init_waitqueue_head(&card->power_sleep); +@@ -446,21 +447,36 @@ static int snd_card_do_free(struct snd_card *card) + return 0; + } + ++/** ++ * snd_card_unref - release the reference counter ++ * @card: the card instance ++ * ++ * Decrements the reference counter. When it reaches to zero, wake up ++ * the sleeper and call the destructor if needed. ++ */ ++void snd_card_unref(struct snd_card *card) ++{ ++ if (atomic_dec_and_test(&card->refcount)) { ++ wake_up(&card->shutdown_sleep); ++ if (card->free_on_last_close) ++ snd_card_do_free(card); ++ } ++} ++EXPORT_SYMBOL(snd_card_unref); ++ + int snd_card_free_when_closed(struct snd_card *card) + { +- int free_now = 0; +- int ret = snd_card_disconnect(card); +- if (ret) +- return ret; ++ int ret; + +- spin_lock(&card->files_lock); +- if (list_empty(&card->files_list)) +- free_now = 1; +- else +- card->free_on_last_close = 1; +- spin_unlock(&card->files_lock); ++ atomic_inc(&card->refcount); ++ ret = snd_card_disconnect(card); ++ if (ret) { ++ atomic_dec(&card->refcount); ++ return ret; ++ } + +- if (free_now) ++ card->free_on_last_close = 1; ++ if (atomic_dec_and_test(&card->refcount)) + snd_card_do_free(card); + return 0; + } +@@ -474,7 +490,7 @@ int snd_card_free(struct snd_card *card) + return ret; + + /* wait, until all devices are ready for the free operation */ +- wait_event(card->shutdown_sleep, list_empty(&card->files_list)); ++ wait_event(card->shutdown_sleep, !atomic_read(&card->refcount)); + snd_card_do_free(card); + return 0; + } +@@ -886,6 +902,7 @@ int snd_card_file_add(struct snd_card *card, struct file *file) + return -ENODEV; + } + list_add(&mfile->list, &card->files_list); ++ atomic_inc(&card->refcount); + spin_unlock(&card->files_lock); + return 0; + } +@@ -908,7 +925,6 @@ EXPORT_SYMBOL(snd_card_file_add); + int snd_card_file_remove(struct snd_card *card, struct file *file) + { + struct snd_monitor_file *mfile, *found = NULL; +- int last_close = 0; + + spin_lock(&card->files_lock); + list_for_each_entry(mfile, &card->files_list, list) { +@@ -923,19 +939,13 @@ int snd_card_file_remove(struct snd_card *card, struct file *file) + break; + } + } +- if (list_empty(&card->files_list)) +- last_close = 1; + spin_unlock(&card->files_lock); +- if (last_close) { +- wake_up(&card->shutdown_sleep); +- if (card->free_on_last_close) +- snd_card_do_free(card); +- } + if (!found) { + snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file); + return -ENOENT; + } + kfree(found); ++ snd_card_unref(card); + return 0; + } + +diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c +index 18297f7..c353768 100644 +--- a/sound/core/oss/mixer_oss.c ++++ b/sound/core/oss/mixer_oss.c +@@ -52,14 +52,19 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file) + SNDRV_OSS_DEVICE_TYPE_MIXER); + if (card == NULL) + return -ENODEV; +- if (card->mixer_oss == NULL) ++ if (card->mixer_oss == NULL) { ++ snd_card_unref(card); + return -ENODEV; ++ } + err = snd_card_file_add(card, file); +- if (err < 0) ++ if (err < 0) { ++ snd_card_unref(card); + return err; ++ } + fmixer = kzalloc(sizeof(*fmixer), GFP_KERNEL); + if (fmixer == NULL) { + snd_card_file_remove(card, file); ++ snd_card_unref(card); + return -ENOMEM; + } + fmixer->card = card; +@@ -68,8 +73,10 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file) + if (!try_module_get(card->module)) { + kfree(fmixer); + snd_card_file_remove(card, file); ++ snd_card_unref(card); + return -EFAULT; + } ++ snd_card_unref(card); + return 0; + } + +diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c +index 08fde00..4c1cc51 100644 +--- a/sound/core/oss/pcm_oss.c ++++ b/sound/core/oss/pcm_oss.c +@@ -2441,6 +2441,10 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) + mutex_unlock(&pcm->open_mutex); + schedule(); + mutex_lock(&pcm->open_mutex); ++ if (pcm->card->shutdown) { ++ err = -ENODEV; ++ break; ++ } + if (signal_pending(current)) { + err = -ERESTARTSYS; + break; +@@ -2450,6 +2454,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) + mutex_unlock(&pcm->open_mutex); + if (err < 0) + goto __error; ++ snd_card_unref(pcm->card); + return err; + + __error: +@@ -2457,6 +2462,8 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) + __error2: + snd_card_file_remove(pcm->card, file); + __error1: ++ if (pcm) ++ snd_card_unref(pcm->card); + return err; + } + +diff --git a/sound/core/pcm.c b/sound/core/pcm.c +index 1a3070b..e30e1be 100644 +--- a/sound/core/pcm.c ++++ b/sound/core/pcm.c +@@ -1086,11 +1086,19 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) + if (list_empty(&pcm->list)) + goto unlock; + ++ mutex_lock(&pcm->open_mutex); ++ wake_up(&pcm->open_wait); + list_del_init(&pcm->list); + for (cidx = 0; cidx < 2; cidx++) +- for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) +- if (substream->runtime) ++ for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) { ++ snd_pcm_stream_lock_irq(substream); ++ if (substream->runtime) { + substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED; ++ wake_up(&substream->runtime->sleep); ++ wake_up(&substream->runtime->tsleep); ++ } ++ snd_pcm_stream_unlock_irq(substream); ++ } + list_for_each_entry(notify, &snd_pcm_notify_list, list) { + notify->n_disconnect(pcm); + } +@@ -1106,6 +1114,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) + } + snd_unregister_device(devtype, pcm->card, pcm->device); + } ++ mutex_unlock(&pcm->open_mutex); + unlock: + mutex_unlock(®ister_mutex); + return 0; +diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c +index 53b5ada..bf3bf43 100644 +--- a/sound/core/pcm_native.c ++++ b/sound/core/pcm_native.c +@@ -369,6 +369,14 @@ static int period_to_usecs(struct snd_pcm_runtime *runtime) + return usecs; + } + ++static void snd_pcm_set_state(struct snd_pcm_substream *substream, int state) ++{ ++ snd_pcm_stream_lock_irq(substream); ++ if (substream->runtime->status->state != SNDRV_PCM_STATE_DISCONNECTED) ++ substream->runtime->status->state = state; ++ snd_pcm_stream_unlock_irq(substream); ++} ++ + static int snd_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) + { +@@ -452,7 +460,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, + runtime->boundary *= 2; + + snd_pcm_timer_resolution_change(substream); +- runtime->status->state = SNDRV_PCM_STATE_SETUP; ++ snd_pcm_set_state(substream, SNDRV_PCM_STATE_SETUP); + + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); +@@ -464,7 +472,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, + /* hardware might be unusable from this time, + so we force application to retry to set + the correct hardware parameter settings */ +- runtime->status->state = SNDRV_PCM_STATE_OPEN; ++ snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); + if (substream->ops->hw_free != NULL) + substream->ops->hw_free(substream); + return err; +@@ -512,7 +520,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream) + return -EBADFD; + if (substream->ops->hw_free) + result = substream->ops->hw_free(substream); +- runtime->status->state = SNDRV_PCM_STATE_OPEN; ++ snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); + pm_qos_remove_request(&substream->latency_pm_qos_req); + return result; + } +@@ -1320,7 +1328,7 @@ static void snd_pcm_post_prepare(struct snd_pcm_substream *substream, int state) + { + struct snd_pcm_runtime *runtime = substream->runtime; + runtime->control->appl_ptr = runtime->status->hw_ptr; +- runtime->status->state = SNDRV_PCM_STATE_PREPARED; ++ snd_pcm_set_state(substream, SNDRV_PCM_STATE_PREPARED); + } + + static struct action_ops snd_pcm_action_prepare = { +@@ -1510,6 +1518,10 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, + down_read(&snd_pcm_link_rwsem); + snd_pcm_stream_lock_irq(substream); + remove_wait_queue(&to_check->sleep, &wait); ++ if (card->shutdown) { ++ result = -ENODEV; ++ break; ++ } + if (tout == 0) { + if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) + result = -ESTRPIPE; +@@ -1633,6 +1645,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) + write_unlock_irq(&snd_pcm_link_rwlock); + up_write(&snd_pcm_link_rwsem); + _nolock: ++ snd_card_unref(substream1->pcm->card); + fput(file); + if (res < 0) + kfree(group); +@@ -2107,7 +2120,10 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file) + return err; + pcm = snd_lookup_minor_data(iminor(inode), + SNDRV_DEVICE_TYPE_PCM_PLAYBACK); +- return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); ++ err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); ++ if (pcm) ++ snd_card_unref(pcm->card); ++ return err; + } + + static int snd_pcm_capture_open(struct inode *inode, struct file *file) +@@ -2118,7 +2134,10 @@ static int snd_pcm_capture_open(struct inode *inode, struct file *file) + return err; + pcm = snd_lookup_minor_data(iminor(inode), + SNDRV_DEVICE_TYPE_PCM_CAPTURE); +- return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); ++ err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); ++ if (pcm) ++ snd_card_unref(pcm->card); ++ return err; + } + + static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) +@@ -2155,6 +2174,10 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) + mutex_unlock(&pcm->open_mutex); + schedule(); + mutex_lock(&pcm->open_mutex); ++ if (pcm->card->shutdown) { ++ err = -ENODEV; ++ break; ++ } + if (signal_pending(current)) { + err = -ERESTARTSYS; + break; +diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c +index ebf6e49..1bb95ae 100644 +--- a/sound/core/rawmidi.c ++++ b/sound/core/rawmidi.c +@@ -379,8 +379,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) + if (rmidi == NULL) + return -ENODEV; + +- if (!try_module_get(rmidi->card->module)) ++ if (!try_module_get(rmidi->card->module)) { ++ snd_card_unref(rmidi->card); + return -ENXIO; ++ } + + mutex_lock(&rmidi->open_mutex); + card = rmidi->card; +@@ -422,6 +424,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) + mutex_unlock(&rmidi->open_mutex); + schedule(); + mutex_lock(&rmidi->open_mutex); ++ if (rmidi->card->shutdown) { ++ err = -ENODEV; ++ break; ++ } + if (signal_pending(current)) { + err = -ERESTARTSYS; + break; +@@ -440,6 +446,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) + #endif + file->private_data = rawmidi_file; + mutex_unlock(&rmidi->open_mutex); ++ snd_card_unref(rmidi->card); + return 0; + + __error: +@@ -447,6 +454,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) + __error_card: + mutex_unlock(&rmidi->open_mutex); + module_put(rmidi->card->module); ++ snd_card_unref(rmidi->card); + return err; + } + +@@ -991,6 +999,8 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun + spin_unlock_irq(&runtime->lock); + schedule(); + remove_wait_queue(&runtime->sleep, &wait); ++ if (rfile->rmidi->card->shutdown) ++ return -ENODEV; + if (signal_pending(current)) + return result > 0 ? result : -ERESTARTSYS; + if (!runtime->avail) +@@ -1234,6 +1244,8 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, + spin_unlock_irq(&runtime->lock); + timeout = schedule_timeout(30 * HZ); + remove_wait_queue(&runtime->sleep, &wait); ++ if (rfile->rmidi->card->shutdown) ++ return -ENODEV; + if (signal_pending(current)) + return result > 0 ? result : -ERESTARTSYS; + if (!runtime->avail && !timeout) +@@ -1609,9 +1621,20 @@ static int snd_rawmidi_dev_register(struct snd_device *device) + static int snd_rawmidi_dev_disconnect(struct snd_device *device) + { + struct snd_rawmidi *rmidi = device->device_data; ++ int dir; + + mutex_lock(®ister_mutex); ++ mutex_lock(&rmidi->open_mutex); ++ wake_up(&rmidi->open_wait); + list_del_init(&rmidi->list); ++ for (dir = 0; dir < 2; dir++) { ++ struct snd_rawmidi_substream *s; ++ list_for_each_entry(s, &rmidi->streams[dir].substreams, list) { ++ if (s->runtime) ++ wake_up(&s->runtime->sleep); ++ } ++ } ++ + #ifdef CONFIG_SND_OSSEMUL + if (rmidi->ossreg) { + if ((int)rmidi->device == midi_map[rmidi->card->number]) { +@@ -1626,6 +1649,7 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device) + } + #endif /* CONFIG_SND_OSSEMUL */ + snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); ++ mutex_unlock(&rmidi->open_mutex); + mutex_unlock(®ister_mutex); + return 0; + } +diff --git a/sound/core/sound.c b/sound/core/sound.c +index 28f3559..3700d96 100644 +--- a/sound/core/sound.c ++++ b/sound/core/sound.c +@@ -99,6 +99,10 @@ static void snd_request_other(int minor) + * + * Checks that a minor device with the specified type is registered, and returns + * its user data pointer. ++ * ++ * This function increments the reference counter of the card instance ++ * if an associated instance with the given minor number and type is found. ++ * The caller must call snd_card_unref() appropriately later. + */ + void *snd_lookup_minor_data(unsigned int minor, int type) + { +@@ -109,9 +113,11 @@ void *snd_lookup_minor_data(unsigned int minor, int type) + return NULL; + mutex_lock(&sound_mutex); + mreg = snd_minors[minor]; +- if (mreg && mreg->type == type) ++ if (mreg && mreg->type == type) { + private_data = mreg->private_data; +- else ++ if (private_data && mreg->card_ptr) ++ atomic_inc(&mreg->card_ptr->refcount); ++ } else + private_data = NULL; + mutex_unlock(&sound_mutex); + return private_data; +@@ -276,6 +282,7 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev, + preg->device = dev; + preg->f_ops = f_ops; + preg->private_data = private_data; ++ preg->card_ptr = card; + mutex_lock(&sound_mutex); + #ifdef CONFIG_SND_DYNAMIC_MINORS + minor = snd_find_free_minor(type); +diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c +index e952833..726a49a 100644 +--- a/sound/core/sound_oss.c ++++ b/sound/core/sound_oss.c +@@ -40,6 +40,9 @@ + static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS]; + static DEFINE_MUTEX(sound_oss_mutex); + ++/* NOTE: This function increments the refcount of the associated card like ++ * snd_lookup_minor_data(); the caller must call snd_card_unref() appropriately ++ */ + void *snd_lookup_oss_minor_data(unsigned int minor, int type) + { + struct snd_minor *mreg; +@@ -49,9 +52,11 @@ void *snd_lookup_oss_minor_data(unsigned int minor, int type) + return NULL; + mutex_lock(&sound_oss_mutex); + mreg = snd_oss_minors[minor]; +- if (mreg && mreg->type == type) ++ if (mreg && mreg->type == type) { + private_data = mreg->private_data; +- else ++ if (private_data && mreg->card_ptr) ++ atomic_inc(&mreg->card_ptr->refcount); ++ } else + private_data = NULL; + mutex_unlock(&sound_oss_mutex); + return private_data; +@@ -123,6 +128,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, + preg->device = dev; + preg->f_ops = f_ops; + preg->private_data = private_data; ++ preg->card_ptr = card; + mutex_lock(&sound_oss_mutex); + snd_oss_minors[minor] = preg; + minor_unit = SNDRV_MINOR_OSS_DEVICE(minor); +diff --git a/sound/usb/card.c b/sound/usb/card.c +index 4a469f0..b3f5ad4 100644 +--- a/sound/usb/card.c ++++ b/sound/usb/card.c +@@ -339,7 +339,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx, + } + + mutex_init(&chip->mutex); +- mutex_init(&chip->shutdown_mutex); ++ init_rwsem(&chip->shutdown_rwsem); + chip->index = idx; + chip->dev = dev; + chip->card = card; +@@ -559,9 +559,11 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, + return; + + card = chip->card; +- mutex_lock(®ister_mutex); +- mutex_lock(&chip->shutdown_mutex); ++ down_write(&chip->shutdown_rwsem); + chip->shutdown = 1; ++ up_write(&chip->shutdown_rwsem); ++ ++ mutex_lock(®ister_mutex); + chip->num_interfaces--; + if (chip->num_interfaces <= 0) { + snd_card_disconnect(card); +@@ -582,11 +584,9 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, + snd_usb_mixer_disconnect(p); + } + usb_chip[chip->index] = NULL; +- mutex_unlock(&chip->shutdown_mutex); + mutex_unlock(®ister_mutex); + snd_card_free_when_closed(card); + } else { +- mutex_unlock(&chip->shutdown_mutex); + mutex_unlock(®ister_mutex); + } + } +@@ -618,16 +618,20 @@ int snd_usb_autoresume(struct snd_usb_audio *chip) + { + int err = -ENODEV; + ++ down_read(&chip->shutdown_rwsem); + if (!chip->shutdown && !chip->probing) + err = usb_autopm_get_interface(chip->pm_intf); ++ up_read(&chip->shutdown_rwsem); + + return err; + } + + void snd_usb_autosuspend(struct snd_usb_audio *chip) + { ++ down_read(&chip->shutdown_rwsem); + if (!chip->shutdown && !chip->probing) + usb_autopm_put_interface(chip->pm_intf); ++ up_read(&chip->shutdown_rwsem); + } + + static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) +diff --git a/sound/usb/card.h b/sound/usb/card.h +index d9d2b5a..6e262c5 100644 +--- a/sound/usb/card.h ++++ b/sound/usb/card.h +@@ -125,6 +125,7 @@ struct snd_usb_substream { + struct snd_usb_endpoint *data_endpoint; + struct snd_usb_endpoint *sync_endpoint; + unsigned long flags; ++ unsigned int speed; /* USB_SPEED_XXX */ + + u64 formats; /* format bitmasks (all or'ed) */ + unsigned int num_formats; /* number of supported audio formats (list) */ +diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c +index fe56c9d..298070e 100644 +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -287,25 +287,32 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v + unsigned char buf[2]; + int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; + int timeout = 10; +- int err; ++ int idx = 0, err; + + err = snd_usb_autoresume(cval->mixer->chip); + if (err < 0) + return -EIO; ++ down_read(&chip->shutdown_rwsem); + while (timeout-- > 0) { ++ if (chip->shutdown) ++ break; ++ idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); + if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, +- validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), +- buf, val_len) >= val_len) { ++ validx, idx, buf, val_len) >= val_len) { + *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); +- snd_usb_autosuspend(cval->mixer->chip); +- return 0; ++ err = 0; ++ goto out; + } + } +- snd_usb_autosuspend(cval->mixer->chip); + snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", +- request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type); +- return -EINVAL; ++ request, validx, idx, cval->val_type); ++ err = -EINVAL; ++ ++ out: ++ up_read(&chip->shutdown_rwsem); ++ snd_usb_autosuspend(cval->mixer->chip); ++ return err; + } + + static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) +@@ -313,7 +320,7 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v + struct snd_usb_audio *chip = cval->mixer->chip; + unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */ + unsigned char *val; +- int ret, size; ++ int idx = 0, ret, size; + __u8 bRequest; + + if (request == UAC_GET_CUR) { +@@ -330,16 +337,22 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v + if (ret) + goto error; + +- ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, ++ down_read(&chip->shutdown_rwsem); ++ if (chip->shutdown) ++ ret = -ENODEV; ++ else { ++ idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); ++ ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, +- validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), +- buf, size); ++ validx, idx, buf, size); ++ } ++ up_read(&chip->shutdown_rwsem); + snd_usb_autosuspend(chip); + + if (ret < 0) { + error: + snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", +- request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type); ++ request, validx, idx, cval->val_type); + return ret; + } + +@@ -417,7 +430,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, + { + struct snd_usb_audio *chip = cval->mixer->chip; + unsigned char buf[2]; +- int val_len, err, timeout = 10; ++ int idx = 0, val_len, err, timeout = 10; + + if (cval->mixer->protocol == UAC_VERSION_1) { + val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; +@@ -440,19 +453,27 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, + err = snd_usb_autoresume(chip); + if (err < 0) + return -EIO; +- while (timeout-- > 0) ++ down_read(&chip->shutdown_rwsem); ++ while (timeout-- > 0) { ++ if (chip->shutdown) ++ break; ++ idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); + if (snd_usb_ctl_msg(chip->dev, + usb_sndctrlpipe(chip->dev, 0), request, + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, +- validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), +- buf, val_len) >= 0) { +- snd_usb_autosuspend(chip); +- return 0; ++ validx, idx, buf, val_len) >= 0) { ++ err = 0; ++ goto out; + } +- snd_usb_autosuspend(chip); ++ } + snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", +- request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]); +- return -EINVAL; ++ request, validx, idx, cval->val_type, buf[0], buf[1]); ++ err = -EINVAL; ++ ++ out: ++ up_read(&chip->shutdown_rwsem); ++ snd_usb_autosuspend(chip); ++ return err; + } + + static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value) +diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c +index 690000d..ae2b714 100644 +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -283,6 +283,11 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e + if (value > 1) + return -EINVAL; + changed = value != mixer->audigy2nx_leds[index]; ++ down_read(&mixer->chip->shutdown_rwsem); ++ if (mixer->chip->shutdown) { ++ err = -ENODEV; ++ goto out; ++ } + if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) + err = snd_usb_ctl_msg(mixer->chip->dev, + usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, +@@ -299,6 +304,8 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e + usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, + value, index + 2, NULL, 0); ++ out: ++ up_read(&mixer->chip->shutdown_rwsem); + if (err < 0) + return err; + mixer->audigy2nx_leds[index] = value; +@@ -392,11 +399,16 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry, + + for (i = 0; jacks[i].name; ++i) { + snd_iprintf(buffer, "%s: ", jacks[i].name); +- err = snd_usb_ctl_msg(mixer->chip->dev, ++ down_read(&mixer->chip->shutdown_rwsem); ++ if (mixer->chip->shutdown) ++ err = 0; ++ else ++ err = snd_usb_ctl_msg(mixer->chip->dev, + usb_rcvctrlpipe(mixer->chip->dev, 0), + UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS | + USB_RECIP_INTERFACE, 0, + jacks[i].unitid << 8, buf, 3); ++ up_read(&mixer->chip->shutdown_rwsem); + if (err == 3 && (buf[0] == 3 || buf[0] == 6)) + snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]); + else +@@ -426,10 +438,15 @@ static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol, + else + new_status = old_status & ~0x02; + changed = new_status != old_status; +- err = snd_usb_ctl_msg(mixer->chip->dev, ++ down_read(&mixer->chip->shutdown_rwsem); ++ if (mixer->chip->shutdown) ++ err = -ENODEV; ++ else ++ err = snd_usb_ctl_msg(mixer->chip->dev, + usb_sndctrlpipe(mixer->chip->dev, 0), 0x08, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, + 50, 0, &new_status, 1); ++ up_read(&mixer->chip->shutdown_rwsem); + if (err < 0) + return err; + mixer->xonar_u1_status = new_status; +@@ -468,11 +485,17 @@ static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol, + u8 bRequest = (kcontrol->private_value >> 16) & 0xff; + u16 wIndex = kcontrol->private_value & 0xffff; + u8 tmp; ++ int ret; + +- int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest, ++ down_read(&mixer->chip->shutdown_rwsem); ++ if (mixer->chip->shutdown) ++ ret = -ENODEV; ++ else ++ ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + 0, cpu_to_le16(wIndex), + &tmp, sizeof(tmp), 1000); ++ up_read(&mixer->chip->shutdown_rwsem); + + if (ret < 0) { + snd_printk(KERN_ERR +@@ -493,11 +516,17 @@ static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol, + u8 bRequest = (kcontrol->private_value >> 16) & 0xff; + u16 wIndex = kcontrol->private_value & 0xffff; + u16 wValue = ucontrol->value.integer.value[0]; ++ int ret; + +- int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest, ++ down_read(&mixer->chip->shutdown_rwsem); ++ if (mixer->chip->shutdown) ++ ret = -ENODEV; ++ else ++ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, + cpu_to_le16(wValue), cpu_to_le16(wIndex), + NULL, 0, 1000); ++ up_read(&mixer->chip->shutdown_rwsem); + + if (ret < 0) { + snd_printk(KERN_ERR +@@ -656,11 +685,16 @@ static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl, + return -EINVAL; + + +- err = snd_usb_ctl_msg(chip->dev, ++ down_read(&mixer->chip->shutdown_rwsem); ++ if (mixer->chip->shutdown) ++ err = -ENODEV; ++ else ++ err = snd_usb_ctl_msg(chip->dev, + usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR, + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), + value, val_len); ++ up_read(&mixer->chip->shutdown_rwsem); + if (err < 0) + return err; + +@@ -703,11 +737,16 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl, + + if (!pval->is_cached) { + /* Read current value */ +- err = snd_usb_ctl_msg(chip->dev, ++ down_read(&mixer->chip->shutdown_rwsem); ++ if (mixer->chip->shutdown) ++ err = -ENODEV; ++ else ++ err = snd_usb_ctl_msg(chip->dev, + usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR, + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), + value, val_len); ++ up_read(&mixer->chip->shutdown_rwsem); + if (err < 0) + return err; + +@@ -719,11 +758,16 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl, + if (cur_val != new_val) { + value[0] = new_val; + value[1] = 0; +- err = snd_usb_ctl_msg(chip->dev, ++ down_read(&mixer->chip->shutdown_rwsem); ++ if (mixer->chip->shutdown) ++ err = -ENODEV; ++ else ++ err = snd_usb_ctl_msg(chip->dev, + usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), + value, val_len); ++ up_read(&mixer->chip->shutdown_rwsem); + if (err < 0) + return err; + +diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c +index f782ce1..ee3c15c 100644 +--- a/sound/usb/pcm.c ++++ b/sound/usb/pcm.c +@@ -71,6 +71,8 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream + unsigned int hwptr_done; + + subs = (struct snd_usb_substream *)substream->runtime->private_data; ++ if (subs->stream->chip->shutdown) ++ return SNDRV_PCM_POS_XRUN; + spin_lock(&subs->lock); + hwptr_done = subs->hwptr_done; + substream->runtime->delay = snd_usb_pcm_delay(subs, +@@ -471,8 +473,14 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, + changed = subs->cur_audiofmt != fmt || + subs->period_bytes != params_period_bytes(hw_params) || + subs->cur_rate != rate; ++ ++ down_read(&subs->stream->chip->shutdown_rwsem); ++ if (subs->stream->chip->shutdown) { ++ ret = -ENODEV; ++ goto unlock; ++ } + if ((ret = set_format(subs, fmt)) < 0) +- return ret; ++ goto unlock; + + if (subs->cur_rate != rate) { + struct usb_host_interface *alts; +@@ -481,12 +489,11 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, + alts = &iface->altsetting[fmt->altset_idx]; + ret = snd_usb_init_sample_rate(subs->stream->chip, fmt->iface, alts, fmt, rate); + if (ret < 0) +- return ret; ++ goto unlock; + subs->cur_rate = rate; + } + + if (changed) { +- mutex_lock(&subs->stream->chip->shutdown_mutex); + /* format changed */ + stop_endpoints(subs, 0, 0, 0); + ret = snd_usb_endpoint_set_params(subs->data_endpoint, hw_params, fmt, +@@ -497,8 +504,6 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, + if (subs->sync_endpoint) + ret = snd_usb_endpoint_set_params(subs->sync_endpoint, + hw_params, fmt, NULL); +-unlock: +- mutex_unlock(&subs->stream->chip->shutdown_mutex); + } + + if (ret == 0) { +@@ -506,6 +511,8 @@ unlock: + subs->altset_idx = fmt->altset_idx; + } + ++unlock: ++ up_read(&subs->stream->chip->shutdown_rwsem); + return ret; + } + +@@ -521,10 +528,12 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream) + subs->cur_audiofmt = NULL; + subs->cur_rate = 0; + subs->period_bytes = 0; +- mutex_lock(&subs->stream->chip->shutdown_mutex); +- stop_endpoints(subs, 0, 1, 1); +- deactivate_endpoints(subs); +- mutex_unlock(&subs->stream->chip->shutdown_mutex); ++ down_read(&subs->stream->chip->shutdown_rwsem); ++ if (!subs->stream->chip->shutdown) { ++ stop_endpoints(subs, 0, 1, 1); ++ deactivate_endpoints(subs); ++ } ++ up_read(&subs->stream->chip->shutdown_rwsem); + return snd_pcm_lib_free_vmalloc_buffer(substream); + } + +@@ -537,14 +546,22 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) + { + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_usb_substream *subs = runtime->private_data; ++ int ret = 0; + + if (! subs->cur_audiofmt) { + snd_printk(KERN_ERR "usbaudio: no format is specified!\n"); + return -ENXIO; + } + +- if (snd_BUG_ON(!subs->data_endpoint)) +- return -EIO; ++ down_read(&subs->stream->chip->shutdown_rwsem); ++ if (subs->stream->chip->shutdown) { ++ ret = -ENODEV; ++ goto unlock; ++ } ++ if (snd_BUG_ON(!subs->data_endpoint)) { ++ ret = -EIO; ++ goto unlock; ++ } + + /* some unit conversions in runtime */ + subs->data_endpoint->maxframesize = +@@ -562,9 +579,11 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) + /* for playback, submit the URBs now; otherwise, the first hwptr_done + * updates for all URBs would happen at the same time when starting */ + if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) +- return start_endpoints(subs, 1); ++ ret = start_endpoints(subs, 1); + +- return 0; ++ unlock: ++ up_read(&subs->stream->chip->shutdown_rwsem); ++ return ret; + } + + static struct snd_pcm_hardware snd_usb_hardware = +@@ -617,7 +636,7 @@ static int hw_check_valid_format(struct snd_usb_substream *subs, + return 0; + } + /* check whether the period time is >= the data packet interval */ +- if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) { ++ if (subs->speed != USB_SPEED_FULL) { + ptime = 125 * (1 << fp->datainterval); + if (ptime > pt->max || (ptime == pt->max && pt->openmax)) { + hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max); +@@ -895,7 +914,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre + return err; + + param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME; +- if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) ++ if (subs->speed == USB_SPEED_FULL) + /* full speed devices have fixed data packet interval */ + ptmin = 1000; + if (ptmin == 1000) +diff --git a/sound/usb/proc.c b/sound/usb/proc.c +index ebc1a5b..d218f76 100644 +--- a/sound/usb/proc.c ++++ b/sound/usb/proc.c +@@ -108,7 +108,7 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s + } + snd_iprintf(buffer, "\n"); + } +- if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) ++ if (subs->speed != USB_SPEED_FULL) + snd_iprintf(buffer, " Data packet interval: %d us\n", + 125 * (1 << fp->datainterval)); + // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize); +@@ -124,7 +124,7 @@ static void proc_dump_ep_status(struct snd_usb_substream *subs, + return; + snd_iprintf(buffer, " Packet Size = %d\n", ep->curpacksize); + snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n", +- snd_usb_get_speed(subs->dev) == USB_SPEED_FULL ++ subs->speed == USB_SPEED_FULL + ? get_full_speed_hz(ep->freqm) + : get_high_speed_hz(ep->freqm), + ep->freqm >> 16, ep->freqm & 0xffff); +diff --git a/sound/usb/stream.c b/sound/usb/stream.c +index 083ed81..1de0c8c 100644 +--- a/sound/usb/stream.c ++++ b/sound/usb/stream.c +@@ -90,6 +90,7 @@ static void snd_usb_init_substream(struct snd_usb_stream *as, + subs->direction = stream; + subs->dev = as->chip->dev; + subs->txfr_quirk = as->chip->txfr_quirk; ++ subs->speed = snd_usb_get_speed(subs->dev); + + snd_usb_set_pcm_ops(as->pcm, stream); + +diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h +index b8233eb..ef42797 100644 +--- a/sound/usb/usbaudio.h ++++ b/sound/usb/usbaudio.h +@@ -37,7 +37,7 @@ struct snd_usb_audio { + struct usb_interface *pm_intf; + u32 usb_id; + struct mutex mutex; +- struct mutex shutdown_mutex; ++ struct rw_semaphore shutdown_rwsem; + unsigned int shutdown:1; + unsigned int probing:1; + unsigned int autosuspended:1; diff --git a/3.6.6/4420_grsecurity-2.9.1-3.6.6-201211122213.patch b/3.6.7/4420_grsecurity-2.9.1-3.6.7-201211181105.patch index 164e8e9..6f0229a 100644 --- a/3.6.6/4420_grsecurity-2.9.1-3.6.6-201211122213.patch +++ b/3.6.7/4420_grsecurity-2.9.1-3.6.7-201211181105.patch @@ -251,7 +251,7 @@ index ad7e2e5..199f49e 100644 pcd. [PARIDE] diff --git a/Makefile b/Makefile -index 471b83c..a290aa2 100644 +index 07f2308..7271d99 100644 --- a/Makefile +++ b/Makefile @@ -241,8 +241,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ @@ -5692,6 +5692,26 @@ index 6cf591b..b49e65a 100644 extra-y := head_$(BITS).o +diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c +index f8b6eee..87f60ee 100644 +--- a/arch/sparc/kernel/leon_kernel.c ++++ b/arch/sparc/kernel/leon_kernel.c +@@ -56,11 +56,13 @@ static inline unsigned int leon_eirq_get(int cpu) + static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc) + { + unsigned int eirq; ++ struct irq_bucket *p; + int cpu = sparc_leon3_cpuid(); + + eirq = leon_eirq_get(cpu); +- if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */ +- generic_handle_irq(irq_map[eirq]->irq); ++ p = irq_map[eirq]; ++ if ((eirq & 0x10) && p && p->irq) /* bit4 tells if IRQ happened */ ++ generic_handle_irq(p->irq); + } + + /* The extended IRQ controller has been found, this function registers it */ diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index 14006d8..8146238 100644 --- a/arch/sparc/kernel/process_32.c @@ -15787,7 +15807,7 @@ index 8f8e8ee..3617d6e 100644 /* diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S -index dcdd0ea..de0bb2d 100644 +index dcdd0ea..8f32835 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -57,6 +57,8 @@ @@ -15863,7 +15883,7 @@ index dcdd0ea..de0bb2d 100644 jmp *%rdi #endif -@@ -180,6 +188,280 @@ ENTRY(native_usergs_sysret64) +@@ -180,6 +188,273 @@ ENTRY(native_usergs_sysret64) ENDPROC(native_usergs_sysret64) #endif /* CONFIG_PARAVIRT */ @@ -15949,13 +15969,6 @@ index dcdd0ea..de0bb2d 100644 + ljmpq __KERNEL_CS,3f +3: SET_RDI_INTO_CR0 + jmp 1b -+#ifdef CONFIG_PARAVIRT -+ PV_RESTORE_REGS(CLBR_RDI); -+#endif -+ -+ popq %rdi -+ pax_force_retaddr -+ retq +ENDPROC(pax_exit_kernel) +#endif + @@ -16144,7 +16157,7 @@ index dcdd0ea..de0bb2d 100644 .macro TRACE_IRQS_IRETQ offset=ARGOFFSET #ifdef CONFIG_TRACE_IRQFLAGS -@@ -271,8 +553,8 @@ ENDPROC(native_usergs_sysret64) +@@ -271,8 +546,8 @@ ENDPROC(native_usergs_sysret64) .endm .macro UNFAKE_STACK_FRAME @@ -16155,7 +16168,7 @@ index dcdd0ea..de0bb2d 100644 .endm /* -@@ -359,7 +641,7 @@ ENDPROC(native_usergs_sysret64) +@@ -359,7 +634,7 @@ ENDPROC(native_usergs_sysret64) movq %rsp, %rsi leaq -RBP(%rsp),%rdi /* arg1 for handler */ @@ -16164,7 +16177,7 @@ index dcdd0ea..de0bb2d 100644 je 1f SWAPGS /* -@@ -394,9 +676,10 @@ ENTRY(save_rest) +@@ -394,9 +669,10 @@ ENTRY(save_rest) movq_cfi r15, R15+16 movq %r11, 8(%rsp) /* return address */ FIXUP_TOP_OF_STACK %r11, 16 @@ -16176,7 +16189,7 @@ index dcdd0ea..de0bb2d 100644 /* save complete stack frame */ .pushsection .kprobes.text, "ax" -@@ -425,9 +708,10 @@ ENTRY(save_paranoid) +@@ -425,9 +701,10 @@ ENTRY(save_paranoid) js 1f /* negative -> in kernel */ SWAPGS xorl %ebx,%ebx @@ -16189,7 +16202,7 @@ index dcdd0ea..de0bb2d 100644 .popsection /* -@@ -449,7 +733,7 @@ ENTRY(ret_from_fork) +@@ -449,7 +726,7 @@ ENTRY(ret_from_fork) RESTORE_REST @@ -16198,7 +16211,7 @@ index dcdd0ea..de0bb2d 100644 jz retint_restore_args testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET -@@ -459,7 +743,7 @@ ENTRY(ret_from_fork) +@@ -459,7 +736,7 @@ ENTRY(ret_from_fork) jmp ret_from_sys_call # go to the SYSRET fastpath CFI_ENDPROC @@ -16207,7 +16220,7 @@ index dcdd0ea..de0bb2d 100644 /* * System call entry. Up to 6 arguments in registers are supported. -@@ -495,7 +779,7 @@ END(ret_from_fork) +@@ -495,7 +772,7 @@ END(ret_from_fork) ENTRY(system_call) CFI_STARTPROC simple CFI_SIGNAL_FRAME @@ -16216,7 +16229,7 @@ index dcdd0ea..de0bb2d 100644 CFI_REGISTER rip,rcx /*CFI_REGISTER rflags,r11*/ SWAPGS_UNSAFE_STACK -@@ -508,16 +792,23 @@ GLOBAL(system_call_after_swapgs) +@@ -508,16 +785,23 @@ GLOBAL(system_call_after_swapgs) movq %rsp,PER_CPU_VAR(old_rsp) movq PER_CPU_VAR(kernel_stack),%rsp @@ -16242,7 +16255,7 @@ index dcdd0ea..de0bb2d 100644 jnz tracesys system_call_fastpath: #if __SYSCALL_MASK == ~0 -@@ -527,7 +818,7 @@ system_call_fastpath: +@@ -527,7 +811,7 @@ system_call_fastpath: cmpl $__NR_syscall_max,%eax #endif ja badsys @@ -16251,7 +16264,7 @@ index dcdd0ea..de0bb2d 100644 call *sys_call_table(,%rax,8) # XXX: rip relative movq %rax,RAX-ARGOFFSET(%rsp) /* -@@ -541,10 +832,13 @@ sysret_check: +@@ -541,10 +825,13 @@ sysret_check: LOCKDEP_SYS_EXIT DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF @@ -16266,7 +16279,7 @@ index dcdd0ea..de0bb2d 100644 /* * sysretq will re-enable interrupts: */ -@@ -596,14 +890,18 @@ badsys: +@@ -596,14 +883,18 @@ badsys: * jump back to the normal fast path. */ auditsys: @@ -16286,7 +16299,7 @@ index dcdd0ea..de0bb2d 100644 jmp system_call_fastpath /* -@@ -624,7 +922,7 @@ sysret_audit: +@@ -624,7 +915,7 @@ sysret_audit: /* Do syscall tracing */ tracesys: #ifdef CONFIG_AUDITSYSCALL @@ -16295,7 +16308,7 @@ index dcdd0ea..de0bb2d 100644 jz auditsys #endif SAVE_REST -@@ -632,12 +930,16 @@ tracesys: +@@ -632,12 +923,16 @@ tracesys: FIXUP_TOP_OF_STACK %rdi movq %rsp,%rdi call syscall_trace_enter @@ -16312,7 +16325,7 @@ index dcdd0ea..de0bb2d 100644 RESTORE_REST #if __SYSCALL_MASK == ~0 cmpq $__NR_syscall_max,%rax -@@ -646,7 +948,7 @@ tracesys: +@@ -646,7 +941,7 @@ tracesys: cmpl $__NR_syscall_max,%eax #endif ja int_ret_from_sys_call /* RAX(%rsp) set to -ENOSYS above */ @@ -16321,7 +16334,7 @@ index dcdd0ea..de0bb2d 100644 call *sys_call_table(,%rax,8) movq %rax,RAX-ARGOFFSET(%rsp) /* Use IRET because user could have changed frame */ -@@ -667,7 +969,9 @@ GLOBAL(int_with_check) +@@ -667,7 +962,9 @@ GLOBAL(int_with_check) andl %edi,%edx jnz int_careful andl $~TS_COMPAT,TI_status(%rcx) @@ -16332,7 +16345,7 @@ index dcdd0ea..de0bb2d 100644 /* Either reschedule or signal or syscall exit tracking needed. */ /* First do a reschedule test. */ -@@ -713,7 +1017,7 @@ int_restore_rest: +@@ -713,7 +1010,7 @@ int_restore_rest: TRACE_IRQS_OFF jmp int_with_check CFI_ENDPROC @@ -16341,7 +16354,7 @@ index dcdd0ea..de0bb2d 100644 /* * Certain special system calls that need to save a complete full stack frame. -@@ -729,7 +1033,7 @@ ENTRY(\label) +@@ -729,7 +1026,7 @@ ENTRY(\label) call \func jmp ptregscall_common CFI_ENDPROC @@ -16350,7 +16363,7 @@ index dcdd0ea..de0bb2d 100644 .endm PTREGSCALL stub_clone, sys_clone, %r8 -@@ -747,9 +1051,10 @@ ENTRY(ptregscall_common) +@@ -747,9 +1044,10 @@ ENTRY(ptregscall_common) movq_cfi_restore R12+8, r12 movq_cfi_restore RBP+8, rbp movq_cfi_restore RBX+8, rbx @@ -16362,7 +16375,7 @@ index dcdd0ea..de0bb2d 100644 ENTRY(stub_execve) CFI_STARTPROC -@@ -764,7 +1069,7 @@ ENTRY(stub_execve) +@@ -764,7 +1062,7 @@ ENTRY(stub_execve) RESTORE_REST jmp int_ret_from_sys_call CFI_ENDPROC @@ -16371,7 +16384,7 @@ index dcdd0ea..de0bb2d 100644 /* * sigreturn is special because it needs to restore all registers on return. -@@ -782,7 +1087,7 @@ ENTRY(stub_rt_sigreturn) +@@ -782,7 +1080,7 @@ ENTRY(stub_rt_sigreturn) RESTORE_REST jmp int_ret_from_sys_call CFI_ENDPROC @@ -16380,7 +16393,7 @@ index dcdd0ea..de0bb2d 100644 #ifdef CONFIG_X86_X32_ABI PTREGSCALL stub_x32_sigaltstack, sys32_sigaltstack, %rdx -@@ -851,7 +1156,7 @@ vector=vector+1 +@@ -851,7 +1149,7 @@ vector=vector+1 2: jmp common_interrupt .endr CFI_ENDPROC @@ -16389,7 +16402,7 @@ index dcdd0ea..de0bb2d 100644 .previous END(interrupt) -@@ -871,6 +1176,16 @@ END(interrupt) +@@ -871,6 +1169,16 @@ END(interrupt) subq $ORIG_RAX-RBP, %rsp CFI_ADJUST_CFA_OFFSET ORIG_RAX-RBP SAVE_ARGS_IRQ @@ -16406,7 +16419,7 @@ index dcdd0ea..de0bb2d 100644 call \func .endm -@@ -902,7 +1217,7 @@ ret_from_intr: +@@ -902,7 +1210,7 @@ ret_from_intr: exit_intr: GET_THREAD_INFO(%rcx) @@ -16415,7 +16428,7 @@ index dcdd0ea..de0bb2d 100644 je retint_kernel /* Interrupt came from user space */ -@@ -924,12 +1239,16 @@ retint_swapgs: /* return to user-space */ +@@ -924,12 +1232,16 @@ retint_swapgs: /* return to user-space */ * The iretq could re-enable interrupts: */ DISABLE_INTERRUPTS(CLBR_ANY) @@ -16432,7 +16445,7 @@ index dcdd0ea..de0bb2d 100644 /* * The iretq could re-enable interrupts: */ -@@ -1012,7 +1331,7 @@ ENTRY(retint_kernel) +@@ -1012,7 +1324,7 @@ ENTRY(retint_kernel) #endif CFI_ENDPROC @@ -16441,7 +16454,7 @@ index dcdd0ea..de0bb2d 100644 /* * End of kprobes section */ -@@ -1029,7 +1348,7 @@ ENTRY(\sym) +@@ -1029,7 +1341,7 @@ ENTRY(\sym) interrupt \do_sym jmp ret_from_intr CFI_ENDPROC @@ -16450,7 +16463,7 @@ index dcdd0ea..de0bb2d 100644 .endm #ifdef CONFIG_SMP -@@ -1084,12 +1403,22 @@ ENTRY(\sym) +@@ -1084,12 +1396,22 @@ ENTRY(\sym) CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 call error_entry DEFAULT_FRAME 0 @@ -16474,7 +16487,7 @@ index dcdd0ea..de0bb2d 100644 .endm .macro paranoidzeroentry sym do_sym -@@ -1101,15 +1430,25 @@ ENTRY(\sym) +@@ -1101,15 +1423,25 @@ ENTRY(\sym) CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 call save_paranoid TRACE_IRQS_OFF @@ -16502,7 +16515,7 @@ index dcdd0ea..de0bb2d 100644 .macro paranoidzeroentry_ist sym do_sym ist ENTRY(\sym) INTR_FRAME -@@ -1119,14 +1458,30 @@ ENTRY(\sym) +@@ -1119,14 +1451,30 @@ ENTRY(\sym) CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 call save_paranoid TRACE_IRQS_OFF_DEBUG @@ -16534,7 +16547,7 @@ index dcdd0ea..de0bb2d 100644 .endm .macro errorentry sym do_sym -@@ -1137,13 +1492,23 @@ ENTRY(\sym) +@@ -1137,13 +1485,23 @@ ENTRY(\sym) CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 call error_entry DEFAULT_FRAME 0 @@ -16559,7 +16572,7 @@ index dcdd0ea..de0bb2d 100644 .endm /* error code is on the stack already */ -@@ -1156,13 +1521,23 @@ ENTRY(\sym) +@@ -1156,13 +1514,23 @@ ENTRY(\sym) call save_paranoid DEFAULT_FRAME 0 TRACE_IRQS_OFF @@ -16584,7 +16597,7 @@ index dcdd0ea..de0bb2d 100644 .endm zeroentry divide_error do_divide_error -@@ -1192,9 +1567,10 @@ gs_change: +@@ -1192,9 +1560,10 @@ gs_change: 2: mfence /* workaround */ SWAPGS popfq_cfi @@ -16596,7 +16609,7 @@ index dcdd0ea..de0bb2d 100644 _ASM_EXTABLE(gs_change,bad_gs) .section .fixup,"ax" -@@ -1213,13 +1589,14 @@ ENTRY(kernel_thread_helper) +@@ -1213,13 +1582,14 @@ ENTRY(kernel_thread_helper) * Here we are in the child and the registers are set as they were * at kernel_thread() invocation in the parent. */ @@ -16612,7 +16625,7 @@ index dcdd0ea..de0bb2d 100644 /* * execve(). This function needs to use IRET, not SYSRET, to set up all state properly. -@@ -1246,11 +1623,11 @@ ENTRY(kernel_execve) +@@ -1246,11 +1616,11 @@ ENTRY(kernel_execve) RESTORE_REST testq %rax,%rax je int_ret_from_sys_call @@ -16626,7 +16639,7 @@ index dcdd0ea..de0bb2d 100644 /* Call softirq on interrupt stack. Interrupts are off. */ ENTRY(call_softirq) -@@ -1268,9 +1645,10 @@ ENTRY(call_softirq) +@@ -1268,9 +1638,10 @@ ENTRY(call_softirq) CFI_DEF_CFA_REGISTER rsp CFI_ADJUST_CFA_OFFSET -8 decl PER_CPU_VAR(irq_count) @@ -16638,7 +16651,7 @@ index dcdd0ea..de0bb2d 100644 #ifdef CONFIG_XEN zeroentry xen_hypervisor_callback xen_do_hypervisor_callback -@@ -1308,7 +1686,7 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) +@@ -1308,7 +1679,7 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) decl PER_CPU_VAR(irq_count) jmp error_exit CFI_ENDPROC @@ -16647,7 +16660,7 @@ index dcdd0ea..de0bb2d 100644 /* * Hypervisor uses this for application faults while it executes. -@@ -1367,7 +1745,7 @@ ENTRY(xen_failsafe_callback) +@@ -1367,7 +1738,7 @@ ENTRY(xen_failsafe_callback) SAVE_ALL jmp error_exit CFI_ENDPROC @@ -16656,7 +16669,7 @@ index dcdd0ea..de0bb2d 100644 apicinterrupt XEN_HVM_EVTCHN_CALLBACK \ xen_hvm_callback_vector xen_evtchn_do_upcall -@@ -1416,16 +1794,31 @@ ENTRY(paranoid_exit) +@@ -1416,16 +1787,31 @@ ENTRY(paranoid_exit) TRACE_IRQS_OFF_DEBUG testl %ebx,%ebx /* swapgs needed? */ jnz paranoid_restore @@ -16689,7 +16702,7 @@ index dcdd0ea..de0bb2d 100644 jmp irq_return paranoid_userspace: GET_THREAD_INFO(%rcx) -@@ -1454,7 +1847,7 @@ paranoid_schedule: +@@ -1454,7 +1840,7 @@ paranoid_schedule: TRACE_IRQS_OFF jmp paranoid_userspace CFI_ENDPROC @@ -16698,7 +16711,7 @@ index dcdd0ea..de0bb2d 100644 /* * Exception entry point. This expects an error code/orig_rax on the stack. -@@ -1481,12 +1874,13 @@ ENTRY(error_entry) +@@ -1481,12 +1867,13 @@ ENTRY(error_entry) movq_cfi r14, R14+8 movq_cfi r15, R15+8 xorl %ebx,%ebx @@ -16713,7 +16726,7 @@ index dcdd0ea..de0bb2d 100644 ret /* -@@ -1513,7 +1907,7 @@ bstep_iret: +@@ -1513,7 +1900,7 @@ bstep_iret: movq %rcx,RIP+8(%rsp) jmp error_swapgs CFI_ENDPROC @@ -16722,7 +16735,7 @@ index dcdd0ea..de0bb2d 100644 /* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */ -@@ -1533,7 +1927,7 @@ ENTRY(error_exit) +@@ -1533,7 +1920,7 @@ ENTRY(error_exit) jnz retint_careful jmp retint_swapgs CFI_ENDPROC @@ -16731,7 +16744,7 @@ index dcdd0ea..de0bb2d 100644 /* * Test if a given stack is an NMI stack or not. -@@ -1591,9 +1985,11 @@ ENTRY(nmi) +@@ -1591,9 +1978,11 @@ ENTRY(nmi) * If %cs was not the kernel segment, then the NMI triggered in user * space, which means it is definitely not nested. */ @@ -16744,7 +16757,7 @@ index dcdd0ea..de0bb2d 100644 /* * Check the special variable on the stack to see if NMIs are * executing. -@@ -1752,6 +2148,17 @@ end_repeat_nmi: +@@ -1752,6 +2141,17 @@ end_repeat_nmi: */ movq %cr2, %r12 @@ -16762,7 +16775,7 @@ index dcdd0ea..de0bb2d 100644 /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */ movq %rsp,%rdi movq $-1,%rsi -@@ -1767,21 +2174,32 @@ end_repeat_nmi: +@@ -1767,21 +2167,32 @@ end_repeat_nmi: testl %ebx,%ebx /* swapgs needed? */ jnz nmi_restore nmi_swapgs: @@ -20427,6 +20440,20 @@ index 0595f13..b544fa3 100644 return 0; out: +diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h +index a10e460..58fc514 100644 +--- a/arch/x86/kvm/cpuid.h ++++ b/arch/x86/kvm/cpuid.h +@@ -24,6 +24,9 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu) + { + struct kvm_cpuid_entry2 *best; + ++ if (!static_cpu_has(X86_FEATURE_XSAVE)) ++ return 0; ++ + best = kvm_find_cpuid_entry(vcpu, 1, 0); + return best && (best->ecx & bit(X86_FEATURE_XSAVE)); + } diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index a3b57a2..ebbe732 100644 --- a/arch/x86/kvm/emulate.c @@ -20626,7 +20653,7 @@ index b1eb202..254e292 100644 vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c -index 2966c84..207d0cb 100644 +index 2966c84..9ac0c3c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1379,8 +1379,8 @@ static int xen_hvm_config(struct kvm_vcpu *vcpu, u64 data) @@ -20667,6 +20694,16 @@ index 2966c84..207d0cb 100644 { int r; struct kvm_x86_ops *ops = (struct kvm_x86_ops *)opaque; +@@ -5762,6 +5764,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, + int pending_vec, max_bits, idx; + struct desc_ptr dt; + ++ if (!guest_cpuid_has_xsave(vcpu) && (sregs->cr4 & X86_CR4_OSXSAVE)) ++ return -EINVAL; ++ + dt.size = sregs->idt.limit; + dt.address = sregs->idt.base; + kvm_x86_ops->set_idt(vcpu, &dt); diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 642d880..cc9ebac 100644 --- a/arch/x86/lguest/boot.c @@ -27411,10 +27448,10 @@ index c1461de..355f120 100644 #ifdef CONFIG_ACPI_NUMA diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c -index 5141d80..6c9fb41 100644 +index dde1a3f..6b663e6 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c -@@ -1765,6 +1765,9 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, +@@ -1784,6 +1784,9 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, convert_pfn_mfn(init_level4_pgt); convert_pfn_mfn(level3_ident_pgt); convert_pfn_mfn(level3_kernel_pgt); @@ -27424,7 +27461,7 @@ index 5141d80..6c9fb41 100644 l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd); l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud); -@@ -1783,7 +1786,11 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, +@@ -1802,7 +1805,11 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, set_page_prot(init_level4_pgt, PAGE_KERNEL_RO); set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO); set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO); @@ -27436,7 +27473,7 @@ index 5141d80..6c9fb41 100644 set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO); set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO); -@@ -1967,6 +1974,7 @@ static void __init xen_post_allocator_init(void) +@@ -1986,6 +1993,7 @@ static void __init xen_post_allocator_init(void) pv_mmu_ops.set_pud = xen_set_pud; #if PAGETABLE_LEVELS == 4 pv_mmu_ops.set_pgd = xen_set_pgd; @@ -27444,7 +27481,7 @@ index 5141d80..6c9fb41 100644 #endif /* This will work as long as patching hasn't happened yet -@@ -2048,6 +2056,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = { +@@ -2067,6 +2075,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = { .pud_val = PV_CALLEE_SAVE(xen_pud_val), .make_pud = PV_CALLEE_SAVE(xen_make_pud), .set_pgd = xen_set_pgd_hyper, @@ -27785,7 +27822,7 @@ index 9a87daa..fb17486 100644 goto error; diff --git a/crypto/cryptd.c b/crypto/cryptd.c -index 671d4d6..5f24030 100644 +index 671d4d6..afec999 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c @@ -63,7 +63,7 @@ struct cryptd_blkcipher_ctx { @@ -27806,6 +27843,28 @@ index 671d4d6..5f24030 100644 static void cryptd_queue_worker(struct work_struct *work); +@@ -137,13 +137,18 @@ static void cryptd_queue_worker(struct work_struct *work) + struct crypto_async_request *req, *backlog; + + cpu_queue = container_of(work, struct cryptd_cpu_queue, work); +- /* Only handle one request at a time to avoid hogging crypto +- * workqueue. preempt_disable/enable is used to prevent +- * being preempted by cryptd_enqueue_request() */ ++ /* ++ * Only handle one request at a time to avoid hogging crypto workqueue. ++ * preempt_disable/enable is used to prevent being preempted by ++ * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent ++ * cryptd_enqueue_request() being accessed from software interrupts. ++ */ ++ local_bh_disable(); + preempt_disable(); + backlog = crypto_get_backlog(&cpu_queue->queue); + req = crypto_dequeue_request(&cpu_queue->queue); + preempt_enable(); ++ local_bh_enable(); + + if (!req) + return; diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c index e6defd8..c26a225 100644 --- a/drivers/acpi/apei/cper.c @@ -30368,7 +30427,7 @@ index 9238de4..a27c72a 100644 DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c -index 5062eec..4e3e51f 100644 +index 7aff5c7..bee6c27 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -71,7 +71,7 @@ static int drm_setup(struct drm_device * dev) @@ -30380,18 +30439,34 @@ index 5062eec..4e3e51f 100644 dev->sigdata.lock = NULL; -@@ -134,8 +134,8 @@ int drm_open(struct inode *inode, struct file *filp) +@@ -134,7 +134,7 @@ int drm_open(struct inode *inode, struct file *filp) + if (drm_device_is_unplugged(dev)) + return -ENODEV; +- if (!dev->open_count++) ++ if (local_inc_return(&dev->open_count) == 1) + need_setup = 1; + mutex_lock(&dev->struct_mutex); + old_mapping = dev->dev_mapping; +@@ -149,7 +149,7 @@ int drm_open(struct inode *inode, struct file *filp) retcode = drm_open_helper(inode, filp, dev); - if (!retcode) { -- atomic_inc(&dev->counts[_DRM_STAT_OPENS]); -- if (!dev->open_count++) -+ atomic_inc_unchecked(&dev->counts[_DRM_STAT_OPENS]); -+ if (local_inc_return(&dev->open_count) == 1) - retcode = drm_setup(dev); - } - if (!retcode) { -@@ -422,7 +422,7 @@ int drm_release(struct inode *inode, struct file *filp) + if (retcode) + goto err_undo; +- atomic_inc(&dev->counts[_DRM_STAT_OPENS]); ++ atomic_inc_unchecked(&dev->counts[_DRM_STAT_OPENS]); + if (need_setup) { + retcode = drm_setup(dev); + if (retcode) +@@ -164,7 +164,7 @@ err_undo: + iput(container_of(dev->dev_mapping, struct inode, i_data)); + dev->dev_mapping = old_mapping; + mutex_unlock(&dev->struct_mutex); +- dev->open_count--; ++ local_dec(&dev->open_count); + return retcode; + } + EXPORT_SYMBOL(drm_open); +@@ -438,7 +438,7 @@ int drm_release(struct inode *inode, struct file *filp) mutex_lock(&drm_global_mutex); @@ -30400,7 +30475,7 @@ index 5062eec..4e3e51f 100644 if (dev->driver->preclose) dev->driver->preclose(dev, file_priv); -@@ -431,10 +431,10 @@ int drm_release(struct inode *inode, struct file *filp) +@@ -447,10 +447,10 @@ int drm_release(struct inode *inode, struct file *filp) * Begin inline drm_release */ @@ -30413,7 +30488,7 @@ index 5062eec..4e3e51f 100644 /* Release any auth tokens that might point to this file_priv, (do that under the drm_global_mutex) */ -@@ -530,8 +530,8 @@ int drm_release(struct inode *inode, struct file *filp) +@@ -546,8 +546,8 @@ int drm_release(struct inode *inode, struct file *filp) * End inline drm_release */ @@ -30654,7 +30729,7 @@ index 359f6e8..ada68fd 100644 if (IS_GEN6(dev) || IS_GEN7(dev)) { seq_printf(m, "Graphics Interrupt mask (%s): %08x\n", diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c -index 914c0df..d47d380 100644 +index 0969a7c..b9ffa45 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1269,7 +1269,7 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev) @@ -35325,18 +35400,6 @@ index 4a518a3..936b334 100644 #define VXGE_HW_VIRTUAL_PATH_HANDLE(vpath) \ ((struct __vxge_hw_vpath_handle *)(vpath)->vpath_handles.next) -diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c -index 53743f7..af8b414 100644 ---- a/drivers/net/ethernet/nxp/lpc_eth.c -+++ b/drivers/net/ethernet/nxp/lpc_eth.c -@@ -1524,6 +1524,7 @@ static int lpc_eth_drv_remove(struct platform_device *pdev) - pldat->dma_buff_base_p); - free_irq(ndev->irq, ndev); - iounmap(pldat->net_base); -+ mdiobus_unregister(pldat->mii_bus); - mdiobus_free(pldat->mii_bus); - clk_disable(pldat->clk); - clk_put(pldat->clk); diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index b47d5b3..273a516 100644 --- a/drivers/net/ethernet/realtek/r8169.c @@ -37943,40 +38006,6 @@ index 0d4aa82..f7832d4 100644 extern void tmem_register_hostops(struct tmem_hostops *m); /* core tmem accessor functions */ -diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c -index 9fc9a60..68d4c10 100644 ---- a/drivers/target/target_core_device.c -+++ b/drivers/target/target_core_device.c -@@ -850,20 +850,20 @@ int se_dev_check_shutdown(struct se_device *dev) - - static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) - { -- u32 tmp, aligned_max_sectors; -+ u32 aligned_max_sectors; -+ u32 alignment; - /* - * Limit max_sectors to a PAGE_SIZE aligned value for modern - * transport_allocate_data_tasks() operation. - */ -- tmp = rounddown((max_sectors * block_size), PAGE_SIZE); -- aligned_max_sectors = (tmp / block_size); -- if (max_sectors != aligned_max_sectors) { -- printk(KERN_INFO "Rounding down aligned max_sectors from %u" -- " to %u\n", max_sectors, aligned_max_sectors); -- return aligned_max_sectors; -- } -+ alignment = max(1ul, PAGE_SIZE / block_size); -+ aligned_max_sectors = rounddown(max_sectors, alignment); - -- return max_sectors; -+ if (max_sectors != aligned_max_sectors) -+ pr_info("Rounding down aligned max_sectors from %u to %u\n", -+ max_sectors, aligned_max_sectors); -+ -+ return aligned_max_sectors; - } - - void se_dev_set_default_attribs( diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 7502660..f214d9f 100644 --- a/drivers/target/target_core_transport.c @@ -42708,6 +42737,22 @@ index 88714ae..16c2e11 100644 static inline u32 get_pll_internal_frequency(u32 ref_freq, +diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c +index c3b3f7f..abd47c7 100644 +--- a/drivers/virtio/virtio.c ++++ b/drivers/virtio/virtio.c +@@ -225,8 +225,10 @@ EXPORT_SYMBOL_GPL(register_virtio_device); + + void unregister_virtio_device(struct virtio_device *dev) + { ++ int index = dev->index; /* save for after device release */ ++ + device_unregister(&dev->dev); +- ida_simple_remove(&virtio_index_ida, dev->index); ++ ida_simple_remove(&virtio_index_ida, index); + } + EXPORT_SYMBOL_GPL(unregister_virtio_device); + diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index 453db0c..604973e 100644 --- a/drivers/virtio/virtio_mmio.c @@ -42989,7 +43034,7 @@ index d146e18..12d1bd1 100644 fd_offset + ex.a_text); if (error != N_DATADDR(ex)) { diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c -index 0225fdd..08bda99 100644 +index 0225fdd..0c0d35d 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -32,6 +32,7 @@ @@ -43135,7 +43180,7 @@ index 0225fdd..08bda99 100644 error = -ENOMEM; goto out_close; } -@@ -523,6 +544,311 @@ out: +@@ -523,6 +544,315 @@ out: return error; } @@ -43369,7 +43414,7 @@ index 0225fdd..08bda99 100644 + unsigned long pax_flags_hardmode = 0UL, pax_flags_softmode = 0UL; + + xattr_size = vfs_getxattr(file->f_path.dentry, XATTR_NAME_PAX_FLAGS, xattr_value, sizeof xattr_value); -+ if (xattr_size <= 0) ++ if (xattr_size <= 0 || xattr_size > 5) + return ~0UL; + + for (i = 0; i < xattr_size; i++) @@ -43379,9 +43424,13 @@ index 0225fdd..08bda99 100644 + +#define parse_flag(option1, option2, flag) \ + case option1: \ ++ if (pax_flags_hardmode & MF_PAX_##flag) \ ++ return ~0UL; \ + pax_flags_hardmode |= MF_PAX_##flag; \ + break; \ + case option2: \ ++ if (pax_flags_softmode & MF_PAX_##flag) \ ++ return ~0UL; \ + pax_flags_softmode |= MF_PAX_##flag; \ + break; + @@ -43447,7 +43496,7 @@ index 0225fdd..08bda99 100644 /* * These are the functions used to load ELF style executables and shared * libraries. There is no binary dependent code anywhere else. -@@ -539,6 +865,11 @@ static unsigned long randomize_stack_top(unsigned long stack_top) +@@ -539,6 +869,11 @@ static unsigned long randomize_stack_top(unsigned long stack_top) { unsigned int random_variable = 0; @@ -43459,7 +43508,7 @@ index 0225fdd..08bda99 100644 if ((current->flags & PF_RANDOMIZE) && !(current->personality & ADDR_NO_RANDOMIZE)) { random_variable = get_random_int() & STACK_RND_MASK; -@@ -557,7 +888,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +@@ -557,7 +892,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) unsigned long load_addr = 0, load_bias = 0; int load_addr_set = 0; char * elf_interpreter = NULL; @@ -43468,7 +43517,7 @@ index 0225fdd..08bda99 100644 struct elf_phdr *elf_ppnt, *elf_phdata; unsigned long elf_bss, elf_brk; int retval, i; -@@ -567,11 +898,11 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +@@ -567,11 +902,11 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) unsigned long start_code, end_code, start_data, end_data; unsigned long reloc_func_desc __maybe_unused = 0; int executable_stack = EXSTACK_DEFAULT; @@ -43481,7 +43530,7 @@ index 0225fdd..08bda99 100644 loc = kmalloc(sizeof(*loc), GFP_KERNEL); if (!loc) { -@@ -707,11 +1038,81 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +@@ -707,11 +1042,81 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) goto out_free_dentry; /* OK, This is the point of no return */ @@ -43564,7 +43613,7 @@ index 0225fdd..08bda99 100644 if (elf_read_implies_exec(loc->elf_ex, executable_stack)) current->personality |= READ_IMPLIES_EXEC; -@@ -802,6 +1203,20 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +@@ -802,6 +1207,20 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) #else load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); #endif @@ -43585,7 +43634,7 @@ index 0225fdd..08bda99 100644 } error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, -@@ -834,9 +1249,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +@@ -834,9 +1253,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) * allowed task size. Note that p_filesz must always be * <= p_memsz so it is only necessary to check p_memsz. */ @@ -43598,7 +43647,7 @@ index 0225fdd..08bda99 100644 /* set_brk can never work. Avoid overflows. */ send_sig(SIGKILL, current, 0); retval = -EINVAL; -@@ -875,17 +1290,44 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) +@@ -875,17 +1294,44 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) goto out_free_dentry; } if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) { @@ -43649,7 +43698,7 @@ index 0225fdd..08bda99 100644 load_bias); if (!IS_ERR((void *)elf_entry)) { /* -@@ -1107,7 +1549,7 @@ static bool always_dump_vma(struct vm_area_struct *vma) +@@ -1107,7 +1553,7 @@ static bool always_dump_vma(struct vm_area_struct *vma) * Decide what to dump of a segment, part, all or none. */ static unsigned long vma_dump_size(struct vm_area_struct *vma, @@ -43658,7 +43707,7 @@ index 0225fdd..08bda99 100644 { #define FILTER(type) (mm_flags & (1UL << MMF_DUMP_##type)) -@@ -1144,7 +1586,7 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma, +@@ -1144,7 +1590,7 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma, if (vma->vm_file == NULL) return 0; @@ -43667,7 +43716,7 @@ index 0225fdd..08bda99 100644 goto whole; /* -@@ -1366,9 +1808,9 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm) +@@ -1366,9 +1812,9 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm) { elf_addr_t *auxv = (elf_addr_t *) mm->saved_auxv; int i = 0; @@ -43679,7 +43728,7 @@ index 0225fdd..08bda99 100644 fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv); } -@@ -1879,14 +2321,14 @@ static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum, +@@ -1879,14 +2325,14 @@ static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum, } static size_t elf_core_vma_data_size(struct vm_area_struct *gate_vma, @@ -43696,7 +43745,7 @@ index 0225fdd..08bda99 100644 return size; } -@@ -1980,7 +2422,7 @@ static int elf_core_dump(struct coredump_params *cprm) +@@ -1980,7 +2426,7 @@ static int elf_core_dump(struct coredump_params *cprm) dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); @@ -43705,7 +43754,7 @@ index 0225fdd..08bda99 100644 offset += elf_core_extra_data_size(); e_shoff = offset; -@@ -1994,10 +2436,12 @@ static int elf_core_dump(struct coredump_params *cprm) +@@ -1994,10 +2440,12 @@ static int elf_core_dump(struct coredump_params *cprm) offset = dataoff; size += sizeof(*elf); @@ -43718,7 +43767,7 @@ index 0225fdd..08bda99 100644 if (size > cprm->limit || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note))) goto end_coredump; -@@ -2011,7 +2455,7 @@ static int elf_core_dump(struct coredump_params *cprm) +@@ -2011,7 +2459,7 @@ static int elf_core_dump(struct coredump_params *cprm) phdr.p_offset = offset; phdr.p_vaddr = vma->vm_start; phdr.p_paddr = 0; @@ -43727,7 +43776,7 @@ index 0225fdd..08bda99 100644 phdr.p_memsz = vma->vm_end - vma->vm_start; offset += phdr.p_filesz; phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; -@@ -2022,6 +2466,7 @@ static int elf_core_dump(struct coredump_params *cprm) +@@ -2022,6 +2470,7 @@ static int elf_core_dump(struct coredump_params *cprm) phdr.p_align = ELF_EXEC_PAGESIZE; size += sizeof(phdr); @@ -43735,7 +43784,7 @@ index 0225fdd..08bda99 100644 if (size > cprm->limit || !dump_write(cprm->file, &phdr, sizeof(phdr))) goto end_coredump; -@@ -2046,7 +2491,7 @@ static int elf_core_dump(struct coredump_params *cprm) +@@ -2046,7 +2495,7 @@ static int elf_core_dump(struct coredump_params *cprm) unsigned long addr; unsigned long end; @@ -43744,7 +43793,7 @@ index 0225fdd..08bda99 100644 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) { struct page *page; -@@ -2055,6 +2500,7 @@ static int elf_core_dump(struct coredump_params *cprm) +@@ -2055,6 +2504,7 @@ static int elf_core_dump(struct coredump_params *cprm) page = get_dump_page(addr); if (page) { void *kaddr = kmap(page); @@ -43752,7 +43801,7 @@ index 0225fdd..08bda99 100644 stop = ((size += PAGE_SIZE) > cprm->limit) || !dump_write(cprm->file, kaddr, PAGE_SIZE); -@@ -2072,6 +2518,7 @@ static int elf_core_dump(struct coredump_params *cprm) +@@ -2072,6 +2522,7 @@ static int elf_core_dump(struct coredump_params *cprm) if (e_phnum == PN_XNUM) { size += sizeof(*shdr4extnum); @@ -43760,7 +43809,7 @@ index 0225fdd..08bda99 100644 if (size > cprm->limit || !dump_write(cprm->file, shdr4extnum, sizeof(*shdr4extnum))) -@@ -2092,6 +2539,97 @@ out: +@@ -2092,6 +2543,97 @@ out: #endif /* CONFIG_ELF_CORE */ @@ -47589,6 +47638,54 @@ index 753af3d..f7b021a 100644 if (!IS_ERR(s)) kfree(s); } +diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c +index a3bde91..2524579 100644 +--- a/fs/gfs2/quota.c ++++ b/fs/gfs2/quota.c +@@ -497,8 +497,11 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) + struct gfs2_quota_data **qd; + int error; + +- if (ip->i_res == NULL) +- gfs2_rs_alloc(ip); ++ if (ip->i_res == NULL) { ++ error = gfs2_rs_alloc(ip); ++ if (error) ++ return error; ++ } + + qd = ip->i_res->rs_qa_qd; + +diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c +index c9ed814..4a45d5f 100644 +--- a/fs/gfs2/rgrp.c ++++ b/fs/gfs2/rgrp.c +@@ -477,7 +477,6 @@ void gfs2_free_clones(struct gfs2_rgrpd *rgd) + */ + int gfs2_rs_alloc(struct gfs2_inode *ip) + { +- int error = 0; + struct gfs2_blkreserv *res; + + if (ip->i_res) +@@ -485,7 +484,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip) + + res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS); + if (!res) +- error = -ENOMEM; ++ return -ENOMEM; + + down_write(&ip->i_rw_mutex); + if (ip->i_res) +@@ -493,7 +492,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip) + else + ip->i_res = res; + up_write(&ip->i_rw_mutex); +- return error; ++ return 0; + } + + static void dump_rs(struct seq_file *seq, struct gfs2_blkreserv *rs) diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 8349a89..51a0254 100644 --- a/fs/hugetlbfs/inode.c @@ -48448,6 +48545,18 @@ index a9269f1..5490437 100644 set_fs(oldfs); if (host_err < 0) +diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c +index f35794b..a506360 100644 +--- a/fs/notify/fanotify/fanotify.c ++++ b/fs/notify/fanotify/fanotify.c +@@ -21,6 +21,7 @@ static bool should_merge(struct fsnotify_event *old, struct fsnotify_event *new) + if ((old->path.mnt == new->path.mnt) && + (old->path.dentry == new->path.dentry)) + return true; ++ break; + case (FSNOTIFY_EVENT_NONE): + return true; + default: diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index d438036..0ecadde 100644 --- a/fs/notify/fanotify/fanotify_user.c @@ -50078,6 +50187,25 @@ index 1ccfa53..0848f95 100644 } else if (mm) { pid_t tid = vm_is_stack(priv->task, vma, is_pid); +diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c +index 29996e8..2d1e0f3 100644 +--- a/fs/pstore/platform.c ++++ b/fs/pstore/platform.c +@@ -161,12 +161,13 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c) + + while (s < e) { + unsigned long flags; ++ u64 id; + + if (c > psinfo->bufsize) + c = psinfo->bufsize; + spin_lock_irqsave(&psinfo->buf_lock, flags); + memcpy(psinfo->buf, s, c); +- psinfo->write(PSTORE_TYPE_CONSOLE, 0, NULL, 0, c, psinfo); ++ psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, c, psinfo); + spin_unlock_irqrestore(&psinfo->buf_lock, flags); + s += c; + c = e - s; diff --git a/fs/quota/netlink.c b/fs/quota/netlink.c index d67908b..d13f6a6 100644 --- a/fs/quota/netlink.c @@ -65250,26 +65378,6 @@ index 9e5425b..8136ffc 100644 struct list_head list; /* Protects from simultaneous access to first_req list */ spinlock_t info_list_lock; -diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h -index f10553c..fb5204b 100644 ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -2633,6 +2633,15 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); - unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc); - - /** -+ * ieee80211_get_mesh_hdrlen - get mesh extension header length -+ * @meshhdr: the mesh extension header, only the flags field -+ * (first byte) will be accessed -+ * Returns the length of the extension header, which is always at -+ * least 6 bytes and at most 18 if address 5 and 6 are present. -+ */ -+unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); -+ -+/** - * DOC: Data path helpers - * - * In addition to generic utilities, cfg80211 also offers diff --git a/include/net/flow.h b/include/net/flow.h index 628e11b..4c475df 100644 --- a/include/net/flow.h @@ -67668,7 +67776,7 @@ index 2c8857e..288c9c7 100644 else new_fs = fs; diff --git a/kernel/futex.c b/kernel/futex.c -index 3717e7b..473c750 100644 +index 20ef219..b3a0cb2 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -54,6 +54,7 @@ @@ -67691,7 +67799,7 @@ index 3717e7b..473c750 100644 /* * The futex address must be "naturally" aligned. */ -@@ -2714,6 +2720,7 @@ static int __init futex_init(void) +@@ -2717,6 +2723,7 @@ static int __init futex_init(void) { u32 curval; int i; @@ -67699,7 +67807,7 @@ index 3717e7b..473c750 100644 /* * This will fail and we want it. Some arch implementations do -@@ -2725,8 +2732,11 @@ static int __init futex_init(void) +@@ -2728,8 +2735,11 @@ static int __init futex_init(void) * implementation, the non-functional ones will return * -ENOSYS. */ @@ -68223,7 +68331,7 @@ index 91c32a0..7b88d63 100644 seq_printf(m, "%40s %14lu %29s %pS\n", name, stats->contending_point[i], diff --git a/kernel/module.c b/kernel/module.c -index 9ad9ee9..f6e05c2 100644 +index 9ad9ee9..731c128 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -58,6 +58,7 @@ @@ -68512,7 +68620,7 @@ index 9ad9ee9..f6e05c2 100644 } } -@@ -2266,7 +2284,7 @@ static void layout_symtab(struct module *mod, struct load_info *info) +@@ -2266,28 +2284,33 @@ static void layout_symtab(struct module *mod, struct load_info *info) /* Put symbol section at end of init part of module. */ symsect->sh_flags |= SHF_ALLOC; @@ -68521,8 +68629,23 @@ index 9ad9ee9..f6e05c2 100644 info->index.sym) | INIT_OFFSET_MASK; pr_debug("\t%s\n", info->secstrings + symsect->sh_name); -@@ -2281,13 +2299,13 @@ static void layout_symtab(struct module *mod, struct load_info *info) + src = (void *)info->hdr + symsect->sh_offset; + nsrc = symsect->sh_size / sizeof(*src); + ++ /* strtab always starts with a nul, so offset 0 is the empty string. */ ++ strtab_size = 1; ++ + /* Compute total space required for the core symbols' strtab. */ +- for (ndst = i = strtab_size = 1; i < nsrc; ++i, ++src) +- if (is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) { +- strtab_size += strlen(&info->strtab[src->st_name]) + 1; ++ for (ndst = i = 0; i < nsrc; i++) { ++ if (i == 0 || ++ is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { ++ strtab_size += strlen(&info->strtab[src[i].st_name])+1; + ndst++; } ++ } /* Append room for core symbols at end of core part. */ - info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1); @@ -68539,7 +68662,7 @@ index 9ad9ee9..f6e05c2 100644 info->index.str) | INIT_OFFSET_MASK; pr_debug("\t%s\n", info->secstrings + strsect->sh_name); } -@@ -2305,12 +2323,14 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) +@@ -2305,24 +2328,28 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) /* Make sure we get permanent strtab: don't use info->strtab. */ mod->strtab = (void *)info->sechdrs[info->index.str].sh_addr; @@ -68554,10 +68677,23 @@ index 9ad9ee9..f6e05c2 100644 + mod->core_symtab = dst = mod->module_core_rx + info->symoffs; + mod->core_strtab = s = mod->module_core_rx + info->stroffs; src = mod->symtab; - *dst = *src; +- *dst = *src; *s++ = 0; -@@ -2323,6 +2343,8 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) - s += strlcpy(s, &mod->strtab[src->st_name], KSYM_NAME_LEN) + 1; +- for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) { +- if (!is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) +- continue; +- +- dst[ndst] = *src; +- dst[ndst++].st_name = s - mod->core_strtab; +- s += strlcpy(s, &mod->strtab[src->st_name], KSYM_NAME_LEN) + 1; ++ for (ndst = i = 0; i < mod->num_symtab; i++) { ++ if (i == 0 || ++ is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { ++ dst[ndst] = src[i]; ++ dst[ndst++].st_name = s - mod->core_strtab; ++ s += strlcpy(s, &mod->strtab[src[i].st_name], ++ KSYM_NAME_LEN) + 1; ++ } } mod->core_num_syms = ndst; + @@ -68565,7 +68701,7 @@ index 9ad9ee9..f6e05c2 100644 } #else static inline void layout_symtab(struct module *mod, struct load_info *info) -@@ -2356,17 +2378,33 @@ void * __weak module_alloc(unsigned long size) +@@ -2356,17 +2383,33 @@ void * __weak module_alloc(unsigned long size) return size == 0 ? NULL : vmalloc_exec(size); } @@ -68604,7 +68740,7 @@ index 9ad9ee9..f6e05c2 100644 mutex_unlock(&module_mutex); } return ret; -@@ -2544,8 +2582,14 @@ static struct module *setup_load_info(struct load_info *info) +@@ -2544,8 +2587,14 @@ static struct module *setup_load_info(struct load_info *info) static int check_modinfo(struct module *mod, struct load_info *info) { const char *modmagic = get_modinfo(info, "vermagic"); @@ -68619,7 +68755,7 @@ index 9ad9ee9..f6e05c2 100644 /* This is allowed: modprobe --force will invalidate it. */ if (!modmagic) { err = try_to_force_load(mod, "bad vermagic"); -@@ -2568,7 +2612,7 @@ static int check_modinfo(struct module *mod, struct load_info *info) +@@ -2568,7 +2617,7 @@ static int check_modinfo(struct module *mod, struct load_info *info) } /* Set up license info based on the info section */ @@ -68628,7 +68764,7 @@ index 9ad9ee9..f6e05c2 100644 return 0; } -@@ -2662,7 +2706,7 @@ static int move_module(struct module *mod, struct load_info *info) +@@ -2662,7 +2711,7 @@ static int move_module(struct module *mod, struct load_info *info) void *ptr; /* Do the allocs. */ @@ -68637,7 +68773,7 @@ index 9ad9ee9..f6e05c2 100644 /* * The pointer to this block is stored in the module structure * which is inside the block. Just mark it as not being a -@@ -2672,23 +2716,50 @@ static int move_module(struct module *mod, struct load_info *info) +@@ -2672,23 +2721,50 @@ static int move_module(struct module *mod, struct load_info *info) if (!ptr) return -ENOMEM; @@ -68696,7 +68832,7 @@ index 9ad9ee9..f6e05c2 100644 /* Transfer each section which specifies SHF_ALLOC */ pr_debug("final section addresses:\n"); -@@ -2699,16 +2770,45 @@ static int move_module(struct module *mod, struct load_info *info) +@@ -2699,16 +2775,45 @@ static int move_module(struct module *mod, struct load_info *info) if (!(shdr->sh_flags & SHF_ALLOC)) continue; @@ -68749,7 +68885,7 @@ index 9ad9ee9..f6e05c2 100644 pr_debug("\t0x%lx %s\n", (long)shdr->sh_addr, info->secstrings + shdr->sh_name); } -@@ -2763,12 +2863,12 @@ static void flush_module_icache(const struct module *mod) +@@ -2763,12 +2868,12 @@ static void flush_module_icache(const struct module *mod) * Do it before processing of module parameters, so the module * can provide parameter accessor functions of its own. */ @@ -68768,7 +68904,7 @@ index 9ad9ee9..f6e05c2 100644 set_fs(old_fs); } -@@ -2838,8 +2938,10 @@ out: +@@ -2838,8 +2943,10 @@ out: static void module_deallocate(struct module *mod, struct load_info *info) { percpu_modfree(mod); @@ -68781,7 +68917,7 @@ index 9ad9ee9..f6e05c2 100644 } int __weak module_finalize(const Elf_Ehdr *hdr, -@@ -2852,7 +2954,9 @@ int __weak module_finalize(const Elf_Ehdr *hdr, +@@ -2852,7 +2959,9 @@ int __weak module_finalize(const Elf_Ehdr *hdr, static int post_relocation(struct module *mod, const struct load_info *info) { /* Sort exception table now relocations are done. */ @@ -68791,7 +68927,7 @@ index 9ad9ee9..f6e05c2 100644 /* Copy relocated percpu area over. */ percpu_modcopy(mod, (void *)info->sechdrs[info->index.pcpu].sh_addr, -@@ -2903,9 +3007,38 @@ static struct module *load_module(void __user *umod, +@@ -2903,9 +3012,38 @@ static struct module *load_module(void __user *umod, if (err) goto free_unload; @@ -68830,7 +68966,7 @@ index 9ad9ee9..f6e05c2 100644 /* Fix up syms, so that st_value is a pointer to location. */ err = simplify_symbols(mod, &info); if (err < 0) -@@ -2921,13 +3054,6 @@ static struct module *load_module(void __user *umod, +@@ -2921,13 +3059,6 @@ static struct module *load_module(void __user *umod, flush_module_icache(mod); @@ -68844,7 +68980,7 @@ index 9ad9ee9..f6e05c2 100644 /* Mark state as coming so strong_try_module_get() ignores us. */ mod->state = MODULE_STATE_COMING; -@@ -2985,11 +3111,10 @@ static struct module *load_module(void __user *umod, +@@ -2985,11 +3116,10 @@ static struct module *load_module(void __user *umod, unlock: mutex_unlock(&module_mutex); synchronize_sched(); @@ -68857,7 +68993,7 @@ index 9ad9ee9..f6e05c2 100644 free_unload: module_unload_free(mod); free_module: -@@ -3030,16 +3155,16 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, +@@ -3030,16 +3160,16 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, MODULE_STATE_COMING, mod); /* Set RO and NX regions for core */ @@ -68882,7 +69018,7 @@ index 9ad9ee9..f6e05c2 100644 do_mod_ctors(mod); /* Start the module */ -@@ -3085,11 +3210,12 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, +@@ -3085,11 +3215,12 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, mod->strtab = mod->core_strtab; #endif unset_module_init_ro_nx(mod); @@ -68900,7 +69036,7 @@ index 9ad9ee9..f6e05c2 100644 mutex_unlock(&module_mutex); return 0; -@@ -3120,10 +3246,16 @@ static const char *get_ksymbol(struct module *mod, +@@ -3120,10 +3251,16 @@ static const char *get_ksymbol(struct module *mod, unsigned long nextval; /* At worse, next value is at end of module */ @@ -68920,7 +69056,7 @@ index 9ad9ee9..f6e05c2 100644 /* Scan for closest preceding symbol, and next symbol. (ELF starts real symbols at 1). */ -@@ -3358,7 +3490,7 @@ static int m_show(struct seq_file *m, void *p) +@@ -3358,7 +3495,7 @@ static int m_show(struct seq_file *m, void *p) char buf[8]; seq_printf(m, "%s %u", @@ -68929,7 +69065,7 @@ index 9ad9ee9..f6e05c2 100644 print_unload_info(m, mod); /* Informative for users. */ -@@ -3367,7 +3499,7 @@ static int m_show(struct seq_file *m, void *p) +@@ -3367,7 +3504,7 @@ static int m_show(struct seq_file *m, void *p) mod->state == MODULE_STATE_COMING ? "Loading": "Live"); /* Used by oprofile and other similar tools. */ @@ -68938,7 +69074,7 @@ index 9ad9ee9..f6e05c2 100644 /* Taints info */ if (mod->taints) -@@ -3403,7 +3535,17 @@ static const struct file_operations proc_modules_operations = { +@@ -3403,7 +3540,17 @@ static const struct file_operations proc_modules_operations = { static int __init proc_modules_init(void) { @@ -68956,7 +69092,7 @@ index 9ad9ee9..f6e05c2 100644 return 0; } module_init(proc_modules_init); -@@ -3462,12 +3604,12 @@ struct module *__module_address(unsigned long addr) +@@ -3462,12 +3609,12 @@ struct module *__module_address(unsigned long addr) { struct module *mod; @@ -68972,7 +69108,7 @@ index 9ad9ee9..f6e05c2 100644 return mod; return NULL; } -@@ -3501,11 +3643,20 @@ bool is_module_text_address(unsigned long addr) +@@ -3501,11 +3648,20 @@ bool is_module_text_address(unsigned long addr) */ struct module *__module_text_address(unsigned long addr) { @@ -71437,6 +71573,55 @@ index bd2bea9..6b3c95e 100644 if (atomic_read(&task->signal->live) != 1) return false; +diff --git a/lib/list_debug.c b/lib/list_debug.c +index c24c2f7..bef49ee 100644 +--- a/lib/list_debug.c ++++ b/lib/list_debug.c +@@ -23,17 +23,19 @@ void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) + { +- WARN(next->prev != prev, ++ if (WARN(next->prev != prev, + "list_add corruption. next->prev should be " + "prev (%p), but was %p. (next=%p).\n", +- prev, next->prev, next); +- WARN(prev->next != next, ++ prev, next->prev, next) || ++ WARN(prev->next != next, + "list_add corruption. prev->next should be " + "next (%p), but was %p. (prev=%p).\n", +- next, prev->next, prev); +- WARN(new == prev || new == next, ++ next, prev->next, prev) || ++ WARN(new == prev || new == next, + "list_add double add: new=%p, prev=%p, next=%p.\n", +- new, prev, next); ++ new, prev, next)) ++ return; ++ + next->prev = new; + new->next = next; + new->prev = prev; +@@ -86,12 +88,14 @@ EXPORT_SYMBOL(list_del); + void __list_add_rcu(struct list_head *new, + struct list_head *prev, struct list_head *next) + { +- WARN(next->prev != prev, ++ if (WARN(next->prev != prev, + "list_add_rcu corruption. next->prev should be prev (%p), but was %p. (next=%p).\n", +- prev, next->prev, next); +- WARN(prev->next != next, ++ prev, next->prev, next) || ++ WARN(prev->next != next, + "list_add_rcu corruption. prev->next should be next (%p), but was %p. (prev=%p).\n", +- next, prev->next, prev); ++ next, prev->next, prev)) ++ return; ++ + new->next = next; + new->prev = prev; + rcu_assign_pointer(list_next_rcu(prev), new); diff --git a/lib/radix-tree.c b/lib/radix-tree.c index e796429..6e38f9f 100644 --- a/lib/radix-tree.c @@ -74702,7 +74887,7 @@ index aa95e59..b681a63 100644 struct anon_vma_chain *avc; struct anon_vma *anon_vma; diff --git a/mm/shmem.c b/mm/shmem.c -index d2eeca1..3f160be 100644 +index d2eeca1..92f3123 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -31,7 +31,7 @@ @@ -74723,7 +74908,35 @@ index d2eeca1..3f160be 100644 struct shmem_xattr { struct list_head list; /* anchored by shmem_inode_info->xattr_list */ -@@ -2594,8 +2594,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) +@@ -2207,6 +2207,11 @@ static const struct xattr_handler *shmem_xattr_handlers[] = { + static int shmem_xattr_validate(const char *name) + { + struct { const char *prefix; size_t len; } arr[] = { ++ ++#ifdef CONFIG_PAX_XATTR_PAX_FLAGS ++ { XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN}, ++#endif ++ + { XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN }, + { XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN } + }; +@@ -2260,6 +2265,15 @@ static int shmem_setxattr(struct dentry *dentry, const char *name, + if (err) + return err; + ++#ifdef CONFIG_PAX_XATTR_PAX_FLAGS ++ if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { ++ if (strcmp(name, XATTR_NAME_PAX_FLAGS)) ++ return -EOPNOTSUPP; ++ if (size > 8) ++ return -EINVAL; ++ } ++#endif ++ + if (size == 0) + value = ""; /* empty EA, do not remove */ + +@@ -2594,8 +2608,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) int err = -ENOMEM; /* Round up to L1_CACHE_BYTES to resist false sharing */ @@ -75718,7 +75931,7 @@ index 8c7265a..c96d884 100644 mm->unmap_area = arch_unmap_area; } diff --git a/mm/vmalloc.c b/mm/vmalloc.c -index 2bb90b1..ed47e53 100644 +index 2bb90b1..3795e47 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -39,8 +39,19 @@ static void vunmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end) @@ -75743,15 +75956,7 @@ index 2bb90b1..ed47e53 100644 } while (pte++, addr += PAGE_SIZE, addr != end); } -@@ -91,6 +102,7 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, - unsigned long end, pgprot_t prot, struct page **pages, int *nr) - { - pte_t *pte; -+ int ret = -ENOMEM; - - /* - * nr is a running index into the array which helps higher level -@@ -100,17 +112,30 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, +@@ -100,16 +111,29 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, pte = pte_alloc_kernel(pmd, addr); if (!pte) return -ENOMEM; @@ -75761,33 +75966,29 @@ index 2bb90b1..ed47e53 100644 struct page *page = pages[*nr]; - if (WARN_ON(!pte_none(*pte))) -- return -EBUSY; -- if (WARN_ON(!page)) -- return -ENOMEM; +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) + if (pgprot_val(prot) & _PAGE_NX) +#endif + -+ if (WARN_ON(!pte_none(*pte))) { -+ ret = -EBUSY; -+ goto out; ++ if (!pte_none(*pte)) { ++ pax_close_kernel(); ++ WARN_ON(1); + return -EBUSY; +- if (WARN_ON(!page)) + } -+ if (WARN_ON(!page)) { -+ ret = -ENOMEM; -+ goto out; ++ if (!page) { ++ pax_close_kernel(); ++ WARN_ON(1); + return -ENOMEM; + } set_pte_at(&init_mm, addr, pte, mk_pte(page, prot)); (*nr)++; } while (pte++, addr += PAGE_SIZE, addr != end); -- return 0; -+ ret = 0; -+out: + pax_close_kernel(); -+ return ret; + return 0; } - static int vmap_pmd_range(pud_t *pud, unsigned long addr, -@@ -119,7 +144,7 @@ static int vmap_pmd_range(pud_t *pud, unsigned long addr, +@@ -119,7 +143,7 @@ static int vmap_pmd_range(pud_t *pud, unsigned long addr, pmd_t *pmd; unsigned long next; @@ -75796,7 +75997,7 @@ index 2bb90b1..ed47e53 100644 if (!pmd) return -ENOMEM; do { -@@ -136,7 +161,7 @@ static int vmap_pud_range(pgd_t *pgd, unsigned long addr, +@@ -136,7 +160,7 @@ static int vmap_pud_range(pgd_t *pgd, unsigned long addr, pud_t *pud; unsigned long next; @@ -75805,7 +76006,7 @@ index 2bb90b1..ed47e53 100644 if (!pud) return -ENOMEM; do { -@@ -191,11 +216,20 @@ int is_vmalloc_or_module_addr(const void *x) +@@ -191,11 +215,20 @@ int is_vmalloc_or_module_addr(const void *x) * and fall back on vmalloc() if that fails. Others * just put it in the vmalloc space. */ @@ -75827,7 +76028,7 @@ index 2bb90b1..ed47e53 100644 return is_vmalloc_addr(x); } -@@ -216,8 +250,14 @@ struct page *vmalloc_to_page(const void *vmalloc_addr) +@@ -216,8 +249,14 @@ struct page *vmalloc_to_page(const void *vmalloc_addr) if (!pgd_none(*pgd)) { pud_t *pud = pud_offset(pgd, addr); @@ -75842,7 +76043,7 @@ index 2bb90b1..ed47e53 100644 if (!pmd_none(*pmd)) { pte_t *ptep, pte; -@@ -329,7 +369,7 @@ static void purge_vmap_area_lazy(void); +@@ -329,7 +368,7 @@ static void purge_vmap_area_lazy(void); * Allocate a region of KVA of the specified size and alignment, within the * vstart and vend. */ @@ -75851,7 +76052,7 @@ index 2bb90b1..ed47e53 100644 unsigned long align, unsigned long vstart, unsigned long vend, int node, gfp_t gfp_mask) -@@ -1328,6 +1368,16 @@ static struct vm_struct *__get_vm_area_node(unsigned long size, +@@ -1328,6 +1367,16 @@ static struct vm_struct *__get_vm_area_node(unsigned long size, struct vm_struct *area; BUG_ON(in_interrupt()); @@ -75868,7 +76069,7 @@ index 2bb90b1..ed47e53 100644 if (flags & VM_IOREMAP) { int bit = fls(size); -@@ -1568,6 +1618,11 @@ void *vmap(struct page **pages, unsigned int count, +@@ -1568,6 +1617,11 @@ void *vmap(struct page **pages, unsigned int count, if (count > totalram_pages) return NULL; @@ -75880,7 +76081,7 @@ index 2bb90b1..ed47e53 100644 area = get_vm_area_caller((count << PAGE_SHIFT), flags, __builtin_return_address(0)); if (!area) -@@ -1669,6 +1724,13 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align, +@@ -1669,6 +1723,13 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align, if (!size || (size >> PAGE_SHIFT) > totalram_pages) goto fail; @@ -75894,7 +76095,7 @@ index 2bb90b1..ed47e53 100644 area = __get_vm_area_node(size, align, VM_ALLOC | VM_UNLIST, start, end, node, gfp_mask, caller); if (!area) -@@ -1842,10 +1904,9 @@ EXPORT_SYMBOL(vzalloc_node); +@@ -1842,10 +1903,9 @@ EXPORT_SYMBOL(vzalloc_node); * For tight control over page level allocator and protection flags * use __vmalloc() instead. */ @@ -75906,7 +76107,7 @@ index 2bb90b1..ed47e53 100644 -1, __builtin_return_address(0)); } -@@ -2136,6 +2197,8 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr, +@@ -2136,6 +2196,8 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr, unsigned long uaddr = vma->vm_start; unsigned long usize = vma->vm_end - vma->vm_start; @@ -75915,7 +76116,7 @@ index 2bb90b1..ed47e53 100644 if ((PAGE_SIZE-1) & (unsigned long)addr) return -EINVAL; -@@ -2572,7 +2635,7 @@ static int s_show(struct seq_file *m, void *p) +@@ -2572,7 +2634,7 @@ static int s_show(struct seq_file *m, void *p) { struct vm_struct *v = p; @@ -75924,6 +76125,19 @@ index 2bb90b1..ed47e53 100644 v->addr, v->addr + v->size, v->size); if (v->caller) +diff --git a/mm/vmscan.c b/mm/vmscan.c +index 99b434b..a018dfc 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -2953,6 +2953,8 @@ static int kswapd(void *p) + &balanced_classzone_idx); + } + } ++ ++ current->reclaim_state = NULL; + return 0; + } + diff --git a/mm/vmstat.c b/mm/vmstat.c index df7a674..8b4a4f3 100644 --- a/mm/vmstat.c @@ -76609,7 +76823,7 @@ index 0337e2b..47914a0 100644 return err; diff --git a/net/core/dev.c b/net/core/dev.c -index 2fb9f59..d9a07df 100644 +index aed87a4..72cc526 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1138,9 +1138,13 @@ void dev_load(struct net *net, const char *name) @@ -77303,10 +77517,10 @@ index d23c657..cb69cc2 100644 static int raw_seq_show(struct seq_file *seq, void *v) diff --git a/net/ipv4/route.c b/net/ipv4/route.c -index 2a1383c..ff99572 100644 +index c017cb1..9eb15b7d 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c -@@ -2523,7 +2523,7 @@ static __net_initdata struct pernet_operations sysctl_route_ops = { +@@ -2526,7 +2526,7 @@ static __net_initdata struct pernet_operations sysctl_route_ops = { static __net_init int rt_genid_init(struct net *net) { @@ -77315,42 +77529,11 @@ index 2a1383c..ff99572 100644 get_random_bytes(&net->ipv4.dev_addr_genid, sizeof(net->ipv4.dev_addr_genid)); return 0; -diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c -index 813b43a..834857f 100644 ---- a/net/ipv4/tcp_illinois.c -+++ b/net/ipv4/tcp_illinois.c -@@ -313,11 +313,13 @@ static void tcp_illinois_info(struct sock *sk, u32 ext, - .tcpv_rttcnt = ca->cnt_rtt, - .tcpv_minrtt = ca->base_rtt, - }; -- u64 t = ca->sum_rtt; - -- do_div(t, ca->cnt_rtt); -- info.tcpv_rtt = t; -+ if (info.tcpv_rttcnt > 0) { -+ u64 t = ca->sum_rtt; - -+ do_div(t, info.tcpv_rttcnt); -+ info.tcpv_rtt = t; -+ } - nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info); - } - } diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c -index d377f48..f19e3ec 100644 +index c92c4da..f19e3ec 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c -@@ -4556,6 +4556,9 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) - struct tcphdr *th; - bool fragstolen; - -+ if (size == 0) -+ return 0; -+ - skb = alloc_skb(size + sizeof(*th), sk->sk_allocation); - if (!skb) - goto err; -@@ -4728,7 +4731,7 @@ static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb, +@@ -4731,7 +4731,7 @@ static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb, * simplifies code) */ static void @@ -78148,31 +78331,6 @@ index 34e4185..8823368 100644 } while (!res); return res; } -diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c -index 3bfb34a..69bf48d 100644 ---- a/net/l2tp/l2tp_eth.c -+++ b/net/l2tp/l2tp_eth.c -@@ -290,6 +290,7 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p - - out_del_dev: - free_netdev(dev); -+ spriv->dev = NULL; - out_del_session: - l2tp_session_delete(session); - out: -diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c -index 5746d62..327aa07 100644 ---- a/net/mac80211/ibss.c -+++ b/net/mac80211/ibss.c -@@ -1074,7 +1074,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, - sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; - sdata->u.ibss.ibss_join_req = jiffies; - -- memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); -+ memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); - sdata->u.ibss.ssid_len = params->ssid_len; - - mutex_unlock(&sdata->u.ibss.mtx); diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index bb61f77..3788d63 100644 --- a/net/mac80211/ieee80211_i.h @@ -78331,111 +78489,11 @@ index c97a065..ff61928 100644 return -EFAULT; return p; -diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c -index 0cb4ede..884155d 100644 ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -491,6 +491,11 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) - - if (ieee80211_is_action(hdr->frame_control)) { - u8 category; -+ -+ /* make sure category field is present */ -+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE) -+ return RX_DROP_MONITOR; -+ - mgmt = (struct ieee80211_mgmt *)hdr; - category = mgmt->u.action.category; - if (category != WLAN_CATEGORY_MESH_ACTION && -@@ -1426,7 +1431,6 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) - frag = sc & IEEE80211_SCTL_FRAG; - - if (likely((!ieee80211_has_morefrags(fc) && frag == 0) || -- (rx->skb)->len < 24 || - is_multicast_ether_addr(hdr->addr1))) { - /* not fragmented */ - goto out; -@@ -1849,6 +1853,20 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) - - hdr = (struct ieee80211_hdr *) skb->data; - hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ -+ /* make sure fixed part of mesh header is there, also checks skb len */ -+ if (!pskb_may_pull(rx->skb, hdrlen + 6)) -+ return RX_DROP_MONITOR; -+ -+ mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); -+ -+ /* make sure full mesh header is there, also checks skb len */ -+ if (!pskb_may_pull(rx->skb, -+ hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr))) -+ return RX_DROP_MONITOR; -+ -+ /* reload pointers */ -+ hdr = (struct ieee80211_hdr *) skb->data; - mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); - - /* frame is in RMC, don't forward */ -@@ -1871,9 +1889,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) - if (is_multicast_ether_addr(hdr->addr1)) { - mpp_addr = hdr->addr3; - proxied_addr = mesh_hdr->eaddr1; -- } else { -+ } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) { -+ /* has_a4 already checked in ieee80211_rx_mesh_check */ - mpp_addr = hdr->addr4; - proxied_addr = mesh_hdr->eaddr2; -+ } else { -+ return RX_DROP_MONITOR; - } - - rcu_read_lock(); -@@ -2313,6 +2334,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) - } - break; - case WLAN_CATEGORY_SELF_PROTECTED: -+ if (len < (IEEE80211_MIN_ACTION_SIZE + -+ sizeof(mgmt->u.action.u.self_prot.action_code))) -+ break; -+ - switch (mgmt->u.action.u.self_prot.action_code) { - case WLAN_SP_MESH_PEERING_OPEN: - case WLAN_SP_MESH_PEERING_CLOSE: -@@ -2331,6 +2356,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) - } - break; - case WLAN_CATEGORY_MESH_ACTION: -+ if (len < (IEEE80211_MIN_ACTION_SIZE + -+ sizeof(mgmt->u.action.u.mesh_action.action_code))) -+ break; -+ - if (!ieee80211_vif_is_mesh(&sdata->vif)) - break; - if (mesh_action_is_path_sel(mgmt) && -@@ -2865,10 +2894,15 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, - if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) - local->dot11ReceivedFragmentCount++; - -- if (ieee80211_is_mgmt(fc)) -- err = skb_linearize(skb); -- else -+ if (ieee80211_is_mgmt(fc)) { -+ /* drop frame if too short for header */ -+ if (skb->len < ieee80211_hdrlen(fc)) -+ err = -ENOBUFS; -+ else -+ err = skb_linearize(skb); -+ } else { - err = !pskb_may_pull(skb, ieee80211_hdrlen(fc)); -+ } - - if (err) { - dev_kfree_skb(skb); diff --git a/net/mac80211/util.c b/net/mac80211/util.c -index c9b52f7..4da1014 100644 +index 1cfe6d5..c428ba3 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c -@@ -1251,7 +1251,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) +@@ -1279,7 +1279,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) } #endif /* everything else happens only if HW was up & running */ @@ -78773,10 +78831,10 @@ index 4fe4fb4..87a89e5 100644 return 0; } diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c -index 9172179..a4035c4 100644 +index 0426b67..d6ddaca 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c -@@ -769,7 +769,7 @@ static void netlink_overrun(struct sock *sk) +@@ -780,7 +780,7 @@ static void netlink_overrun(struct sock *sk) sk->sk_error_report(sk); } } @@ -78785,7 +78843,7 @@ index 9172179..a4035c4 100644 } static struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid) -@@ -2059,7 +2059,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v) +@@ -2070,7 +2070,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v) sk_wmem_alloc_get(s), nlk->cb, atomic_read(&s->sk_refcnt), @@ -80023,27 +80081,6 @@ index bc7430b..35349de 100644 struct rfkill *rfkill; struct work_struct rfkill_sync; -diff --git a/net/wireless/util.c b/net/wireless/util.c -index 994e2f0..f67aeb1 100644 ---- a/net/wireless/util.c -+++ b/net/wireless/util.c -@@ -309,7 +309,7 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) - } - EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); - --static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) -+unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) - { - int ae = meshhdr->flags & MESH_FLAGS_AE; - /* 7.1.3.5a.2 */ -@@ -326,6 +326,7 @@ static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) - return 6; - } - } -+EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); - - int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, - enum nl80211_iftype iftype) diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index b0eb7aa..7d73e82 100644 --- a/net/wireless/wext-core.c @@ -81829,7 +81866,7 @@ index ffd2025..df062c9 100644 /* PCM3052 register definitions */ diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c -index 08fde00..0bf641a 100644 +index 4c1cc51..16040040 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -1189,10 +1189,10 @@ snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, const @@ -81917,10 +81954,10 @@ index 91cdf94..4085161 100644 if (err < 0) return err; diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c -index 53b5ada..2db94c8 100644 +index bf3bf43..3826cbc 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c -@@ -2780,11 +2780,11 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, +@@ -2803,11 +2803,11 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, switch (substream->stream) { case SNDRV_PCM_STREAM_PLAYBACK: result = snd_pcm_playback_ioctl1(NULL, substream, cmd, @@ -87665,10 +87702,10 @@ index 0000000..9332f17 +_003896_hash nfs_parse_server_name 2 1899 _003896_hash NULL diff --git a/tools/gcc/size_overflow_plugin.c b/tools/gcc/size_overflow_plugin.c new file mode 100644 -index 0000000..244559e +index 0000000..1aa0dce --- /dev/null +++ b/tools/gcc/size_overflow_plugin.c -@@ -0,0 +1,1879 @@ +@@ -0,0 +1,1865 @@ +/* + * Copyright 2011, 2012 by Emese Revfy <re.emese@gmail.com> + * Licensed under the GPL v2, or (at your option) v3 @@ -87746,10 +87783,10 @@ index 0000000..244559e +static unsigned int handle_function(void); +static void check_size_overflow(gimple stmt, tree size_overflow_type, tree cast_rhs, tree rhs, bool before); +static tree get_size_overflow_type(gimple stmt, const_tree node); -+static tree dup_assign(struct pointer_set_t *visited, gimple oldstmt, tree size_overflow_type, tree rhs1, tree rhs2, tree __unused rhs3); ++static tree dup_assign(struct pointer_set_t *visited, gimple oldstmt, const_tree node, tree rhs1, tree rhs2, tree __unused rhs3); + +static struct plugin_info size_overflow_plugin_info = { -+ .version = "20120930beta", ++ .version = "20121113beta", + .help = "no-size-overflow\tturn off size overflow checking\n", +}; + @@ -88068,6 +88105,7 @@ index 0000000..244559e + tree type = TREE_TYPE(rhs1); + tree lhs = create_new_var(type); + ++ gcc_assert(types_compatible_p(type, TREE_TYPE(rhs2))); + assign = gimple_build_assign_with_ops(code, lhs, rhs1, rhs2); + gimple_set_lhs(assign, make_ssa_name(lhs, assign)); + @@ -88133,42 +88171,41 @@ index 0000000..244559e + return assign; +} + -+static tree cast_to_new_size_overflow_type(gimple stmt, tree new_rhs1, tree size_overflow_type, bool before) ++static tree cast_to_new_size_overflow_type(gimple stmt, tree rhs, tree size_overflow_type, bool before) +{ -+ const_gimple assign; ++ gimple assign; + gimple_stmt_iterator gsi; + -+ if (new_rhs1 == NULL_TREE) ++ if (rhs == NULL_TREE) + return NULL_TREE; + -+ if (!useless_type_conversion_p(TREE_TYPE(new_rhs1), size_overflow_type)) { -+ gsi = gsi_for_stmt(stmt); -+ assign = build_cast_stmt(size_overflow_type, new_rhs1, CREATE_NEW_VAR, &gsi, before); -+ return gimple_get_lhs(assign); -+ } -+ return new_rhs1; ++ if (types_compatible_p(TREE_TYPE(rhs), size_overflow_type) && gimple_plf(stmt, MY_STMT)) ++ return rhs; ++ ++ gsi = gsi_for_stmt(stmt); ++ assign = build_cast_stmt(size_overflow_type, rhs, CREATE_NEW_VAR, &gsi, before); ++ gimple_set_plf(assign, MY_STMT, true); ++ return gimple_get_lhs(assign); +} + -+static tree follow_overflow_type_and_dup(struct pointer_set_t *visited, gimple stmt, const_tree node, tree new_rhs1, tree new_rhs2, tree new_rhs3) ++static tree cast_to_TI_type(gimple stmt, tree node) +{ -+ tree size_overflow_type = get_size_overflow_type(stmt, node); -+ -+ new_rhs1 = cast_to_new_size_overflow_type(stmt, new_rhs1, size_overflow_type, BEFORE_STMT); -+ -+ if (new_rhs2 != NULL_TREE) -+ new_rhs2 = cast_to_new_size_overflow_type(stmt, new_rhs2, size_overflow_type, BEFORE_STMT); ++ gimple_stmt_iterator gsi; ++ gimple cast_stmt; ++ tree type = TREE_TYPE(node); + -+ if (new_rhs3 != NULL_TREE) -+ new_rhs3 = cast_to_new_size_overflow_type(stmt, new_rhs3, size_overflow_type, BEFORE_STMT); ++ if (types_compatible_p(type, intTI_type_node)) ++ return node; + -+ return dup_assign(visited, stmt, size_overflow_type, new_rhs1, new_rhs2, new_rhs3); ++ gsi = gsi_for_stmt(stmt); ++ cast_stmt = build_cast_stmt(intTI_type_node, node, CREATE_NEW_VAR, &gsi, BEFORE_STMT); ++ gimple_set_plf(cast_stmt, MY_STMT, true); ++ return gimple_get_lhs(cast_stmt); +} + -+ +static tree create_assign(struct pointer_set_t *visited, gimple oldstmt, tree rhs1, bool before) +{ -+ tree size_overflow_type, lhs; -+ gimple stmt; ++ tree lhs; + gimple_stmt_iterator gsi; + + if (rhs1 == NULL_TREE) { @@ -88206,18 +88243,14 @@ index 0000000..244559e + oldstmt = gsi_stmt(gsi); + } + -+ size_overflow_type = get_size_overflow_type(oldstmt, lhs); -+ -+ stmt = build_cast_stmt(size_overflow_type, rhs1, CREATE_NEW_VAR, &gsi, before); -+ gimple_set_plf(stmt, MY_STMT, true); -+ return gimple_get_lhs(stmt); ++ return cast_to_new_size_overflow_type(oldstmt, rhs1, get_size_overflow_type(oldstmt, lhs), before); +} + -+static tree dup_assign(struct pointer_set_t *visited, gimple oldstmt, tree size_overflow_type, tree rhs1, tree rhs2, tree __unused rhs3) ++static tree dup_assign(struct pointer_set_t *visited, gimple oldstmt, const_tree node, tree rhs1, tree rhs2, tree __unused rhs3) +{ + gimple stmt; + gimple_stmt_iterator gsi; -+ tree new_var, lhs = gimple_get_lhs(oldstmt); ++ tree size_overflow_type, new_var, lhs = gimple_get_lhs(oldstmt); + + if (gimple_plf(oldstmt, MY_STMT)) + return lhs; @@ -88238,6 +88271,8 @@ index 0000000..244559e + if (gimple_assign_rhs_code(oldstmt) == WIDEN_MULT_EXPR) + gimple_assign_set_rhs_code(stmt, MULT_EXPR); + ++ size_overflow_type = get_size_overflow_type(oldstmt, node); ++ + if (is_bool(lhs)) + new_var = SSA_NAME_VAR(lhs); + else @@ -88246,7 +88281,7 @@ index 0000000..244559e + gimple_set_lhs(stmt, new_var); + + if (rhs1 != NULL_TREE) { -+ if (!gimple_assign_cast_p(oldstmt)) ++ if (!gimple_assign_cast_p(oldstmt) && TREE_CODE_CLASS(gimple_assign_rhs_code(oldstmt)) != tcc_comparison) + rhs1 = cast_a_tree(size_overflow_type, rhs1); + gimple_assign_set_rhs1(stmt, rhs1); + } @@ -88498,7 +88533,7 @@ index 0000000..244559e + return lhs; + + if (gimple_plf(stmt, NO_CAST_CHECK)) -+ return follow_overflow_type_and_dup(visited, stmt, rhs1, new_rhs1, NULL_TREE, NULL_TREE); ++ return dup_assign(visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); + + if (gimple_assign_rhs_code(stmt) == BIT_NOT_EXPR) { + size_overflow_type = get_size_overflow_type(stmt, rhs1); @@ -88508,7 +88543,7 @@ index 0000000..244559e + } + + if (!gimple_assign_cast_p(stmt) || check_undefined_integer_operation(stmt)) -+ return follow_overflow_type_and_dup(visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); ++ return dup_assign(visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); + + size_overflow_type = get_size_overflow_type(stmt, rhs1); + new_rhs1 = cast_to_new_size_overflow_type(stmt, new_rhs1, size_overflow_type, BEFORE_STMT); @@ -88693,8 +88728,8 @@ index 0000000..244559e + cast_rhs_type = TREE_TYPE(cast_rhs); + type_max_type = TREE_TYPE(type_max); + type_min_type = TREE_TYPE(type_min); -+ gcc_assert(useless_type_conversion_p(cast_rhs_type, type_max_type)); -+ gcc_assert(useless_type_conversion_p(type_max_type, type_min_type)); ++ gcc_assert(types_compatible_p(cast_rhs_type, type_max_type)); ++ gcc_assert(types_compatible_p(type_max_type, type_min_type)); + + insert_check_size_overflow(stmt, GT_EXPR, cast_rhs, type_max, before, false); + insert_check_size_overflow(stmt, LT_EXPR, cast_rhs, type_min, before, true); @@ -88722,7 +88757,7 @@ index 0000000..244559e + if (gimple_assign_rhs_code(def_stmt) == RSHIFT_EXPR) + return get_size_overflow_type(change_rhs_def_stmt, change_rhs); + -+ if (!useless_type_conversion_p(lhs_type, rhs1_type) || !useless_type_conversion_p(rhs1_type, rhs2_type)) { ++ if (!types_compatible_p(lhs_type, rhs1_type) || !useless_type_conversion_p(rhs1_type, rhs2_type)) { + debug_gimple_stmt(def_stmt); + gcc_unreachable(); + } @@ -88739,64 +88774,20 @@ index 0000000..244559e + return true; +} + -+static tree get_cast_def_stmt_rhs(const_tree new_rhs) -+{ -+ gimple def_stmt; -+ -+ def_stmt = get_def_stmt(new_rhs); -+ // get_size_overflow_type -+ if (LONG_TYPE_SIZE != GET_MODE_BITSIZE(SImode)) -+ gcc_assert(gimple_assign_cast_p(def_stmt)); -+ return gimple_assign_rhs1(def_stmt); -+} -+ -+static tree cast_to_int_TI_type_and_check(gimple stmt, tree new_rhs) -+{ -+ gimple_stmt_iterator gsi; -+ const_gimple cast_stmt; -+ gimple def_stmt; -+ enum machine_mode mode = TYPE_MODE(TREE_TYPE(new_rhs)); -+ -+ if (mode != TImode && mode != DImode) { -+ def_stmt = get_def_stmt(new_rhs); -+ gcc_assert(gimple_assign_cast_p(def_stmt)); -+ new_rhs = gimple_assign_rhs1(def_stmt); -+ mode = TYPE_MODE(TREE_TYPE(new_rhs)); -+ } -+ -+ gcc_assert(mode == TImode || mode == DImode); -+ -+ if (mode == TYPE_MODE(intTI_type_node) && useless_type_conversion_p(TREE_TYPE(new_rhs), intTI_type_node)) -+ return new_rhs; -+ -+ gsi = gsi_for_stmt(stmt); -+ cast_stmt = build_cast_stmt(intTI_type_node, new_rhs, CREATE_NEW_VAR, &gsi, BEFORE_STMT); -+ new_rhs = gimple_get_lhs(cast_stmt); -+ -+ if (mode == DImode) -+ return new_rhs; -+ -+ check_size_overflow(stmt, intTI_type_node, new_rhs, new_rhs, BEFORE_STMT); -+ -+ return new_rhs; -+} -+ -+static bool is_an_integer_trunction(const_gimple stmt) ++static bool is_subtraction_special(const_gimple stmt) +{ + gimple rhs1_def_stmt, rhs2_def_stmt; -+ const_tree rhs1_def_stmt_rhs1, rhs2_def_stmt_rhs1; -+ enum machine_mode rhs1_def_stmt_rhs1_mode, rhs2_def_stmt_rhs1_mode; ++ const_tree rhs1_def_stmt_rhs1, rhs2_def_stmt_rhs1, rhs1_def_stmt_lhs, rhs2_def_stmt_lhs; ++ enum machine_mode rhs1_def_stmt_rhs1_mode, rhs2_def_stmt_rhs1_mode, rhs1_def_stmt_lhs_mode, rhs2_def_stmt_lhs_mode; + const_tree rhs1 = gimple_assign_rhs1(stmt); + const_tree rhs2 = gimple_assign_rhs2(stmt); -+ enum machine_mode rhs1_mode = TYPE_MODE(TREE_TYPE(rhs1)); -+ enum machine_mode rhs2_mode = TYPE_MODE(TREE_TYPE(rhs2)); + + if (is_gimple_constant(rhs1) || is_gimple_constant(rhs2)) + return false; + + gcc_assert(TREE_CODE(rhs1) == SSA_NAME && TREE_CODE(rhs2) == SSA_NAME); + -+ if (gimple_assign_rhs_code(stmt) != MINUS_EXPR || rhs1_mode != SImode || rhs2_mode != SImode) ++ if (gimple_assign_rhs_code(stmt) != MINUS_EXPR) + return false; + + rhs1_def_stmt = get_def_stmt(rhs1); @@ -88806,9 +88797,15 @@ index 0000000..244559e + + rhs1_def_stmt_rhs1 = gimple_assign_rhs1(rhs1_def_stmt); + rhs2_def_stmt_rhs1 = gimple_assign_rhs1(rhs2_def_stmt); ++ rhs1_def_stmt_lhs = gimple_get_lhs(rhs1_def_stmt); ++ rhs2_def_stmt_lhs = gimple_get_lhs(rhs2_def_stmt); + rhs1_def_stmt_rhs1_mode = TYPE_MODE(TREE_TYPE(rhs1_def_stmt_rhs1)); + rhs2_def_stmt_rhs1_mode = TYPE_MODE(TREE_TYPE(rhs2_def_stmt_rhs1)); -+ if (rhs1_def_stmt_rhs1_mode != DImode || rhs2_def_stmt_rhs1_mode != DImode) ++ rhs1_def_stmt_lhs_mode = TYPE_MODE(TREE_TYPE(rhs1_def_stmt_lhs)); ++ rhs2_def_stmt_lhs_mode = TYPE_MODE(TREE_TYPE(rhs2_def_stmt_lhs)); ++ if (GET_MODE_BITSIZE(rhs1_def_stmt_rhs1_mode) <= GET_MODE_BITSIZE(rhs1_def_stmt_lhs_mode)) ++ return false; ++ if (GET_MODE_BITSIZE(rhs2_def_stmt_rhs1_mode) <= GET_MODE_BITSIZE(rhs2_def_stmt_lhs_mode)) + return false; + + gimple_set_plf(rhs1_def_stmt, NO_CAST_CHECK, true); @@ -88816,37 +88813,63 @@ index 0000000..244559e + return true; +} + ++static tree get_def_stmt_rhs(const_tree var) ++{ ++ tree rhs1, def_stmt_rhs1; ++ gimple rhs1_def_stmt, def_stmt_rhs1_def_stmt, def_stmt; ++ ++ def_stmt = get_def_stmt(var); ++ gcc_assert(gimple_code(def_stmt) != GIMPLE_NOP && gimple_plf(def_stmt, MY_STMT) && gimple_assign_cast_p(def_stmt)); ++ ++ rhs1 = gimple_assign_rhs1(def_stmt); ++ rhs1_def_stmt = get_def_stmt(rhs1); ++ gcc_assert(gimple_code(rhs1_def_stmt) != GIMPLE_NOP); ++ if (!gimple_assign_cast_p(rhs1_def_stmt)) ++ return rhs1; ++ ++ def_stmt_rhs1 = gimple_assign_rhs1(rhs1_def_stmt); ++ def_stmt_rhs1_def_stmt = get_def_stmt(def_stmt_rhs1); ++ ++ switch (gimple_code(def_stmt_rhs1_def_stmt)) { ++ case GIMPLE_CALL: ++ case GIMPLE_NOP: ++ case GIMPLE_ASM: ++ return def_stmt_rhs1; ++ case GIMPLE_ASSIGN: ++ return rhs1; ++ default: ++ debug_gimple_stmt(def_stmt_rhs1_def_stmt); ++ gcc_unreachable(); ++ } ++} ++ +static tree handle_integer_truncation(struct pointer_set_t *visited, const_tree lhs) +{ + tree new_rhs1, new_rhs2; + tree new_rhs1_def_stmt_rhs1, new_rhs2_def_stmt_rhs1, new_lhs; -+ tree new_rhs1_def_stmt_rhs1_type, new_rhs2_def_stmt_rhs1_type; + gimple assign, stmt = get_def_stmt(lhs); + tree rhs1 = gimple_assign_rhs1(stmt); + tree rhs2 = gimple_assign_rhs2(stmt); + -+ if (!is_an_integer_trunction(stmt)) ++ if (!is_subtraction_special(stmt)) + return NULL_TREE; + + new_rhs1 = expand(visited, rhs1); + new_rhs2 = expand(visited, rhs2); + -+ new_rhs1_def_stmt_rhs1 = get_cast_def_stmt_rhs(new_rhs1); -+ new_rhs2_def_stmt_rhs1 = get_cast_def_stmt_rhs(new_rhs2); -+ -+ new_rhs1_def_stmt_rhs1_type = TREE_TYPE(new_rhs1_def_stmt_rhs1); -+ new_rhs2_def_stmt_rhs1_type = TREE_TYPE(new_rhs2_def_stmt_rhs1); ++ new_rhs1_def_stmt_rhs1 = get_def_stmt_rhs(new_rhs1); ++ new_rhs2_def_stmt_rhs1 = get_def_stmt_rhs(new_rhs2); + -+ if (!useless_type_conversion_p(new_rhs1_def_stmt_rhs1_type, new_rhs2_def_stmt_rhs1_type)) { -+ new_rhs1_def_stmt_rhs1 = cast_to_int_TI_type_and_check(stmt, new_rhs1_def_stmt_rhs1); -+ new_rhs2_def_stmt_rhs1 = cast_to_int_TI_type_and_check(stmt, new_rhs2_def_stmt_rhs1); ++ if (!types_compatible_p(TREE_TYPE(new_rhs1_def_stmt_rhs1), TREE_TYPE(new_rhs2_def_stmt_rhs1))) { ++ new_rhs1_def_stmt_rhs1 = cast_to_TI_type(stmt, new_rhs1_def_stmt_rhs1); ++ new_rhs2_def_stmt_rhs1 = cast_to_TI_type(stmt, new_rhs2_def_stmt_rhs1); + } + + assign = create_binary_assign(MINUS_EXPR, stmt, new_rhs1_def_stmt_rhs1, new_rhs2_def_stmt_rhs1); + new_lhs = gimple_get_lhs(assign); + check_size_overflow(assign, TREE_TYPE(new_lhs), new_lhs, rhs1, AFTER_STMT); + -+ return follow_overflow_type_and_dup(visited, stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); ++ return dup_assign(visited, stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); +} + +static bool is_a_neg_overflow(const_gimple stmt, const_tree rhs) @@ -88949,7 +88972,7 @@ index 0000000..244559e + if (is_a_constant_overflow(def_stmt, rhs1)) + return handle_intentional_overflow(visited, !is_a_cast_and_const_overflow(rhs2), def_stmt, new_rhs2, NULL_TREE, new_rhs2); + -+ return follow_overflow_type_and_dup(visited, def_stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); ++ return dup_assign(visited, def_stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); +} + +#if BUILDING_GCC_VERSION >= 4007 @@ -88976,7 +88999,7 @@ index 0000000..244559e + new_rhs2 = get_new_rhs(visited, size_overflow_type, rhs2); + new_rhs3 = get_new_rhs(visited, size_overflow_type, rhs3); + -+ return follow_overflow_type_and_dup(visited, def_stmt, lhs, new_rhs1, new_rhs2, new_rhs3); ++ return dup_assign(visited, def_stmt, lhs, new_rhs1, new_rhs2, new_rhs3); +} +#endif + diff --git a/3.6.6/4425-tmpfs-user-namespace.patch b/3.6.7/4425-tmpfs-user-namespace.patch index b48d735..b48d735 100644 --- a/3.6.6/4425-tmpfs-user-namespace.patch +++ b/3.6.7/4425-tmpfs-user-namespace.patch diff --git a/3.6.6/4430_grsec-remove-localversion-grsec.patch b/3.6.7/4430_grsec-remove-localversion-grsec.patch index 31cf878..31cf878 100644 --- a/3.6.6/4430_grsec-remove-localversion-grsec.patch +++ b/3.6.7/4430_grsec-remove-localversion-grsec.patch diff --git a/3.6.6/4435_grsec-mute-warnings.patch b/3.6.7/4435_grsec-mute-warnings.patch index e1a7a3c..e1a7a3c 100644 --- a/3.6.6/4435_grsec-mute-warnings.patch +++ b/3.6.7/4435_grsec-mute-warnings.patch diff --git a/3.6.6/4440_grsec-remove-protected-paths.patch b/3.6.7/4440_grsec-remove-protected-paths.patch index 637934a..637934a 100644 --- a/3.6.6/4440_grsec-remove-protected-paths.patch +++ b/3.6.7/4440_grsec-remove-protected-paths.patch diff --git a/3.6.6/4450_grsec-kconfig-default-gids.patch b/3.6.7/4450_grsec-kconfig-default-gids.patch index d4b0b7e..d4b0b7e 100644 --- a/3.6.6/4450_grsec-kconfig-default-gids.patch +++ b/3.6.7/4450_grsec-kconfig-default-gids.patch diff --git a/3.6.6/4465_selinux-avc_audit-log-curr_ip.patch b/3.6.7/4465_selinux-avc_audit-log-curr_ip.patch index 4fb50f4..4fb50f4 100644 --- a/3.6.6/4465_selinux-avc_audit-log-curr_ip.patch +++ b/3.6.7/4465_selinux-avc_audit-log-curr_ip.patch diff --git a/3.6.6/4470_disable-compat_vdso.patch b/3.6.7/4470_disable-compat_vdso.patch index 4a1947b..4a1947b 100644 --- a/3.6.6/4470_disable-compat_vdso.patch +++ b/3.6.7/4470_disable-compat_vdso.patch |