diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2012-11-01 09:09:15 -0400 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2012-11-01 09:09:15 -0400 |
commit | f4907cfe7e0e2c027f6e4dbdd7dbbb7353c4e65e (patch) | |
tree | 41bb78d2250d59f08a0adfb0f6f500ef688ec276 | |
parent | Grsec/PaX: 2.9.1-{2.6.32.60,3.2.32,3.6.4}-201210291446 (diff) | |
download | hardened-patchset-f4907cfe7e0e2c027f6e4dbdd7dbbb7353c4e65e.tar.gz hardened-patchset-f4907cfe7e0e2c027f6e4dbdd7dbbb7353c4e65e.tar.bz2 hardened-patchset-f4907cfe7e0e2c027f6e4dbdd7dbbb7353c4e65e.zip |
Grsec/PaX: 2.9.1-{2.6.32.60,3.2.33,3.6.5}-20121031212120121031
-rw-r--r-- | 2.6.32/0000_README | 2 | ||||
-rw-r--r-- | 2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201210310820.patch (renamed from 2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201210291444.patch) | 6 | ||||
-rw-r--r-- | 3.2.33/0000_README (renamed from 3.2.32/0000_README) | 6 | ||||
-rw-r--r-- | 3.2.33/1021_linux-3.2.22.patch (renamed from 3.2.32/1021_linux-3.2.22.patch) | 0 | ||||
-rw-r--r-- | 3.2.33/1022_linux-3.2.23.patch (renamed from 3.2.32/1022_linux-3.2.23.patch) | 0 | ||||
-rw-r--r-- | 3.2.33/1023_linux-3.2.24.patch (renamed from 3.2.32/1023_linux-3.2.24.patch) | 0 | ||||
-rw-r--r-- | 3.2.33/1024_linux-3.2.25.patch (renamed from 3.2.32/1024_linux-3.2.25.patch) | 0 | ||||
-rw-r--r-- | 3.2.33/1025_linux-3.2.26.patch (renamed from 3.2.32/1025_linux-3.2.26.patch) | 0 | ||||
-rw-r--r-- | 3.2.33/1026_linux-3.2.27.patch (renamed from 3.2.32/1026_linux-3.2.27.patch) | 0 | ||||
-rw-r--r-- | 3.2.33/1027_linux-3.2.28.patch (renamed from 3.2.32/1027_linux-3.2.28.patch) | 0 | ||||
-rw-r--r-- | 3.2.33/1028_linux-3.2.29.patch (renamed from 3.2.32/1028_linux-3.2.29.patch) | 0 | ||||
-rw-r--r-- | 3.2.33/1029_linux-3.2.30.patch (renamed from 3.2.32/1029_linux-3.2.30.patch) | 0 | ||||
-rw-r--r-- | 3.2.33/1030_linux-3.2.31.patch (renamed from 3.2.32/1030_linux-3.2.31.patch) | 0 | ||||
-rw-r--r-- | 3.2.33/1031_linux-3.2.32.patch (renamed from 3.2.32/1031_linux-3.2.32.patch) | 0 | ||||
-rw-r--r-- | 3.2.33/1032_linux-3.2.33.patch | 3450 | ||||
-rw-r--r-- | 3.2.33/4420_grsecurity-2.9.1-3.2.33-201210310843.patch (renamed from 3.2.32/4420_grsecurity-2.9.1-3.2.32-201210291445.patch) | 260 | ||||
-rw-r--r-- | 3.2.33/4430_grsec-remove-localversion-grsec.patch (renamed from 3.2.32/4430_grsec-remove-localversion-grsec.patch) | 0 | ||||
-rw-r--r-- | 3.2.33/4435_grsec-mute-warnings.patch (renamed from 3.2.32/4435_grsec-mute-warnings.patch) | 0 | ||||
-rw-r--r-- | 3.2.33/4440_grsec-remove-protected-paths.patch (renamed from 3.2.32/4440_grsec-remove-protected-paths.patch) | 0 | ||||
-rw-r--r-- | 3.2.33/4450_grsec-kconfig-default-gids.patch (renamed from 3.2.32/4450_grsec-kconfig-default-gids.patch) | 0 | ||||
-rw-r--r-- | 3.2.33/4465_selinux-avc_audit-log-curr_ip.patch (renamed from 3.2.32/4465_selinux-avc_audit-log-curr_ip.patch) | 0 | ||||
-rw-r--r-- | 3.2.33/4470_disable-compat_vdso.patch (renamed from 3.2.32/4470_disable-compat_vdso.patch) | 0 | ||||
-rw-r--r-- | 3.6.5/0000_README (renamed from 3.6.4/0000_README) | 6 | ||||
-rw-r--r-- | 3.6.5/1004_linux-3.6.5.patch | 4649 | ||||
-rw-r--r-- | 3.6.5/4420_grsecurity-2.9.1-3.6.5-201210312121.patch (renamed from 3.6.4/4420_grsecurity-2.9.1-3.6.4-201210291446.patch) | 188 | ||||
-rw-r--r-- | 3.6.5/4430_grsec-remove-localversion-grsec.patch (renamed from 3.6.4/4430_grsec-remove-localversion-grsec.patch) | 0 | ||||
-rw-r--r-- | 3.6.5/4435_grsec-mute-warnings.patch (renamed from 3.6.4/4435_grsec-mute-warnings.patch) | 0 | ||||
-rw-r--r-- | 3.6.5/4440_grsec-remove-protected-paths.patch (renamed from 3.6.4/4440_grsec-remove-protected-paths.patch) | 0 | ||||
-rw-r--r-- | 3.6.5/4450_grsec-kconfig-default-gids.patch (renamed from 3.6.4/4450_grsec-kconfig-default-gids.patch) | 0 | ||||
-rw-r--r-- | 3.6.5/4465_selinux-avc_audit-log-curr_ip.patch (renamed from 3.6.4/4465_selinux-avc_audit-log-curr_ip.patch) | 0 | ||||
-rw-r--r-- | 3.6.5/4470_disable-compat_vdso.patch (renamed from 3.6.4/4470_disable-compat_vdso.patch) | 0 |
31 files changed, 8285 insertions, 282 deletions
diff --git a/2.6.32/0000_README b/2.6.32/0000_README index 288d745..77cac16 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-201210291444.patch +Patch: 4420_grsecurity-2.9.1-2.6.32.60-201210310820.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-201210291444.patch b/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201210310820.patch index 489cffc..04f2458 100644 --- a/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201210291444.patch +++ b/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201210310820.patch @@ -103771,7 +103771,7 @@ index 5c9dc22..d271117 100644 .clock_get = thread_cpu_clock_get, .clock_set = do_posix_clock_nosettime, diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c -index 5e76d22..cf1baeb 100644 +index 5e76d22..f2d062c 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -42,6 +42,7 @@ @@ -103817,10 +103817,10 @@ index 5e76d22..cf1baeb 100644 return 1; - if (posix_clocks[which_clock].clock_getres != NULL) + if (posix_clocks[which_clock] == NULL) ++ return 1; ++ if (posix_clocks[which_clock]->clock_getres != NULL) return 0; - if (posix_clocks[which_clock].res != 0) -+ if (posix_clocks[which_clock]->clock_getres != NULL) -+ return 0; + if (posix_clocks[which_clock]->res != 0) return 0; return 1; diff --git a/3.2.32/0000_README b/3.2.33/0000_README index 037da24..245166a 100644 --- a/3.2.32/0000_README +++ b/3.2.33/0000_README @@ -46,7 +46,11 @@ Patch: 1031_linux-3.2.32.patch From: http://www.kernel.org Desc: Linux 3.2.32 -Patch: 4420_grsecurity-2.9.1-3.2.32-201210291445.patch +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-201210310843.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.2.32/1021_linux-3.2.22.patch b/3.2.33/1021_linux-3.2.22.patch index e6ad93a..e6ad93a 100644 --- a/3.2.32/1021_linux-3.2.22.patch +++ b/3.2.33/1021_linux-3.2.22.patch diff --git a/3.2.32/1022_linux-3.2.23.patch b/3.2.33/1022_linux-3.2.23.patch index 3d796d0..3d796d0 100644 --- a/3.2.32/1022_linux-3.2.23.patch +++ b/3.2.33/1022_linux-3.2.23.patch diff --git a/3.2.32/1023_linux-3.2.24.patch b/3.2.33/1023_linux-3.2.24.patch index 4692eb4..4692eb4 100644 --- a/3.2.32/1023_linux-3.2.24.patch +++ b/3.2.33/1023_linux-3.2.24.patch diff --git a/3.2.32/1024_linux-3.2.25.patch b/3.2.33/1024_linux-3.2.25.patch index e95c213..e95c213 100644 --- a/3.2.32/1024_linux-3.2.25.patch +++ b/3.2.33/1024_linux-3.2.25.patch diff --git a/3.2.32/1025_linux-3.2.26.patch b/3.2.33/1025_linux-3.2.26.patch index 44065b9..44065b9 100644 --- a/3.2.32/1025_linux-3.2.26.patch +++ b/3.2.33/1025_linux-3.2.26.patch diff --git a/3.2.32/1026_linux-3.2.27.patch b/3.2.33/1026_linux-3.2.27.patch index 5878eb4..5878eb4 100644 --- a/3.2.32/1026_linux-3.2.27.patch +++ b/3.2.33/1026_linux-3.2.27.patch diff --git a/3.2.32/1027_linux-3.2.28.patch b/3.2.33/1027_linux-3.2.28.patch index 4dbba4b..4dbba4b 100644 --- a/3.2.32/1027_linux-3.2.28.patch +++ b/3.2.33/1027_linux-3.2.28.patch diff --git a/3.2.32/1028_linux-3.2.29.patch b/3.2.33/1028_linux-3.2.29.patch index 3c65179..3c65179 100644 --- a/3.2.32/1028_linux-3.2.29.patch +++ b/3.2.33/1028_linux-3.2.29.patch diff --git a/3.2.32/1029_linux-3.2.30.patch b/3.2.33/1029_linux-3.2.30.patch index 86aea4b..86aea4b 100644 --- a/3.2.32/1029_linux-3.2.30.patch +++ b/3.2.33/1029_linux-3.2.30.patch diff --git a/3.2.32/1030_linux-3.2.31.patch b/3.2.33/1030_linux-3.2.31.patch index c6accf5..c6accf5 100644 --- a/3.2.32/1030_linux-3.2.31.patch +++ b/3.2.33/1030_linux-3.2.31.patch diff --git a/3.2.32/1031_linux-3.2.32.patch b/3.2.33/1031_linux-3.2.32.patch index 247fc0b..247fc0b 100644 --- a/3.2.32/1031_linux-3.2.32.patch +++ b/3.2.33/1031_linux-3.2.32.patch diff --git a/3.2.33/1032_linux-3.2.33.patch b/3.2.33/1032_linux-3.2.33.patch new file mode 100644 index 0000000..c32fb75 --- /dev/null +++ b/3.2.33/1032_linux-3.2.33.patch @@ -0,0 +1,3450 @@ +diff --git a/Makefile b/Makefile +index b6d8282..63ca1ea2 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 2 +-SUBLEVEL = 32 ++SUBLEVEL = 33 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/include/asm/vfpmacros.h b/arch/arm/include/asm/vfpmacros.h +index 3d5fc41..bf53047 100644 +--- a/arch/arm/include/asm/vfpmacros.h ++++ b/arch/arm/include/asm/vfpmacros.h +@@ -28,7 +28,7 @@ + ldr \tmp, =elf_hwcap @ may not have MVFR regs + ldr \tmp, [\tmp, #0] + tst \tmp, #HWCAP_VFPv3D16 +- ldceq p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} ++ ldceql p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} + addne \base, \base, #32*4 @ step over unused register space + #else + VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 +@@ -52,7 +52,7 @@ + ldr \tmp, =elf_hwcap @ may not have MVFR regs + ldr \tmp, [\tmp, #0] + tst \tmp, #HWCAP_VFPv3D16 +- stceq p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} ++ stceql p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} + addne \base, \base, #32*4 @ step over unused register space + #else + VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 +diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c +index 1d1710e..bfa0eeb 100644 +--- a/arch/arm/kernel/smp.c ++++ b/arch/arm/kernel/smp.c +@@ -295,18 +295,24 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid) + asmlinkage void __cpuinit secondary_start_kernel(void) + { + struct mm_struct *mm = &init_mm; +- unsigned int cpu = smp_processor_id(); ++ unsigned int cpu; ++ ++ /* ++ * The identity mapping is uncached (strongly ordered), so ++ * switch away from it before attempting any exclusive accesses. ++ */ ++ cpu_switch_mm(mm->pgd, mm); ++ enter_lazy_tlb(mm, current); ++ local_flush_tlb_all(); + + /* + * All kernel threads share the same mm context; grab a + * reference and switch to it. + */ ++ cpu = smp_processor_id(); + atomic_inc(&mm->mm_count); + current->active_mm = mm; + cpumask_set_cpu(cpu, mm_cpumask(mm)); +- cpu_switch_mm(mm->pgd, mm); +- enter_lazy_tlb(mm, current); +- local_flush_tlb_all(); + + printk("CPU%u: Booted secondary processor\n", cpu); + +diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c +index f4546e9..23817a6 100644 +--- a/arch/mips/kernel/kgdb.c ++++ b/arch/mips/kernel/kgdb.c +@@ -283,6 +283,15 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd, + struct pt_regs *regs = args->regs; + int trap = (regs->cp0_cause & 0x7c) >> 2; + ++#ifdef CONFIG_KPROBES ++ /* ++ * Return immediately if the kprobes fault notifier has set ++ * DIE_PAGE_FAULT. ++ */ ++ if (cmd == DIE_PAGE_FAULT) ++ return NOTIFY_DONE; ++#endif /* CONFIG_KPROBES */ ++ + /* Userspace events, ignore. */ + if (user_mode(regs)) + return NOTIFY_DONE; +diff --git a/arch/s390/boot/compressed/vmlinux.lds.S b/arch/s390/boot/compressed/vmlinux.lds.S +index d80f79d..8e1fb82 100644 +--- a/arch/s390/boot/compressed/vmlinux.lds.S ++++ b/arch/s390/boot/compressed/vmlinux.lds.S +@@ -5,7 +5,7 @@ OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") + OUTPUT_ARCH(s390:64-bit) + #else + OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390") +-OUTPUT_ARCH(s390) ++OUTPUT_ARCH(s390:31-bit) + #endif + + ENTRY(startup) +diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S +index e4c79eb..e43d21e 100644 +--- a/arch/s390/kernel/vmlinux.lds.S ++++ b/arch/s390/kernel/vmlinux.lds.S +@@ -8,7 +8,7 @@ + + #ifndef CONFIG_64BIT + OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390") +-OUTPUT_ARCH(s390) ++OUTPUT_ARCH(s390:31-bit) + ENTRY(_start) + jiffies = jiffies_64 + 4; + #else +diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c +index 614da62..3c8f220 100644 +--- a/arch/sparc/kernel/perf_event.c ++++ b/arch/sparc/kernel/perf_event.c +@@ -555,11 +555,13 @@ static u64 nop_for_index(int idx) + + static inline void sparc_pmu_enable_event(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc, int idx) + { +- u64 val, mask = mask_for_index(idx); ++ u64 enc, val, mask = mask_for_index(idx); ++ ++ enc = perf_event_get_enc(cpuc->events[idx]); + + val = cpuc->pcr; + val &= ~mask; +- val |= hwc->config; ++ val |= event_encoding(enc, idx); + cpuc->pcr = val; + + pcr_ops->write(cpuc->pcr); +@@ -1422,8 +1424,6 @@ static void perf_callchain_user_64(struct perf_callchain_entry *entry, + { + unsigned long ufp; + +- perf_callchain_store(entry, regs->tpc); +- + ufp = regs->u_regs[UREG_I6] + STACK_BIAS; + do { + struct sparc_stackf *usf, sf; +@@ -1444,8 +1444,6 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, + { + unsigned long ufp; + +- perf_callchain_store(entry, regs->tpc); +- + ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; + do { + struct sparc_stackf32 *usf, sf; +@@ -1464,6 +1462,11 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, + void + perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) + { ++ perf_callchain_store(entry, regs->tpc); ++ ++ if (!current->mm) ++ return; ++ + flushw_user(); + if (test_thread_flag(TIF_32BIT)) + perf_callchain_user_32(entry, regs); +diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c +index 441521a..5e4252b 100644 +--- a/arch/sparc/kernel/sys_sparc_64.c ++++ b/arch/sparc/kernel/sys_sparc_64.c +@@ -519,12 +519,12 @@ SYSCALL_DEFINE1(sparc64_personality, unsigned long, personality) + { + int ret; + +- if (current->personality == PER_LINUX32 && +- personality == PER_LINUX) +- personality = PER_LINUX32; ++ if (personality(current->personality) == PER_LINUX32 && ++ personality(personality) == PER_LINUX) ++ personality |= PER_LINUX32; + ret = sys_personality(personality); +- if (ret == PER_LINUX32) +- ret = PER_LINUX; ++ if (personality(ret) == PER_LINUX32) ++ ret &= ~PER_LINUX32; + + return ret; + } +diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S +index 1d7e274..7f5f65d 100644 +--- a/arch/sparc/kernel/syscalls.S ++++ b/arch/sparc/kernel/syscalls.S +@@ -212,24 +212,20 @@ linux_sparc_syscall: + 3: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] + ret_sys_call: + ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3 +- ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc + sra %o0, 0, %o0 + mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2 + sllx %g2, 32, %g2 + +- /* Check if force_successful_syscall_return() +- * was invoked. +- */ +- ldub [%g6 + TI_SYS_NOERROR], %l2 +- brnz,a,pn %l2, 80f +- stb %g0, [%g6 + TI_SYS_NOERROR] +- + cmp %o0, -ERESTART_RESTARTBLOCK + bgeu,pn %xcc, 1f +- andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6 +-80: ++ andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 ++ ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc ++ ++2: ++ stb %g0, [%g6 + TI_SYS_NOERROR] + /* System call success, clear Carry condition code. */ + andn %g3, %g2, %g3 ++3: + stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] + bne,pn %icc, linux_syscall_trace2 + add %l1, 0x4, %l2 ! npc = npc+4 +@@ -238,20 +234,20 @@ ret_sys_call: + stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] + + 1: ++ /* Check if force_successful_syscall_return() ++ * was invoked. ++ */ ++ ldub [%g6 + TI_SYS_NOERROR], %l2 ++ brnz,pn %l2, 2b ++ ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc + /* System call failure, set Carry condition code. + * Also, get abs(errno) to return to the process. + */ +- andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6 + sub %g0, %o0, %o0 +- or %g3, %g2, %g3 + stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] +- stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] +- bne,pn %icc, linux_syscall_trace2 +- add %l1, 0x4, %l2 ! npc = npc+4 +- stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] ++ ba,pt %xcc, 3b ++ or %g3, %g2, %g3 + +- b,pt %xcc, rtrap +- stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] + linux_syscall_trace2: + call syscall_trace_leave + add %sp, PTREGS_OFF, %o0 +diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c +index 8e073d8..6ff4d78 100644 +--- a/arch/sparc/mm/init_64.c ++++ b/arch/sparc/mm/init_64.c +@@ -2118,6 +2118,9 @@ EXPORT_SYMBOL(_PAGE_CACHE); + #ifdef CONFIG_SPARSEMEM_VMEMMAP + unsigned long vmemmap_table[VMEMMAP_SIZE]; + ++static long __meminitdata addr_start, addr_end; ++static int __meminitdata node_start; ++ + int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node) + { + unsigned long vstart = (unsigned long) start; +@@ -2148,15 +2151,30 @@ int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node) + + *vmem_pp = pte_base | __pa(block); + +- printk(KERN_INFO "[%p-%p] page_structs=%lu " +- "node=%d entry=%lu/%lu\n", start, block, nr, +- node, +- addr >> VMEMMAP_CHUNK_SHIFT, +- VMEMMAP_SIZE); ++ /* check to see if we have contiguous blocks */ ++ if (addr_end != addr || node_start != node) { ++ if (addr_start) ++ printk(KERN_DEBUG " [%lx-%lx] on node %d\n", ++ addr_start, addr_end-1, node_start); ++ addr_start = addr; ++ node_start = node; ++ } ++ addr_end = addr + VMEMMAP_CHUNK; + } + } + return 0; + } ++ ++void __meminit vmemmap_populate_print_last(void) ++{ ++ if (addr_start) { ++ printk(KERN_DEBUG " [%lx-%lx] on node %d\n", ++ addr_start, addr_end-1, node_start); ++ addr_start = 0; ++ addr_end = 0; ++ node_start = 0; ++ } ++} + #endif /* CONFIG_SPARSEMEM_VMEMMAP */ + + static void prot_init_common(unsigned long page_none, +diff --git a/arch/tile/Makefile b/arch/tile/Makefile +index 17acce7..04c637c 100644 +--- a/arch/tile/Makefile ++++ b/arch/tile/Makefile +@@ -26,6 +26,10 @@ $(error Set TILERA_ROOT or CROSS_COMPILE when building $(ARCH) on $(HOST_ARCH)) + endif + endif + ++# The tile compiler may emit .eh_frame information for backtracing. ++# In kernel modules, this causes load failures due to unsupported relocations. ++KBUILD_CFLAGS += -fno-asynchronous-unwind-tables ++ + ifneq ($(CONFIG_DEBUG_EXTRA_FLAGS),"") + KBUILD_CFLAGS += $(CONFIG_DEBUG_EXTRA_FLAGS) + endif +diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S +index bcda816..4893d58 100644 +--- a/arch/x86/kernel/entry_32.S ++++ b/arch/x86/kernel/entry_32.S +@@ -1025,7 +1025,7 @@ ENTRY(xen_sysenter_target) + + ENTRY(xen_hypervisor_callback) + CFI_STARTPROC +- pushl_cfi $0 ++ pushl_cfi $-1 /* orig_ax = -1 => not a system call */ + SAVE_ALL + TRACE_IRQS_OFF + +@@ -1067,14 +1067,16 @@ ENTRY(xen_failsafe_callback) + 2: mov 8(%esp),%es + 3: mov 12(%esp),%fs + 4: mov 16(%esp),%gs ++ /* EAX == 0 => Category 1 (Bad segment) ++ EAX != 0 => Category 2 (Bad IRET) */ + testl %eax,%eax + popl_cfi %eax + lea 16(%esp),%esp + CFI_ADJUST_CFA_OFFSET -16 + jz 5f + addl $16,%esp +- jmp iret_exc # EAX != 0 => Category 2 (Bad IRET) +-5: pushl_cfi $0 # EAX == 0 => Category 1 (Bad segment) ++ jmp iret_exc ++5: pushl_cfi $-1 /* orig_ax = -1 => not a system call */ + SAVE_ALL + jmp ret_from_exception + CFI_ENDPROC +diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S +index faf8d5e..6274f5f 100644 +--- a/arch/x86/kernel/entry_64.S ++++ b/arch/x86/kernel/entry_64.S +@@ -1303,7 +1303,7 @@ ENTRY(xen_failsafe_callback) + CFI_RESTORE r11 + addq $0x30,%rsp + CFI_ADJUST_CFA_OFFSET -0x30 +- pushq_cfi $0 ++ pushq_cfi $-1 /* orig_ax = -1 => not a system call */ + SAVE_ALL + jmp error_exit + CFI_ENDPROC +diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c +index 75f9528..6bc0899 100644 +--- a/arch/x86/oprofile/nmi_int.c ++++ b/arch/x86/oprofile/nmi_int.c +@@ -55,7 +55,7 @@ u64 op_x86_get_ctrl(struct op_x86_model_spec const *model, + val |= counter_config->extra; + event &= model->event_mask ? model->event_mask : 0xFF; + val |= event & 0xFF; +- val |= (event & 0x0F00) << 24; ++ val |= (u64)(event & 0x0F00) << 24; + + return val; + } +diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c +index a1e21ae..69b9ef6 100644 +--- a/arch/x86/xen/enlighten.c ++++ b/arch/x86/xen/enlighten.c +@@ -818,7 +818,16 @@ static void xen_write_cr4(unsigned long cr4) + + native_write_cr4(cr4); + } +- ++#ifdef CONFIG_X86_64 ++static inline unsigned long xen_read_cr8(void) ++{ ++ return 0; ++} ++static inline void xen_write_cr8(unsigned long val) ++{ ++ BUG_ON(val); ++} ++#endif + static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) + { + int ret; +@@ -987,6 +996,11 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = { + .read_cr4_safe = native_read_cr4_safe, + .write_cr4 = xen_write_cr4, + ++#ifdef CONFIG_X86_64 ++ .read_cr8 = xen_read_cr8, ++ .write_cr8 = xen_write_cr8, ++#endif ++ + .wbinvd = native_wbinvd, + + .read_msr = native_read_msr_safe, +@@ -997,6 +1011,8 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = { + .read_tsc = native_read_tsc, + .read_pmc = native_read_pmc, + ++ .read_tscp = native_read_tscp, ++ + .iret = xen_iret, + .irq_enable_sysexit = xen_sysexit, + #ifdef CONFIG_X86_64 +diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c +index b19a18d..d2519b2 100644 +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -71,9 +71,6 @@ enum ec_command { + #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ + #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ + +-#define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts +- per one transaction */ +- + enum { + EC_FLAGS_QUERY_PENDING, /* Query is pending */ + EC_FLAGS_GPE_STORM, /* GPE storm detected */ +@@ -87,6 +84,15 @@ static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY; + module_param(ec_delay, uint, 0644); + MODULE_PARM_DESC(ec_delay, "Timeout(ms) waited until an EC command completes"); + ++/* ++ * If the number of false interrupts per one transaction exceeds ++ * this threshold, will think there is a GPE storm happened and ++ * will disable the GPE for normal transaction. ++ */ ++static unsigned int ec_storm_threshold __read_mostly = 8; ++module_param(ec_storm_threshold, uint, 0644); ++MODULE_PARM_DESC(ec_storm_threshold, "Maxim false GPE numbers not considered as GPE storm"); ++ + /* If we find an EC via the ECDT, we need to keep a ptr to its context */ + /* External interfaces use first EC only, so remember */ + typedef int (*acpi_ec_query_func) (void *data); +@@ -319,7 +325,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) + msleep(1); + /* It is safe to enable the GPE outside of the transaction. */ + acpi_enable_gpe(NULL, ec->gpe); +- } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) { ++ } else if (t->irq_count > ec_storm_threshold) { + pr_info(PREFIX "GPE storm detected, " + "transactions will use polling mode\n"); + set_bit(EC_FLAGS_GPE_STORM, &ec->flags); +@@ -914,6 +920,17 @@ static int ec_flag_msi(const struct dmi_system_id *id) + return 0; + } + ++/* ++ * Clevo M720 notebook actually works ok with IRQ mode, if we lifted ++ * the GPE storm threshold back to 20 ++ */ ++static int ec_enlarge_storm_threshold(const struct dmi_system_id *id) ++{ ++ pr_debug("Setting the EC GPE storm threshold to 20\n"); ++ ec_storm_threshold = 20; ++ return 0; ++} ++ + static struct dmi_system_id __initdata ec_dmi_table[] = { + { + ec_skip_dsdt_scan, "Compal JFL92", { +@@ -945,10 +962,13 @@ static struct dmi_system_id __initdata ec_dmi_table[] = { + { + ec_validate_ecdt, "ASUS hardware", { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc.") }, NULL}, ++ { ++ ec_enlarge_storm_threshold, "CLEVO hardware", { ++ DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "M720T/M730T"),}, NULL}, + {}, + }; + +- + int __init acpi_ec_ecdt_probe(void) + { + acpi_status status; +diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c +index 10f92b3..7a987a7 100644 +--- a/drivers/bcma/main.c ++++ b/drivers/bcma/main.c +@@ -124,9 +124,10 @@ static int bcma_register_cores(struct bcma_bus *bus) + + static void bcma_unregister_cores(struct bcma_bus *bus) + { +- struct bcma_device *core; ++ struct bcma_device *core, *tmp; + +- list_for_each_entry(core, &bus->cores, list) { ++ list_for_each_entry_safe(core, tmp, &bus->cores, list) { ++ list_del(&core->list); + if (core->dev_registered) + device_unregister(&core->dev); + } +diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c +index b366b34..0d91655 100644 +--- a/drivers/char/tpm/tpm.c ++++ b/drivers/char/tpm/tpm.c +@@ -1072,17 +1072,20 @@ ssize_t tpm_write(struct file *file, const char __user *buf, + size_t size, loff_t *off) + { + struct tpm_chip *chip = file->private_data; +- size_t in_size = size, out_size; ++ size_t in_size = size; ++ ssize_t out_size; + + /* cannot perform a write until the read has cleared +- either via tpm_read or a user_read_timer timeout */ +- while (atomic_read(&chip->data_pending) != 0) +- msleep(TPM_TIMEOUT); +- +- mutex_lock(&chip->buffer_mutex); ++ either via tpm_read or a user_read_timer timeout. ++ This also prevents splitted buffered writes from blocking here. ++ */ ++ if (atomic_read(&chip->data_pending) != 0) ++ return -EBUSY; + + if (in_size > TPM_BUFSIZE) +- in_size = TPM_BUFSIZE; ++ return -E2BIG; ++ ++ mutex_lock(&chip->buffer_mutex); + + if (copy_from_user + (chip->data_buffer, (void __user *) buf, in_size)) { +@@ -1092,6 +1095,10 @@ ssize_t tpm_write(struct file *file, const char __user *buf, + + /* atomic tpm command send and result receive */ + out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE); ++ if (out_size < 0) { ++ mutex_unlock(&chip->buffer_mutex); ++ return out_size; ++ } + + atomic_set(&chip->data_pending, out_size); + mutex_unlock(&chip->buffer_mutex); +diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c +index b7fe343..f6cd315 100644 +--- a/drivers/cpufreq/powernow-k8.c ++++ b/drivers/cpufreq/powernow-k8.c +@@ -1216,14 +1216,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, + struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq, + .relation = relation }; + +- /* +- * Must run on @pol->cpu. cpufreq core is responsible for ensuring +- * that we're bound to the current CPU and pol->cpu stays online. +- */ +- if (smp_processor_id() == pol->cpu) +- return powernowk8_target_fn(&pta); +- else +- return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); ++ return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); + } + + /* Driver entry point to verify the policy and range of frequencies */ +diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c +index c9eee6d..a9d5482 100644 +--- a/drivers/edac/amd64_edac.c ++++ b/drivers/edac/amd64_edac.c +@@ -170,8 +170,11 @@ static int __amd64_set_scrub_rate(struct pci_dev *ctl, u32 new_bw, u32 min_rate) + * memory controller and apply to register. Search for the first + * bandwidth entry that is greater or equal than the setting requested + * and program that. If at last entry, turn off DRAM scrubbing. ++ * ++ * If no suitable bandwidth is found, turn off DRAM scrubbing entirely ++ * by falling back to the last element in scrubrates[]. + */ +- for (i = 0; i < ARRAY_SIZE(scrubrates); i++) { ++ for (i = 0; i < ARRAY_SIZE(scrubrates) - 1; i++) { + /* + * skip scrub rates which aren't recommended + * (see F10 BKDG, F3x58) +@@ -181,12 +184,6 @@ static int __amd64_set_scrub_rate(struct pci_dev *ctl, u32 new_bw, u32 min_rate) + + if (scrubrates[i].bandwidth <= new_bw) + break; +- +- /* +- * if no suitable bandwidth found, turn off DRAM scrubbing +- * entirely by falling back to the last element in the +- * scrubrates array. +- */ + } + + scrubval = scrubrates[i].scrubval; +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 33e1555..dbe4dbe 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -999,6 +999,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, + if (obj->phys_obj) + ret = i915_gem_phys_pwrite(dev, obj, args, file); + else if (obj->gtt_space && ++ obj->tiling_mode == I915_TILING_NONE && + obj->base.write_domain != I915_GEM_DOMAIN_CPU) { + ret = i915_gem_object_pin(obj, 0, true); + if (ret) +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index f07bde2..57152a7 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -771,6 +771,14 @@ static const struct dmi_system_id intel_no_lvds[] = { + DMI_MATCH(DMI_BOARD_NAME, "MS-7469"), + }, + }, ++ { ++ .callback = intel_no_lvds_dmi_callback, ++ .ident = "ZOTAC ZBOXSD-ID12/ID13", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "ZOTAC"), ++ DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"), ++ }, ++ }, + + { } /* terminating entry */ + }; +diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +index 2f46e0c..3ad3cc6 100644 +--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c ++++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +@@ -973,11 +973,7 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, + static void radeon_ext_tmds_enc_destroy(struct drm_encoder *encoder) + { + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); +- struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv; +- if (tmds) { +- if (tmds->i2c_bus) +- radeon_i2c_destroy(tmds->i2c_bus); +- } ++ /* don't destroy the i2c bus record here, this will be done in radeon_i2c_fini */ + kfree(radeon_encoder->enc_priv); + drm_encoder_cleanup(encoder); + kfree(radeon_encoder); +diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c +index 4065374..f4c3d28 100644 +--- a/drivers/hv/channel.c ++++ b/drivers/hv/channel.c +@@ -146,14 +146,14 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, + + if (ret != 0) { + err = ret; +- goto errorout; ++ goto error0; + } + + ret = hv_ringbuffer_init( + &newchannel->inbound, in, recv_ringbuffer_size); + if (ret != 0) { + err = ret; +- goto errorout; ++ goto error0; + } + + +@@ -168,7 +168,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, + + if (ret != 0) { + err = ret; +- goto errorout; ++ goto error0; + } + + /* Create and init the channel open message */ +@@ -177,7 +177,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, + GFP_KERNEL); + if (!open_info) { + err = -ENOMEM; +- goto errorout; ++ goto error0; + } + + init_completion(&open_info->waitevent); +@@ -193,7 +193,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, + + if (userdatalen > MAX_USER_DEFINED_BYTES) { + err = -EINVAL; +- goto errorout; ++ goto error0; + } + + if (userdatalen) +@@ -208,19 +208,18 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, + sizeof(struct vmbus_channel_open_channel)); + + if (ret != 0) +- goto cleanup; ++ goto error1; + + t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ); + if (t == 0) { + err = -ETIMEDOUT; +- goto errorout; ++ goto error1; + } + + + if (open_info->response.open_result.status) + err = open_info->response.open_result.status; + +-cleanup: + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); + list_del(&open_info->msglistentry); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); +@@ -228,9 +227,12 @@ cleanup: + kfree(open_info); + return err; + +-errorout: +- hv_ringbuffer_cleanup(&newchannel->outbound); +- hv_ringbuffer_cleanup(&newchannel->inbound); ++error1: ++ spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); ++ list_del(&open_info->msglistentry); ++ spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); ++ ++error0: + free_pages((unsigned long)out, + get_order(send_ringbuffer_size + recv_ringbuffer_size)); + kfree(open_info); +diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c +index 0634ee5..8f67c4d 100644 +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -2641,7 +2641,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, + else { + bad_sectors -= (sector - first_bad); + if (max_sync > bad_sectors) +- max_sync = max_sync; ++ max_sync = bad_sectors; + continue; + } + } +diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c +index 0b3e481..eab0641 100644 +--- a/drivers/media/video/au0828/au0828-video.c ++++ b/drivers/media/video/au0828/au0828-video.c +@@ -1692,14 +1692,18 @@ static int vidioc_streamoff(struct file *file, void *priv, + (AUVI_INPUT(i).audio_setup)(dev, 0); + } + +- videobuf_streamoff(&fh->vb_vidq); +- res_free(fh, AU0828_RESOURCE_VIDEO); ++ if (res_check(fh, AU0828_RESOURCE_VIDEO)) { ++ videobuf_streamoff(&fh->vb_vidq); ++ res_free(fh, AU0828_RESOURCE_VIDEO); ++ } + } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { + dev->vbi_timeout_running = 0; + del_timer_sync(&dev->vbi_timeout); + +- videobuf_streamoff(&fh->vb_vbiq); +- res_free(fh, AU0828_RESOURCE_VBI); ++ if (res_check(fh, AU0828_RESOURCE_VBI)) { ++ videobuf_streamoff(&fh->vb_vbiq); ++ res_free(fh, AU0828_RESOURCE_VBI); ++ } + } + + return 0; +diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c +index 3ed9c5e..daed698 100644 +--- a/drivers/mtd/nand/nand_base.c ++++ b/drivers/mtd/nand/nand_base.c +@@ -2903,9 +2903,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, + if (le16_to_cpu(p->features) & 1) + *busw = NAND_BUSWIDTH_16; + +- chip->options &= ~NAND_CHIPOPTIONS_MSK; +- chip->options |= (NAND_NO_READRDY | +- NAND_NO_AUTOINCR) & NAND_CHIPOPTIONS_MSK; ++ chip->options |= NAND_NO_READRDY | NAND_NO_AUTOINCR; + + return 1; + } +@@ -3069,9 +3067,8 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, + mtd->erasesize <<= ((id_data[3] & 0x03) << 1); + } + } +- /* Get chip options, preserve non chip based options */ +- chip->options &= ~NAND_CHIPOPTIONS_MSK; +- chip->options |= type->options & NAND_CHIPOPTIONS_MSK; ++ /* Get chip options */ ++ chip->options |= type->options; + + /* + * Check if chip is not a Samsung device. Do not clear the +diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c +index c5f6b0e..6546191 100644 +--- a/drivers/net/ethernet/intel/e1000/e1000_main.c ++++ b/drivers/net/ethernet/intel/e1000/e1000_main.c +@@ -168,6 +168,8 @@ static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter, + + static bool e1000_vlan_used(struct e1000_adapter *adapter); + static void e1000_vlan_mode(struct net_device *netdev, u32 features); ++static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter, ++ bool filter_on); + static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid); + static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid); + static void e1000_restore_vlan(struct e1000_adapter *adapter); +@@ -1219,7 +1221,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, + if (err) + goto err_register; + +- e1000_vlan_mode(netdev, netdev->features); ++ e1000_vlan_filter_on_off(adapter, false); + + /* print bus type/speed/width info */ + e_info(probe, "(PCI%s:%dMHz:%d-bit) %pM\n", +@@ -4553,6 +4555,21 @@ static bool e1000_vlan_used(struct e1000_adapter *adapter) + return false; + } + ++static void __e1000_vlan_mode(struct e1000_adapter *adapter, u32 features) ++{ ++ struct e1000_hw *hw = &adapter->hw; ++ u32 ctrl; ++ ++ ctrl = er32(CTRL); ++ if (features & NETIF_F_HW_VLAN_RX) { ++ /* enable VLAN tag insert/strip */ ++ ctrl |= E1000_CTRL_VME; ++ } else { ++ /* disable VLAN tag insert/strip */ ++ ctrl &= ~E1000_CTRL_VME; ++ } ++ ew32(CTRL, ctrl); ++} + static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter, + bool filter_on) + { +@@ -4562,6 +4579,7 @@ static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter, + if (!test_bit(__E1000_DOWN, &adapter->flags)) + e1000_irq_disable(adapter); + ++ __e1000_vlan_mode(adapter, adapter->netdev->features); + if (filter_on) { + /* enable VLAN receive filtering */ + rctl = er32(RCTL); +@@ -4584,21 +4602,11 @@ static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter, + static void e1000_vlan_mode(struct net_device *netdev, u32 features) + { + struct e1000_adapter *adapter = netdev_priv(netdev); +- struct e1000_hw *hw = &adapter->hw; +- u32 ctrl; + + if (!test_bit(__E1000_DOWN, &adapter->flags)) + e1000_irq_disable(adapter); + +- ctrl = er32(CTRL); +- if (features & NETIF_F_HW_VLAN_RX) { +- /* enable VLAN tag insert/strip */ +- ctrl |= E1000_CTRL_VME; +- } else { +- /* disable VLAN tag insert/strip */ +- ctrl &= ~E1000_CTRL_VME; +- } +- ew32(CTRL, ctrl); ++ __e1000_vlan_mode(adapter, features); + + if (!test_bit(__E1000_DOWN, &adapter->flags)) + e1000_irq_enable(adapter); +diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c +index dea0cb4..57be855 100644 +--- a/drivers/net/ethernet/marvell/skge.c ++++ b/drivers/net/ethernet/marvell/skge.c +@@ -4143,6 +4143,13 @@ static struct dmi_system_id skge_32bit_dma_boards[] = { + DMI_MATCH(DMI_BOARD_NAME, "nForce"), + }, + }, ++ { ++ .ident = "ASUS P5NSLI", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), ++ DMI_MATCH(DMI_BOARD_NAME, "P5NSLI") ++ }, ++ }, + {} + }; + +diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +index 026f9de..cc54153 100644 +--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h ++++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +@@ -835,107 +835,107 @@ static const u32 ar9300_2p2_baseband_core[][2] = { + + static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ +- {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, +- {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, +- {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, ++ {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, ++ {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, ++ {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, + {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, + {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, +- {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202}, +- {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400}, +- {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402}, +- {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404}, +- {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603}, +- {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02}, +- {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04}, +- {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20}, +- {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20}, +- {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22}, +- {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24}, +- {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640}, +- {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660}, +- {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861}, +- {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81}, +- {0x0000a54c, 0x5a08442e, 0x5a08442e, 0x47001a83, 0x47001a83}, +- {0x0000a550, 0x5e0a4431, 0x5e0a4431, 0x4a001c84, 0x4a001c84}, +- {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3}, +- {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5}, +- {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9}, +- {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb}, +- {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, ++ {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, ++ {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, ++ {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402}, ++ {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, ++ {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, ++ {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, ++ {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, ++ {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, ++ {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, ++ {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, ++ {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, ++ {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, ++ {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, ++ {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861}, ++ {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81}, ++ {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83}, ++ {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84}, ++ {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3}, ++ {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5}, ++ {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9}, ++ {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb}, ++ {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, ++ {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, ++ {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, ++ {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, ++ {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, ++ {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, ++ {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, + {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, + {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, + {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, +- {0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202}, +- {0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400}, +- {0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402}, +- {0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404}, +- {0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603}, +- {0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02}, +- {0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04}, +- {0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20}, +- {0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20}, +- {0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22}, +- {0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24}, +- {0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640}, +- {0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660}, +- {0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861}, +- {0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81}, +- {0x0000a5cc, 0x5a88442e, 0x5a88442e, 0x47801a83, 0x47801a83}, +- {0x0000a5d0, 0x5e8a4431, 0x5e8a4431, 0x4a801c84, 0x4a801c84}, +- {0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3}, +- {0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5}, +- {0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9}, +- {0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb}, +- {0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, +- {0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, +- {0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, +- {0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, +- {0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, +- {0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, +- {0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, ++ {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, ++ {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, ++ {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402}, ++ {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404}, ++ {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, ++ {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, ++ {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, ++ {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, ++ {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, ++ {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, ++ {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, ++ {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, ++ {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, ++ {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861}, ++ {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81}, ++ {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83}, ++ {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84}, ++ {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3}, ++ {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5}, ++ {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9}, ++ {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb}, ++ {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, ++ {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, ++ {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, ++ {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, ++ {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, ++ {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, ++ {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, +- {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, +- {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, +- {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000}, +- {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501}, +- {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501}, +- {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03}, +- {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, +- {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04}, +- {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, +- {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, +- {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, +- {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, +- {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, +- {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, +- {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, +- {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, ++ {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000}, ++ {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501}, ++ {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501}, ++ {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03}, ++ {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04}, ++ {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04}, ++ {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, ++ {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, ++ {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, ++ {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, ++ {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, ++ {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, ++ {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, ++ {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, +- {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, +- {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, +- {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, ++ {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, ++ {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, ++ {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, + {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, +- {0x00016048, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, ++ {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, +- {0x00016448, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, ++ {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, +- {0x00016848, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, ++ {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + }; + +diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c +index 56bd370..da567f0 100644 +--- a/drivers/net/wireless/ipw2x00/ipw2200.c ++++ b/drivers/net/wireless/ipw2x00/ipw2200.c +@@ -10463,7 +10463,7 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv, + } else + len = src->len; + +- dst = alloc_skb(len + sizeof(*rt_hdr), GFP_ATOMIC); ++ dst = alloc_skb(len + sizeof(*rt_hdr) + sizeof(u16)*2, GFP_ATOMIC); + if (!dst) + continue; + +diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c +index 9b6b010..4ac4ef0 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-6000.c ++++ b/drivers/net/wireless/iwlwifi/iwl-6000.c +@@ -193,7 +193,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, + * See iwlagn_mac_channel_switch. + */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; +- struct iwl6000_channel_switch_cmd cmd; ++ struct iwl6000_channel_switch_cmd *cmd; + const struct iwl_channel_info *ch_info; + u32 switch_time_in_usec, ucode_switch_time; + u16 ch; +@@ -203,18 +203,25 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, + struct ieee80211_vif *vif = ctx->vif; + struct iwl_host_cmd hcmd = { + .id = REPLY_CHANNEL_SWITCH, +- .len = { sizeof(cmd), }, ++ .len = { sizeof(*cmd), }, + .flags = CMD_SYNC, +- .data = { &cmd, }, ++ .dataflags[0] = IWL_HCMD_DFL_NOCOPY, + }; ++ int err; + +- cmd.band = priv->band == IEEE80211_BAND_2GHZ; ++ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); ++ if (!cmd) ++ return -ENOMEM; ++ ++ hcmd.data[0] = cmd; ++ ++ cmd->band = priv->band == IEEE80211_BAND_2GHZ; + ch = ch_switch->channel->hw_value; + IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", + ctx->active.channel, ch); +- cmd.channel = cpu_to_le16(ch); +- cmd.rxon_flags = ctx->staging.flags; +- cmd.rxon_filter_flags = ctx->staging.filter_flags; ++ cmd->channel = cpu_to_le16(ch); ++ cmd->rxon_flags = ctx->staging.flags; ++ cmd->rxon_filter_flags = ctx->staging.filter_flags; + switch_count = ch_switch->count; + tsf_low = ch_switch->timestamp & 0x0ffffffff; + /* +@@ -230,30 +237,32 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, + switch_count = 0; + } + if (switch_count <= 1) +- cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); ++ cmd->switch_time = cpu_to_le32(priv->ucode_beacon_time); + else { + switch_time_in_usec = + vif->bss_conf.beacon_int * switch_count * TIME_UNIT; + ucode_switch_time = iwl_usecs_to_beacons(priv, + switch_time_in_usec, + beacon_interval); +- cmd.switch_time = iwl_add_beacon_time(priv, +- priv->ucode_beacon_time, +- ucode_switch_time, +- beacon_interval); ++ cmd->switch_time = iwl_add_beacon_time(priv, ++ priv->ucode_beacon_time, ++ ucode_switch_time, ++ beacon_interval); + } + IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", +- cmd.switch_time); ++ cmd->switch_time); + ch_info = iwl_get_channel_info(priv, priv->band, ch); + if (ch_info) +- cmd.expect_beacon = is_channel_radar(ch_info); ++ cmd->expect_beacon = is_channel_radar(ch_info); + else { + IWL_ERR(priv, "invalid channel switch from %u to %u\n", + ctx->active.channel, ch); + return -EFAULT; + } + +- return iwl_trans_send_cmd(trans(priv), &hcmd); ++ err = iwl_trans_send_cmd(trans(priv), &hcmd); ++ kfree(cmd); ++ return err; + } + + static struct iwl_lib_ops iwl6000_lib = { +diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c +index 69ae2fd..b938163 100644 +--- a/drivers/pcmcia/pxa2xx_sharpsl.c ++++ b/drivers/pcmcia/pxa2xx_sharpsl.c +@@ -219,7 +219,7 @@ static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) + sharpsl_pcmcia_init_reset(skt); + } + +-static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = { ++static struct pcmcia_low_level sharpsl_pcmcia_ops = { + .owner = THIS_MODULE, + .hw_init = sharpsl_pcmcia_hw_init, + .hw_shutdown = sharpsl_pcmcia_hw_shutdown, +diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c +index af1e296..21bc1a7 100644 +--- a/drivers/platform/x86/samsung-laptop.c ++++ b/drivers/platform/x86/samsung-laptop.c +@@ -21,6 +21,7 @@ + #include <linux/dmi.h> + #include <linux/platform_device.h> + #include <linux/rfkill.h> ++#include <linux/acpi.h> + + /* + * This driver is needed because a number of Samsung laptops do not hook +@@ -226,6 +227,7 @@ static struct backlight_device *backlight_device; + static struct mutex sabi_mutex; + static struct platform_device *sdev; + static struct rfkill *rfk; ++static bool handle_backlight; + static bool has_stepping_quirk; + + static int force; +@@ -602,6 +604,13 @@ static int __init samsung_init(void) + int retval; + + mutex_init(&sabi_mutex); ++ handle_backlight = true; ++ ++#ifdef CONFIG_ACPI ++ /* Don't handle backlight here if the acpi video already handle it */ ++ if (acpi_video_backlight_support()) ++ handle_backlight = false; ++#endif + + if (!force && !dmi_check_system(samsung_dmi_table)) + return -ENODEV; +@@ -661,7 +670,8 @@ static int __init samsung_init(void) + printk(KERN_DEBUG "ifaceP = 0x%08x\n", ifaceP); + printk(KERN_DEBUG "sabi_iface = %p\n", sabi_iface); + +- test_backlight(); ++ if (handle_backlight) ++ test_backlight(); + test_wireless(); + + retval = sabi_get_command(sabi_config->commands.get_brightness, +@@ -680,13 +690,23 @@ static int __init samsung_init(void) + } + + /* Check for stepping quirk */ +- check_for_stepping_quirk(); ++ if (handle_backlight) ++ check_for_stepping_quirk(); ++ ++#ifdef CONFIG_ACPI ++ /* Only log that if we are really on a sabi platform */ ++ if (acpi_video_backlight_support()) ++ pr_info("Backlight controlled by ACPI video driver\n"); ++#endif + + /* knock up a platform device to hang stuff off of */ + sdev = platform_device_register_simple("samsung", -1, NULL, 0); + if (IS_ERR(sdev)) + goto error_no_platform; + ++ if (!handle_backlight) ++ goto skip_backlight; ++ + /* create a backlight device to talk to this one */ + memset(&props, 0, sizeof(struct backlight_properties)); + props.type = BACKLIGHT_PLATFORM; +@@ -702,6 +722,7 @@ static int __init samsung_init(void) + backlight_device->props.power = FB_BLANK_UNBLANK; + backlight_update_status(backlight_device); + ++skip_backlight: + retval = init_wireless(sdev); + if (retval) + goto error_no_rfk; +diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c +index d93a960..bc744b4 100644 +--- a/drivers/rtc/rtc-imxdi.c ++++ b/drivers/rtc/rtc-imxdi.c +@@ -392,6 +392,8 @@ static int dryice_rtc_probe(struct platform_device *pdev) + if (imxdi->ioaddr == NULL) + return -ENOMEM; + ++ spin_lock_init(&imxdi->irq_lock); ++ + imxdi->irq = platform_get_irq(pdev, 0); + if (imxdi->irq < 0) + return imxdi->irq; +diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c +index 6888b2c..b3a729c 100644 +--- a/drivers/scsi/scsi_debug.c ++++ b/drivers/scsi/scsi_debug.c +@@ -2045,8 +2045,7 @@ static void unmap_region(sector_t lba, unsigned int len) + block = lba + alignment; + rem = do_div(block, granularity); + +- if (rem == 0 && lba + granularity <= end && +- block < map_size) ++ if (rem == 0 && lba + granularity < end && block < map_size) + clear_bit(block, map_storep); + + lba += granularity - rem; +diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c +index 48246cd..b4311bf 100644 +--- a/drivers/staging/comedi/drivers/amplc_pc236.c ++++ b/drivers/staging/comedi/drivers/amplc_pc236.c +@@ -470,7 +470,7 @@ static int pc236_detach(struct comedi_device *dev) + { + printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, + PC236_DRIVER_NAME); +- if (devpriv) ++ if (dev->iobase) + pc236_intr_disable(dev); + + if (dev->irq) +diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c +index ae8c33e..abc5ac5 100644 +--- a/drivers/staging/hv/storvsc_drv.c ++++ b/drivers/staging/hv/storvsc_drv.c +@@ -1043,7 +1043,12 @@ static int storvsc_host_reset(struct hv_device *device) + /* + * At this point, all outstanding requests in the adapter + * should have been flushed out and return to us ++ * There is a potential race here where the host may be in ++ * the process of responding when we return from here. ++ * Just wait for all in-transit packets to be accounted for ++ * before we return from here. + */ ++ storvsc_wait_to_drain(stor_device); + + cleanup: + return ret; +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index dbf7d20..df7f15d 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -760,10 +760,6 @@ static const __u32 acm_tty_speed[] = { + 2500000, 3000000, 3500000, 4000000 + }; + +-static const __u8 acm_tty_size[] = { +- 5, 6, 7, 8 +-}; +- + static void acm_tty_set_termios(struct tty_struct *tty, + struct ktermios *termios_old) + { +@@ -780,7 +776,21 @@ static void acm_tty_set_termios(struct tty_struct *tty, + newline.bParityType = termios->c_cflag & PARENB ? + (termios->c_cflag & PARODD ? 1 : 2) + + (termios->c_cflag & CMSPAR ? 2 : 0) : 0; +- newline.bDataBits = acm_tty_size[(termios->c_cflag & CSIZE) >> 4]; ++ switch (termios->c_cflag & CSIZE) { ++ case CS5: ++ newline.bDataBits = 5; ++ break; ++ case CS6: ++ newline.bDataBits = 6; ++ break; ++ case CS7: ++ newline.bDataBits = 7; ++ break; ++ case CS8: ++ default: ++ newline.bDataBits = 8; ++ break; ++ } + /* FIXME: Needs to clear unsupported bits in the termios */ + acm->clocal = ((termios->c_cflag & CLOCAL) != 0); + +@@ -1172,7 +1182,7 @@ made_compressed_probe: + + if (usb_endpoint_xfer_int(epwrite)) + usb_fill_int_urb(snd->urb, usb_dev, +- usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), ++ usb_sndintpipe(usb_dev, epwrite->bEndpointAddress), + NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval); + else + usb_fill_bulk_urb(snd->urb, usb_dev, +@@ -1496,6 +1506,9 @@ static const struct usb_device_id acm_ids[] = { + Maybe we should define a new + quirk for this. */ + }, ++ { USB_DEVICE(0x0572, 0x1340), /* Conexant CX93010-2x UCMxx */ ++ .driver_info = NO_UNION_NORMAL, ++ }, + { USB_DEVICE(0x1bbb, 0x0003), /* Alcatel OT-I650 */ + .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ + }, +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 52340cc..a9a74d2 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -482,13 +482,16 @@ static void hub_tt_work(struct work_struct *work) + int limit = 100; + + spin_lock_irqsave (&hub->tt.lock, flags); +- while (--limit && !list_empty (&hub->tt.clear_list)) { ++ while (!list_empty(&hub->tt.clear_list)) { + struct list_head *next; + struct usb_tt_clear *clear; + struct usb_device *hdev = hub->hdev; + const struct hc_driver *drv; + int status; + ++ if (!hub->quiescing && --limit < 0) ++ break; ++ + next = hub->tt.clear_list.next; + clear = list_entry (next, struct usb_tt_clear, clear_list); + list_del (&clear->clear_list); +@@ -952,7 +955,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) + if (hub->has_indicators) + cancel_delayed_work_sync(&hub->leds); + if (hub->tt.hub) +- cancel_work_sync(&hub->tt.clear_work); ++ flush_work_sync(&hub->tt.clear_work); + } + + /* caller has locked the hub device */ +diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c +index d0ec2f0..c2815a5 100644 +--- a/drivers/usb/host/pci-quirks.c ++++ b/drivers/usb/host/pci-quirks.c +@@ -545,7 +545,14 @@ static const struct dmi_system_id __devinitconst ehci_dmi_nohandoff_table[] = { + /* Pegatron Lucid (Ordissimo AIRIS) */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "M11JB"), +- DMI_MATCH(DMI_BIOS_VERSION, "Lucid-GE-133"), ++ DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"), ++ }, ++ }, ++ { ++ /* Pegatron Lucid (Ordissimo) */ ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "Ordissimo"), ++ DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"), + }, + }, + { } +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index 950aef8..0c6fb19 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1212,6 +1212,17 @@ static void xhci_cmd_to_noop(struct xhci_hcd *xhci, struct xhci_cd *cur_cd) + cur_seg = find_trb_seg(xhci->cmd_ring->first_seg, + xhci->cmd_ring->dequeue, &cycle_state); + ++ if (!cur_seg) { ++ xhci_warn(xhci, "Command ring mismatch, dequeue = %p %llx (dma)\n", ++ xhci->cmd_ring->dequeue, ++ (unsigned long long) ++ xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, ++ xhci->cmd_ring->dequeue)); ++ xhci_debug_ring(xhci, xhci->cmd_ring); ++ xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); ++ return; ++ } ++ + /* find the command trb matched by cd from command ring */ + for (cmd_trb = xhci->cmd_ring->dequeue; + cmd_trb != xhci->cmd_ring->enqueue; +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index f5c0f38..5a23f4d 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -471,7 +471,8 @@ static bool compliance_mode_recovery_timer_quirk_check(void) + + if (strstr(dmi_product_name, "Z420") || + strstr(dmi_product_name, "Z620") || +- strstr(dmi_product_name, "Z820")) ++ strstr(dmi_product_name, "Z820") || ++ strstr(dmi_product_name, "Z1")) + return true; + + return false; +diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c +index 42de17b..d3addb2 100644 +--- a/drivers/usb/serial/mct_u232.c ++++ b/drivers/usb/serial/mct_u232.c +@@ -577,12 +577,14 @@ static void mct_u232_close(struct usb_serial_port *port) + { + dbg("%s port %d", __func__, port->number); + +- if (port->serial->dev) { +- /* shutdown our urbs */ +- usb_kill_urb(port->write_urb); +- usb_kill_urb(port->read_urb); +- usb_kill_urb(port->interrupt_in_urb); +- } ++ /* ++ * Must kill the read urb as it is actually an interrupt urb, which ++ * generic close thus fails to kill. ++ */ ++ usb_kill_urb(port->read_urb); ++ usb_kill_urb(port->interrupt_in_urb); ++ ++ usb_serial_generic_close(port); + } /* mct_u232_close */ + + +diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c +index b150ed9..d481f80 100644 +--- a/drivers/usb/serial/mos7840.c ++++ b/drivers/usb/serial/mos7840.c +@@ -235,12 +235,10 @@ struct moschip_port { + int port_num; /*Actual port number in the device(1,2,etc) */ + struct urb *write_urb; /* write URB for this port */ + struct urb *read_urb; /* read URB for this port */ +- struct urb *int_urb; + __u8 shadowLCR; /* last LCR value received */ + __u8 shadowMCR; /* last MCR value received */ + char open; + char open_ports; +- char zombie; + wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ + wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ + int delta_msr_cond; +@@ -505,7 +503,6 @@ static void mos7840_control_callback(struct urb *urb) + unsigned char *data; + struct moschip_port *mos7840_port; + __u8 regval = 0x0; +- int result = 0; + int status = urb->status; + + mos7840_port = urb->context; +@@ -524,7 +521,7 @@ static void mos7840_control_callback(struct urb *urb) + default: + dbg("%s - nonzero urb status received: %d", __func__, + status); +- goto exit; ++ return; + } + + dbg("%s urb buffer size is %d", __func__, urb->actual_length); +@@ -537,17 +534,6 @@ static void mos7840_control_callback(struct urb *urb) + mos7840_handle_new_msr(mos7840_port, regval); + else if (mos7840_port->MsrLsr == 1) + mos7840_handle_new_lsr(mos7840_port, regval); +- +-exit: +- spin_lock(&mos7840_port->pool_lock); +- if (!mos7840_port->zombie) +- result = usb_submit_urb(mos7840_port->int_urb, GFP_ATOMIC); +- spin_unlock(&mos7840_port->pool_lock); +- if (result) { +- dev_err(&urb->dev->dev, +- "%s - Error %d submitting interrupt urb\n", +- __func__, result); +- } + } + + static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg, +@@ -655,14 +641,7 @@ static void mos7840_interrupt_callback(struct urb *urb) + wreg = MODEM_STATUS_REGISTER; + break; + } +- spin_lock(&mos7840_port->pool_lock); +- if (!mos7840_port->zombie) { +- rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data); +- } else { +- spin_unlock(&mos7840_port->pool_lock); +- return; +- } +- spin_unlock(&mos7840_port->pool_lock); ++ rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data); + } + } + } +@@ -2594,7 +2573,6 @@ error: + kfree(mos7840_port->ctrl_buf); + usb_free_urb(mos7840_port->control_urb); + kfree(mos7840_port); +- serial->port[i] = NULL; + } + return status; + } +@@ -2625,9 +2603,6 @@ static void mos7840_disconnect(struct usb_serial *serial) + mos7840_port = mos7840_get_port_private(serial->port[i]); + dbg ("mos7840_port %d = %p", i, mos7840_port); + if (mos7840_port) { +- spin_lock_irqsave(&mos7840_port->pool_lock, flags); +- mos7840_port->zombie = 1; +- spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); + usb_kill_urb(mos7840_port->control_urb); + } + } +@@ -2661,6 +2636,7 @@ static void mos7840_release(struct usb_serial *serial) + mos7840_port = mos7840_get_port_private(serial->port[i]); + dbg("mos7840_port %d = %p", i, mos7840_port); + if (mos7840_port) { ++ usb_free_urb(mos7840_port->control_urb); + kfree(mos7840_port->ctrl_buf); + kfree(mos7840_port->dr); + kfree(mos7840_port); +diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c +index c248a91..d6c5ed6 100644 +--- a/drivers/usb/serial/opticon.c ++++ b/drivers/usb/serial/opticon.c +@@ -160,7 +160,11 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype, + { + struct usb_serial *serial = port->serial; + int retval; +- u8 buffer[2]; ++ u8 *buffer; ++ ++ buffer = kzalloc(1, GFP_KERNEL); ++ if (!buffer) ++ return -ENOMEM; + + buffer[0] = val; + /* Send the message to the vendor control endpoint +@@ -169,6 +173,7 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype, + requesttype, + USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, + 0, 0, buffer, 1, 0); ++ kfree(buffer); + + return retval; + } +@@ -292,7 +297,7 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, + if (!dr) { + dev_err(&port->dev, "out of memory\n"); + count = -ENOMEM; +- goto error; ++ goto error_no_dr; + } + + dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT; +@@ -322,6 +327,8 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, + + return count; + error: ++ kfree(dr); ++error_no_dr: + usb_free_urb(urb); + error_no_urb: + kfree(buffer); +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 3fd4e6f..c334670 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -503,11 +503,19 @@ static const struct option_blacklist_info net_intf5_blacklist = { + .reserved = BIT(5), + }; + ++static const struct option_blacklist_info net_intf6_blacklist = { ++ .reserved = BIT(6), ++}; ++ + static const struct option_blacklist_info zte_mf626_blacklist = { + .sendsetup = BIT(0) | BIT(1), + .reserved = BIT(4), + }; + ++static const struct option_blacklist_info zte_1255_blacklist = { ++ .reserved = BIT(3) | BIT(4), ++}; ++ + static const struct usb_device_id option_ids[] = { + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, +@@ -853,13 +861,19 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0122, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0142, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) }, +@@ -872,7 +886,8 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) }, +@@ -880,13 +895,22 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0191, 0xff, 0xff, 0xff), /* ZTE EuFi890 */ ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0199, 0xff, 0xff, 0xff), /* ZTE MF820S */ ++ .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0257, 0xff, 0xff, 0xff), /* ZTE MF821 */ ++ .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1021, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, +@@ -1002,18 +1026,24 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1169, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1170, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1244, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1246, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1248, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1249, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1250, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1251, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1253, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&zte_1255_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1257, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1258, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1259, 0xff, 0xff, 0xff) }, +@@ -1058,8 +1088,16 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1401, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1424, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1425, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1426, 0xff, 0xff, 0xff), /* ZTE MF91 */ ++ .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, + 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, +@@ -1071,15 +1109,21 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0170, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, +diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c +index 535d087..e1f1ebd 100644 +--- a/drivers/usb/serial/sierra.c ++++ b/drivers/usb/serial/sierra.c +@@ -171,7 +171,6 @@ static int sierra_probe(struct usb_serial *serial, + { + int result = 0; + struct usb_device *udev; +- struct sierra_intf_private *data; + u8 ifnum; + + udev = serial->dev; +@@ -199,11 +198,6 @@ static int sierra_probe(struct usb_serial *serial, + return -ENODEV; + } + +- data = serial->private = kzalloc(sizeof(struct sierra_intf_private), GFP_KERNEL); +- if (!data) +- return -ENOMEM; +- spin_lock_init(&data->susp_lock); +- + return result; + } + +@@ -915,6 +909,7 @@ static void sierra_dtr_rts(struct usb_serial_port *port, int on) + static int sierra_startup(struct usb_serial *serial) + { + struct usb_serial_port *port; ++ struct sierra_intf_private *intfdata; + struct sierra_port_private *portdata; + struct sierra_iface_info *himemoryp = NULL; + int i; +@@ -922,6 +917,14 @@ static int sierra_startup(struct usb_serial *serial) + + dev_dbg(&serial->dev->dev, "%s\n", __func__); + ++ intfdata = kzalloc(sizeof(*intfdata), GFP_KERNEL); ++ if (!intfdata) ++ return -ENOMEM; ++ ++ spin_lock_init(&intfdata->susp_lock); ++ ++ usb_set_serial_data(serial, intfdata); ++ + /* Set Device mode to D0 */ + sierra_set_power_state(serial->dev, 0x0000); + +@@ -937,7 +940,7 @@ static int sierra_startup(struct usb_serial *serial) + dev_dbg(&port->dev, "%s: kmalloc for " + "sierra_port_private (%d) failed!\n", + __func__, i); +- return -ENOMEM; ++ goto err; + } + spin_lock_init(&portdata->lock); + init_usb_anchor(&portdata->active); +@@ -974,6 +977,14 @@ static int sierra_startup(struct usb_serial *serial) + } + + return 0; ++err: ++ for (--i; i >= 0; --i) { ++ portdata = usb_get_serial_port_data(serial->port[i]); ++ kfree(portdata); ++ } ++ kfree(intfdata); ++ ++ return -ENOMEM; + } + + static void sierra_release(struct usb_serial *serial) +@@ -993,6 +1004,7 @@ static void sierra_release(struct usb_serial *serial) + continue; + kfree(portdata); + } ++ kfree(serial->private); + } + + #ifdef CONFIG_PM +diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c +index 5b073bc..59d646d 100644 +--- a/drivers/usb/serial/whiteheat.c ++++ b/drivers/usb/serial/whiteheat.c +@@ -576,6 +576,7 @@ no_firmware: + "%s: please contact support@connecttech.com\n", + serial->type->description); + kfree(result); ++ kfree(command); + return -ENODEV; + + no_command_private: +diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h +index 591f57f..fa8a1b2 100644 +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -1004,6 +1004,12 @@ UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9999, + USB_SC_8070, USB_PR_CB, NULL, + US_FL_NEED_OVERRIDE | US_FL_FIX_INQUIRY ), + ++/* Submitted by Oleksandr Chumachenko <ledest@gmail.com> */ ++UNUSUAL_DEV( 0x07cf, 0x1167, 0x0100, 0x0100, ++ "Casio", ++ "EX-N1 DigitalCamera", ++ USB_SC_8070, USB_PR_DEVICE, NULL, 0), ++ + /* Submitted by Hartmut Wahl <hwahl@hwahl.de>*/ + UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001, + "Samsung", +diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c +index 882a51f..b76071e 100644 +--- a/drivers/vhost/net.c ++++ b/drivers/vhost/net.c +@@ -371,7 +371,8 @@ static void handle_rx(struct vhost_net *net) + .hdr.gso_type = VIRTIO_NET_HDR_GSO_NONE + }; + size_t total_len = 0; +- int err, headcount, mergeable; ++ int err, mergeable; ++ s16 headcount; + size_t vhost_hlen, sock_hlen; + size_t vhost_len, sock_len; + /* TODO: check that we are running from vhost_worker? */ +diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c +index 41746bb..cb5988f 100644 +--- a/drivers/video/udlfb.c ++++ b/drivers/video/udlfb.c +@@ -646,7 +646,7 @@ static ssize_t dlfb_ops_write(struct fb_info *info, const char __user *buf, + result = fb_sys_write(info, buf, count, ppos); + + if (result > 0) { +- int start = max((int)(offset / info->fix.line_length) - 1, 0); ++ int start = max((int)(offset / info->fix.line_length), 0); + int lines = min((u32)((result / info->fix.line_length) + 1), + (u32)info->var.yres); + +diff --git a/drivers/video/via/via_clock.c b/drivers/video/via/via_clock.c +index af8f26b..db1e392 100644 +--- a/drivers/video/via/via_clock.c ++++ b/drivers/video/via/via_clock.c +@@ -25,6 +25,7 @@ + + #include <linux/kernel.h> + #include <linux/via-core.h> ++#include <asm/olpc.h> + #include "via_clock.h" + #include "global.h" + #include "debug.h" +@@ -289,6 +290,10 @@ static void dummy_set_pll(struct via_pll_config config) + printk(KERN_INFO "Using undocumented set PLL.\n%s", via_slap); + } + ++static void noop_set_clock_state(u8 state) ++{ ++} ++ + void via_clock_init(struct via_clock *clock, int gfx_chip) + { + switch (gfx_chip) { +@@ -346,4 +351,18 @@ void via_clock_init(struct via_clock *clock, int gfx_chip) + break; + + } ++ ++ if (machine_is_olpc()) { ++ /* The OLPC XO-1.5 cannot suspend/resume reliably if the ++ * IGA1/IGA2 clocks are set as on or off (memory rot ++ * occasionally happens during suspend under such ++ * configurations). ++ * ++ * The only known stable scenario is to leave this bits as-is, ++ * which in their default states are documented to enable the ++ * clock only when it is needed. ++ */ ++ clock->set_primary_clock_state = noop_set_clock_state; ++ clock->set_secondary_clock_state = noop_set_clock_state; ++ } + } +diff --git a/fs/ceph/export.c b/fs/ceph/export.c +index 9fbcdec..b001030 100644 +--- a/fs/ceph/export.c ++++ b/fs/ceph/export.c +@@ -91,7 +91,7 @@ static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len, + * FIXME: we should try harder by querying the mds for the ino. + */ + static struct dentry *__fh_to_dentry(struct super_block *sb, +- struct ceph_nfs_fh *fh) ++ struct ceph_nfs_fh *fh, int fh_len) + { + struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc; + struct inode *inode; +@@ -99,6 +99,9 @@ static struct dentry *__fh_to_dentry(struct super_block *sb, + struct ceph_vino vino; + int err; + ++ if (fh_len < sizeof(*fh) / 4) ++ return ERR_PTR(-ESTALE); ++ + dout("__fh_to_dentry %llx\n", fh->ino); + vino.ino = fh->ino; + vino.snap = CEPH_NOSNAP; +@@ -142,7 +145,7 @@ static struct dentry *__fh_to_dentry(struct super_block *sb, + * convert connectable fh to dentry + */ + static struct dentry *__cfh_to_dentry(struct super_block *sb, +- struct ceph_nfs_confh *cfh) ++ struct ceph_nfs_confh *cfh, int fh_len) + { + struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc; + struct inode *inode; +@@ -150,6 +153,9 @@ static struct dentry *__cfh_to_dentry(struct super_block *sb, + struct ceph_vino vino; + int err; + ++ if (fh_len < sizeof(*cfh) / 4) ++ return ERR_PTR(-ESTALE); ++ + dout("__cfh_to_dentry %llx (%llx/%x)\n", + cfh->ino, cfh->parent_ino, cfh->parent_name_hash); + +@@ -199,9 +205,11 @@ static struct dentry *ceph_fh_to_dentry(struct super_block *sb, struct fid *fid, + int fh_len, int fh_type) + { + if (fh_type == 1) +- return __fh_to_dentry(sb, (struct ceph_nfs_fh *)fid->raw); ++ return __fh_to_dentry(sb, (struct ceph_nfs_fh *)fid->raw, ++ fh_len); + else +- return __cfh_to_dentry(sb, (struct ceph_nfs_confh *)fid->raw); ++ return __cfh_to_dentry(sb, (struct ceph_nfs_confh *)fid->raw, ++ fh_len); + } + + /* +@@ -222,6 +230,8 @@ static struct dentry *ceph_fh_to_parent(struct super_block *sb, + + if (fh_type == 1) + return ERR_PTR(-ESTALE); ++ if (fh_len < sizeof(*cfh) / 4) ++ return ERR_PTR(-ESTALE); + + pr_debug("fh_to_parent %llx/%d\n", cfh->parent_ino, + cfh->parent_name_hash); +diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c +index 51352de..f854cf9 100644 +--- a/fs/compat_ioctl.c ++++ b/fs/compat_ioctl.c +@@ -210,6 +210,8 @@ static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, + + err = get_user(palp, &up->palette); + err |= get_user(length, &up->length); ++ if (err) ++ return -EFAULT; + + up_native = compat_alloc_user_space(sizeof(struct video_spu_palette)); + err = put_user(compat_ptr(palp), &up_native->palette); +diff --git a/fs/exec.c b/fs/exec.c +index 160cd2f..121ccae 100644 +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -1095,7 +1095,7 @@ int flush_old_exec(struct linux_binprm * bprm) + bprm->mm = NULL; /* We're using it now */ + + set_fs(USER_DS); +- current->flags &= ~(PF_RANDOMIZE | PF_KTHREAD); ++ current->flags &= ~(PF_RANDOMIZE | PF_KTHREAD | PF_NOFREEZE); + flush_thread(); + current->personality &= ~bprm->per_clear; + +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index 54f2bdc..191580a 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -2715,6 +2715,9 @@ static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex) + #define EXT4_EXT_MARK_UNINIT1 0x2 /* mark first half uninitialized */ + #define EXT4_EXT_MARK_UNINIT2 0x4 /* mark second half uninitialized */ + ++#define EXT4_EXT_DATA_VALID1 0x8 /* first half contains valid data */ ++#define EXT4_EXT_DATA_VALID2 0x10 /* second half contains valid data */ ++ + /* + * ext4_split_extent_at() splits an extent at given block. + * +@@ -2750,6 +2753,9 @@ static int ext4_split_extent_at(handle_t *handle, + unsigned int ee_len, depth; + int err = 0; + ++ BUG_ON((split_flag & (EXT4_EXT_DATA_VALID1 | EXT4_EXT_DATA_VALID2)) == ++ (EXT4_EXT_DATA_VALID1 | EXT4_EXT_DATA_VALID2)); ++ + ext_debug("ext4_split_extents_at: inode %lu, logical" + "block %llu\n", inode->i_ino, (unsigned long long)split); + +@@ -2808,7 +2814,14 @@ static int ext4_split_extent_at(handle_t *handle, + + err = ext4_ext_insert_extent(handle, inode, path, &newex, flags); + if (err == -ENOSPC && (EXT4_EXT_MAY_ZEROOUT & split_flag)) { +- err = ext4_ext_zeroout(inode, &orig_ex); ++ if (split_flag & (EXT4_EXT_DATA_VALID1|EXT4_EXT_DATA_VALID2)) { ++ if (split_flag & EXT4_EXT_DATA_VALID1) ++ err = ext4_ext_zeroout(inode, ex2); ++ else ++ err = ext4_ext_zeroout(inode, ex); ++ } else ++ err = ext4_ext_zeroout(inode, &orig_ex); ++ + if (err) + goto fix_extent_len; + /* update the extent length and mark as initialized */ +@@ -2861,12 +2874,13 @@ static int ext4_split_extent(handle_t *handle, + uninitialized = ext4_ext_is_uninitialized(ex); + + if (map->m_lblk + map->m_len < ee_block + ee_len) { +- split_flag1 = split_flag & EXT4_EXT_MAY_ZEROOUT ? +- EXT4_EXT_MAY_ZEROOUT : 0; ++ split_flag1 = split_flag & EXT4_EXT_MAY_ZEROOUT; + flags1 = flags | EXT4_GET_BLOCKS_PRE_IO; + if (uninitialized) + split_flag1 |= EXT4_EXT_MARK_UNINIT1 | + EXT4_EXT_MARK_UNINIT2; ++ if (split_flag & EXT4_EXT_DATA_VALID2) ++ split_flag1 |= EXT4_EXT_DATA_VALID1; + err = ext4_split_extent_at(handle, inode, path, + map->m_lblk + map->m_len, split_flag1, flags1); + if (err) +@@ -2879,8 +2893,8 @@ static int ext4_split_extent(handle_t *handle, + return PTR_ERR(path); + + if (map->m_lblk >= ee_block) { +- split_flag1 = split_flag & EXT4_EXT_MAY_ZEROOUT ? +- EXT4_EXT_MAY_ZEROOUT : 0; ++ split_flag1 = split_flag & (EXT4_EXT_MAY_ZEROOUT | ++ EXT4_EXT_DATA_VALID2); + if (uninitialized) + split_flag1 |= EXT4_EXT_MARK_UNINIT1; + if (split_flag & EXT4_EXT_MARK_UNINIT2) +@@ -3158,26 +3172,47 @@ static int ext4_split_unwritten_extents(handle_t *handle, + + split_flag |= ee_block + ee_len <= eof_block ? EXT4_EXT_MAY_ZEROOUT : 0; + split_flag |= EXT4_EXT_MARK_UNINIT2; +- ++ if (flags & EXT4_GET_BLOCKS_CONVERT) ++ split_flag |= EXT4_EXT_DATA_VALID2; + flags |= EXT4_GET_BLOCKS_PRE_IO; + return ext4_split_extent(handle, inode, path, map, split_flag, flags); + } + + static int ext4_convert_unwritten_extents_endio(handle_t *handle, +- struct inode *inode, +- struct ext4_ext_path *path) ++ struct inode *inode, ++ struct ext4_map_blocks *map, ++ struct ext4_ext_path *path) + { + struct ext4_extent *ex; ++ ext4_lblk_t ee_block; ++ unsigned int ee_len; + int depth; + int err = 0; + + depth = ext_depth(inode); + ex = path[depth].p_ext; ++ ee_block = le32_to_cpu(ex->ee_block); ++ ee_len = ext4_ext_get_actual_len(ex); + + ext_debug("ext4_convert_unwritten_extents_endio: inode %lu, logical" + "block %llu, max_blocks %u\n", inode->i_ino, +- (unsigned long long)le32_to_cpu(ex->ee_block), +- ext4_ext_get_actual_len(ex)); ++ (unsigned long long)ee_block, ee_len); ++ ++ /* If extent is larger than requested then split is required */ ++ if (ee_block != map->m_lblk || ee_len > map->m_len) { ++ err = ext4_split_unwritten_extents(handle, inode, map, path, ++ EXT4_GET_BLOCKS_CONVERT); ++ if (err < 0) ++ goto out; ++ ext4_ext_drop_refs(path); ++ path = ext4_ext_find_extent(inode, map->m_lblk, path); ++ if (IS_ERR(path)) { ++ err = PTR_ERR(path); ++ goto out; ++ } ++ depth = ext_depth(inode); ++ ex = path[depth].p_ext; ++ } + + err = ext4_ext_get_access(handle, inode, path + depth); + if (err) +@@ -3479,7 +3514,7 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, + } + /* IO end_io complete, convert the filled extent to written */ + if ((flags & EXT4_GET_BLOCKS_CONVERT)) { +- ret = ext4_convert_unwritten_extents_endio(handle, inode, ++ ret = ext4_convert_unwritten_extents_endio(handle, inode, map, + path); + if (ret >= 0) { + ext4_update_inode_fsync_trans(handle, inode, 1); +diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c +index fe9945f..5235d6e 100644 +--- a/fs/gfs2/export.c ++++ b/fs/gfs2/export.c +@@ -167,6 +167,8 @@ static struct dentry *gfs2_fh_to_dentry(struct super_block *sb, struct fid *fid, + case GFS2_SMALL_FH_SIZE: + case GFS2_LARGE_FH_SIZE: + case GFS2_OLD_FH_SIZE: ++ if (fh_len < GFS2_SMALL_FH_SIZE) ++ return NULL; + this.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32; + this.no_formal_ino |= be32_to_cpu(fh[1]); + this.no_addr = ((u64)be32_to_cpu(fh[2])) << 32; +@@ -186,6 +188,8 @@ static struct dentry *gfs2_fh_to_parent(struct super_block *sb, struct fid *fid, + switch (fh_type) { + case GFS2_LARGE_FH_SIZE: + case GFS2_OLD_FH_SIZE: ++ if (fh_len < GFS2_LARGE_FH_SIZE) ++ return NULL; + parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32; + parent.no_formal_ino |= be32_to_cpu(fh[5]); + parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32; +diff --git a/fs/isofs/export.c b/fs/isofs/export.c +index dd4687f..516eb21 100644 +--- a/fs/isofs/export.c ++++ b/fs/isofs/export.c +@@ -179,7 +179,7 @@ static struct dentry *isofs_fh_to_parent(struct super_block *sb, + { + struct isofs_fid *ifid = (struct isofs_fid *)fid; + +- if (fh_type != 2) ++ if (fh_len < 2 || fh_type != 2) + return NULL; + + return isofs_export_iget(sb, +diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c +index 8799207..931bf95 100644 +--- a/fs/jbd/commit.c ++++ b/fs/jbd/commit.c +@@ -86,7 +86,12 @@ nope: + static void release_data_buffer(struct buffer_head *bh) + { + if (buffer_freed(bh)) { ++ WARN_ON_ONCE(buffer_dirty(bh)); + clear_buffer_freed(bh); ++ clear_buffer_mapped(bh); ++ clear_buffer_new(bh); ++ clear_buffer_req(bh); ++ bh->b_bdev = NULL; + release_buffer_page(bh); + } else + put_bh(bh); +@@ -847,17 +852,35 @@ restart_loop: + * there's no point in keeping a checkpoint record for + * it. */ + +- /* A buffer which has been freed while still being +- * journaled by a previous transaction may end up still +- * being dirty here, but we want to avoid writing back +- * that buffer in the future after the "add to orphan" +- * operation been committed, That's not only a performance +- * gain, it also stops aliasing problems if the buffer is +- * left behind for writeback and gets reallocated for another +- * use in a different page. */ +- if (buffer_freed(bh) && !jh->b_next_transaction) { +- clear_buffer_freed(bh); +- clear_buffer_jbddirty(bh); ++ /* ++ * A buffer which has been freed while still being journaled by ++ * a previous transaction. ++ */ ++ if (buffer_freed(bh)) { ++ /* ++ * If the running transaction is the one containing ++ * "add to orphan" operation (b_next_transaction != ++ * NULL), we have to wait for that transaction to ++ * commit before we can really get rid of the buffer. ++ * So just clear b_modified to not confuse transaction ++ * credit accounting and refile the buffer to ++ * BJ_Forget of the running transaction. If the just ++ * committed transaction contains "add to orphan" ++ * operation, we can completely invalidate the buffer ++ * now. We are rather throughout in that since the ++ * buffer may be still accessible when blocksize < ++ * pagesize and it is attached to the last partial ++ * page. ++ */ ++ jh->b_modified = 0; ++ if (!jh->b_next_transaction) { ++ clear_buffer_freed(bh); ++ clear_buffer_jbddirty(bh); ++ clear_buffer_mapped(bh); ++ clear_buffer_new(bh); ++ clear_buffer_req(bh); ++ bh->b_bdev = NULL; ++ } + } + + if (buffer_jbddirty(bh)) { +diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c +index 7e59c6e..edac004 100644 +--- a/fs/jbd/transaction.c ++++ b/fs/jbd/transaction.c +@@ -1839,15 +1839,16 @@ static int __dispose_buffer(struct journal_head *jh, transaction_t *transaction) + * We're outside-transaction here. Either or both of j_running_transaction + * and j_committing_transaction may be NULL. + */ +-static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh) ++static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh, ++ int partial_page) + { + transaction_t *transaction; + struct journal_head *jh; + int may_free = 1; +- int ret; + + BUFFER_TRACE(bh, "entry"); + ++retry: + /* + * It is safe to proceed here without the j_list_lock because the + * buffers cannot be stolen by try_to_free_buffers as long as we are +@@ -1875,10 +1876,18 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh) + * clear the buffer dirty bit at latest at the moment when the + * transaction marking the buffer as freed in the filesystem + * structures is committed because from that moment on the +- * buffer can be reallocated and used by a different page. ++ * block can be reallocated and used by a different page. + * Since the block hasn't been freed yet but the inode has + * already been added to orphan list, it is safe for us to add + * the buffer to BJ_Forget list of the newest transaction. ++ * ++ * Also we have to clear buffer_mapped flag of a truncated buffer ++ * because the buffer_head may be attached to the page straddling ++ * i_size (can happen only when blocksize < pagesize) and thus the ++ * buffer_head can be reused when the file is extended again. So we end ++ * up keeping around invalidated buffers attached to transactions' ++ * BJ_Forget list just to stop checkpointing code from cleaning up ++ * the transaction this buffer was modified in. + */ + transaction = jh->b_transaction; + if (transaction == NULL) { +@@ -1905,13 +1914,9 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh) + * committed, the buffer won't be needed any + * longer. */ + JBUFFER_TRACE(jh, "checkpointed: add to BJ_Forget"); +- ret = __dispose_buffer(jh, ++ may_free = __dispose_buffer(jh, + journal->j_running_transaction); +- journal_put_journal_head(jh); +- spin_unlock(&journal->j_list_lock); +- jbd_unlock_bh_state(bh); +- spin_unlock(&journal->j_state_lock); +- return ret; ++ goto zap_buffer; + } else { + /* There is no currently-running transaction. So the + * orphan record which we wrote for this file must have +@@ -1919,13 +1924,9 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh) + * the committing transaction, if it exists. */ + if (journal->j_committing_transaction) { + JBUFFER_TRACE(jh, "give to committing trans"); +- ret = __dispose_buffer(jh, ++ may_free = __dispose_buffer(jh, + journal->j_committing_transaction); +- journal_put_journal_head(jh); +- spin_unlock(&journal->j_list_lock); +- jbd_unlock_bh_state(bh); +- spin_unlock(&journal->j_state_lock); +- return ret; ++ goto zap_buffer; + } else { + /* The orphan record's transaction has + * committed. We can cleanse this buffer */ +@@ -1946,10 +1947,24 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh) + } + /* + * The buffer is committing, we simply cannot touch +- * it. So we just set j_next_transaction to the +- * running transaction (if there is one) and mark +- * buffer as freed so that commit code knows it should +- * clear dirty bits when it is done with the buffer. ++ * it. If the page is straddling i_size we have to wait ++ * for commit and try again. ++ */ ++ if (partial_page) { ++ tid_t tid = journal->j_committing_transaction->t_tid; ++ ++ journal_put_journal_head(jh); ++ spin_unlock(&journal->j_list_lock); ++ jbd_unlock_bh_state(bh); ++ spin_unlock(&journal->j_state_lock); ++ log_wait_commit(journal, tid); ++ goto retry; ++ } ++ /* ++ * OK, buffer won't be reachable after truncate. We just set ++ * j_next_transaction to the running transaction (if there is ++ * one) and mark buffer as freed so that commit code knows it ++ * should clear dirty bits when it is done with the buffer. + */ + set_buffer_freed(bh); + if (journal->j_running_transaction && buffer_jbddirty(bh)) +@@ -1972,6 +1987,14 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh) + } + + zap_buffer: ++ /* ++ * This is tricky. Although the buffer is truncated, it may be reused ++ * if blocksize < pagesize and it is attached to the page straddling ++ * EOF. Since the buffer might have been added to BJ_Forget list of the ++ * running transaction, journal_get_write_access() won't clear ++ * b_modified and credit accounting gets confused. So clear b_modified ++ * here. */ ++ jh->b_modified = 0; + journal_put_journal_head(jh); + zap_buffer_no_jh: + spin_unlock(&journal->j_list_lock); +@@ -2020,7 +2043,8 @@ void journal_invalidatepage(journal_t *journal, + if (offset <= curr_off) { + /* This block is wholly outside the truncation point */ + lock_buffer(bh); +- may_free &= journal_unmap_buffer(journal, bh); ++ may_free &= journal_unmap_buffer(journal, bh, ++ offset > 0); + unlock_buffer(bh); + } + curr_off = next_off; +diff --git a/fs/lockd/clntxdr.c b/fs/lockd/clntxdr.c +index 36057ce..6e2a2d5 100644 +--- a/fs/lockd/clntxdr.c ++++ b/fs/lockd/clntxdr.c +@@ -223,7 +223,7 @@ static void encode_nlm_stat(struct xdr_stream *xdr, + { + __be32 *p; + +- BUG_ON(be32_to_cpu(stat) > NLM_LCK_DENIED_GRACE_PERIOD); ++ WARN_ON_ONCE(be32_to_cpu(stat) > NLM_LCK_DENIED_GRACE_PERIOD); + p = xdr_reserve_space(xdr, 4); + *p = stat; + } +diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c +index df753a1..23d7451 100644 +--- a/fs/lockd/mon.c ++++ b/fs/lockd/mon.c +@@ -40,7 +40,6 @@ struct nsm_args { + u32 proc; + + char *mon_name; +- char *nodename; + }; + + struct nsm_res { +@@ -94,7 +93,6 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res) + .vers = 3, + .proc = NLMPROC_NSM_NOTIFY, + .mon_name = nsm->sm_mon_name, +- .nodename = utsname()->nodename, + }; + struct rpc_message msg = { + .rpc_argp = &args, +@@ -431,7 +429,7 @@ static void encode_my_id(struct xdr_stream *xdr, const struct nsm_args *argp) + { + __be32 *p; + +- encode_nsm_string(xdr, argp->nodename); ++ encode_nsm_string(xdr, utsname()->nodename); + p = xdr_reserve_space(xdr, 4 + 4 + 4); + *p++ = cpu_to_be32(argp->prog); + *p++ = cpu_to_be32(argp->vers); +diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c +index d27aab1..d413af3 100644 +--- a/fs/lockd/svcproc.c ++++ b/fs/lockd/svcproc.c +@@ -67,7 +67,8 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, + + /* Obtain file pointer. Not used by FREE_ALL call. */ + if (filp != NULL) { +- if ((error = nlm_lookup_file(rqstp, &file, &lock->fh)) != 0) ++ error = cast_status(nlm_lookup_file(rqstp, &file, &lock->fh)); ++ if (error != 0) + goto no_locks; + *filp = file; + +diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c +index 4cfe260..d225b51 100644 +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -3673,6 +3673,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); + + nfsd4_close_open_stateid(stp); ++ release_last_closed_stateid(oo); + oo->oo_last_closed_stid = stp; + + /* place unused nfs4_stateowners on so_close_lru list to be +diff --git a/fs/proc/stat.c b/fs/proc/stat.c +index 0855e6f..4c9a859 100644 +--- a/fs/proc/stat.c ++++ b/fs/proc/stat.c +@@ -24,11 +24,14 @@ + + static cputime64_t get_idle_time(int cpu) + { +- u64 idle_time = get_cpu_idle_time_us(cpu, NULL); ++ u64 idle_time = -1ULL; + cputime64_t idle; + ++ if (cpu_online(cpu)) ++ idle_time = get_cpu_idle_time_us(cpu, NULL); ++ + if (idle_time == -1ULL) { +- /* !NO_HZ so we can rely on cpustat.idle */ ++ /* !NO_HZ or cpu offline so we can rely on cpustat.idle */ + idle = kstat_cpu(cpu).cpustat.idle; + idle = cputime64_add(idle, arch_idle_time(cpu)); + } else +@@ -39,11 +42,14 @@ static cputime64_t get_idle_time(int cpu) + + static cputime64_t get_iowait_time(int cpu) + { +- u64 iowait_time = get_cpu_iowait_time_us(cpu, NULL); ++ u64 iowait_time = -1ULL; + cputime64_t iowait; + ++ if (cpu_online(cpu)) ++ iowait_time = get_cpu_iowait_time_us(cpu, NULL); ++ + if (iowait_time == -1ULL) +- /* !NO_HZ so we can rely on cpustat.iowait */ ++ /* !NO_HZ or cpu offline so we can rely on cpustat.iowait */ + iowait = kstat_cpu(cpu).cpustat.iowait; + else + iowait = usecs_to_cputime64(iowait_time); +diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c +index 950f13a..5809abb 100644 +--- a/fs/reiserfs/inode.c ++++ b/fs/reiserfs/inode.c +@@ -1573,8 +1573,10 @@ struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid, + reiserfs_warning(sb, "reiserfs-13077", + "nfsd/reiserfs, fhtype=%d, len=%d - odd", + fh_type, fh_len); +- fh_type = 5; ++ fh_type = fh_len; + } ++ if (fh_len < 2) ++ return NULL; + + return reiserfs_get_dentry(sb, fid->raw[0], fid->raw[1], + (fh_type == 3 || fh_type >= 5) ? fid->raw[2] : 0); +@@ -1583,6 +1585,8 @@ struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid, + struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid, + int fh_len, int fh_type) + { ++ if (fh_type > fh_len) ++ fh_type = fh_len; + if (fh_type < 4) + return NULL; + +diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c +index 7fdf6a7..fabbb81 100644 +--- a/fs/sysfs/dir.c ++++ b/fs/sysfs/dir.c +@@ -430,20 +430,18 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) + /** + * sysfs_pathname - return full path to sysfs dirent + * @sd: sysfs_dirent whose path we want +- * @path: caller allocated buffer ++ * @path: caller allocated buffer of size PATH_MAX + * + * Gives the name "/" to the sysfs_root entry; any path returned + * is relative to wherever sysfs is mounted. +- * +- * XXX: does no error checking on @path size + */ + static char *sysfs_pathname(struct sysfs_dirent *sd, char *path) + { + if (sd->s_parent) { + sysfs_pathname(sd->s_parent, path); +- strcat(path, "/"); ++ strlcat(path, "/", PATH_MAX); + } +- strcat(path, sd->s_name); ++ strlcat(path, sd->s_name, PATH_MAX); + return path; + } + +@@ -476,9 +474,11 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) + char *path = kzalloc(PATH_MAX, GFP_KERNEL); + WARN(1, KERN_WARNING + "sysfs: cannot create duplicate filename '%s'\n", +- (path == NULL) ? sd->s_name : +- strcat(strcat(sysfs_pathname(acxt->parent_sd, path), "/"), +- sd->s_name)); ++ (path == NULL) ? sd->s_name ++ : (sysfs_pathname(acxt->parent_sd, path), ++ strlcat(path, "/", PATH_MAX), ++ strlcat(path, sd->s_name, PATH_MAX), ++ path)); + kfree(path); + } + +diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c +index 558910f..5703fb8 100644 +--- a/fs/xfs/xfs_export.c ++++ b/fs/xfs/xfs_export.c +@@ -195,6 +195,9 @@ xfs_fs_fh_to_parent(struct super_block *sb, struct fid *fid, + struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fid; + struct inode *inode = NULL; + ++ if (fh_len < xfs_fileid_length(fileid_type)) ++ return NULL; ++ + switch (fileid_type) { + case FILEID_INO32_GEN_PARENT: + inode = xfs_nfs_get_inode(sb, fid->i32.parent_ino, +diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h +index 12d5543..c944c4f 100644 +--- a/include/linux/if_vlan.h ++++ b/include/linux/if_vlan.h +@@ -97,6 +97,8 @@ static inline int is_vlan_dev(struct net_device *dev) + } + + #define vlan_tx_tag_present(__skb) ((__skb)->vlan_tci & VLAN_TAG_PRESENT) ++#define vlan_tx_nonzero_tag_present(__skb) \ ++ (vlan_tx_tag_present(__skb) && ((__skb)->vlan_tci & VLAN_VID_MASK)) + #define vlan_tx_tag_get(__skb) ((__skb)->vlan_tci & ~VLAN_TAG_PRESENT) + + #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +@@ -106,7 +108,7 @@ extern struct net_device *__vlan_find_dev_deep(struct net_device *real_dev, + extern struct net_device *vlan_dev_real_dev(const struct net_device *dev); + extern u16 vlan_dev_vlan_id(const struct net_device *dev); + +-extern bool vlan_do_receive(struct sk_buff **skb, bool last_handler); ++extern bool vlan_do_receive(struct sk_buff **skb); + extern struct sk_buff *vlan_untag(struct sk_buff *skb); + + #else +@@ -128,10 +130,8 @@ static inline u16 vlan_dev_vlan_id(const struct net_device *dev) + return 0; + } + +-static inline bool vlan_do_receive(struct sk_buff **skb, bool last_handler) ++static inline bool vlan_do_receive(struct sk_buff **skb) + { +- if (((*skb)->vlan_tci & VLAN_VID_MASK) && last_handler) +- (*skb)->pkt_type = PACKET_OTHERHOST; + return false; + } + +diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h +index 904131b..b25b09b 100644 +--- a/include/linux/mtd/nand.h ++++ b/include/linux/mtd/nand.h +@@ -215,9 +215,6 @@ typedef enum { + #define NAND_SUBPAGE_READ(chip) ((chip->ecc.mode == NAND_ECC_SOFT) \ + && (chip->page_shift > 9)) + +-/* Mask to zero out the chip options, which come from the id table */ +-#define NAND_CHIPOPTIONS_MSK (0x0000ffff & ~NAND_NO_AUTOINCR) +- + /* Non chip related options */ + /* This option skips the bbt scan during initialization. */ + #define NAND_SKIP_BBTSCAN 0x00010000 +diff --git a/include/linux/netfilter/xt_set.h b/include/linux/netfilter/xt_set.h +index c0405ac..e3a9978 100644 +--- a/include/linux/netfilter/xt_set.h ++++ b/include/linux/netfilter/xt_set.h +@@ -58,8 +58,8 @@ struct xt_set_info_target_v1 { + struct xt_set_info_target_v2 { + struct xt_set_info add_set; + struct xt_set_info del_set; +- u32 flags; +- u32 timeout; ++ __u32 flags; ++ __u32 timeout; + }; + + #endif /*_XT_SET_H*/ +diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h +index a88fb69..ea6f8a4 100644 +--- a/include/net/netfilter/nf_conntrack_ecache.h ++++ b/include/net/netfilter/nf_conntrack_ecache.h +@@ -18,6 +18,7 @@ struct nf_conntrack_ecache { + u16 ctmask; /* bitmask of ct events to be delivered */ + u16 expmask; /* bitmask of expect events to be delivered */ + u32 pid; /* netlink pid of destroyer */ ++ struct timer_list timeout; + }; + + static inline struct nf_conntrack_ecache * +diff --git a/kernel/cgroup.c b/kernel/cgroup.c +index cdc0354..6337535 100644 +--- a/kernel/cgroup.c ++++ b/kernel/cgroup.c +@@ -1803,9 +1803,8 @@ static int cgroup_task_migrate(struct cgroup *cgrp, struct cgroup *oldcgrp, + * trading it for newcg is protected by cgroup_mutex, we're safe to drop + * it here; it will be freed under RCU. + */ +- put_css_set(oldcg); +- + set_bit(CGRP_RELEASABLE, &oldcgrp->flags); ++ put_css_set(oldcg); + return 0; + } + +diff --git a/kernel/module.c b/kernel/module.c +index 6969ef0..6c8fa34 100644 +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -2659,6 +2659,10 @@ static int check_module_license_and_versions(struct module *mod) + if (strcmp(mod->name, "driverloader") == 0) + add_taint_module(mod, TAINT_PROPRIETARY_MODULE); + ++ /* lve claims to be GPL but upstream won't provide source */ ++ if (strcmp(mod->name, "lve") == 0) ++ add_taint_module(mod, TAINT_PROPRIETARY_MODULE); ++ + #ifdef CONFIG_MODVERSIONS + if ((mod->num_syms && !mod->crcs) + || (mod->num_gpl_syms && !mod->gpl_crcs) +diff --git a/kernel/sys.c b/kernel/sys.c +index c504302..d7c4ab0 100644 +--- a/kernel/sys.c ++++ b/kernel/sys.c +@@ -1171,15 +1171,16 @@ DECLARE_RWSEM(uts_sem); + * Work around broken programs that cannot handle "Linux 3.0". + * Instead we map 3.x to 2.6.40+x, so e.g. 3.0 would be 2.6.40 + */ +-static int override_release(char __user *release, int len) ++static int override_release(char __user *release, size_t len) + { + int ret = 0; +- char buf[65]; + + if (current->personality & UNAME26) { +- char *rest = UTS_RELEASE; ++ const char *rest = UTS_RELEASE; ++ char buf[65] = { 0 }; + int ndots = 0; + unsigned v; ++ size_t copy; + + while (*rest) { + if (*rest == '.' && ++ndots >= 3) +@@ -1189,8 +1190,9 @@ static int override_release(char __user *release, int len) + rest++; + } + v = ((LINUX_VERSION_CODE >> 8) & 0xff) + 40; +- snprintf(buf, len, "2.6.%u%s", v, rest); +- ret = copy_to_user(release, buf, len); ++ copy = min(sizeof(buf), max_t(size_t, 1, len)); ++ copy = scnprintf(buf, copy, "2.6.%u%s", v, rest); ++ ret = copy_to_user(release, buf, copy + 1); + } + return ret; + } +diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c +index 5ee1ac0..cb7f33e 100644 +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -992,7 +992,7 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift) + } + + /* Accumulate raw time */ +- raw_nsecs = timekeeper.raw_interval << shift; ++ raw_nsecs = (u64)timekeeper.raw_interval << shift; + raw_nsecs += raw_time.tv_nsec; + if (raw_nsecs >= NSEC_PER_SEC) { + u64 raw_secs = raw_nsecs; +diff --git a/kernel/timer.c b/kernel/timer.c +index 9c3c62b..c219db6 100644 +--- a/kernel/timer.c ++++ b/kernel/timer.c +@@ -63,6 +63,7 @@ EXPORT_SYMBOL(jiffies_64); + #define TVR_SIZE (1 << TVR_BITS) + #define TVN_MASK (TVN_SIZE - 1) + #define TVR_MASK (TVR_SIZE - 1) ++#define MAX_TVAL ((unsigned long)((1ULL << (TVR_BITS + 4*TVN_BITS)) - 1)) + + struct tvec { + struct list_head vec[TVN_SIZE]; +@@ -356,11 +357,12 @@ static void internal_add_timer(struct tvec_base *base, struct timer_list *timer) + vec = base->tv1.vec + (base->timer_jiffies & TVR_MASK); + } else { + int i; +- /* If the timeout is larger than 0xffffffff on 64-bit +- * architectures then we use the maximum timeout: ++ /* If the timeout is larger than MAX_TVAL (on 64-bit ++ * architectures or with CONFIG_BASE_SMALL=1) then we ++ * use the maximum timeout. + */ +- if (idx > 0xffffffffUL) { +- idx = 0xffffffffUL; ++ if (idx > MAX_TVAL) { ++ idx = MAX_TVAL; + expires = idx + base->timer_jiffies; + } + i = (expires >> (TVR_BITS + 3 * TVN_BITS)) & TVN_MASK; +diff --git a/lib/genalloc.c b/lib/genalloc.c +index f352cc4..716f947 100644 +--- a/lib/genalloc.c ++++ b/lib/genalloc.c +@@ -176,7 +176,7 @@ int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phy + struct gen_pool_chunk *chunk; + int nbits = size >> pool->min_alloc_order; + int nbytes = sizeof(struct gen_pool_chunk) + +- (nbits + BITS_PER_BYTE - 1) / BITS_PER_BYTE; ++ BITS_TO_LONGS(nbits) * sizeof(long); + + chunk = kmalloc_node(nbytes, GFP_KERNEL | __GFP_ZERO, nid); + if (unlikely(chunk == NULL)) +diff --git a/mm/rmap.c b/mm/rmap.c +index a4fd368..8685697 100644 +--- a/mm/rmap.c ++++ b/mm/rmap.c +@@ -56,6 +56,7 @@ + #include <linux/mmu_notifier.h> + #include <linux/migrate.h> + #include <linux/hugetlb.h> ++#include <linux/backing-dev.h> + + #include <asm/tlbflush.h> + +@@ -935,11 +936,8 @@ int page_mkclean(struct page *page) + + if (page_mapped(page)) { + struct address_space *mapping = page_mapping(page); +- if (mapping) { ++ if (mapping) + ret = page_mkclean_file(mapping, page); +- if (page_test_and_clear_dirty(page_to_pfn(page), 1)) +- ret = 1; +- } + } + + return ret; +@@ -1120,6 +1118,8 @@ void page_add_file_rmap(struct page *page) + */ + void page_remove_rmap(struct page *page) + { ++ struct address_space *mapping = page_mapping(page); ++ + /* page still mapped by someone else? */ + if (!atomic_add_negative(-1, &page->_mapcount)) + return; +@@ -1130,8 +1130,19 @@ void page_remove_rmap(struct page *page) + * this if the page is anon, so about to be freed; but perhaps + * not if it's in swapcache - there might be another pte slot + * containing the swap entry, but page not yet written to swap. ++ * ++ * And we can skip it on file pages, so long as the filesystem ++ * participates in dirty tracking; but need to catch shm and tmpfs ++ * and ramfs pages which have been modified since creation by read ++ * fault. ++ * ++ * Note that mapping must be decided above, before decrementing ++ * mapcount (which luckily provides a barrier): once page is unmapped, ++ * it could be truncated and page->mapping reset to NULL at any moment. ++ * Note also that we are relying on page_mapping(page) to set mapping ++ * to &swapper_space when PageSwapCache(page). + */ +- if ((!PageAnon(page) || PageSwapCache(page)) && ++ if (mapping && !mapping_cap_account_dirty(mapping) && + page_test_and_clear_dirty(page_to_pfn(page), 1)) + set_page_dirty(page); + /* +diff --git a/mm/shmem.c b/mm/shmem.c +index 7a82174..126ca35 100644 +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -1962,12 +1962,14 @@ static struct dentry *shmem_fh_to_dentry(struct super_block *sb, + { + struct inode *inode; + struct dentry *dentry = NULL; +- u64 inum = fid->raw[2]; +- inum = (inum << 32) | fid->raw[1]; ++ u64 inum; + + if (fh_len < 3) + return NULL; + ++ inum = fid->raw[2]; ++ inum = (inum << 32) | fid->raw[1]; ++ + inode = ilookup5(sb, (unsigned long)(inum + fid->raw[0]), + shmem_match, fid->raw); + if (inode) { +diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c +index 9ddbd4e..e860a4f 100644 +--- a/net/8021q/vlan_core.c ++++ b/net/8021q/vlan_core.c +@@ -5,7 +5,7 @@ + #include <linux/export.h> + #include "vlan.h" + +-bool vlan_do_receive(struct sk_buff **skbp, bool last_handler) ++bool vlan_do_receive(struct sk_buff **skbp) + { + struct sk_buff *skb = *skbp; + u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK; +@@ -13,14 +13,8 @@ bool vlan_do_receive(struct sk_buff **skbp, bool last_handler) + struct vlan_pcpu_stats *rx_stats; + + vlan_dev = vlan_find_dev(skb->dev, vlan_id); +- if (!vlan_dev) { +- /* Only the last call to vlan_do_receive() should change +- * pkt_type to PACKET_OTHERHOST +- */ +- if (vlan_id && last_handler) +- skb->pkt_type = PACKET_OTHERHOST; ++ if (!vlan_dev) + return false; +- } + + skb = *skbp = skb_share_check(skb, GFP_ATOMIC); + if (unlikely(!skb)) +diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c +index c27b4e3..1849ee0 100644 +--- a/net/bluetooth/smp.c ++++ b/net/bluetooth/smp.c +@@ -30,6 +30,8 @@ + + #define SMP_TIMEOUT 30000 /* 30 seconds */ + ++#define AUTH_REQ_MASK 0x07 ++ + static inline void swap128(u8 src[16], u8 dst[16]) + { + int i; +@@ -206,7 +208,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn, + req->max_key_size = SMP_MAX_ENC_KEY_SIZE; + req->init_key_dist = dist_keys; + req->resp_key_dist = dist_keys; +- req->auth_req = authreq; ++ req->auth_req = (authreq & AUTH_REQ_MASK); + return; + } + +@@ -215,7 +217,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn, + rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE; + rsp->init_key_dist = req->init_key_dist & dist_keys; + rsp->resp_key_dist = req->resp_key_dist & dist_keys; +- rsp->auth_req = authreq; ++ rsp->auth_req = (authreq & AUTH_REQ_MASK); + } + + static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) +diff --git a/net/core/dev.c b/net/core/dev.c +index abe1147..f500a69 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -3278,18 +3278,18 @@ another_round: + ncls: + #endif + +- rx_handler = rcu_dereference(skb->dev->rx_handler); + if (vlan_tx_tag_present(skb)) { + if (pt_prev) { + ret = deliver_skb(skb, pt_prev, orig_dev); + pt_prev = NULL; + } +- if (vlan_do_receive(&skb, !rx_handler)) ++ if (vlan_do_receive(&skb)) + goto another_round; + else if (unlikely(!skb)) + goto out; + } + ++ rx_handler = rcu_dereference(skb->dev->rx_handler); + if (rx_handler) { + if (pt_prev) { + ret = deliver_skb(skb, pt_prev, orig_dev); +@@ -3309,6 +3309,9 @@ ncls: + } + } + ++ if (vlan_tx_nonzero_tag_present(skb)) ++ skb->pkt_type = PACKET_OTHERHOST; ++ + /* deliver only exact match when indicated */ + null_or_dev = deliver_exact ? skb->dev : NULL; + +diff --git a/net/core/neighbour.c b/net/core/neighbour.c +index 7aafaed..5b9709f 100644 +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -1254,8 +1254,6 @@ int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb) + if (!dst) + goto discard; + +- __skb_pull(skb, skb_network_offset(skb)); +- + if (!neigh_event_send(neigh, skb)) { + int err; + struct net_device *dev = neigh->dev; +@@ -1265,6 +1263,7 @@ int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb) + neigh_hh_init(neigh, dst); + + do { ++ __skb_pull(skb, skb_network_offset(skb)); + seq = read_seqbegin(&neigh->ha_lock); + err = dev_hard_header(skb, dev, ntohs(skb->protocol), + neigh->ha, NULL, skb->len); +@@ -1295,9 +1294,8 @@ int neigh_connected_output(struct neighbour *neigh, struct sk_buff *skb) + unsigned int seq; + int err; + +- __skb_pull(skb, skb_network_offset(skb)); +- + do { ++ __skb_pull(skb, skb_network_offset(skb)); + seq = read_seqbegin(&neigh->ha_lock); + err = dev_hard_header(skb, dev, ntohs(skb->protocol), + neigh->ha, NULL, skb->len); +diff --git a/net/core/pktgen.c b/net/core/pktgen.c +index df878de..7bc9991 100644 +--- a/net/core/pktgen.c ++++ b/net/core/pktgen.c +@@ -2935,7 +2935,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, + sizeof(struct ipv6hdr) - sizeof(struct udphdr) - + pkt_dev->pkt_overhead; + +- if (datalen < sizeof(struct pktgen_hdr)) { ++ if (datalen < 0 || datalen < sizeof(struct pktgen_hdr)) { + datalen = sizeof(struct pktgen_hdr); + if (net_ratelimit()) + pr_info("increased datalen to %d\n", datalen); +diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c +index de69cec..58c09a0 100644 +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -651,10 +651,11 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) + arg.csumoffset = offsetof(struct tcphdr, check) / 2; + arg.flags = (sk && inet_sk(sk)->transparent) ? IP_REPLY_ARG_NOSRCCHECK : 0; + /* When socket is gone, all binding information is lost. +- * routing might fail in this case. using iif for oif to +- * make sure we can deliver it ++ * routing might fail in this case. No choice here, if we choose to force ++ * input interface, we will misroute in case of asymmetric route. + */ +- arg.bound_dev_if = sk ? sk->sk_bound_dev_if : inet_iif(skb); ++ if (sk) ++ arg.bound_dev_if = sk->sk_bound_dev_if; + + net = dev_net(skb_dst(skb)->dev); + arg.tos = ip_hdr(skb)->tos; +diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c +index 4a56574..ccab3c8 100644 +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -1048,7 +1048,8 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, + __tcp_v6_send_check(buff, &fl6.saddr, &fl6.daddr); + + fl6.flowi6_proto = IPPROTO_TCP; +- fl6.flowi6_oif = inet6_iif(skb); ++ if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL) ++ fl6.flowi6_oif = inet6_iif(skb); + fl6.fl6_dport = t1->dest; + fl6.fl6_sport = t1->source; + security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); +diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c +index 28a39bb..a582504 100644 +--- a/net/mac80211/wpa.c ++++ b/net/mac80211/wpa.c +@@ -106,7 +106,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) + if (status->flag & RX_FLAG_MMIC_ERROR) + goto mic_fail; + +- if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key) ++ if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key && ++ rx->key->conf.cipher == WLAN_CIPHER_SUITE_TKIP) + goto update_iv; + + return RX_CONTINUE; +diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c +index 1d15193..7489bd3 100644 +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -247,12 +247,15 @@ static void death_by_event(unsigned long ul_conntrack) + { + struct nf_conn *ct = (void *)ul_conntrack; + struct net *net = nf_ct_net(ct); ++ struct nf_conntrack_ecache *ecache = nf_ct_ecache_find(ct); ++ ++ BUG_ON(ecache == NULL); + + if (nf_conntrack_event(IPCT_DESTROY, ct) < 0) { + /* bad luck, let's retry again */ +- ct->timeout.expires = jiffies + ++ ecache->timeout.expires = jiffies + + (random32() % net->ct.sysctl_events_retry_timeout); +- add_timer(&ct->timeout); ++ add_timer(&ecache->timeout); + return; + } + /* we've got the event delivered, now it's dying */ +@@ -266,6 +269,9 @@ static void death_by_event(unsigned long ul_conntrack) + void nf_ct_insert_dying_list(struct nf_conn *ct) + { + struct net *net = nf_ct_net(ct); ++ struct nf_conntrack_ecache *ecache = nf_ct_ecache_find(ct); ++ ++ BUG_ON(ecache == NULL); + + /* add this conntrack to the dying list */ + spin_lock_bh(&nf_conntrack_lock); +@@ -273,10 +279,10 @@ void nf_ct_insert_dying_list(struct nf_conn *ct) + &net->ct.dying); + spin_unlock_bh(&nf_conntrack_lock); + /* set a new timer to retry event delivery */ +- setup_timer(&ct->timeout, death_by_event, (unsigned long)ct); +- ct->timeout.expires = jiffies + ++ setup_timer(&ecache->timeout, death_by_event, (unsigned long)ct); ++ ecache->timeout.expires = jiffies + + (random32() % net->ct.sysctl_events_retry_timeout); +- add_timer(&ct->timeout); ++ add_timer(&ecache->timeout); + } + EXPORT_SYMBOL_GPL(nf_ct_insert_dying_list); + +diff --git a/net/rds/send.c b/net/rds/send.c +index 96531d4..88eace5 100644 +--- a/net/rds/send.c ++++ b/net/rds/send.c +@@ -1122,7 +1122,7 @@ rds_send_pong(struct rds_connection *conn, __be16 dport) + rds_stats_inc(s_send_pong); + + if (!test_bit(RDS_LL_SEND_FULL, &conn->c_flags)) +- rds_send_xmit(conn); ++ queue_delayed_work(rds_wq, &conn->c_send_w, 0); + + rds_message_put(rm); + return 0; +diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c +index 4530a91..237a2ee 100644 +--- a/net/sunrpc/cache.c ++++ b/net/sunrpc/cache.c +@@ -1404,11 +1404,11 @@ static ssize_t read_flush(struct file *file, char __user *buf, + size_t count, loff_t *ppos, + struct cache_detail *cd) + { +- char tbuf[20]; ++ char tbuf[22]; + unsigned long p = *ppos; + size_t len; + +- sprintf(tbuf, "%lu\n", convert_to_wallclock(cd->flush_time)); ++ snprintf(tbuf, sizeof(tbuf), "%lu\n", convert_to_wallclock(cd->flush_time)); + len = strlen(tbuf); + if (p >= len) + return 0; +diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c +index 10a385b..65fe23b 100644 +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -254,7 +254,6 @@ struct sock_xprt { + void (*old_data_ready)(struct sock *, int); + void (*old_state_change)(struct sock *); + void (*old_write_space)(struct sock *); +- void (*old_error_report)(struct sock *); + }; + + /* +@@ -737,10 +736,10 @@ static int xs_tcp_send_request(struct rpc_task *task) + dprintk("RPC: sendmsg returned unrecognized error %d\n", + -status); + case -ECONNRESET: +- case -EPIPE: + xs_tcp_shutdown(xprt); + case -ECONNREFUSED: + case -ENOTCONN: ++ case -EPIPE: + clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); + } + +@@ -781,7 +780,6 @@ static void xs_save_old_callbacks(struct sock_xprt *transport, struct sock *sk) + transport->old_data_ready = sk->sk_data_ready; + transport->old_state_change = sk->sk_state_change; + transport->old_write_space = sk->sk_write_space; +- transport->old_error_report = sk->sk_error_report; + } + + static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *sk) +@@ -789,7 +787,6 @@ static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *s + sk->sk_data_ready = transport->old_data_ready; + sk->sk_state_change = transport->old_state_change; + sk->sk_write_space = transport->old_write_space; +- sk->sk_error_report = transport->old_error_report; + } + + static void xs_reset_transport(struct sock_xprt *transport) +@@ -1465,7 +1462,7 @@ static void xs_tcp_cancel_linger_timeout(struct rpc_xprt *xprt) + xprt_clear_connecting(xprt); + } + +-static void xs_sock_mark_closed(struct rpc_xprt *xprt) ++static void xs_sock_reset_connection_flags(struct rpc_xprt *xprt) + { + smp_mb__before_clear_bit(); + clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); +@@ -1473,6 +1470,11 @@ static void xs_sock_mark_closed(struct rpc_xprt *xprt) + clear_bit(XPRT_CLOSE_WAIT, &xprt->state); + clear_bit(XPRT_CLOSING, &xprt->state); + smp_mb__after_clear_bit(); ++} ++ ++static void xs_sock_mark_closed(struct rpc_xprt *xprt) ++{ ++ xs_sock_reset_connection_flags(xprt); + /* Mark transport as closed and wake up all pending tasks */ + xprt_disconnect_done(xprt); + } +@@ -1528,6 +1530,7 @@ static void xs_tcp_state_change(struct sock *sk) + case TCP_CLOSE_WAIT: + /* The server initiated a shutdown of the socket */ + xprt->connect_cookie++; ++ clear_bit(XPRT_CONNECTED, &xprt->state); + xs_tcp_force_close(xprt); + case TCP_CLOSING: + /* +@@ -1552,25 +1555,6 @@ static void xs_tcp_state_change(struct sock *sk) + read_unlock_bh(&sk->sk_callback_lock); + } + +-/** +- * xs_error_report - callback mainly for catching socket errors +- * @sk: socket +- */ +-static void xs_error_report(struct sock *sk) +-{ +- struct rpc_xprt *xprt; +- +- read_lock_bh(&sk->sk_callback_lock); +- if (!(xprt = xprt_from_sock(sk))) +- goto out; +- dprintk("RPC: %s client %p...\n" +- "RPC: error %d\n", +- __func__, xprt, sk->sk_err); +- xprt_wake_pending_tasks(xprt, -EAGAIN); +-out: +- read_unlock_bh(&sk->sk_callback_lock); +-} +- + static void xs_write_space(struct sock *sk) + { + struct socket *sock; +@@ -1870,7 +1854,6 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt, + sk->sk_user_data = xprt; + sk->sk_data_ready = xs_local_data_ready; + sk->sk_write_space = xs_udp_write_space; +- sk->sk_error_report = xs_error_report; + sk->sk_allocation = GFP_ATOMIC; + + xprt_clear_connected(xprt); +@@ -1959,7 +1942,6 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) + sk->sk_user_data = xprt; + sk->sk_data_ready = xs_udp_data_ready; + sk->sk_write_space = xs_udp_write_space; +- sk->sk_error_report = xs_error_report; + sk->sk_no_check = UDP_CSUM_NORCV; + sk->sk_allocation = GFP_ATOMIC; + +@@ -2027,10 +2009,8 @@ static void xs_abort_connection(struct sock_xprt *transport) + any.sa_family = AF_UNSPEC; + result = kernel_connect(transport->sock, &any, sizeof(any), 0); + if (!result) +- xs_sock_mark_closed(&transport->xprt); +- else +- dprintk("RPC: AF_UNSPEC connect return code %d\n", +- result); ++ xs_sock_reset_connection_flags(&transport->xprt); ++ dprintk("RPC: AF_UNSPEC connect return code %d\n", result); + } + + static void xs_tcp_reuse_connection(struct sock_xprt *transport) +@@ -2075,7 +2055,6 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) + sk->sk_data_ready = xs_tcp_data_ready; + sk->sk_state_change = xs_tcp_state_change; + sk->sk_write_space = xs_tcp_write_space; +- sk->sk_error_report = xs_error_report; + sk->sk_allocation = GFP_ATOMIC; + + /* socket options */ +@@ -2488,6 +2467,7 @@ static struct rpc_xprt_ops xs_tcp_ops = { + static struct rpc_xprt_ops bc_tcp_ops = { + .reserve_xprt = xprt_reserve_xprt, + .release_xprt = xprt_release_xprt, ++ .alloc_slot = xprt_alloc_slot, + .buf_alloc = bc_malloc, + .buf_free = bc_free, + .send_request = bc_send_request, +diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c +index fac51ee..1e7cfba 100644 +--- a/sound/pci/ac97/ac97_codec.c ++++ b/sound/pci/ac97/ac97_codec.c +@@ -1271,6 +1271,8 @@ static int snd_ac97_cvol_new(struct snd_card *card, char *name, int reg, unsigne + tmp.index = ac97->num; + kctl = snd_ctl_new1(&tmp, ac97); + } ++ if (!kctl) ++ return -ENOMEM; + if (reg >= AC97_PHONE && reg <= AC97_PCM) + set_tlv_db_scale(kctl, db_scale_5bit_12db_max); + else +diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c +index 6a3e567..d37b946 100644 +--- a/sound/pci/emu10k1/emu10k1_main.c ++++ b/sound/pci/emu10k1/emu10k1_main.c +@@ -1416,6 +1416,15 @@ static struct snd_emu_chip_details emu_chip_details[] = { + .ca0108_chip = 1, + .spk71 = 1, + .emu_model = EMU_MODEL_EMU1010B}, /* EMU 1010 new revision */ ++ /* Tested by Maxim Kachur <mcdebugger@duganet.ru> 17th Oct 2012. */ ++ /* This is MAEM8986, 0202 is MAEM8980 */ ++ {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40071102, ++ .driver = "Audigy2", .name = "E-mu 1010 PCIe [MAEM8986]", ++ .id = "EMU1010", ++ .emu10k2_chip = 1, ++ .ca0108_chip = 1, ++ .spk71 = 1, ++ .emu_model = EMU_MODEL_EMU1010B}, /* EMU 1010 PCIe */ + /* Tested by James@superbug.co.uk 8th July 2005. */ + /* This is MAEM8810, 0202 is MAEM8820 */ + {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102, +diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c +index ec0518e..e449278 100644 +--- a/sound/pci/hda/patch_cirrus.c ++++ b/sound/pci/hda/patch_cirrus.c +@@ -1404,7 +1404,7 @@ static int patch_cs420x(struct hda_codec *codec) + return 0; + + error: +- kfree(codec->spec); ++ cs_free(codec); + codec->spec = NULL; + return err; + } +@@ -1949,7 +1949,7 @@ static int patch_cs421x(struct hda_codec *codec) + return 0; + + error: +- kfree(codec->spec); ++ cs_free(codec); + codec->spec = NULL; + return err; + } +diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c +index 94f0c4a..58c287b 100644 +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -4463,7 +4463,9 @@ static void apply_fixup(struct hda_codec *codec, + struct conexant_spec *spec = codec->spec; + + quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); +- if (quirk && table[quirk->value]) { ++ if (!quirk) ++ return; ++ if (table[quirk->value]) { + snd_printdd(KERN_INFO "hda_codec: applying pincfg for %s\n", + quirk->name); + apply_pincfg(codec, table[quirk->value]); +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 32c8169..c2c7f90 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -620,6 +620,8 @@ static void alc_line_automute(struct hda_codec *codec) + { + struct alc_spec *spec = codec->spec; + ++ if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) ++ return; + /* check LO jack only when it's different from HP */ + if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0]) + return; +@@ -2663,8 +2665,10 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, + return "PCM"; + break; + } +- if (snd_BUG_ON(ch >= ARRAY_SIZE(channel_name))) ++ if (ch >= ARRAY_SIZE(channel_name)) { ++ snd_BUG(); + return "PCM"; ++ } + + return channel_name[ch]; + } +@@ -5080,6 +5084,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), + SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK), + SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), ++ SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), + SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), + SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), + SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), +diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c +index af0f22f..aca6edc 100644 +--- a/usr/gen_init_cpio.c ++++ b/usr/gen_init_cpio.c +@@ -303,7 +303,7 @@ static int cpio_mkfile(const char *name, const char *location, + int retval; + int rc = -1; + int namesize; +- int i; ++ unsigned int i; + + mode |= S_IFREG; + +@@ -381,25 +381,28 @@ error: + + static char *cpio_replace_env(char *new_location) + { +- char expanded[PATH_MAX + 1]; +- char env_var[PATH_MAX + 1]; +- char *start; +- char *end; +- +- for (start = NULL; (start = strstr(new_location, "${")); ) { +- end = strchr(start, '}'); +- if (start < end) { +- *env_var = *expanded = '\0'; +- strncat(env_var, start + 2, end - start - 2); +- strncat(expanded, new_location, start - new_location); +- strncat(expanded, getenv(env_var), PATH_MAX); +- strncat(expanded, end + 1, PATH_MAX); +- strncpy(new_location, expanded, PATH_MAX); +- } else +- break; +- } +- +- return new_location; ++ char expanded[PATH_MAX + 1]; ++ char env_var[PATH_MAX + 1]; ++ char *start; ++ char *end; ++ ++ for (start = NULL; (start = strstr(new_location, "${")); ) { ++ end = strchr(start, '}'); ++ if (start < end) { ++ *env_var = *expanded = '\0'; ++ strncat(env_var, start + 2, end - start - 2); ++ strncat(expanded, new_location, start - new_location); ++ strncat(expanded, getenv(env_var), ++ PATH_MAX - strlen(expanded)); ++ strncat(expanded, end + 1, ++ PATH_MAX - strlen(expanded)); ++ strncpy(new_location, expanded, PATH_MAX); ++ new_location[PATH_MAX] = 0; ++ } else ++ break; ++ } ++ ++ return new_location; + } + + diff --git a/3.2.32/4420_grsecurity-2.9.1-3.2.32-201210291445.patch b/3.2.33/4420_grsecurity-2.9.1-3.2.33-201210310843.patch index 7d16a10..81903cd 100644 --- a/3.2.32/4420_grsecurity-2.9.1-3.2.32-201210291445.patch +++ b/3.2.33/4420_grsecurity-2.9.1-3.2.33-201210310843.patch @@ -255,7 +255,7 @@ index 88fd7f5..b318a78 100644 ============================================================== diff --git a/Makefile b/Makefile -index b6d8282..f804e48 100644 +index 63ca1ea2..811946a 100644 --- a/Makefile +++ b/Makefile @@ -245,8 +245,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ @@ -5996,7 +5996,7 @@ index 42b282f..28ce9f2 100644 addr = vmm->vm_end; if (flags & MAP_SHARED) diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c -index 441521a..b767073 100644 +index 5e4252b..cbc22e8 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi @@ -6147,7 +6147,7 @@ index 441521a..b767073 100644 mm->unmap_area = arch_unmap_area_topdown; } diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S -index 1d7e274..b39c527 100644 +index 7f5f65d..3308382 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S @@ -62,7 +62,7 @@ sys32_rt_sigreturn: @@ -6177,24 +6177,15 @@ index 1d7e274..b39c527 100644 bne,pn %icc, linux_syscall_trace ! CTI Group mov %i0, %l5 ! IEU0 2: call %l7 ! CTI Group brk forced -@@ -226,7 +226,7 @@ ret_sys_call: +@@ -218,7 +218,7 @@ ret_sys_call: cmp %o0, -ERESTART_RESTARTBLOCK bgeu,pn %xcc, 1f -- andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6 -+ andcc %l0, _TIF_WORK_SYSCALL, %l6 - 80: - /* System call success, clear Carry condition code. */ - andn %g3, %g2, %g3 -@@ -241,7 +241,7 @@ ret_sys_call: - /* System call failure, set Carry condition code. - * Also, get abs(errno) to return to the process. - */ -- andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6 -+ andcc %l0, _TIF_WORK_SYSCALL, %l6 - sub %g0, %o0, %o0 - or %g3, %g2, %g3 - stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] +- andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 ++ andcc %l0, _TIF_WORK_SYSCALL, %g0 + ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc + + 2: diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c index 591f20c..0f1b925 100644 --- a/arch/sparc/kernel/traps_32.c @@ -15002,7 +14993,7 @@ index cd28a35..c72ed9a 100644 #include <asm/processor.h> #include <asm/fcntl.h> diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S -index bcda816..cbab6db 100644 +index 4893d58..0152a42 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -180,13 +180,153 @@ @@ -15685,7 +15676,7 @@ index bcda816..cbab6db 100644 /* * End of kprobes section */ -@@ -1112,7 +1377,7 @@ BUILD_INTERRUPT3(xen_hvm_callback_vector, XEN_HVM_EVTCHN_CALLBACK, +@@ -1114,7 +1379,7 @@ BUILD_INTERRUPT3(xen_hvm_callback_vector, XEN_HVM_EVTCHN_CALLBACK, ENTRY(mcount) ret @@ -15694,7 +15685,7 @@ index bcda816..cbab6db 100644 ENTRY(ftrace_caller) cmpl $0, function_trace_stop -@@ -1141,7 +1406,7 @@ ftrace_graph_call: +@@ -1143,7 +1408,7 @@ ftrace_graph_call: .globl ftrace_stub ftrace_stub: ret @@ -15703,7 +15694,7 @@ index bcda816..cbab6db 100644 #else /* ! CONFIG_DYNAMIC_FTRACE */ -@@ -1177,7 +1442,7 @@ trace: +@@ -1179,7 +1444,7 @@ trace: popl %ecx popl %eax jmp ftrace_stub @@ -15712,7 +15703,7 @@ index bcda816..cbab6db 100644 #endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* CONFIG_FUNCTION_TRACER */ -@@ -1198,7 +1463,7 @@ ENTRY(ftrace_graph_caller) +@@ -1200,7 +1465,7 @@ ENTRY(ftrace_graph_caller) popl %ecx popl %eax ret @@ -15721,7 +15712,7 @@ index bcda816..cbab6db 100644 .globl return_to_handler return_to_handler: -@@ -1212,7 +1477,6 @@ return_to_handler: +@@ -1214,7 +1479,6 @@ return_to_handler: jmp *%ecx #endif @@ -15729,7 +15720,7 @@ index bcda816..cbab6db 100644 #include "syscall_table_32.S" syscall_table_size=(.-sys_call_table) -@@ -1258,15 +1522,18 @@ error_code: +@@ -1260,15 +1524,18 @@ error_code: movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart REG_TO_PTGS %ecx SET_KERNEL_GS %ecx @@ -15750,7 +15741,7 @@ index bcda816..cbab6db 100644 /* * Debug traps and NMI can happen at the one SYSENTER instruction -@@ -1308,7 +1575,7 @@ debug_stack_correct: +@@ -1310,7 +1577,7 @@ debug_stack_correct: call do_debug jmp ret_from_exception CFI_ENDPROC @@ -15759,7 +15750,7 @@ index bcda816..cbab6db 100644 /* * NMI is doubly nasty. It can happen _while_ we're handling -@@ -1345,6 +1612,9 @@ nmi_stack_correct: +@@ -1347,6 +1614,9 @@ nmi_stack_correct: xorl %edx,%edx # zero error code movl %esp,%eax # pt_regs pointer call do_nmi @@ -15769,7 +15760,7 @@ index bcda816..cbab6db 100644 jmp restore_all_notrace CFI_ENDPROC -@@ -1381,12 +1651,15 @@ nmi_espfix_stack: +@@ -1383,12 +1653,15 @@ nmi_espfix_stack: FIXUP_ESPFIX_STACK # %eax == %esp xorl %edx,%edx # zero error code call do_nmi @@ -15786,7 +15777,7 @@ index bcda816..cbab6db 100644 ENTRY(int3) RING0_INT_FRAME -@@ -1398,14 +1671,14 @@ ENTRY(int3) +@@ -1400,14 +1673,14 @@ ENTRY(int3) call do_int3 jmp ret_from_exception CFI_ENDPROC @@ -15803,7 +15794,7 @@ index bcda816..cbab6db 100644 #ifdef CONFIG_KVM_GUEST ENTRY(async_page_fault) -@@ -1413,7 +1686,7 @@ ENTRY(async_page_fault) +@@ -1415,7 +1688,7 @@ ENTRY(async_page_fault) pushl_cfi $do_async_page_fault jmp error_code CFI_ENDPROC @@ -15813,7 +15804,7 @@ index bcda816..cbab6db 100644 /* diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S -index faf8d5e..ed7340c 100644 +index 6274f5f..b451ef1 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -55,6 +55,8 @@ @@ -27436,7 +27427,7 @@ index 153407c..611cba9 100644 -} -__setup("vdso=", vdso_setup); diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c -index a1e21ae..0b6bc7b 100644 +index 69b9ef6..cbe5f3a 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -86,8 +86,6 @@ EXPORT_SYMBOL_GPL(xen_start_info); @@ -27467,7 +27458,7 @@ index a1e21ae..0b6bc7b 100644 } #endif -@@ -1041,7 +1039,7 @@ static const struct pv_apic_ops xen_apic_ops __initconst = { +@@ -1057,7 +1055,7 @@ static const struct pv_apic_ops xen_apic_ops __initconst = { #endif }; @@ -27476,7 +27467,7 @@ index a1e21ae..0b6bc7b 100644 { struct sched_shutdown r = { .reason = reason }; -@@ -1049,17 +1047,17 @@ static void xen_reboot(int reason) +@@ -1065,17 +1063,17 @@ static void xen_reboot(int reason) BUG(); } @@ -27497,7 +27488,7 @@ index a1e21ae..0b6bc7b 100644 { xen_reboot(SHUTDOWN_poweroff); } -@@ -1165,7 +1163,17 @@ asmlinkage void __init xen_start_kernel(void) +@@ -1181,7 +1179,17 @@ asmlinkage void __init xen_start_kernel(void) __userpte_alloc_gfp &= ~__GFP_HIGHMEM; /* Work out if we support NX */ @@ -27516,7 +27507,7 @@ index a1e21ae..0b6bc7b 100644 xen_setup_features(); -@@ -1196,13 +1204,6 @@ asmlinkage void __init xen_start_kernel(void) +@@ -1212,13 +1220,6 @@ asmlinkage void __init xen_start_kernel(void) machine_ops = xen_machine_ops; @@ -30155,7 +30146,7 @@ index 1ee8ce7..b778bef 100644 return 0; diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c -index b366b34..7e61653 100644 +index 0d91655..96118e0 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -414,7 +414,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, @@ -30250,10 +30241,10 @@ index eb1d864..39ee5a7 100644 pr_info("dmatest: Started %u threads using %s\n", diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c -index c9eee6d..f9d5280 100644 +index a9d5482..376077f 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c -@@ -2685,7 +2685,7 @@ static void __devexit amd64_remove_one_instance(struct pci_dev *pdev) +@@ -2682,7 +2682,7 @@ static void __devexit amd64_remove_one_instance(struct pci_dev *pdev) * PCI core identifies what devices are on a system during boot, and then * inquiry this table to see if this driver is for a given device found. */ @@ -31972,10 +31963,10 @@ index 4ef02b2..8a96831 100644 for (i = 0; i < hid->maxcollection; i++) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c -index 4065374..10ed7dc 100644 +index f4c3d28..82f45a9 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c -@@ -400,8 +400,8 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, +@@ -402,8 +402,8 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, int ret = 0; int t; @@ -34363,7 +34354,7 @@ index 62306e5..c32000a 100644 "md/raid1:%s: read error corrected " "(%d sectors at %llu on %s)\n", diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c -index 0634ee5..1686c46 100644 +index 8f67c4d..cea5925 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1455,7 +1455,7 @@ static void end_sync_read(struct bio *bio, int error) @@ -42615,7 +42606,7 @@ index 3c14e43..eafa544 100644 +4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 +4 4 4 4 4 4 diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c -index 41746bb..febcb44 100644 +index cb5988f..a44fee7 100644 --- a/drivers/video/udlfb.c +++ b/drivers/video/udlfb.c @@ -619,11 +619,11 @@ int dlfb_handle_damage(struct dlfb_data *dev, int x, int y, @@ -44871,19 +44862,10 @@ index 112e45a..b59845b 100644 /* diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c -index 51352de..93292ff 100644 +index f854cf9..93292ff 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c -@@ -210,6 +210,8 @@ static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, - - err = get_user(palp, &up->palette); - err |= get_user(length, &up->length); -+ if (err) -+ return -EFAULT; - - up_native = compat_alloc_user_space(sizeof(struct video_spu_palette)); - err = put_user(compat_ptr(palp), &up_native->palette); -@@ -621,7 +623,7 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd, +@@ -623,7 +623,7 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd, return -EFAULT; if (__get_user(udata, &ss32->iomem_base)) return -EFAULT; @@ -44892,7 +44874,7 @@ index 51352de..93292ff 100644 if (__get_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift) || __get_user(ss.port_high, &ss32->port_high)) return -EFAULT; -@@ -796,7 +798,7 @@ static int compat_ioctl_preallocate(struct file *file, +@@ -798,7 +798,7 @@ static int compat_ioctl_preallocate(struct file *file, copy_in_user(&p->l_len, &p32->l_len, sizeof(s64)) || copy_in_user(&p->l_sysid, &p32->l_sysid, sizeof(s32)) || copy_in_user(&p->l_pid, &p32->l_pid, sizeof(u32)) || @@ -44901,7 +44883,7 @@ index 51352de..93292ff 100644 return -EFAULT; return ioctl_preallocate(file, p); -@@ -1644,8 +1646,8 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, +@@ -1646,8 +1646,8 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, static int __init init_sys32_ioctl_cmp(const void *p, const void *q) { unsigned int a, b; @@ -45066,7 +45048,7 @@ index a6f3763..f38ed00 100644 out_free_fd: diff --git a/fs/exec.c b/fs/exec.c -index 160cd2f..7f5ba47 100644 +index 121ccae..c12bdc7 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -55,12 +55,33 @@ @@ -47845,7 +47827,7 @@ index ee4e66b..9a39f9c 100644 spin_unlock(&inode->i_lock); } diff --git a/fs/isofs/export.c b/fs/isofs/export.c -index dd4687f..e9b81e0 100644 +index 516eb21..fd88add 100644 --- a/fs/isofs/export.c +++ b/fs/isofs/export.c @@ -135,6 +135,7 @@ isofs_export_encode_fh(struct dentry *dentry, @@ -50947,7 +50929,7 @@ index 014fcb4..980206f 100644 pipe_unlock(ipipe); diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c -index 7fdf6a7..e6cd8ad 100644 +index fabbb81..91a12e3 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -642,6 +642,18 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd, @@ -67493,10 +67475,10 @@ index b463871..fa3ea1f 100644 * nsown_capable - Check superior capability to one's own user_ns * @cap: The capability in question diff --git a/kernel/cgroup.c b/kernel/cgroup.c -index cdc0354..aab57fc 100644 +index 6337535..861ca46 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c -@@ -5156,7 +5156,7 @@ static int cgroup_css_links_read(struct cgroup *cont, +@@ -5155,7 +5155,7 @@ static int cgroup_css_links_read(struct cgroup *cont, struct css_set *cg = link->cg; struct task_struct *task; int count = 0; @@ -68968,7 +68950,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 6969ef0..39c391d 100644 +index 6c8fa34..0ab39b6 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -58,6 +58,7 @@ @@ -69486,7 +69468,7 @@ index 6969ef0..39c391d 100644 DEBUGP("\t0x%lx %s\n", shdr->sh_addr, info->secstrings + shdr->sh_name); } -@@ -2688,12 +2787,12 @@ static void flush_module_icache(const struct module *mod) +@@ -2692,12 +2791,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. */ @@ -69505,7 +69487,7 @@ index 6969ef0..39c391d 100644 set_fs(old_fs); } -@@ -2773,8 +2872,10 @@ static void module_deallocate(struct module *mod, struct load_info *info) +@@ -2777,8 +2876,10 @@ static void module_deallocate(struct module *mod, struct load_info *info) { kfree(info->strmap); percpu_modfree(mod); @@ -69518,7 +69500,7 @@ index 6969ef0..39c391d 100644 } int __weak module_finalize(const Elf_Ehdr *hdr, -@@ -2838,9 +2939,38 @@ static struct module *load_module(void __user *umod, +@@ -2842,9 +2943,38 @@ static struct module *load_module(void __user *umod, if (err) goto free_unload; @@ -69557,7 +69539,7 @@ index 6969ef0..39c391d 100644 /* Fix up syms, so that st_value is a pointer to location. */ err = simplify_symbols(mod, &info); if (err < 0) -@@ -2856,13 +2986,6 @@ static struct module *load_module(void __user *umod, +@@ -2860,13 +2990,6 @@ static struct module *load_module(void __user *umod, flush_module_icache(mod); @@ -69571,7 +69553,7 @@ index 6969ef0..39c391d 100644 /* Mark state as coming so strong_try_module_get() ignores us. */ mod->state = MODULE_STATE_COMING; -@@ -2920,11 +3043,10 @@ static struct module *load_module(void __user *umod, +@@ -2924,11 +3047,10 @@ static struct module *load_module(void __user *umod, unlock: mutex_unlock(&module_mutex); synchronize_sched(); @@ -69584,7 +69566,7 @@ index 6969ef0..39c391d 100644 free_unload: module_unload_free(mod); free_module: -@@ -2965,16 +3087,16 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, +@@ -2969,16 +3091,16 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, MODULE_STATE_COMING, mod); /* Set RO and NX regions for core */ @@ -69609,7 +69591,7 @@ index 6969ef0..39c391d 100644 do_mod_ctors(mod); /* Start the module */ -@@ -3020,11 +3142,12 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, +@@ -3024,11 +3146,12 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, mod->strtab = mod->core_strtab; #endif unset_module_init_ro_nx(mod); @@ -69627,7 +69609,7 @@ index 6969ef0..39c391d 100644 mutex_unlock(&module_mutex); return 0; -@@ -3055,10 +3178,16 @@ static const char *get_ksymbol(struct module *mod, +@@ -3059,10 +3182,16 @@ static const char *get_ksymbol(struct module *mod, unsigned long nextval; /* At worse, next value is at end of module */ @@ -69647,7 +69629,7 @@ index 6969ef0..39c391d 100644 /* Scan for closest preceding symbol, and next symbol. (ELF starts real symbols at 1). */ -@@ -3306,7 +3435,7 @@ static int m_show(struct seq_file *m, void *p) +@@ -3310,7 +3439,7 @@ static int m_show(struct seq_file *m, void *p) char buf[8]; seq_printf(m, "%s %u", @@ -69656,7 +69638,7 @@ index 6969ef0..39c391d 100644 print_unload_info(m, mod); /* Informative for users. */ -@@ -3315,7 +3444,7 @@ static int m_show(struct seq_file *m, void *p) +@@ -3319,7 +3448,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. */ @@ -69665,7 +69647,7 @@ index 6969ef0..39c391d 100644 /* Taints info */ if (mod->taints) -@@ -3351,7 +3480,17 @@ static const struct file_operations proc_modules_operations = { +@@ -3355,7 +3484,17 @@ static const struct file_operations proc_modules_operations = { static int __init proc_modules_init(void) { @@ -69683,7 +69665,7 @@ index 6969ef0..39c391d 100644 return 0; } module_init(proc_modules_init); -@@ -3410,12 +3549,12 @@ struct module *__module_address(unsigned long addr) +@@ -3414,12 +3553,12 @@ struct module *__module_address(unsigned long addr) { struct module *mod; @@ -69699,7 +69681,7 @@ index 6969ef0..39c391d 100644 return mod; return NULL; } -@@ -3449,11 +3588,20 @@ bool is_module_text_address(unsigned long addr) +@@ -3453,11 +3592,20 @@ bool is_module_text_address(unsigned long addr) */ struct module *__module_text_address(unsigned long addr) { @@ -71140,7 +71122,7 @@ index 2c71d91..1021f81 100644 struct tasklet_struct *list; diff --git a/kernel/sys.c b/kernel/sys.c -index c504302..b76c328 100644 +index d7c4ab0..fc14d2f 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -158,6 +158,12 @@ static int set_one_prio(struct task_struct *p, int niceval, int error) @@ -71264,35 +71246,7 @@ index c504302..b76c328 100644 abort_creds(new); return old_fsgid; -@@ -1171,13 +1207,13 @@ DECLARE_RWSEM(uts_sem); - * Work around broken programs that cannot handle "Linux 3.0". - * Instead we map 3.x to 2.6.40+x, so e.g. 3.0 would be 2.6.40 - */ --static int override_release(char __user *release, int len) -+static int override_release(char __user *release, size_t len) - { - int ret = 0; -- char buf[65]; - - if (current->personality & UNAME26) { -- char *rest = UTS_RELEASE; -+ char buf[65] = { 0 }; -+ const char *rest = UTS_RELEASE; - int ndots = 0; - unsigned v; - -@@ -1189,7 +1225,10 @@ static int override_release(char __user *release, int len) - rest++; - } - v = ((LINUX_VERSION_CODE >> 8) & 0xff) + 40; -+ if (sizeof buf < len) -+ len = sizeof buf; - snprintf(buf, len, "2.6.%u%s", v, rest); -+ buf[len - 1] = 0; - ret = copy_to_user(release, buf, len); - } - return ret; -@@ -1244,19 +1283,19 @@ SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name) +@@ -1246,19 +1282,19 @@ SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name) return -EFAULT; down_read(&uts_sem); @@ -71317,7 +71271,7 @@ index c504302..b76c328 100644 __OLD_UTS_LEN); error |= __put_user(0, name->machine + __OLD_UTS_LEN); up_read(&uts_sem); -@@ -1721,7 +1760,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, +@@ -1723,7 +1759,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, error = get_dumpable(me->mm); break; case PR_SET_DUMPABLE: @@ -71753,7 +71707,7 @@ index fd4a7b1..fae5c2a 100644 cpumask_clear_cpu(cpu, tick_get_broadcast_mask()); tick_broadcast_clear_oneshot(cpu); diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c -index 5ee1ac0..335188f 100644 +index cb7f33e..7504d61 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -14,6 +14,7 @@ @@ -71892,10 +71846,10 @@ index 0b537f2..40d6c20 100644 return -ENOMEM; return 0; diff --git a/kernel/timer.c b/kernel/timer.c -index 9c3c62b..441690e 100644 +index c219db6..bb98998 100644 --- a/kernel/timer.c +++ b/kernel/timer.c -@@ -1304,7 +1304,7 @@ void update_process_times(int user_tick) +@@ -1306,7 +1306,7 @@ void update_process_times(int user_tick) /* * This function runs timers and the timer-tq in bottom half context. */ @@ -75710,10 +75664,10 @@ index e920aa3..137702a 100644 rc = process_vm_rw_single_vec( (unsigned long)rvec[i].iov_base, rvec[i].iov_len, diff --git a/mm/rmap.c b/mm/rmap.c -index a4fd368..e0ffec7 100644 +index 8685697..b490361 100644 --- a/mm/rmap.c +++ b/mm/rmap.c -@@ -152,6 +152,10 @@ int anon_vma_prepare(struct vm_area_struct *vma) +@@ -153,6 +153,10 @@ int anon_vma_prepare(struct vm_area_struct *vma) struct anon_vma *anon_vma = vma->anon_vma; struct anon_vma_chain *avc; @@ -75724,7 +75678,7 @@ index a4fd368..e0ffec7 100644 might_sleep(); if (unlikely(!anon_vma)) { struct mm_struct *mm = vma->vm_mm; -@@ -161,6 +165,12 @@ int anon_vma_prepare(struct vm_area_struct *vma) +@@ -162,6 +166,12 @@ int anon_vma_prepare(struct vm_area_struct *vma) if (!avc) goto out_enomem; @@ -75737,7 +75691,7 @@ index a4fd368..e0ffec7 100644 anon_vma = find_mergeable_anon_vma(vma); allocated = NULL; if (!anon_vma) { -@@ -174,6 +184,21 @@ int anon_vma_prepare(struct vm_area_struct *vma) +@@ -175,6 +185,21 @@ int anon_vma_prepare(struct vm_area_struct *vma) /* page_table_lock to protect against threads */ spin_lock(&mm->page_table_lock); if (likely(!vma->anon_vma)) { @@ -75759,7 +75713,7 @@ index a4fd368..e0ffec7 100644 vma->anon_vma = anon_vma; avc->anon_vma = anon_vma; avc->vma = vma; -@@ -187,12 +212,24 @@ int anon_vma_prepare(struct vm_area_struct *vma) +@@ -188,12 +213,24 @@ int anon_vma_prepare(struct vm_area_struct *vma) if (unlikely(allocated)) put_anon_vma(allocated); @@ -75784,7 +75738,7 @@ index a4fd368..e0ffec7 100644 anon_vma_chain_free(avc); out_enomem: return -ENOMEM; -@@ -243,7 +280,7 @@ static void anon_vma_chain_link(struct vm_area_struct *vma, +@@ -244,7 +281,7 @@ static void anon_vma_chain_link(struct vm_area_struct *vma, * Attach the anon_vmas from src to dst. * Returns 0 on success, -ENOMEM on failure. */ @@ -75793,7 +75747,7 @@ index a4fd368..e0ffec7 100644 { struct anon_vma_chain *avc, *pavc; struct anon_vma *root = NULL; -@@ -276,7 +313,7 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src) +@@ -277,7 +314,7 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src) * the corresponding VMA in the parent process is attached to. * Returns 0 on success, non-zero on failure. */ @@ -75803,7 +75757,7 @@ index a4fd368..e0ffec7 100644 struct anon_vma_chain *avc; struct anon_vma *anon_vma; diff --git a/mm/shmem.c b/mm/shmem.c -index 7a82174..75d1c8b 100644 +index 126ca35..77e6609 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -31,7 +31,7 @@ @@ -75824,7 +75778,7 @@ index 7a82174..75d1c8b 100644 struct shmem_xattr { struct list_head list; /* anchored by shmem_inode_info->xattr_list */ -@@ -2181,8 +2181,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) +@@ -2183,8 +2183,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 */ @@ -77891,7 +77845,7 @@ index 68bbf9f..5ef0d12 100644 return err; diff --git a/net/core/dev.c b/net/core/dev.c -index abe1147..d7e4046 100644 +index f500a69..94fbae3 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1142,10 +1142,14 @@ void dev_load(struct net *net, const char *name) @@ -77954,7 +77908,7 @@ index abe1147..d7e4046 100644 { struct softnet_data *sd = &__get_cpu_var(softnet_data); -@@ -3327,7 +3331,7 @@ ncls: +@@ -3330,7 +3334,7 @@ ncls: if (pt_prev) { ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev); } else { @@ -77963,7 +77917,7 @@ index abe1147..d7e4046 100644 kfree_skb(skb); /* Jamal, now you will not able to escape explaining * me how you were going to use this. :-) -@@ -3892,7 +3896,7 @@ void netif_napi_del(struct napi_struct *napi) +@@ -3895,7 +3899,7 @@ void netif_napi_del(struct napi_struct *napi) } EXPORT_SYMBOL(netif_napi_del); @@ -77972,7 +77926,7 @@ index abe1147..d7e4046 100644 { struct softnet_data *sd = &__get_cpu_var(softnet_data); unsigned long time_limit = jiffies + 2; -@@ -4362,8 +4366,13 @@ static int ptype_seq_show(struct seq_file *seq, void *v) +@@ -4365,8 +4369,13 @@ static int ptype_seq_show(struct seq_file *seq, void *v) else seq_printf(seq, "%04x", ntohs(pt->type)); @@ -77986,7 +77940,7 @@ index abe1147..d7e4046 100644 } return 0; -@@ -5920,7 +5929,7 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, +@@ -5923,7 +5932,7 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, } else { netdev_stats_to_stats64(storage, &dev->stats); } @@ -78693,7 +78647,7 @@ index a08a621..a1ca37e 100644 if (icsk->icsk_af_ops->conn_request(sk, skb) < 0) return 1; diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c -index de69cec..74908e1 100644 +index 58c09a0..b62df0b 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -87,6 +87,9 @@ int sysctl_tcp_tw_reuse __read_mostly; @@ -78706,7 +78660,7 @@ index de69cec..74908e1 100644 #ifdef CONFIG_TCP_MD5SIG static struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk, -@@ -1636,6 +1639,9 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) +@@ -1637,6 +1640,9 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) return 0; reset: @@ -78716,7 +78670,7 @@ index de69cec..74908e1 100644 tcp_v4_send_reset(rsk, skb); discard: kfree_skb(skb); -@@ -1698,12 +1704,19 @@ int tcp_v4_rcv(struct sk_buff *skb) +@@ -1699,12 +1705,19 @@ int tcp_v4_rcv(struct sk_buff *skb) TCP_SKB_CB(skb)->sacked = 0; sk = __inet_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest); @@ -78739,7 +78693,7 @@ index de69cec..74908e1 100644 if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) { NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP); -@@ -1753,6 +1766,10 @@ no_tcp_socket: +@@ -1754,6 +1767,10 @@ no_tcp_socket: bad_packet: TCP_INC_STATS_BH(net, TCP_MIB_INERRS); } else { @@ -78750,7 +78704,7 @@ index de69cec..74908e1 100644 tcp_v4_send_reset(NULL, skb); } -@@ -2413,7 +2430,11 @@ static void get_openreq4(const struct sock *sk, const struct request_sock *req, +@@ -2414,7 +2431,11 @@ static void get_openreq4(const struct sock *sk, const struct request_sock *req, 0, /* non standard timer */ 0, /* open_requests have no inode */ atomic_read(&sk->sk_refcnt), @@ -78762,7 +78716,7 @@ index de69cec..74908e1 100644 len); } -@@ -2463,7 +2484,12 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len) +@@ -2464,7 +2485,12 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len) sock_i_uid(sk), icsk->icsk_probes_out, sock_i_ino(sk), @@ -78776,7 +78730,7 @@ index de69cec..74908e1 100644 jiffies_to_clock_t(icsk->icsk_rto), jiffies_to_clock_t(icsk->icsk_ack.ato), (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong, -@@ -2491,7 +2517,13 @@ static void get_timewait4_sock(const struct inet_timewait_sock *tw, +@@ -2492,7 +2518,13 @@ static void get_timewait4_sock(const struct inet_timewait_sock *tw, " %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %pK%n", i, src, srcp, dest, destp, tw->tw_substate, 0, 0, 3, jiffies_to_clock_t(ttd), 0, 0, 0, 0, @@ -79188,7 +79142,7 @@ index 6e6c2c4..942cebf 100644 static int raw6_seq_show(struct seq_file *seq, void *v) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c -index 4a56574..9745b8a 100644 +index ccab3c8..99f760b 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -93,6 +93,10 @@ static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk, @@ -79202,7 +79156,7 @@ index 4a56574..9745b8a 100644 static void tcp_v6_hash(struct sock *sk) { if (sk->sk_state != TCP_CLOSE) { -@@ -1655,6 +1659,9 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) +@@ -1656,6 +1660,9 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) return 0; reset: @@ -79212,7 +79166,7 @@ index 4a56574..9745b8a 100644 tcp_v6_send_reset(sk, skb); discard: if (opt_skb) -@@ -1734,12 +1741,20 @@ static int tcp_v6_rcv(struct sk_buff *skb) +@@ -1735,12 +1742,20 @@ static int tcp_v6_rcv(struct sk_buff *skb) TCP_SKB_CB(skb)->sacked = 0; sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest); @@ -79235,7 +79189,7 @@ index 4a56574..9745b8a 100644 if (hdr->hop_limit < inet6_sk(sk)->min_hopcount) { NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP); -@@ -1787,6 +1802,10 @@ no_tcp_socket: +@@ -1788,6 +1803,10 @@ no_tcp_socket: bad_packet: TCP_INC_STATS_BH(net, TCP_MIB_INERRS); } else { @@ -79246,7 +79200,7 @@ index 4a56574..9745b8a 100644 tcp_v6_send_reset(NULL, skb); } -@@ -2047,7 +2066,13 @@ static void get_openreq6(struct seq_file *seq, +@@ -2048,7 +2067,13 @@ static void get_openreq6(struct seq_file *seq, uid, 0, /* non standard timer */ 0, /* open_requests have no inode */ @@ -79261,7 +79215,7 @@ index 4a56574..9745b8a 100644 } static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) -@@ -2097,7 +2122,12 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) +@@ -2098,7 +2123,12 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) sock_i_uid(sp), icsk->icsk_probes_out, sock_i_ino(sp), @@ -79275,7 +79229,7 @@ index 4a56574..9745b8a 100644 jiffies_to_clock_t(icsk->icsk_rto), jiffies_to_clock_t(icsk->icsk_ack.ato), (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong, -@@ -2132,7 +2162,13 @@ static void get_timewait6_sock(struct seq_file *seq, +@@ -2133,7 +2163,13 @@ static void get_timewait6_sock(struct seq_file *seq, dest->s6_addr32[2], dest->s6_addr32[3], destp, tw->tw_substate, 0, 0, 3, jiffies_to_clock_t(ttd), 0, 0, 0, 0, @@ -79897,10 +79851,10 @@ index aa2d720..d8aa111 100644 } diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c -index 1d15193..257c9255 100644 +index 7489bd3..5f4df88 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c -@@ -1485,6 +1485,10 @@ err_proto: +@@ -1491,6 +1491,10 @@ err_proto: #define UNCONFIRMED_NULLS_VAL ((1<<30)+0) #define DYING_NULLS_VAL ((1<<30)+1) @@ -79911,7 +79865,7 @@ index 1d15193..257c9255 100644 static int nf_conntrack_init_net(struct net *net) { int ret; -@@ -1498,7 +1502,11 @@ static int nf_conntrack_init_net(struct net *net) +@@ -1504,7 +1508,11 @@ static int nf_conntrack_init_net(struct net *net) goto err_stat; } @@ -91055,32 +91009,6 @@ index 6789d78..4afd019e 100644 + .endm + #endif -diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c -index af0f22f..9a7d479 100644 ---- a/usr/gen_init_cpio.c -+++ b/usr/gen_init_cpio.c -@@ -303,7 +303,7 @@ static int cpio_mkfile(const char *name, const char *location, - int retval; - int rc = -1; - int namesize; -- int i; -+ unsigned int i; - - mode |= S_IFREG; - -@@ -392,9 +392,10 @@ static char *cpio_replace_env(char *new_location) - *env_var = *expanded = '\0'; - strncat(env_var, start + 2, end - start - 2); - strncat(expanded, new_location, start - new_location); -- strncat(expanded, getenv(env_var), PATH_MAX); -- strncat(expanded, end + 1, PATH_MAX); -+ strncat(expanded, getenv(env_var), PATH_MAX - strlen(expanded)); -+ strncat(expanded, end + 1, PATH_MAX - strlen(expanded)); - strncpy(new_location, expanded, PATH_MAX); -+ new_location[PATH_MAX] = 0; - } else - break; - } diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index ec747dc..d3e1f29 100644 --- a/virt/kvm/kvm_main.c diff --git a/3.2.32/4430_grsec-remove-localversion-grsec.patch b/3.2.33/4430_grsec-remove-localversion-grsec.patch index 31cf878..31cf878 100644 --- a/3.2.32/4430_grsec-remove-localversion-grsec.patch +++ b/3.2.33/4430_grsec-remove-localversion-grsec.patch diff --git a/3.2.32/4435_grsec-mute-warnings.patch b/3.2.33/4435_grsec-mute-warnings.patch index e85abd6..e85abd6 100644 --- a/3.2.32/4435_grsec-mute-warnings.patch +++ b/3.2.33/4435_grsec-mute-warnings.patch diff --git a/3.2.32/4440_grsec-remove-protected-paths.patch b/3.2.33/4440_grsec-remove-protected-paths.patch index 637934a..637934a 100644 --- a/3.2.32/4440_grsec-remove-protected-paths.patch +++ b/3.2.33/4440_grsec-remove-protected-paths.patch diff --git a/3.2.32/4450_grsec-kconfig-default-gids.patch b/3.2.33/4450_grsec-kconfig-default-gids.patch index d4b0b7e..d4b0b7e 100644 --- a/3.2.32/4450_grsec-kconfig-default-gids.patch +++ b/3.2.33/4450_grsec-kconfig-default-gids.patch diff --git a/3.2.32/4465_selinux-avc_audit-log-curr_ip.patch b/3.2.33/4465_selinux-avc_audit-log-curr_ip.patch index 3ea7bcc..3ea7bcc 100644 --- a/3.2.32/4465_selinux-avc_audit-log-curr_ip.patch +++ b/3.2.33/4465_selinux-avc_audit-log-curr_ip.patch diff --git a/3.2.32/4470_disable-compat_vdso.patch b/3.2.33/4470_disable-compat_vdso.patch index 4742d01..4742d01 100644 --- a/3.2.32/4470_disable-compat_vdso.patch +++ b/3.2.33/4470_disable-compat_vdso.patch diff --git a/3.6.4/0000_README b/3.6.5/0000_README index 4789a33..dfd814a 100644 --- a/3.6.4/0000_README +++ b/3.6.5/0000_README @@ -2,7 +2,11 @@ README ----------------------------------------------------------------------------- Individual Patch Descriptions: ----------------------------------------------------------------------------- -Patch: 4420_grsecurity-2.9.1-3.6.4-201210291446.patch +Patch: 1004_linux-3.6.5.patch +From: http://www.kernel.org +Desc: Linux 3.6.5 + +Patch: 4420_grsecurity-2.9.1-3.6.5-201210312121.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.6.5/1004_linux-3.6.5.patch b/3.6.5/1004_linux-3.6.5.patch new file mode 100644 index 0000000..738b926 --- /dev/null +++ b/3.6.5/1004_linux-3.6.5.patch @@ -0,0 +1,4649 @@ +diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt +index ecc81e3..d187e9f 100644 +--- a/Documentation/devicetree/bindings/arm/atmel-at91.txt ++++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt +@@ -8,7 +8,7 @@ PIT Timer required properties: + shared across all System Controller members. + + TC/TCLIB Timer required properties: +-- compatible: Should be "atmel,<chip>-pit". ++- compatible: Should be "atmel,<chip>-tcb". + <chip> can be "at91rm9200" or "at91sam9x5" + - reg: Should contain registers location and length + - interrupts: Should contain all interrupts for the TC block +diff --git a/Makefile b/Makefile +index dcf132a..6e4a00d 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 6 +-SUBLEVEL = 4 ++SUBLEVEL = 5 + EXTRAVERSION = + NAME = Terrified Chipmunk + +diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c +index ebd8ad2..0181f7e 100644 +--- a/arch/arm/kernel/smp.c ++++ b/arch/arm/kernel/smp.c +@@ -222,18 +222,24 @@ static void percpu_timer_setup(void); + asmlinkage void __cpuinit secondary_start_kernel(void) + { + struct mm_struct *mm = &init_mm; +- unsigned int cpu = smp_processor_id(); ++ unsigned int cpu; ++ ++ /* ++ * The identity mapping is uncached (strongly ordered), so ++ * switch away from it before attempting any exclusive accesses. ++ */ ++ cpu_switch_mm(mm->pgd, mm); ++ enter_lazy_tlb(mm, current); ++ local_flush_tlb_all(); + + /* + * All kernel threads share the same mm context; grab a + * reference and switch to it. + */ ++ cpu = smp_processor_id(); + atomic_inc(&mm->mm_count); + current->active_mm = mm; + cpumask_set_cpu(cpu, mm_cpumask(mm)); +- cpu_switch_mm(mm->pgd, mm); +- enter_lazy_tlb(mm, current); +- local_flush_tlb_all(); + + printk("CPU%u: Booted secondary processor\n", cpu); + +diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c +index 01fb732..d5a4913 100644 +--- a/arch/arm/mach-at91/at91rm9200_devices.c ++++ b/arch/arm/mach-at91/at91rm9200_devices.c +@@ -463,7 +463,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 bce572a..18ca240 100644 +--- a/arch/arm/mach-at91/at91sam9260_devices.c ++++ b/arch/arm/mach-at91/at91sam9260_devices.c +@@ -471,7 +471,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 bc2590d..2495de8 100644 +--- a/arch/arm/mach-at91/at91sam9261_devices.c ++++ b/arch/arm/mach-at91/at91sam9261_devices.c +@@ -285,7 +285,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 9b6ca73..9877963 100644 +--- a/arch/arm/mach-at91/at91sam9263_devices.c ++++ b/arch/arm/mach-at91/at91sam9263_devices.c +@@ -542,7 +542,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 b3d365d..c82a427 100644 +--- a/arch/arm/mach-at91/at91sam9rl_devices.c ++++ b/arch/arm/mach-at91/at91sam9rl_devices.c +@@ -314,7 +314,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/board-neocore926.c b/arch/arm/mach-at91/board-neocore926.c +index 18103c5d..997d359 100644 +--- a/arch/arm/mach-at91/board-neocore926.c ++++ b/arch/arm/mach-at91/board-neocore926.c +@@ -129,7 +129,7 @@ static struct spi_board_info neocore926_spi_devices[] = { + .max_speed_hz = 125000 * 16, + .bus_num = 0, + .platform_data = &ads_info, +- .irq = AT91SAM9263_ID_IRQ1, ++ .irq = NR_IRQS_LEGACY + AT91SAM9263_ID_IRQ1, + }, + #endif + }; +diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c +index 2269be5..17659be 100644 +--- a/arch/arm/mach-at91/board-sam9261ek.c ++++ b/arch/arm/mach-at91/board-sam9261ek.c +@@ -309,7 +309,7 @@ static struct spi_board_info ek_spi_devices[] = { + .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ + .bus_num = 0, + .platform_data = &ads_info, +- .irq = AT91SAM9261_ID_IRQ0, ++ .irq = NR_IRQS_LEGACY + AT91SAM9261_ID_IRQ0, + .controller_data = (void *) AT91_PIN_PA28, /* CS pin */ + }, + #endif +diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c +index 82adf58..9e7153b 100644 +--- a/arch/arm/mach-at91/board-sam9263ek.c ++++ b/arch/arm/mach-at91/board-sam9263ek.c +@@ -132,7 +132,7 @@ static struct spi_board_info ek_spi_devices[] = { + .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ + .bus_num = 0, + .platform_data = &ads_info, +- .irq = AT91SAM9263_ID_IRQ1, ++ .irq = NR_IRQS_LEGACY + AT91SAM9263_ID_IRQ1, + }, + #endif + }; +diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h +index f496506..b62f560e 100644 +--- a/arch/arm/mach-at91/generic.h ++++ b/arch/arm/mach-at91/generic.h +@@ -26,7 +26,8 @@ extern void __init at91_dt_initialize(void); + extern void __init at91_init_irq_default(void); + extern void __init at91_init_interrupts(unsigned int priority[]); + extern void __init at91x40_init_interrupts(unsigned int priority[]); +-extern void __init at91_aic_init(unsigned int priority[]); ++extern void __init at91_aic_init(unsigned int priority[], ++ unsigned int ext_irq_mask); + extern int __init at91_aic_of_init(struct device_node *node, + struct device_node *parent); + extern int __init at91_aic5_of_init(struct device_node *node, +diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c +index 1e02c0e..febc2ee 100644 +--- a/arch/arm/mach-at91/irq.c ++++ b/arch/arm/mach-at91/irq.c +@@ -502,14 +502,19 @@ int __init at91_aic5_of_init(struct device_node *node, + /* + * Initialize the AIC interrupt controller. + */ +-void __init at91_aic_init(unsigned int *priority) ++void __init at91_aic_init(unsigned int *priority, unsigned int ext_irq_mask) + { + unsigned int i; + int irq_base; + +- if (at91_aic_pm_init()) ++ at91_extern_irq = kzalloc(BITS_TO_LONGS(n_irqs) ++ * sizeof(*at91_extern_irq), GFP_KERNEL); ++ ++ if (at91_aic_pm_init() || at91_extern_irq == NULL) + panic("Unable to allocate bit maps\n"); + ++ *at91_extern_irq = ext_irq_mask; ++ + at91_aic_base = ioremap(AT91_AIC, 512); + if (!at91_aic_base) + panic("Unable to ioremap AIC registers\n"); +diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c +index 944bffb..bd0e88c 100644 +--- a/arch/arm/mach-at91/setup.c ++++ b/arch/arm/mach-at91/setup.c +@@ -47,7 +47,7 @@ void __init at91_init_irq_default(void) + void __init at91_init_interrupts(unsigned int *priority) + { + /* Initialize the AIC interrupt controller */ +- at91_aic_init(priority); ++ at91_aic_init(priority, at91_extern_irq); + + /* Enable GPIO interrupts */ + at91_gpio_irq_setup(); +@@ -151,7 +151,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/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c +index 4eb39cd..3e02ae6 100644 +--- a/arch/arm/mach-exynos/common.c ++++ b/arch/arm/mach-exynos/common.c +@@ -47,6 +47,7 @@ + #include <plat/fimc-core.h> + #include <plat/iic-core.h> + #include <plat/tv-core.h> ++#include <plat/spi-core.h> + #include <plat/regs-serial.h> + + #include "common.h" +@@ -346,6 +347,8 @@ static void __init exynos4_map_io(void) + + s5p_fb_setname(0, "exynos4-fb"); + s5p_hdmi_setname("exynos4-hdmi"); ++ ++ s3c64xx_spi_setname("exynos4210-spi"); + } + + static void __init exynos5_map_io(void) +@@ -366,6 +369,8 @@ static void __init exynos5_map_io(void) + s3c_i2c0_setname("s3c2440-i2c"); + s3c_i2c1_setname("s3c2440-i2c"); + s3c_i2c2_setname("s3c2440-i2c"); ++ ++ s3c64xx_spi_setname("exynos4210-spi"); + } + + static void __init exynos4_init_clocks(int xtal) +diff --git a/arch/arm/mach-s3c24xx/s3c2416.c b/arch/arm/mach-s3c24xx/s3c2416.c +index ed5a95ec..77ee0b7 100644 +--- a/arch/arm/mach-s3c24xx/s3c2416.c ++++ b/arch/arm/mach-s3c24xx/s3c2416.c +@@ -61,6 +61,7 @@ + #include <plat/nand-core.h> + #include <plat/adc-core.h> + #include <plat/rtc-core.h> ++#include <plat/spi-core.h> + + static struct map_desc s3c2416_iodesc[] __initdata = { + IODESC_ENT(WATCHDOG), +@@ -132,6 +133,7 @@ void __init s3c2416_map_io(void) + /* initialize device information early */ + s3c2416_default_sdhci0(); + s3c2416_default_sdhci1(); ++ s3c64xx_spi_setname("s3c2443-spi"); + + iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc)); + } +diff --git a/arch/arm/mach-s3c24xx/s3c2443.c b/arch/arm/mach-s3c24xx/s3c2443.c +index ab648ad..165b6a6 100644 +--- a/arch/arm/mach-s3c24xx/s3c2443.c ++++ b/arch/arm/mach-s3c24xx/s3c2443.c +@@ -43,6 +43,7 @@ + #include <plat/nand-core.h> + #include <plat/adc-core.h> + #include <plat/rtc-core.h> ++#include <plat/spi-core.h> + + static struct map_desc s3c2443_iodesc[] __initdata = { + IODESC_ENT(WATCHDOG), +@@ -100,6 +101,9 @@ void __init s3c2443_map_io(void) + s3c24xx_gpiocfg_default.set_pull = s3c2443_gpio_setpull; + s3c24xx_gpiocfg_default.get_pull = s3c2443_gpio_getpull; + ++ /* initialize device information early */ ++ s3c64xx_spi_setname("s3c2443-spi"); ++ + iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc)); + } + +diff --git a/arch/arm/mach-s5p64x0/common.c b/arch/arm/mach-s5p64x0/common.c +index 6e6a0a9..111e404 100644 +--- a/arch/arm/mach-s5p64x0/common.c ++++ b/arch/arm/mach-s5p64x0/common.c +@@ -44,6 +44,7 @@ + #include <plat/sdhci.h> + #include <plat/adc-core.h> + #include <plat/fb-core.h> ++#include <plat/spi-core.h> + #include <plat/gpio-cfg.h> + #include <plat/regs-irqtype.h> + #include <plat/regs-serial.h> +@@ -179,6 +180,7 @@ void __init s5p6440_map_io(void) + /* initialize any device information early */ + s3c_adc_setname("s3c64xx-adc"); + s3c_fb_setname("s5p64x0-fb"); ++ s3c64xx_spi_setname("s5p64x0-spi"); + + s5p64x0_default_sdhci0(); + s5p64x0_default_sdhci1(); +@@ -193,6 +195,7 @@ void __init s5p6450_map_io(void) + /* initialize any device information early */ + s3c_adc_setname("s3c64xx-adc"); + s3c_fb_setname("s5p64x0-fb"); ++ s3c64xx_spi_setname("s5p64x0-spi"); + + s5p64x0_default_sdhci0(); + s5p64x0_default_sdhci1(); +diff --git a/arch/arm/mach-s5pc100/common.c b/arch/arm/mach-s5pc100/common.c +index 6219086..cc6e561 100644 +--- a/arch/arm/mach-s5pc100/common.c ++++ b/arch/arm/mach-s5pc100/common.c +@@ -45,6 +45,7 @@ + #include <plat/fb-core.h> + #include <plat/iic-core.h> + #include <plat/onenand-core.h> ++#include <plat/spi-core.h> + #include <plat/regs-serial.h> + #include <plat/watchdog-reset.h> + +@@ -165,6 +166,8 @@ void __init s5pc100_map_io(void) + s3c_onenand_setname("s5pc100-onenand"); + s3c_fb_setname("s5pc100-fb"); + s3c_cfcon_setname("s5pc100-pata"); ++ ++ s3c64xx_spi_setname("s5pc100-spi"); + } + + void __init s5pc100_init_clocks(int xtal) +diff --git a/arch/arm/mach-s5pv210/common.c b/arch/arm/mach-s5pv210/common.c +index 4c9e902..a0c50ef 100644 +--- a/arch/arm/mach-s5pv210/common.c ++++ b/arch/arm/mach-s5pv210/common.c +@@ -43,6 +43,7 @@ + #include <plat/iic-core.h> + #include <plat/keypad-core.h> + #include <plat/tv-core.h> ++#include <plat/spi-core.h> + #include <plat/regs-serial.h> + + #include "common.h" +@@ -196,6 +197,8 @@ void __init s5pv210_map_io(void) + + /* setup TV devices */ + s5p_hdmi_setname("s5pv210-hdmi"); ++ ++ s3c64xx_spi_setname("s5pv210-spi"); + } + + void __init s5pv210_init_clocks(int xtal) +diff --git a/arch/arm/plat-samsung/include/plat/spi-core.h b/arch/arm/plat-samsung/include/plat/spi-core.h +new file mode 100644 +index 0000000..0b9428a +--- /dev/null ++++ b/arch/arm/plat-samsung/include/plat/spi-core.h +@@ -0,0 +1,30 @@ ++/* ++ * Copyright (C) 2012 Heiko Stuebner <heiko@sntech.de> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#ifndef __PLAT_S3C_SPI_CORE_H ++#define __PLAT_S3C_SPI_CORE_H ++ ++/* These functions are only for use with the core support code, such as ++ * the cpu specific initialisation code ++ */ ++ ++/* re-define device name depending on support. */ ++static inline void s3c64xx_spi_setname(char *name) ++{ ++#ifdef CONFIG_S3C64XX_DEV_SPI0 ++ s3c64xx_device_spi0.name = name; ++#endif ++#ifdef CONFIG_S3C64XX_DEV_SPI1 ++ s3c64xx_device_spi1.name = name; ++#endif ++#ifdef CONFIG_S3C64XX_DEV_SPI2 ++ s3c64xx_device_spi2.name = name; ++#endif ++} ++ ++#endif /* __PLAT_S3C_SPI_CORE_H */ +diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h +index c9dcc18..029189d 100644 +--- a/arch/x86/include/asm/efi.h ++++ b/arch/x86/include/asm/efi.h +@@ -98,6 +98,7 @@ extern void efi_set_executable(efi_memory_desc_t *md, bool executable); + extern int efi_memblock_x86_reserve_range(void); + extern void efi_call_phys_prelog(void); + extern void efi_call_phys_epilog(void); ++extern void efi_unmap_memmap(void); + + #ifndef CONFIG_EFI + /* +diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c +index ed858e9..df06ade 100644 +--- a/arch/x86/kernel/e820.c ++++ b/arch/x86/kernel/e820.c +@@ -1077,6 +1077,9 @@ void __init memblock_x86_fill(void) + memblock_add(ei->addr, ei->size); + } + ++ /* throw away partial pages */ ++ memblock_trim_memory(PAGE_SIZE); ++ + memblock_dump_all(); + } + +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index 198e774..5cee802 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -920,18 +920,19 @@ void __init setup_arch(char **cmdline_p) + #ifdef CONFIG_X86_64 + if (max_pfn > max_low_pfn) { + int i; +- for (i = 0; i < e820.nr_map; i++) { +- struct e820entry *ei = &e820.map[i]; ++ unsigned long start, end; ++ unsigned long start_pfn, end_pfn; + +- if (ei->addr + ei->size <= 1UL << 32) +- continue; ++ for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, ++ NULL) { + +- if (ei->type == E820_RESERVED) ++ end = PFN_PHYS(end_pfn); ++ if (end <= (1UL<<32)) + continue; + ++ start = PFN_PHYS(start_pfn); + max_pfn_mapped = init_memory_mapping( +- ei->addr < 1UL << 32 ? 1UL << 32 : ei->addr, +- ei->addr + ei->size); ++ max((1UL<<32), start), end); + } + + /* can we preseve max_low_pfn ?*/ +@@ -1047,6 +1048,18 @@ void __init setup_arch(char **cmdline_p) + mcheck_init(); + + arch_init_ideal_nops(); ++ ++#ifdef CONFIG_EFI ++ /* Once setup is done above, disable efi_enabled on mismatched ++ * firmware/kernel archtectures since there is no support for ++ * runtime services. ++ */ ++ if (efi_enabled && IS_ENABLED(CONFIG_X86_64) != efi_64bit) { ++ pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); ++ efi_unmap_memmap(); ++ efi_enabled = 0; ++ } ++#endif + } + + #ifdef CONFIG_X86_32 +diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c +index ab1f6a9..d7aea41 100644 +--- a/arch/x86/mm/init.c ++++ b/arch/x86/mm/init.c +@@ -35,40 +35,44 @@ struct map_range { + unsigned page_size_mask; + }; + +-static void __init find_early_table_space(struct map_range *mr, unsigned long end, +- int use_pse, int use_gbpages) ++/* ++ * First calculate space needed for kernel direct mapping page tables to cover ++ * mr[0].start to mr[nr_range - 1].end, while accounting for possible 2M and 1GB ++ * pages. Then find enough contiguous space for those page tables. ++ */ ++static void __init find_early_table_space(struct map_range *mr, int nr_range) + { +- unsigned long puds, pmds, ptes, tables, start = 0, good_end = end; ++ int i; ++ unsigned long puds = 0, pmds = 0, ptes = 0, tables; ++ unsigned long start = 0, good_end; + phys_addr_t base; + +- puds = (end + PUD_SIZE - 1) >> PUD_SHIFT; +- tables = roundup(puds * sizeof(pud_t), PAGE_SIZE); +- +- if (use_gbpages) { +- unsigned long extra; +- +- extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT); +- pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT; +- } else +- pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; ++ for (i = 0; i < nr_range; i++) { ++ unsigned long range, extra; + +- tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE); ++ range = mr[i].end - mr[i].start; ++ puds += (range + PUD_SIZE - 1) >> PUD_SHIFT; + +- if (use_pse) { +- unsigned long extra; ++ if (mr[i].page_size_mask & (1 << PG_LEVEL_1G)) { ++ extra = range - ((range >> PUD_SHIFT) << PUD_SHIFT); ++ pmds += (extra + PMD_SIZE - 1) >> PMD_SHIFT; ++ } else { ++ pmds += (range + PMD_SIZE - 1) >> PMD_SHIFT; ++ } + +- extra = end - ((end>>PMD_SHIFT) << PMD_SHIFT); ++ if (mr[i].page_size_mask & (1 << PG_LEVEL_2M)) { ++ extra = range - ((range >> PMD_SHIFT) << PMD_SHIFT); + #ifdef CONFIG_X86_32 +- extra += PMD_SIZE; ++ extra += PMD_SIZE; + #endif +- /* The first 2/4M doesn't use large pages. */ +- if (mr->start < PMD_SIZE) +- extra += mr->end - mr->start; +- +- ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT; +- } else +- ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ ptes += (extra + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ } else { ++ ptes += (range + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ } ++ } + ++ tables = roundup(puds * sizeof(pud_t), PAGE_SIZE); ++ tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE); + tables += roundup(ptes * sizeof(pte_t), PAGE_SIZE); + + #ifdef CONFIG_X86_32 +@@ -86,7 +90,7 @@ static void __init find_early_table_space(struct map_range *mr, unsigned long en + pgt_buf_top = pgt_buf_start + (tables >> PAGE_SHIFT); + + printk(KERN_DEBUG "kernel direct mapping tables up to %#lx @ [mem %#010lx-%#010lx]\n", +- end - 1, pgt_buf_start << PAGE_SHIFT, ++ mr[nr_range - 1].end - 1, pgt_buf_start << PAGE_SHIFT, + (pgt_buf_top << PAGE_SHIFT) - 1); + } + +@@ -267,7 +271,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, + * nodes are discovered. + */ + if (!after_bootmem) +- find_early_table_space(&mr[0], end, use_pse, use_gbpages); ++ find_early_table_space(mr, nr_range); + + for (i = 0; i < nr_range; i++) + ret = kernel_physical_mapping_init(mr[i].start, mr[i].end, +diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c +index 2b6b4a3..3baff25 100644 +--- a/arch/x86/mm/init_64.c ++++ b/arch/x86/mm/init_64.c +@@ -386,7 +386,8 @@ phys_pte_init(pte_t *pte_page, unsigned long addr, unsigned long end, + * these mappings are more intelligent. + */ + if (pte_val(*pte)) { +- pages++; ++ if (!after_bootmem) ++ pages++; + continue; + } + +@@ -451,6 +452,8 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end, + * attributes. + */ + if (page_size_mask & (1 << PG_LEVEL_2M)) { ++ if (!after_bootmem) ++ pages++; + last_map_addr = next; + continue; + } +@@ -526,6 +529,8 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end, + * attributes. + */ + if (page_size_mask & (1 << PG_LEVEL_1G)) { ++ if (!after_bootmem) ++ pages++; + last_map_addr = next; + continue; + } +diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c +index f55a4ce..72d8899 100644 +--- a/arch/x86/platform/efi/efi.c ++++ b/arch/x86/platform/efi/efi.c +@@ -69,11 +69,15 @@ EXPORT_SYMBOL(efi); + struct efi_memory_map memmap; + + bool efi_64bit; +-static bool efi_native; + + static struct efi efi_phys __initdata; + static efi_system_table_t efi_systab __initdata; + ++static inline bool efi_is_native(void) ++{ ++ return IS_ENABLED(CONFIG_X86_64) == efi_64bit; ++} ++ + static int __init setup_noefi(char *arg) + { + efi_enabled = 0; +@@ -419,10 +423,21 @@ void __init efi_reserve_boot_services(void) + } + } + +-static void __init efi_free_boot_services(void) ++void __init efi_unmap_memmap(void) ++{ ++ if (memmap.map) { ++ early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); ++ memmap.map = NULL; ++ } ++} ++ ++void __init efi_free_boot_services(void) + { + void *p; + ++ if (!efi_is_native()) ++ return; ++ + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { + efi_memory_desc_t *md = p; + unsigned long long start = md->phys_addr; +@@ -438,6 +453,8 @@ static void __init efi_free_boot_services(void) + + free_bootmem_late(start, size); + } ++ ++ efi_unmap_memmap(); + } + + static int __init efi_systab_init(void *phys) +@@ -670,12 +687,10 @@ void __init efi_init(void) + return; + } + efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab; +- efi_native = !efi_64bit; + #else + efi_phys.systab = (efi_system_table_t *) + (boot_params.efi_info.efi_systab | + ((__u64)boot_params.efi_info.efi_systab_hi<<32)); +- efi_native = efi_64bit; + #endif + + if (efi_systab_init(efi_phys.systab)) { +@@ -709,7 +724,7 @@ void __init efi_init(void) + * that doesn't match the kernel 32/64-bit mode. + */ + +- if (!efi_native) ++ if (!efi_is_native()) + pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); + else if (efi_runtime_init()) { + efi_enabled = 0; +@@ -721,7 +736,7 @@ void __init efi_init(void) + return; + } + #ifdef CONFIG_X86_32 +- if (efi_native) { ++ if (efi_is_native()) { + x86_platform.get_wallclock = efi_get_time; + x86_platform.set_wallclock = efi_set_rtc_mmss; + } +@@ -787,8 +802,10 @@ void __init efi_enter_virtual_mode(void) + * non-native EFI + */ + +- if (!efi_native) +- goto out; ++ if (!efi_is_native()) { ++ efi_unmap_memmap(); ++ return; ++ } + + /* Merge contiguous regions of the same type and attribute */ + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { +@@ -878,13 +895,6 @@ void __init efi_enter_virtual_mode(void) + } + + /* +- * Thankfully, it does seem that no runtime services other than +- * SetVirtualAddressMap() will touch boot services code, so we can +- * get rid of it all at this point +- */ +- efi_free_boot_services(); +- +- /* + * Now that EFI is in virtual mode, update the function + * pointers in the runtime service table to the new virtual addresses. + * +@@ -907,9 +917,6 @@ void __init efi_enter_virtual_mode(void) + if (__supported_pte_mask & _PAGE_NX) + runtime_code_page_mkexec(); + +-out: +- early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); +- memmap.map = NULL; + kfree(new_memmap); + } + +diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c +index 758af9c..0059e26 100644 +--- a/drivers/bcma/main.c ++++ b/drivers/bcma/main.c +@@ -141,9 +141,10 @@ static int bcma_register_cores(struct bcma_bus *bus) + + static void bcma_unregister_cores(struct bcma_bus *bus) + { +- struct bcma_device *core; ++ struct bcma_device *core, *tmp; + +- list_for_each_entry(core, &bus->cores, list) { ++ list_for_each_entry_safe(core, tmp, &bus->cores, list) { ++ list_del(&core->list); + if (core->dev_registered) + device_unregister(&core->dev); + } +diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c +index 1a40935..c671369 100644 +--- a/drivers/cpufreq/powernow-k8.c ++++ b/drivers/cpufreq/powernow-k8.c +@@ -1223,14 +1223,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, + struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq, + .relation = relation }; + +- /* +- * Must run on @pol->cpu. cpufreq core is responsible for ensuring +- * that we're bound to the current CPU and pol->cpu stays online. +- */ +- if (smp_processor_id() == pol->cpu) +- return powernowk8_target_fn(&pta); +- else +- return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); ++ return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); + } + + /* Driver entry point to verify the policy and range of frequencies */ +diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c +index 5084975..8aa9113 100644 +--- a/drivers/dma/imx-dma.c ++++ b/drivers/dma/imx-dma.c +@@ -474,8 +474,10 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) + slot = i; + break; + } +- if (slot < 0) ++ if (slot < 0) { ++ spin_unlock_irqrestore(&imxdma->lock, flags); + return -EBUSY; ++ } + + imxdma->slots_2d[slot].xsr = d->x; + imxdma->slots_2d[slot].ysr = d->y; +diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c +index 434ad31..c439489 100644 +--- a/drivers/dma/sirf-dma.c ++++ b/drivers/dma/sirf-dma.c +@@ -109,7 +109,7 @@ static void sirfsoc_dma_execute(struct sirfsoc_dma_chan *schan) + sdesc = list_first_entry(&schan->queued, struct sirfsoc_dma_desc, + node); + /* Move the first queued descriptor to active list */ +- list_move_tail(&schan->queued, &schan->active); ++ list_move_tail(&sdesc->node, &schan->active); + + /* Start the DMA transfer */ + writel_relaxed(sdesc->width, sdma->base + SIRFSOC_DMA_WIDTH_0 + +@@ -428,7 +428,7 @@ static struct dma_async_tx_descriptor *sirfsoc_dma_prep_interleaved( + unsigned long iflags; + int ret; + +- if ((xt->dir != DMA_MEM_TO_DEV) || (xt->dir != DMA_DEV_TO_MEM)) { ++ if ((xt->dir != DMA_MEM_TO_DEV) && (xt->dir != DMA_DEV_TO_MEM)) { + ret = -EINVAL; + goto err_dir; + } +diff --git a/drivers/extcon/extcon_class.c b/drivers/extcon/extcon_class.c +index f6419f9..7dcfb7c 100644 +--- a/drivers/extcon/extcon_class.c ++++ b/drivers/extcon/extcon_class.c +@@ -575,6 +575,10 @@ static void extcon_cleanup(struct extcon_dev *edev, bool skip) + kfree(edev->cables); + } + ++#if defined(CONFIG_ANDROID) ++ if (switch_class) ++ class_compat_remove_link(switch_class, edev->dev, NULL); ++#endif + device_unregister(edev->dev); + put_device(edev->dev); + } +@@ -821,6 +825,9 @@ module_init(extcon_class_init); + + static void __exit extcon_class_exit(void) + { ++#if defined(CONFIG_ANDROID) ++ class_compat_unregister(switch_class); ++#endif + class_destroy(extcon_class); + } + module_exit(extcon_class_exit); +diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c +index d883b20..e932810 100644 +--- a/drivers/gpu/drm/radeon/evergreen_cs.c ++++ b/drivers/gpu/drm/radeon/evergreen_cs.c +@@ -2829,6 +2829,7 @@ static bool evergreen_vm_reg_valid(u32 reg) + case CAYMAN_SQ_EX_ALLOC_TABLE_SLOTS: + return true; + default: ++ DRM_ERROR("Invalid register 0x%x in CS\n", reg); + return false; + } + } +diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c +index 4065374..f4c3d28 100644 +--- a/drivers/hv/channel.c ++++ b/drivers/hv/channel.c +@@ -146,14 +146,14 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, + + if (ret != 0) { + err = ret; +- goto errorout; ++ goto error0; + } + + ret = hv_ringbuffer_init( + &newchannel->inbound, in, recv_ringbuffer_size); + if (ret != 0) { + err = ret; +- goto errorout; ++ goto error0; + } + + +@@ -168,7 +168,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, + + if (ret != 0) { + err = ret; +- goto errorout; ++ goto error0; + } + + /* Create and init the channel open message */ +@@ -177,7 +177,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, + GFP_KERNEL); + if (!open_info) { + err = -ENOMEM; +- goto errorout; ++ goto error0; + } + + init_completion(&open_info->waitevent); +@@ -193,7 +193,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, + + if (userdatalen > MAX_USER_DEFINED_BYTES) { + err = -EINVAL; +- goto errorout; ++ goto error0; + } + + if (userdatalen) +@@ -208,19 +208,18 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, + sizeof(struct vmbus_channel_open_channel)); + + if (ret != 0) +- goto cleanup; ++ goto error1; + + t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ); + if (t == 0) { + err = -ETIMEDOUT; +- goto errorout; ++ goto error1; + } + + + if (open_info->response.open_result.status) + err = open_info->response.open_result.status; + +-cleanup: + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); + list_del(&open_info->msglistentry); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); +@@ -228,9 +227,12 @@ cleanup: + kfree(open_info); + return err; + +-errorout: +- hv_ringbuffer_cleanup(&newchannel->outbound); +- hv_ringbuffer_cleanup(&newchannel->inbound); ++error1: ++ spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); ++ list_del(&open_info->msglistentry); ++ spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); ++ ++error0: + free_pages((unsigned long)out, + get_order(send_ringbuffer_size + recv_ringbuffer_size)); + kfree(open_info); +diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c +index 4e2a162..4e98100 100644 +--- a/drivers/net/ethernet/tile/tilegx.c ++++ b/drivers/net/ethernet/tile/tilegx.c +@@ -1334,11 +1334,11 @@ static int tso_count_edescs(struct sk_buff *skb) + { + struct skb_shared_info *sh = skb_shinfo(skb); + unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); +- unsigned int data_len = skb->data_len + skb->hdr_len - sh_len; ++ unsigned int data_len = skb->len - sh_len; + unsigned int p_len = sh->gso_size; + long f_id = -1; /* id of the current fragment */ +- long f_size = skb->hdr_len; /* size of the current fragment */ +- long f_used = sh_len; /* bytes used from the current fragment */ ++ long f_size = skb_headlen(skb) - sh_len; /* current fragment size */ ++ long f_used = 0; /* bytes used from the current fragment */ + long n; /* size of the current piece of payload */ + int num_edescs = 0; + int segment; +@@ -1353,7 +1353,7 @@ static int tso_count_edescs(struct sk_buff *skb) + /* Advance as needed. */ + while (f_used >= f_size) { + f_id++; +- f_size = sh->frags[f_id].size; ++ f_size = skb_frag_size(&sh->frags[f_id]); + f_used = 0; + } + +@@ -1384,13 +1384,13 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, + struct iphdr *ih; + struct tcphdr *th; + unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); +- unsigned int data_len = skb->data_len + skb->hdr_len - sh_len; ++ unsigned int data_len = skb->len - sh_len; + unsigned char *data = skb->data; + unsigned int ih_off, th_off, p_len; + unsigned int isum_seed, tsum_seed, id, seq; + long f_id = -1; /* id of the current fragment */ +- long f_size = skb->hdr_len; /* size of the current fragment */ +- long f_used = sh_len; /* bytes used from the current fragment */ ++ long f_size = skb_headlen(skb) - sh_len; /* current fragment size */ ++ long f_used = 0; /* bytes used from the current fragment */ + long n; /* size of the current piece of payload */ + int segment; + +@@ -1405,7 +1405,7 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, + isum_seed = ((0xFFFF - ih->check) + + (0xFFFF - ih->tot_len) + + (0xFFFF - ih->id)); +- tsum_seed = th->check + (0xFFFF ^ htons(sh_len + data_len)); ++ tsum_seed = th->check + (0xFFFF ^ htons(skb->len)); + id = ntohs(ih->id); + seq = ntohl(th->seq); + +@@ -1444,7 +1444,7 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, + /* Advance as needed. */ + while (f_used >= f_size) { + f_id++; +- f_size = sh->frags[f_id].size; ++ f_size = skb_frag_size(&sh->frags[f_id]); + f_used = 0; + } + +@@ -1478,14 +1478,14 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, + struct tile_net_priv *priv = netdev_priv(dev); + struct skb_shared_info *sh = skb_shinfo(skb); + unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); +- unsigned int data_len = skb->data_len + skb->hdr_len - sh_len; ++ unsigned int data_len = skb->len - sh_len; + unsigned int p_len = sh->gso_size; + gxio_mpipe_edesc_t edesc_head = { { 0 } }; + gxio_mpipe_edesc_t edesc_body = { { 0 } }; + long f_id = -1; /* id of the current fragment */ +- long f_size = skb->hdr_len; /* size of the current fragment */ +- long f_used = sh_len; /* bytes used from the current fragment */ +- void *f_data = skb->data; ++ long f_size = skb_headlen(skb) - sh_len; /* current fragment size */ ++ long f_used = 0; /* bytes used from the current fragment */ ++ void *f_data = skb->data + sh_len; + long n; /* size of the current piece of payload */ + unsigned long tx_packets = 0, tx_bytes = 0; + unsigned int csum_start; +@@ -1516,15 +1516,18 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, + + /* Egress the payload. */ + while (p_used < p_len) { ++ void *va; + + /* Advance as needed. */ + while (f_used >= f_size) { + f_id++; +- f_size = sh->frags[f_id].size; +- f_used = 0; ++ f_size = skb_frag_size(&sh->frags[f_id]); + f_data = tile_net_frag_buf(&sh->frags[f_id]); ++ f_used = 0; + } + ++ va = f_data + f_used; ++ + /* Use bytes from the current fragment. */ + n = p_len - p_used; + if (n > f_size - f_used) +@@ -1533,7 +1536,7 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, + p_used += n; + + /* Egress a piece of the payload. */ +- edesc_body.va = va_to_tile_io_addr(f_data) + f_used; ++ edesc_body.va = va_to_tile_io_addr(va); + edesc_body.xfer_size = n; + edesc_body.bound = !(p_used < p_len); + gxio_mpipe_equeue_put_at(equeue, edesc_body, slot); +diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c +index a03de71..d012982 100644 +--- a/drivers/net/usb/cdc_ether.c ++++ b/drivers/net/usb/cdc_ether.c +@@ -592,6 +592,32 @@ static const struct usb_device_id products [] = { + .driver_info = 0, + }, + ++/* Novatel USB551L and MC551 - handled by qmi_wwan */ ++{ ++ .match_flags = USB_DEVICE_ID_MATCH_VENDOR ++ | USB_DEVICE_ID_MATCH_PRODUCT ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = NOVATEL_VENDOR_ID, ++ .idProduct = 0xB001, ++ .bInterfaceClass = USB_CLASS_COMM, ++ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, ++ .bInterfaceProtocol = USB_CDC_PROTO_NONE, ++ .driver_info = 0, ++}, ++ ++/* Novatel E362 - handled by qmi_wwan */ ++{ ++ .match_flags = USB_DEVICE_ID_MATCH_VENDOR ++ | USB_DEVICE_ID_MATCH_PRODUCT ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = NOVATEL_VENDOR_ID, ++ .idProduct = 0x9010, ++ .bInterfaceClass = USB_CLASS_COMM, ++ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, ++ .bInterfaceProtocol = USB_CDC_PROTO_NONE, ++ .driver_info = 0, ++}, ++ + /* + * WHITELIST!!! + * +@@ -604,21 +630,6 @@ static const struct usb_device_id products [] = { + * because of bugs/quirks in a given product (like Zaurus, above). + */ + { +- /* Novatel USB551L */ +- /* This match must come *before* the generic CDC-ETHER match so that +- * we get FLAG_WWAN set on the device, since it's descriptors are +- * generic CDC-ETHER. +- */ +- .match_flags = USB_DEVICE_ID_MATCH_VENDOR +- | USB_DEVICE_ID_MATCH_PRODUCT +- | USB_DEVICE_ID_MATCH_INT_INFO, +- .idVendor = NOVATEL_VENDOR_ID, +- .idProduct = 0xB001, +- .bInterfaceClass = USB_CLASS_COMM, +- .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, +- .bInterfaceProtocol = USB_CDC_PROTO_NONE, +- .driver_info = (unsigned long)&wwan_info, +-}, { + /* ZTE (Vodafone) K3805-Z */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index 3543c9e..3585f93 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -364,6 +364,20 @@ static const struct usb_device_id products[] = { + USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 57), + .driver_info = (unsigned long)&qmi_wwan_info, + }, ++ { /* Novatel USB551L and MC551 */ ++ USB_DEVICE_AND_INTERFACE_INFO(0x1410, 0xb001, ++ USB_CLASS_COMM, ++ USB_CDC_SUBCLASS_ETHERNET, ++ USB_CDC_PROTO_NONE), ++ .driver_info = (unsigned long)&qmi_wwan_info, ++ }, ++ { /* Novatel E362 */ ++ USB_DEVICE_AND_INTERFACE_INFO(0x1410, 0x9010, ++ USB_CLASS_COMM, ++ USB_CDC_SUBCLASS_ETHERNET, ++ USB_CDC_PROTO_NONE), ++ .driver_info = (unsigned long)&qmi_wwan_info, ++ }, + + /* 2. Combined interface devices matching on class+protocol */ + { /* Huawei E367 and possibly others in "Windows mode" */ +diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +index 89bf94d..6f7cf49 100644 +--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h ++++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +@@ -534,107 +534,107 @@ static const u32 ar9300_2p2_baseband_core[][2] = { + + static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ +- {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, +- {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, +- {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, ++ {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, ++ {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, ++ {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, + {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, + {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, +- {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202}, +- {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400}, +- {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402}, +- {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404}, +- {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603}, +- {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02}, +- {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04}, +- {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20}, +- {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20}, +- {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22}, +- {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24}, +- {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640}, +- {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660}, +- {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861}, +- {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81}, +- {0x0000a54c, 0x5a08442e, 0x5a08442e, 0x47001a83, 0x47001a83}, +- {0x0000a550, 0x5e0a4431, 0x5e0a4431, 0x4a001c84, 0x4a001c84}, +- {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3}, +- {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5}, +- {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9}, +- {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb}, +- {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, ++ {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, ++ {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, ++ {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402}, ++ {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, ++ {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, ++ {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, ++ {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, ++ {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, ++ {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, ++ {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, ++ {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, ++ {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, ++ {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, ++ {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861}, ++ {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81}, ++ {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83}, ++ {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84}, ++ {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3}, ++ {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5}, ++ {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9}, ++ {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb}, ++ {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, ++ {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, ++ {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, ++ {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, ++ {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, ++ {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, ++ {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, + {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, + {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, + {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, +- {0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202}, +- {0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400}, +- {0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402}, +- {0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404}, +- {0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603}, +- {0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02}, +- {0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04}, +- {0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20}, +- {0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20}, +- {0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22}, +- {0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24}, +- {0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640}, +- {0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660}, +- {0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861}, +- {0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81}, +- {0x0000a5cc, 0x5a88442e, 0x5a88442e, 0x47801a83, 0x47801a83}, +- {0x0000a5d0, 0x5e8a4431, 0x5e8a4431, 0x4a801c84, 0x4a801c84}, +- {0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3}, +- {0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5}, +- {0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9}, +- {0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb}, +- {0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, +- {0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, +- {0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, +- {0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, +- {0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, +- {0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, +- {0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, ++ {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, ++ {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, ++ {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402}, ++ {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404}, ++ {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, ++ {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, ++ {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, ++ {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, ++ {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, ++ {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, ++ {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, ++ {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, ++ {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, ++ {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861}, ++ {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81}, ++ {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83}, ++ {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84}, ++ {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3}, ++ {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5}, ++ {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9}, ++ {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb}, ++ {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, ++ {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, ++ {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, ++ {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, ++ {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, ++ {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, ++ {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, +- {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, +- {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, +- {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000}, +- {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501}, +- {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501}, +- {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03}, +- {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, +- {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04}, +- {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, +- {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, +- {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, +- {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, +- {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, +- {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, +- {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, +- {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, ++ {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000}, ++ {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501}, ++ {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501}, ++ {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03}, ++ {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04}, ++ {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04}, ++ {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, ++ {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, ++ {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, ++ {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, ++ {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, ++ {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, ++ {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, ++ {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, +- {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, +- {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, +- {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, ++ {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, ++ {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, ++ {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, + {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, +- {0x00016048, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, ++ {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, +- {0x00016448, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, ++ {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, +- {0x00016848, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, ++ {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + }; + +diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c +index a140165..46d9d4e 100644 +--- a/drivers/net/wireless/b43/main.c ++++ b/drivers/net/wireless/b43/main.c +@@ -5374,6 +5374,8 @@ static void b43_bcma_remove(struct bcma_device *core) + cancel_work_sync(&wldev->restart_work); + + B43_WARN_ON(!wl); ++ if (!wldev->fw.ucode.data) ++ return; /* NULL if firmware never loaded */ + if (wl->current_dev == wldev && wl->hw_registred) { + b43_leds_stop(wldev); + ieee80211_unregister_hw(wl->hw); +@@ -5448,6 +5450,8 @@ static void b43_ssb_remove(struct ssb_device *sdev) + cancel_work_sync(&wldev->restart_work); + + B43_WARN_ON(!wl); ++ if (!wldev->fw.ucode.data) ++ return; /* NULL if firmware never loaded */ + if (wl->current_dev == wldev && wl->hw_registred) { + b43_leds_stop(wldev); + ieee80211_unregister_hw(wl->hw); +diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c +index 0df4591..6d1754a 100644 +--- a/drivers/net/wireless/ipw2x00/ipw2200.c ++++ b/drivers/net/wireless/ipw2x00/ipw2200.c +@@ -10479,7 +10479,7 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv, + } else + len = src->len; + +- dst = alloc_skb(len + sizeof(*rt_hdr), GFP_ATOMIC); ++ dst = alloc_skb(len + sizeof(*rt_hdr) + sizeof(u16)*2, GFP_ATOMIC); + if (!dst) + continue; + +diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c +index 349c205..da58620 100644 +--- a/drivers/net/wireless/iwlwifi/dvm/devices.c ++++ b/drivers/net/wireless/iwlwifi/dvm/devices.c +@@ -518,7 +518,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, + * See iwlagn_mac_channel_switch. + */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; +- struct iwl6000_channel_switch_cmd cmd; ++ struct iwl6000_channel_switch_cmd *cmd; + u32 switch_time_in_usec, ucode_switch_time; + u16 ch; + u32 tsf_low; +@@ -527,18 +527,25 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, + struct ieee80211_vif *vif = ctx->vif; + struct iwl_host_cmd hcmd = { + .id = REPLY_CHANNEL_SWITCH, +- .len = { sizeof(cmd), }, ++ .len = { sizeof(*cmd), }, + .flags = CMD_SYNC, +- .data = { &cmd, }, ++ .dataflags[0] = IWL_HCMD_DFL_NOCOPY, + }; ++ int err; + +- cmd.band = priv->band == IEEE80211_BAND_2GHZ; ++ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); ++ if (!cmd) ++ return -ENOMEM; ++ ++ hcmd.data[0] = cmd; ++ ++ cmd->band = priv->band == IEEE80211_BAND_2GHZ; + ch = ch_switch->channel->hw_value; + IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", + ctx->active.channel, ch); +- cmd.channel = cpu_to_le16(ch); +- cmd.rxon_flags = ctx->staging.flags; +- cmd.rxon_filter_flags = ctx->staging.filter_flags; ++ cmd->channel = cpu_to_le16(ch); ++ cmd->rxon_flags = ctx->staging.flags; ++ cmd->rxon_filter_flags = ctx->staging.filter_flags; + switch_count = ch_switch->count; + tsf_low = ch_switch->timestamp & 0x0ffffffff; + /* +@@ -554,23 +561,25 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, + switch_count = 0; + } + if (switch_count <= 1) +- cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); ++ cmd->switch_time = cpu_to_le32(priv->ucode_beacon_time); + else { + switch_time_in_usec = + vif->bss_conf.beacon_int * switch_count * TIME_UNIT; + ucode_switch_time = iwl_usecs_to_beacons(priv, + switch_time_in_usec, + beacon_interval); +- cmd.switch_time = iwl_add_beacon_time(priv, +- priv->ucode_beacon_time, +- ucode_switch_time, +- beacon_interval); ++ cmd->switch_time = iwl_add_beacon_time(priv, ++ priv->ucode_beacon_time, ++ ucode_switch_time, ++ beacon_interval); + } + IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", +- cmd.switch_time); +- cmd.expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; ++ cmd->switch_time); ++ cmd->expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; + +- return iwl_dvm_send_cmd(priv, &hcmd); ++ err = iwl_dvm_send_cmd(priv, &hcmd); ++ kfree(cmd); ++ return err; + } + + struct iwl_lib_ops iwl6000_lib = { +diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c +index 891cd6c..4eed510 100644 +--- a/drivers/rtc/rtc-imxdi.c ++++ b/drivers/rtc/rtc-imxdi.c +@@ -392,6 +392,8 @@ static int dryice_rtc_probe(struct platform_device *pdev) + if (imxdi->ioaddr == NULL) + return -ENOMEM; + ++ spin_lock_init(&imxdi->irq_lock); ++ + imxdi->irq = platform_get_irq(pdev, 0); + if (imxdi->irq < 0) + return imxdi->irq; +diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c +index 574e992..467d493 100644 +--- a/drivers/staging/android/binder.c ++++ b/drivers/staging/android/binder.c +@@ -655,7 +655,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, + page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE]; + + BUG_ON(*page); +- *page = alloc_page(GFP_KERNEL | __GFP_ZERO); ++ *page = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO); + if (*page == NULL) { + pr_err("binder: %d: binder_alloc_buf failed " + "for page at %p\n", proc->pid, page_addr); +@@ -2507,14 +2507,38 @@ static void binder_release_work(struct list_head *list) + struct binder_transaction *t; + + t = container_of(w, struct binder_transaction, work); +- if (t->buffer->target_node && !(t->flags & TF_ONE_WAY)) ++ if (t->buffer->target_node && ++ !(t->flags & TF_ONE_WAY)) { + binder_send_failed_reply(t, BR_DEAD_REPLY); ++ } else { ++ binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, ++ "binder: undelivered transaction %d\n", ++ t->debug_id); ++ t->buffer->transaction = NULL; ++ kfree(t); ++ binder_stats_deleted(BINDER_STAT_TRANSACTION); ++ } + } break; + case BINDER_WORK_TRANSACTION_COMPLETE: { ++ binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, ++ "binder: undelivered TRANSACTION_COMPLETE\n"); + kfree(w); + binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); + } break; ++ case BINDER_WORK_DEAD_BINDER_AND_CLEAR: ++ case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: { ++ struct binder_ref_death *death; ++ ++ death = container_of(w, struct binder_ref_death, work); ++ binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, ++ "binder: undelivered death notification, %p\n", ++ death->cookie); ++ kfree(death); ++ binder_stats_deleted(BINDER_STAT_DEATH); ++ } break; + default: ++ pr_err("binder: unexpected work type, %d, not freed\n", ++ w->type); + break; + } + } +@@ -2984,6 +3008,7 @@ static void binder_deferred_release(struct binder_proc *proc) + nodes++; + rb_erase(&node->rb_node, &proc->nodes); + list_del_init(&node->work.entry); ++ binder_release_work(&node->async_todo); + if (hlist_empty(&node->refs)) { + kfree(node); + binder_stats_deleted(BINDER_STAT_NODE); +@@ -3022,6 +3047,7 @@ static void binder_deferred_release(struct binder_proc *proc) + binder_delete_ref(ref); + } + binder_release_work(&proc->todo); ++ binder_release_work(&proc->delivered_death); + buffers = 0; + + while ((n = rb_first(&proc->allocated_buffers))) { +diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c +index cc8931f..aee22fd 100644 +--- a/drivers/staging/comedi/drivers/amplc_dio200.c ++++ b/drivers/staging/comedi/drivers/amplc_dio200.c +@@ -1429,6 +1429,8 @@ static void dio200_detach(struct comedi_device *dev) + const struct dio200_layout_struct *layout; + unsigned n; + ++ if (!thisboard) ++ return; + if (dev->irq) + free_irq(dev->irq, dev); + if (dev->subdevices) { +diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c +index f502879..b46e663 100644 +--- a/drivers/staging/comedi/drivers/amplc_pc236.c ++++ b/drivers/staging/comedi/drivers/amplc_pc236.c +@@ -577,10 +577,12 @@ static int __devinit pc236_attach_pci(struct comedi_device *dev, + + static void pc236_detach(struct comedi_device *dev) + { +- struct pc236_private *devpriv = dev->private; ++ const struct pc236_board *thisboard = comedi_board(dev); + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + +- if (devpriv) ++ if (!thisboard) ++ return; ++ if (dev->iobase) + pc236_intr_disable(dev); + if (dev->irq) + free_irq(dev->irq, dev); +diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c +index 8191c4e..8c0fbd1 100644 +--- a/drivers/staging/comedi/drivers/amplc_pc263.c ++++ b/drivers/staging/comedi/drivers/amplc_pc263.c +@@ -310,8 +310,11 @@ static int __devinit pc263_attach_pci(struct comedi_device *dev, + + static void pc263_detach(struct comedi_device *dev) + { ++ const struct pc263_board *thisboard = comedi_board(dev); + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + ++ if (!thisboard) ++ return; + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); +diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c +index 67a914a..d893e3b 100644 +--- a/drivers/staging/comedi/drivers/das08.c ++++ b/drivers/staging/comedi/drivers/das08.c +@@ -1028,6 +1028,8 @@ static void __maybe_unused das08_detach(struct comedi_device *dev) + const struct das08_board_struct *thisboard = comedi_board(dev); + struct das08_private_struct *devpriv = dev->private; + ++ if (!thisboard) ++ return; + das08_common_detach(dev); + if (IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) && + (thisboard->bustype == isa || thisboard->bustype == pc104)) { +diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c +index 83016b4..bcf6a65 100644 +--- a/drivers/staging/comedi/drivers/ni_daq_700.c ++++ b/drivers/staging/comedi/drivers/ni_daq_700.c +@@ -71,7 +71,7 @@ static int subdev_700_insn(struct comedi_device *dev, + } + + data[1] = s->state & 0xff; +- data[1] |= inb(dev->iobase + DIO_R); ++ data[1] |= inb(dev->iobase + DIO_R) << 8; + + return insn->n; + } +diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c +index ab8b787..d3a1d65 100644 +--- a/drivers/staging/comedi/drivers/ni_labpc.c ++++ b/drivers/staging/comedi/drivers/ni_labpc.c +@@ -809,6 +809,8 @@ static int labpc_find_device(struct comedi_device *dev, int bus, int slot) + + void labpc_common_detach(struct comedi_device *dev) + { ++ if (!thisboard) ++ return; + if (dev->subdevices) + subdev_8255_cleanup(dev, dev->subdevices + 2); + #ifdef CONFIG_ISA_DMA_API +diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c +index 653b074..6edefde 100644 +--- a/drivers/staging/zram/zram_drv.c ++++ b/drivers/staging/zram/zram_drv.c +@@ -223,8 +223,13 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, + cmem = zs_map_object(zram->mem_pool, zram->table[index].handle, + ZS_MM_RO); + +- ret = lzo1x_decompress_safe(cmem, zram->table[index].size, ++ if (zram->table[index].size == PAGE_SIZE) { ++ memcpy(uncmem, cmem, PAGE_SIZE); ++ ret = LZO_E_OK; ++ } else { ++ ret = lzo1x_decompress_safe(cmem, zram->table[index].size, + uncmem, &clen); ++ } + + if (is_partial_io(bvec)) { + memcpy(user_mem + bvec->bv_offset, uncmem + offset, +@@ -342,8 +347,11 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, + goto out; + } + +- if (unlikely(clen > max_zpage_size)) ++ if (unlikely(clen > max_zpage_size)) { + zram_stat_inc(&zram->stats.bad_compress); ++ src = uncmem; ++ clen = PAGE_SIZE; ++ } + + handle = zs_malloc(zram->mem_pool, clen); + if (!handle) { +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index bbff143..fe7faf0 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -730,13 +730,16 @@ static void hub_tt_work(struct work_struct *work) + int limit = 100; + + spin_lock_irqsave (&hub->tt.lock, flags); +- while (--limit && !list_empty (&hub->tt.clear_list)) { ++ while (!list_empty(&hub->tt.clear_list)) { + struct list_head *next; + struct usb_tt_clear *clear; + struct usb_device *hdev = hub->hdev; + const struct hc_driver *drv; + int status; + ++ if (!hub->quiescing && --limit < 0) ++ break; ++ + next = hub->tt.clear_list.next; + clear = list_entry (next, struct usb_tt_clear, clear_list); + list_del (&clear->clear_list); +@@ -1201,7 +1204,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) + if (hub->has_indicators) + cancel_delayed_work_sync(&hub->leds); + if (hub->tt.hub) +- cancel_work_sync(&hub->tt.clear_work); ++ flush_work_sync(&hub->tt.clear_work); + } + + /* caller has locked the hub device */ +diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c +index 966d148..39f9e4a 100644 +--- a/drivers/usb/host/pci-quirks.c ++++ b/drivers/usb/host/pci-quirks.c +@@ -545,7 +545,14 @@ static const struct dmi_system_id __devinitconst ehci_dmi_nohandoff_table[] = { + /* Pegatron Lucid (Ordissimo AIRIS) */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "M11JB"), +- DMI_MATCH(DMI_BIOS_VERSION, "Lucid-GE-133"), ++ DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"), ++ }, ++ }, ++ { ++ /* Pegatron Lucid (Ordissimo) */ ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "Ordissimo"), ++ DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"), + }, + }, + { } +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index a6e18b9..4f1e265 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1228,6 +1228,17 @@ static void xhci_cmd_to_noop(struct xhci_hcd *xhci, struct xhci_cd *cur_cd) + cur_seg = find_trb_seg(xhci->cmd_ring->first_seg, + xhci->cmd_ring->dequeue, &cycle_state); + ++ if (!cur_seg) { ++ xhci_warn(xhci, "Command ring mismatch, dequeue = %p %llx (dma)\n", ++ xhci->cmd_ring->dequeue, ++ (unsigned long long) ++ xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, ++ xhci->cmd_ring->dequeue)); ++ xhci_debug_ring(xhci, xhci->cmd_ring); ++ xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); ++ return; ++ } ++ + /* find the command trb matched by cd from command ring */ + for (cmd_trb = xhci->cmd_ring->dequeue; + cmd_trb != xhci->cmd_ring->enqueue; +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 0644f65..a6e910b 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -4020,7 +4020,7 @@ int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev) + static unsigned long long xhci_service_interval_to_ns( + struct usb_endpoint_descriptor *desc) + { +- return (1 << (desc->bInterval - 1)) * 125 * 1000; ++ return (1ULL << (desc->bInterval - 1)) * 125 * 1000; + } + + static u16 xhci_get_timeout_no_hub_lpm(struct usb_device *udev, +@@ -4141,7 +4141,7 @@ static u16 xhci_calculate_intel_u2_timeout(struct usb_device *udev, + (xhci_service_interval_to_ns(desc) > timeout_ns)) + timeout_ns = xhci_service_interval_to_ns(desc); + +- u2_del_ns = udev->bos->ss_cap->bU2DevExitLat * 1000; ++ u2_del_ns = le16_to_cpu(udev->bos->ss_cap->bU2DevExitLat) * 1000ULL; + if (u2_del_ns > timeout_ns) + timeout_ns = u2_del_ns; + +diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c +index cabd1b1..8391d30 100644 +--- a/drivers/usb/serial/ch341.c ++++ b/drivers/usb/serial/ch341.c +@@ -241,13 +241,11 @@ out: kfree(buffer); + return r; + } + +-/* allocate private data */ +-static int ch341_attach(struct usb_serial *serial) ++static int ch341_port_probe(struct usb_serial_port *port) + { + struct ch341_private *priv; + int r; + +- /* private data */ + priv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL); + if (!priv) + return -ENOMEM; +@@ -257,17 +255,27 @@ static int ch341_attach(struct usb_serial *serial) + priv->baud_rate = DEFAULT_BAUD_RATE; + priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR; + +- r = ch341_configure(serial->dev, priv); ++ r = ch341_configure(port->serial->dev, priv); + if (r < 0) + goto error; + +- usb_set_serial_port_data(serial->port[0], priv); ++ usb_set_serial_port_data(port, priv); + return 0; + + error: kfree(priv); + return r; + } + ++static int ch341_port_remove(struct usb_serial_port *port) ++{ ++ struct ch341_private *priv; ++ ++ priv = usb_get_serial_port_data(port); ++ kfree(priv); ++ ++ return 0; ++} ++ + static int ch341_carrier_raised(struct usb_serial_port *port) + { + struct ch341_private *priv = usb_get_serial_port_data(port); +@@ -303,7 +311,7 @@ static void ch341_close(struct usb_serial_port *port) + static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port) + { + struct usb_serial *serial = port->serial; +- struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]); ++ struct ch341_private *priv = usb_get_serial_port_data(port); + int r; + + priv->baud_rate = DEFAULT_BAUD_RATE; +@@ -606,7 +614,8 @@ static struct usb_serial_driver ch341_device = { + .tiocmget = ch341_tiocmget, + .tiocmset = ch341_tiocmset, + .read_int_callback = ch341_read_int_callback, +- .attach = ch341_attach, ++ .port_probe = ch341_port_probe, ++ .port_remove = ch341_port_remove, + .reset_resume = ch341_reset_resume, + }; + +diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c +index b5cd838..06e8bf4 100644 +--- a/drivers/usb/serial/digi_acceleport.c ++++ b/drivers/usb/serial/digi_acceleport.c +@@ -244,6 +244,8 @@ static int digi_startup_device(struct usb_serial *serial); + static int digi_startup(struct usb_serial *serial); + static void digi_disconnect(struct usb_serial *serial); + static void digi_release(struct usb_serial *serial); ++static int digi_port_probe(struct usb_serial_port *port); ++static int digi_port_remove(struct usb_serial_port *port); + static void digi_read_bulk_callback(struct urb *urb); + static int digi_read_inb_callback(struct urb *urb); + static int digi_read_oob_callback(struct urb *urb); +@@ -298,6 +300,8 @@ static struct usb_serial_driver digi_acceleport_2_device = { + .attach = digi_startup, + .disconnect = digi_disconnect, + .release = digi_release, ++ .port_probe = digi_port_probe, ++ .port_remove = digi_port_remove, + }; + + static struct usb_serial_driver digi_acceleport_4_device = { +@@ -324,6 +328,8 @@ static struct usb_serial_driver digi_acceleport_4_device = { + .attach = digi_startup, + .disconnect = digi_disconnect, + .release = digi_release, ++ .port_probe = digi_port_probe, ++ .port_remove = digi_port_remove, + }; + + static struct usb_serial_driver * const serial_drivers[] = { +@@ -1237,59 +1243,50 @@ static int digi_startup_device(struct usb_serial *serial) + return ret; + } + +- +-static int digi_startup(struct usb_serial *serial) ++static int digi_port_init(struct usb_serial_port *port, unsigned port_num) + { +- +- int i; + struct digi_port *priv; +- struct digi_serial *serial_priv; + +- /* allocate the private data structures for all ports */ +- /* number of regular ports + 1 for the out-of-band port */ +- for (i = 0; i < serial->type->num_ports + 1; i++) { +- /* allocate port private structure */ +- priv = kmalloc(sizeof(struct digi_port), GFP_KERNEL); +- if (priv == NULL) { +- while (--i >= 0) +- kfree(usb_get_serial_port_data(serial->port[i])); +- return 1; /* error */ +- } ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; + +- /* initialize port private structure */ +- spin_lock_init(&priv->dp_port_lock); +- priv->dp_port_num = i; +- priv->dp_out_buf_len = 0; +- priv->dp_write_urb_in_use = 0; +- priv->dp_modem_signals = 0; +- init_waitqueue_head(&priv->dp_modem_change_wait); +- priv->dp_transmit_idle = 0; +- init_waitqueue_head(&priv->dp_transmit_idle_wait); +- priv->dp_throttled = 0; +- priv->dp_throttle_restart = 0; +- init_waitqueue_head(&priv->dp_flush_wait); +- init_waitqueue_head(&priv->dp_close_wait); +- INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); +- priv->dp_port = serial->port[i]; +- /* initialize write wait queue for this port */ +- init_waitqueue_head(&serial->port[i]->write_wait); +- +- usb_set_serial_port_data(serial->port[i], priv); +- } ++ spin_lock_init(&priv->dp_port_lock); ++ priv->dp_port_num = port_num; ++ init_waitqueue_head(&priv->dp_modem_change_wait); ++ init_waitqueue_head(&priv->dp_transmit_idle_wait); ++ init_waitqueue_head(&priv->dp_flush_wait); ++ init_waitqueue_head(&priv->dp_close_wait); ++ INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); ++ priv->dp_port = port; + +- /* allocate serial private structure */ +- serial_priv = kmalloc(sizeof(struct digi_serial), GFP_KERNEL); +- if (serial_priv == NULL) { +- for (i = 0; i < serial->type->num_ports + 1; i++) +- kfree(usb_get_serial_port_data(serial->port[i])); +- return 1; /* error */ +- } ++ init_waitqueue_head(&port->write_wait); ++ ++ usb_set_serial_port_data(port, priv); ++ ++ return 0; ++} ++ ++static int digi_startup(struct usb_serial *serial) ++{ ++ struct digi_serial *serial_priv; ++ int ret; ++ ++ serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL); ++ if (!serial_priv) ++ return -ENOMEM; + +- /* initialize serial private structure */ + spin_lock_init(&serial_priv->ds_serial_lock); + serial_priv->ds_oob_port_num = serial->type->num_ports; + serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num]; +- serial_priv->ds_device_started = 0; ++ ++ ret = digi_port_init(serial_priv->ds_oob_port, ++ serial_priv->ds_oob_port_num); ++ if (ret) { ++ kfree(serial_priv); ++ return ret; ++ } ++ + usb_set_serial_data(serial, serial_priv); + + return 0; +@@ -1310,15 +1307,35 @@ static void digi_disconnect(struct usb_serial *serial) + + static void digi_release(struct usb_serial *serial) + { +- int i; ++ struct digi_serial *serial_priv; ++ struct digi_port *priv; ++ ++ serial_priv = usb_get_serial_data(serial); ++ ++ priv = usb_get_serial_port_data(serial_priv->ds_oob_port); ++ kfree(priv); + +- /* free the private data structures for all ports */ +- /* number of regular ports + 1 for the out-of-band port */ +- for (i = 0; i < serial->type->num_ports + 1; i++) +- kfree(usb_get_serial_port_data(serial->port[i])); +- kfree(usb_get_serial_data(serial)); ++ kfree(serial_priv); + } + ++static int digi_port_probe(struct usb_serial_port *port) ++{ ++ unsigned port_num; ++ ++ port_num = port->number - port->serial->minor; ++ ++ return digi_port_init(port, port_num); ++} ++ ++static int digi_port_remove(struct usb_serial_port *port) ++{ ++ struct digi_port *priv; ++ ++ priv = usb_get_serial_port_data(port); ++ kfree(priv); ++ ++ return 0; ++} + + static void digi_read_bulk_callback(struct urb *urb) + { +diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c +index 2cb30c5..8df011f 100644 +--- a/drivers/usb/serial/ipw.c ++++ b/drivers/usb/serial/ipw.c +@@ -209,8 +209,7 @@ static int ipw_open(struct tty_struct *tty, struct usb_serial_port *port) + return 0; + } + +-/* fake probe - only to allocate data structures */ +-static int ipw_probe(struct usb_serial *serial, const struct usb_device_id *id) ++static int ipw_attach(struct usb_serial *serial) + { + struct usb_wwan_intf_private *data; + +@@ -310,9 +309,9 @@ static struct usb_serial_driver ipw_device = { + .num_ports = 1, + .open = ipw_open, + .close = ipw_close, +- .probe = ipw_probe, +- .attach = usb_wwan_startup, ++ .attach = ipw_attach, + .release = ipw_release, ++ .port_probe = usb_wwan_port_probe, + .port_remove = usb_wwan_port_remove, + .dtr_rts = ipw_dtr_rts, + .write = usb_wwan_write, +diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c +index af0b70e..f6788d7 100644 +--- a/drivers/usb/serial/keyspan.c ++++ b/drivers/usb/serial/keyspan.c +@@ -1392,13 +1392,9 @@ static struct callbacks { + data in device_details */ + static void keyspan_setup_urbs(struct usb_serial *serial) + { +- int i, j; + struct keyspan_serial_private *s_priv; + const struct keyspan_device_details *d_details; +- struct usb_serial_port *port; +- struct keyspan_port_private *p_priv; + struct callbacks *cback; +- int endp; + + s_priv = usb_get_serial_data(serial); + d_details = s_priv->device_details; +@@ -1422,45 +1418,6 @@ static void keyspan_setup_urbs(struct usb_serial *serial) + (serial, d_details->glocont_endpoint, USB_DIR_OUT, + serial, s_priv->glocont_buf, GLOCONT_BUFLEN, + cback->glocont_callback); +- +- /* Setup endpoints for each port specific thing */ +- for (i = 0; i < d_details->num_ports; i++) { +- port = serial->port[i]; +- p_priv = usb_get_serial_port_data(port); +- +- /* Do indat endpoints first, once for each flip */ +- endp = d_details->indat_endpoints[i]; +- for (j = 0; j <= d_details->indat_endp_flip; ++j, ++endp) { +- p_priv->in_urbs[j] = keyspan_setup_urb +- (serial, endp, USB_DIR_IN, port, +- p_priv->in_buffer[j], 64, +- cback->indat_callback); +- } +- for (; j < 2; ++j) +- p_priv->in_urbs[j] = NULL; +- +- /* outdat endpoints also have flip */ +- endp = d_details->outdat_endpoints[i]; +- for (j = 0; j <= d_details->outdat_endp_flip; ++j, ++endp) { +- p_priv->out_urbs[j] = keyspan_setup_urb +- (serial, endp, USB_DIR_OUT, port, +- p_priv->out_buffer[j], 64, +- cback->outdat_callback); +- } +- for (; j < 2; ++j) +- p_priv->out_urbs[j] = NULL; +- +- /* inack endpoint */ +- p_priv->inack_urb = keyspan_setup_urb +- (serial, d_details->inack_endpoints[i], USB_DIR_IN, +- port, p_priv->inack_buffer, 1, cback->inack_callback); +- +- /* outcont endpoint */ +- p_priv->outcont_urb = keyspan_setup_urb +- (serial, d_details->outcont_endpoints[i], USB_DIR_OUT, +- port, p_priv->outcont_buffer, 64, +- cback->outcont_callback); +- } + } + + /* usa19 function doesn't require prescaler */ +@@ -2422,9 +2379,7 @@ static void keyspan_send_setup(struct usb_serial_port *port, int reset_port) + static int keyspan_startup(struct usb_serial *serial) + { + int i, err; +- struct usb_serial_port *port; + struct keyspan_serial_private *s_priv; +- struct keyspan_port_private *p_priv; + const struct keyspan_device_details *d_details; + + for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i) +@@ -2448,19 +2403,6 @@ static int keyspan_startup(struct usb_serial *serial) + s_priv->device_details = d_details; + usb_set_serial_data(serial, s_priv); + +- /* Now setup per port private data */ +- for (i = 0; i < serial->num_ports; i++) { +- port = serial->port[i]; +- p_priv = kzalloc(sizeof(struct keyspan_port_private), +- GFP_KERNEL); +- if (!p_priv) { +- dbg("%s - kmalloc for keyspan_port_private (%d) failed!.", __func__, i); +- return 1; +- } +- p_priv->device_details = d_details; +- usb_set_serial_port_data(port, p_priv); +- } +- + keyspan_setup_urbs(serial); + + if (s_priv->instat_urb != NULL) { +@@ -2481,61 +2423,112 @@ static int keyspan_startup(struct usb_serial *serial) + + static void keyspan_disconnect(struct usb_serial *serial) + { +- int i, j; +- struct usb_serial_port *port; +- struct keyspan_serial_private *s_priv; +- struct keyspan_port_private *p_priv; ++ struct keyspan_serial_private *s_priv; + + s_priv = usb_get_serial_data(serial); + +- /* Stop reading/writing urbs */ + stop_urb(s_priv->instat_urb); + stop_urb(s_priv->glocont_urb); + stop_urb(s_priv->indat_urb); +- for (i = 0; i < serial->num_ports; ++i) { +- port = serial->port[i]; +- p_priv = usb_get_serial_port_data(port); +- stop_urb(p_priv->inack_urb); +- stop_urb(p_priv->outcont_urb); +- for (j = 0; j < 2; j++) { +- stop_urb(p_priv->in_urbs[j]); +- stop_urb(p_priv->out_urbs[j]); +- } +- } ++} ++ ++static void keyspan_release(struct usb_serial *serial) ++{ ++ struct keyspan_serial_private *s_priv; ++ ++ s_priv = usb_get_serial_data(serial); + +- /* Now free them */ + usb_free_urb(s_priv->instat_urb); + usb_free_urb(s_priv->indat_urb); + usb_free_urb(s_priv->glocont_urb); +- for (i = 0; i < serial->num_ports; ++i) { +- port = serial->port[i]; +- p_priv = usb_get_serial_port_data(port); +- usb_free_urb(p_priv->inack_urb); +- usb_free_urb(p_priv->outcont_urb); +- for (j = 0; j < 2; j++) { +- usb_free_urb(p_priv->in_urbs[j]); +- usb_free_urb(p_priv->out_urbs[j]); +- } +- } ++ ++ kfree(s_priv); + } + +-static void keyspan_release(struct usb_serial *serial) ++static int keyspan_port_probe(struct usb_serial_port *port) + { +- int i; +- struct usb_serial_port *port; +- struct keyspan_serial_private *s_priv; ++ struct usb_serial *serial = port->serial; ++ struct keyspan_port_private *s_priv; ++ struct keyspan_port_private *p_priv; ++ const struct keyspan_device_details *d_details; ++ struct callbacks *cback; ++ int endp; ++ int port_num; ++ int i; + + s_priv = usb_get_serial_data(serial); ++ d_details = s_priv->device_details; + +- /* dbg("Freeing serial->private."); */ +- kfree(s_priv); ++ p_priv = kzalloc(sizeof(*p_priv), GFP_KERNEL); ++ if (!p_priv) ++ return -ENOMEM; + +- /* dbg("Freeing port->private."); */ +- /* Now free per port private data */ +- for (i = 0; i < serial->num_ports; i++) { +- port = serial->port[i]; +- kfree(usb_get_serial_port_data(port)); ++ s_priv = usb_get_serial_data(port->serial); ++ p_priv->device_details = d_details; ++ ++ /* Setup values for the various callback routines */ ++ cback = &keyspan_callbacks[d_details->msg_format]; ++ ++ port_num = port->number - port->serial->minor; ++ ++ /* Do indat endpoints first, once for each flip */ ++ endp = d_details->indat_endpoints[port_num]; ++ for (i = 0; i <= d_details->indat_endp_flip; ++i, ++endp) { ++ p_priv->in_urbs[i] = keyspan_setup_urb(serial, endp, ++ USB_DIR_IN, port, ++ p_priv->in_buffer[i], 64, ++ cback->indat_callback); ++ } ++ /* outdat endpoints also have flip */ ++ endp = d_details->outdat_endpoints[port_num]; ++ for (i = 0; i <= d_details->outdat_endp_flip; ++i, ++endp) { ++ p_priv->out_urbs[i] = keyspan_setup_urb(serial, endp, ++ USB_DIR_OUT, port, ++ p_priv->out_buffer[i], 64, ++ cback->outdat_callback); ++ } ++ /* inack endpoint */ ++ p_priv->inack_urb = keyspan_setup_urb(serial, ++ d_details->inack_endpoints[port_num], ++ USB_DIR_IN, port, ++ p_priv->inack_buffer, 1, ++ cback->inack_callback); ++ /* outcont endpoint */ ++ p_priv->outcont_urb = keyspan_setup_urb(serial, ++ d_details->outcont_endpoints[port_num], ++ USB_DIR_OUT, port, ++ p_priv->outcont_buffer, 64, ++ cback->outcont_callback); ++ ++ usb_set_serial_port_data(port, p_priv); ++ ++ return 0; ++} ++ ++static int keyspan_port_remove(struct usb_serial_port *port) ++{ ++ struct keyspan_port_private *p_priv; ++ int i; ++ ++ p_priv = usb_get_serial_port_data(port); ++ ++ stop_urb(p_priv->inack_urb); ++ stop_urb(p_priv->outcont_urb); ++ for (i = 0; i < 2; i++) { ++ stop_urb(p_priv->in_urbs[i]); ++ stop_urb(p_priv->out_urbs[i]); ++ } ++ ++ usb_free_urb(p_priv->inack_urb); ++ usb_free_urb(p_priv->outcont_urb); ++ for (i = 0; i < 2; i++) { ++ usb_free_urb(p_priv->in_urbs[i]); ++ usb_free_urb(p_priv->out_urbs[i]); + } ++ ++ kfree(p_priv); ++ ++ return 0; + } + + MODULE_AUTHOR(DRIVER_AUTHOR); +diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h +index fe1c5d9..90a7b36 100644 +--- a/drivers/usb/serial/keyspan.h ++++ b/drivers/usb/serial/keyspan.h +@@ -42,6 +42,8 @@ static void keyspan_dtr_rts (struct usb_serial_port *port, int on); + static int keyspan_startup (struct usb_serial *serial); + static void keyspan_disconnect (struct usb_serial *serial); + static void keyspan_release (struct usb_serial *serial); ++static int keyspan_port_probe(struct usb_serial_port *port); ++static int keyspan_port_remove(struct usb_serial_port *port); + static int keyspan_write_room (struct tty_struct *tty); + + static int keyspan_write (struct tty_struct *tty, +@@ -562,6 +564,8 @@ static struct usb_serial_driver keyspan_1port_device = { + .attach = keyspan_startup, + .disconnect = keyspan_disconnect, + .release = keyspan_release, ++ .port_probe = keyspan_port_probe, ++ .port_remove = keyspan_port_remove, + }; + + static struct usb_serial_driver keyspan_2port_device = { +@@ -584,6 +588,8 @@ static struct usb_serial_driver keyspan_2port_device = { + .attach = keyspan_startup, + .disconnect = keyspan_disconnect, + .release = keyspan_release, ++ .port_probe = keyspan_port_probe, ++ .port_remove = keyspan_port_remove, + }; + + static struct usb_serial_driver keyspan_4port_device = { +@@ -606,6 +612,8 @@ static struct usb_serial_driver keyspan_4port_device = { + .attach = keyspan_startup, + .disconnect = keyspan_disconnect, + .release = keyspan_release, ++ .port_probe = keyspan_port_probe, ++ .port_remove = keyspan_port_remove, + }; + + static struct usb_serial_driver * const serial_drivers[] = { +diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c +index a71fa0a..c088250 100644 +--- a/drivers/usb/serial/mct_u232.c ++++ b/drivers/usb/serial/mct_u232.c +@@ -51,7 +51,8 @@ static bool debug; + * Function prototypes + */ + static int mct_u232_startup(struct usb_serial *serial); +-static void mct_u232_release(struct usb_serial *serial); ++static int mct_u232_port_probe(struct usb_serial_port *port); ++static int mct_u232_port_remove(struct usb_serial_port *remove); + static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port); + static void mct_u232_close(struct usb_serial_port *port); + static void mct_u232_dtr_rts(struct usb_serial_port *port, int on); +@@ -101,7 +102,8 @@ static struct usb_serial_driver mct_u232_device = { + .tiocmget = mct_u232_tiocmget, + .tiocmset = mct_u232_tiocmset, + .attach = mct_u232_startup, +- .release = mct_u232_release, ++ .port_probe = mct_u232_port_probe, ++ .port_remove = mct_u232_port_remove, + .ioctl = mct_u232_ioctl, + .get_icount = mct_u232_get_icount, + }; +@@ -392,18 +394,8 @@ static void mct_u232_msr_to_state(unsigned int *control_state, + + static int mct_u232_startup(struct usb_serial *serial) + { +- struct mct_u232_private *priv; + struct usb_serial_port *port, *rport; + +- priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL); +- if (!priv) +- return -ENOMEM; +- spin_lock_init(&priv->lock); +- init_waitqueue_head(&priv->msr_wait); +- usb_set_serial_port_data(serial->port[0], priv); +- +- init_waitqueue_head(&serial->port[0]->write_wait); +- + /* Puh, that's dirty */ + port = serial->port[0]; + rport = serial->port[1]; +@@ -416,18 +408,31 @@ static int mct_u232_startup(struct usb_serial *serial) + return 0; + } /* mct_u232_startup */ + ++static int mct_u232_port_probe(struct usb_serial_port *port) ++{ ++ struct mct_u232_private *priv; ++ ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ spin_lock_init(&priv->lock); ++ init_waitqueue_head(&priv->msr_wait); ++ ++ usb_set_serial_port_data(port, priv); + +-static void mct_u232_release(struct usb_serial *serial) ++ return 0; ++} ++ ++static int mct_u232_port_remove(struct usb_serial_port *port) + { + struct mct_u232_private *priv; +- int i; + +- for (i = 0; i < serial->num_ports; ++i) { +- /* My special items, the standard routines free my urbs */ +- priv = usb_get_serial_port_data(serial->port[i]); +- kfree(priv); +- } +-} /* mct_u232_release */ ++ priv = usb_get_serial_port_data(port); ++ kfree(priv); ++ ++ return 0; ++} + + static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port) + { +@@ -519,12 +524,14 @@ static void mct_u232_dtr_rts(struct usb_serial_port *port, int on) + + static void mct_u232_close(struct usb_serial_port *port) + { +- if (port->serial->dev) { +- /* shutdown our urbs */ +- usb_kill_urb(port->write_urb); +- usb_kill_urb(port->read_urb); +- usb_kill_urb(port->interrupt_in_urb); +- } ++ /* ++ * Must kill the read urb as it is actually an interrupt urb, which ++ * generic close thus fails to kill. ++ */ ++ usb_kill_urb(port->read_urb); ++ usb_kill_urb(port->interrupt_in_urb); ++ ++ usb_serial_generic_close(port); + } /* mct_u232_close */ + + +diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c +index d47eb06..d284fb8 100644 +--- a/drivers/usb/serial/metro-usb.c ++++ b/drivers/usb/serial/metro-usb.c +@@ -188,16 +188,13 @@ static void metrousb_cleanup(struct usb_serial_port *port) + { + dev_dbg(&port->dev, "%s\n", __func__); + +- if (port->serial->dev) { +- /* Shutdown any interrupt in urbs. */ +- if (port->interrupt_in_urb) { +- usb_unlink_urb(port->interrupt_in_urb); +- usb_kill_urb(port->interrupt_in_urb); +- } +- +- /* Send deactivate cmd to device */ ++ usb_unlink_urb(port->interrupt_in_urb); ++ usb_kill_urb(port->interrupt_in_urb); ++ ++ mutex_lock(&port->serial->disc_mutex); ++ if (!port->serial->disconnected) + metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port); +- } ++ mutex_unlock(&port->serial->disc_mutex); + } + + static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) +@@ -280,51 +277,27 @@ static int metrousb_set_modem_ctrl(struct usb_serial *serial, unsigned int contr + return retval; + } + +-static void metrousb_shutdown(struct usb_serial *serial) ++static int metrousb_port_probe(struct usb_serial_port *port) + { +- int i = 0; ++ struct metrousb_private *metro_priv; + +- dev_dbg(&serial->dev->dev, "%s\n", __func__); ++ metro_priv = kzalloc(sizeof(*metro_priv), GFP_KERNEL); ++ if (!metro_priv) ++ return -ENOMEM; + +- /* Stop reading and writing on all ports. */ +- for (i = 0; i < serial->num_ports; ++i) { +- /* Close any open urbs. */ +- metrousb_cleanup(serial->port[i]); ++ spin_lock_init(&metro_priv->lock); + +- /* Free memory. */ +- kfree(usb_get_serial_port_data(serial->port[i])); +- usb_set_serial_port_data(serial->port[i], NULL); ++ usb_set_serial_port_data(port, metro_priv); + +- dev_dbg(&serial->dev->dev, "%s - freed port number=%d\n", +- __func__, serial->port[i]->number); +- } ++ return 0; + } + +-static int metrousb_startup(struct usb_serial *serial) ++static int metrousb_port_remove(struct usb_serial_port *port) + { + struct metrousb_private *metro_priv; +- struct usb_serial_port *port; +- int i = 0; + +- dev_dbg(&serial->dev->dev, "%s\n", __func__); +- +- /* Loop through the serial ports setting up the private structures. +- * Currently we only use one port. */ +- for (i = 0; i < serial->num_ports; ++i) { +- port = serial->port[i]; +- +- /* Declare memory. */ +- metro_priv = kzalloc(sizeof(struct metrousb_private), GFP_KERNEL); +- if (!metro_priv) +- return -ENOMEM; +- +- /* Initialize memory. */ +- spin_lock_init(&metro_priv->lock); +- usb_set_serial_port_data(port, metro_priv); +- +- dev_dbg(&serial->dev->dev, "%s - port number=%d\n ", +- __func__, port->number); +- } ++ metro_priv = usb_get_serial_port_data(port); ++ kfree(metro_priv); + + return 0; + } +@@ -423,8 +396,8 @@ static struct usb_serial_driver metrousb_device = { + .close = metrousb_cleanup, + .read_int_callback = metrousb_read_int_callback, + .write_int_callback = metrousb_write_int_callback, +- .attach = metrousb_startup, +- .release = metrousb_shutdown, ++ .port_probe = metrousb_port_probe, ++ .port_remove = metrousb_port_remove, + .throttle = metrousb_throttle, + .unthrottle = metrousb_unthrottle, + .tiocmget = metrousb_tiocmget, +diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c +index a07dd3c..eb84767 100644 +--- a/drivers/usb/serial/mos7720.c ++++ b/drivers/usb/serial/mos7720.c +@@ -2023,9 +2023,7 @@ static int mos7720_ioctl(struct tty_struct *tty, + + static int mos7720_startup(struct usb_serial *serial) + { +- struct moschip_port *mos7720_port; + struct usb_device *dev; +- int i; + char data; + u16 product; + int ret_val; +@@ -2063,29 +2061,6 @@ static int mos7720_startup(struct usb_serial *serial) + serial->port[1]->interrupt_in_buffer = NULL; + } + +- +- /* set up serial port private structures */ +- for (i = 0; i < serial->num_ports; ++i) { +- mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); +- if (mos7720_port == NULL) { +- dev_err(&dev->dev, "%s - Out of memory\n", __func__); +- return -ENOMEM; +- } +- +- /* Initialize all port interrupt end point to port 0 int +- * endpoint. Our device has only one interrupt endpoint +- * common to all ports */ +- serial->port[i]->interrupt_in_endpointAddress = +- serial->port[0]->interrupt_in_endpointAddress; +- +- mos7720_port->port = serial->port[i]; +- usb_set_serial_port_data(serial->port[i], mos7720_port); +- +- dbg("port number is %d", serial->port[i]->number); +- dbg("serial number is %d", serial->minor); +- } +- +- + /* setting configuration feature to one */ + usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ); +@@ -2113,8 +2088,6 @@ static int mos7720_startup(struct usb_serial *serial) + + static void mos7720_release(struct usb_serial *serial) + { +- int i; +- + #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT + /* close the parallel port */ + +@@ -2153,9 +2126,36 @@ static void mos7720_release(struct usb_serial *serial) + kref_put(&mos_parport->ref_count, destroy_mos_parport); + } + #endif +- /* free private structure allocated for serial port */ +- for (i = 0; i < serial->num_ports; ++i) +- kfree(usb_get_serial_port_data(serial->port[i])); ++} ++ ++static int mos7720_port_probe(struct usb_serial_port *port) ++{ ++ struct moschip_port *mos7720_port; ++ ++ mos7720_port = kzalloc(sizeof(*mos7720_port), GFP_KERNEL); ++ if (!mos7720_port) ++ return -ENOMEM; ++ ++ /* Initialize all port interrupt end point to port 0 int endpoint. ++ * Our device has only one interrupt endpoint common to all ports. ++ */ ++ port->interrupt_in_endpointAddress = ++ port->serial->port[0]->interrupt_in_endpointAddress; ++ mos7720_port->port = port; ++ ++ usb_set_serial_port_data(port, mos7720_port); ++ ++ return 0; ++} ++ ++static int mos7720_port_remove(struct usb_serial_port *port) ++{ ++ struct moschip_port *mos7720_port; ++ ++ mos7720_port = usb_get_serial_port_data(port); ++ kfree(mos7720_port); ++ ++ return 0; + } + + static struct usb_serial_driver moschip7720_2port_driver = { +@@ -2173,6 +2173,8 @@ static struct usb_serial_driver moschip7720_2port_driver = { + .probe = mos77xx_probe, + .attach = mos7720_startup, + .release = mos7720_release, ++ .port_probe = mos7720_port_probe, ++ .port_remove = mos7720_port_remove, + .ioctl = mos7720_ioctl, + .tiocmget = mos7720_tiocmget, + .tiocmset = mos7720_tiocmset, +diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c +index 2f6da1e..52e5ca7 100644 +--- a/drivers/usb/serial/mos7840.c ++++ b/drivers/usb/serial/mos7840.c +@@ -218,12 +218,10 @@ struct moschip_port { + int port_num; /*Actual port number in the device(1,2,etc) */ + struct urb *write_urb; /* write URB for this port */ + struct urb *read_urb; /* read URB for this port */ +- struct urb *int_urb; + __u8 shadowLCR; /* last LCR value received */ + __u8 shadowMCR; /* last MCR value received */ + char open; + char open_ports; +- char zombie; + wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ + wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ + int delta_msr_cond; +@@ -493,7 +491,6 @@ static void mos7840_control_callback(struct urb *urb) + unsigned char *data; + struct moschip_port *mos7840_port; + __u8 regval = 0x0; +- int result = 0; + int status = urb->status; + + mos7840_port = urb->context; +@@ -512,7 +509,7 @@ static void mos7840_control_callback(struct urb *urb) + default: + dbg("%s - nonzero urb status received: %d", __func__, + status); +- goto exit; ++ return; + } + + dbg("%s urb buffer size is %d", __func__, urb->actual_length); +@@ -525,17 +522,6 @@ static void mos7840_control_callback(struct urb *urb) + mos7840_handle_new_msr(mos7840_port, regval); + else if (mos7840_port->MsrLsr == 1) + mos7840_handle_new_lsr(mos7840_port, regval); +- +-exit: +- spin_lock(&mos7840_port->pool_lock); +- if (!mos7840_port->zombie) +- result = usb_submit_urb(mos7840_port->int_urb, GFP_ATOMIC); +- spin_unlock(&mos7840_port->pool_lock); +- if (result) { +- dev_err(&urb->dev->dev, +- "%s - Error %d submitting interrupt urb\n", +- __func__, result); +- } + } + + static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg, +@@ -704,14 +690,7 @@ static void mos7840_interrupt_callback(struct urb *urb) + wreg = MODEM_STATUS_REGISTER; + break; + } +- spin_lock(&mos7840_port->pool_lock); +- if (!mos7840_port->zombie) { +- rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data); +- } else { +- spin_unlock(&mos7840_port->pool_lock); +- return; +- } +- spin_unlock(&mos7840_port->pool_lock); ++ rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data); + } + } + } +@@ -2684,7 +2663,6 @@ error: + kfree(mos7840_port->ctrl_buf); + usb_free_urb(mos7840_port->control_urb); + kfree(mos7840_port); +- serial->port[i] = NULL; + } + return status; + } +@@ -2714,9 +2692,6 @@ static void mos7840_disconnect(struct usb_serial *serial) + mos7840_port = mos7840_get_port_private(serial->port[i]); + dbg ("mos7840_port %d = %p", i, mos7840_port); + if (mos7840_port) { +- spin_lock_irqsave(&mos7840_port->pool_lock, flags); +- mos7840_port->zombie = 1; +- spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); + usb_kill_urb(mos7840_port->control_urb); + } + } +@@ -2754,6 +2729,7 @@ static void mos7840_release(struct usb_serial *serial) + del_timer_sync(&mos7840_port->led_timer1); + del_timer_sync(&mos7840_port->led_timer2); + } ++ usb_free_urb(mos7840_port->control_urb); + kfree(mos7840_port->ctrl_buf); + kfree(mos7840_port->dr); + kfree(mos7840_port); +diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c +index 6f3d705..27c9d06 100644 +--- a/drivers/usb/serial/omninet.c ++++ b/drivers/usb/serial/omninet.c +@@ -46,8 +46,8 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, + const unsigned char *buf, int count); + static int omninet_write_room(struct tty_struct *tty); + static void omninet_disconnect(struct usb_serial *serial); +-static void omninet_release(struct usb_serial *serial); +-static int omninet_attach(struct usb_serial *serial); ++static int omninet_port_probe(struct usb_serial_port *port); ++static int omninet_port_remove(struct usb_serial_port *port); + + static const struct usb_device_id id_table[] = { + { USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) }, +@@ -64,7 +64,8 @@ static struct usb_serial_driver zyxel_omninet_device = { + .description = "ZyXEL - omni.net lcd plus usb", + .id_table = id_table, + .num_ports = 1, +- .attach = omninet_attach, ++ .port_probe = omninet_port_probe, ++ .port_remove = omninet_port_remove, + .open = omninet_open, + .close = omninet_close, + .write = omninet_write, +@@ -72,7 +73,6 @@ static struct usb_serial_driver zyxel_omninet_device = { + .read_bulk_callback = omninet_read_bulk_callback, + .write_bulk_callback = omninet_write_bulk_callback, + .disconnect = omninet_disconnect, +- .release = omninet_release, + }; + + static struct usb_serial_driver * const serial_drivers[] = { +@@ -114,18 +114,26 @@ struct omninet_data { + __u8 od_outseq; /* Sequence number for bulk_out URBs */ + }; + +-static int omninet_attach(struct usb_serial *serial) ++static int omninet_port_probe(struct usb_serial_port *port) + { + struct omninet_data *od; +- struct usb_serial_port *port = serial->port[0]; + + od = kmalloc(sizeof(struct omninet_data), GFP_KERNEL); +- if (!od) { +- dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", +- __func__, sizeof(struct omninet_data)); ++ if (!od) + return -ENOMEM; +- } ++ + usb_set_serial_port_data(port, od); ++ ++ return 0; ++} ++ ++static int omninet_port_remove(struct usb_serial_port *port) ++{ ++ struct omninet_data *od; ++ ++ od = usb_get_serial_port_data(port); ++ kfree(od); ++ + return 0; + } + +@@ -291,14 +299,6 @@ static void omninet_disconnect(struct usb_serial *serial) + usb_kill_urb(wport->write_urb); + } + +- +-static void omninet_release(struct usb_serial *serial) +-{ +- struct usb_serial_port *port = serial->port[0]; +- +- kfree(usb_get_serial_port_data(port)); +-} +- + module_usb_serial_driver(serial_drivers, id_table); + + MODULE_AUTHOR(DRIVER_AUTHOR); +diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c +index 02cb1b7..623358a 100644 +--- a/drivers/usb/serial/opticon.c ++++ b/drivers/usb/serial/opticon.c +@@ -158,7 +158,11 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype, + { + struct usb_serial *serial = port->serial; + int retval; +- u8 buffer[2]; ++ u8 *buffer; ++ ++ buffer = kzalloc(1, GFP_KERNEL); ++ if (!buffer) ++ return -ENOMEM; + + buffer[0] = val; + /* Send the message to the vendor control endpoint +@@ -167,6 +171,7 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype, + requesttype, + USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, + 0, 0, buffer, 1, 0); ++ kfree(buffer); + + return retval; + } +@@ -284,7 +289,7 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, + if (!dr) { + dev_err(&port->dev, "out of memory\n"); + count = -ENOMEM; +- goto error; ++ goto error_no_dr; + } + + dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT; +@@ -314,6 +319,8 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, + + return count; + error: ++ kfree(dr); ++error_no_dr: + usb_free_urb(urb); + error_no_urb: + kfree(buffer); +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index a0542ca..76a48e4 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -47,6 +47,7 @@ + /* Function prototypes */ + static int option_probe(struct usb_serial *serial, + const struct usb_device_id *id); ++static int option_attach(struct usb_serial *serial); + static void option_release(struct usb_serial *serial); + static int option_send_setup(struct usb_serial_port *port); + static void option_instat_callback(struct urb *urb); +@@ -1288,8 +1289,9 @@ static struct usb_serial_driver option_1port_device = { + .tiocmget = usb_wwan_tiocmget, + .tiocmset = usb_wwan_tiocmset, + .ioctl = usb_wwan_ioctl, +- .attach = usb_wwan_startup, ++ .attach = option_attach, + .release = option_release, ++ .port_probe = usb_wwan_port_probe, + .port_remove = usb_wwan_port_remove, + .read_int_callback = option_instat_callback, + #ifdef CONFIG_PM +@@ -1337,8 +1339,6 @@ static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, + static int option_probe(struct usb_serial *serial, + const struct usb_device_id *id) + { +- struct usb_wwan_intf_private *data; +- struct option_private *priv; + struct usb_interface_descriptor *iface_desc = + &serial->interface->cur_altsetting->desc; + struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; +@@ -1376,6 +1376,19 @@ static int option_probe(struct usb_serial *serial, + iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) + return -ENODEV; + ++ /* Store device id so we can use it during attach. */ ++ usb_set_serial_data(serial, (void *)id); ++ ++ return 0; ++} ++ ++static int option_attach(struct usb_serial *serial) ++{ ++ struct usb_interface_descriptor *iface_desc; ++ const struct usb_device_id *id; ++ struct usb_wwan_intf_private *data; ++ struct option_private *priv; ++ + data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); + if (!data) + return -ENOMEM; +@@ -1386,6 +1399,10 @@ static int option_probe(struct usb_serial *serial, + return -ENOMEM; + } + ++ /* Retrieve device id stored at probe. */ ++ id = usb_get_serial_data(serial); ++ iface_desc = &serial->interface->cur_altsetting->desc; ++ + priv->bInterfaceNumber = iface_desc->bInterfaceNumber; + data->private = priv; + +diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c +index bfd5077..93232ca 100644 +--- a/drivers/usb/serial/qcserial.c ++++ b/drivers/usb/serial/qcserial.c +@@ -140,7 +140,6 @@ MODULE_DEVICE_TABLE(usb, id_table); + + static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) + { +- struct usb_wwan_intf_private *data; + struct usb_host_interface *intf = serial->interface->cur_altsetting; + struct device *dev = &serial->dev->dev; + int retval = -ENODEV; +@@ -156,13 +155,6 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) + ifnum = intf->desc.bInterfaceNumber; + dev_dbg(dev, "This Interface = %d\n", ifnum); + +- data = kzalloc(sizeof(struct usb_wwan_intf_private), +- GFP_KERNEL); +- if (!data) +- return -ENOMEM; +- +- spin_lock_init(&data->susp_lock); +- + if (nintf == 1) { + /* QDL mode */ + /* Gobi 2000 has a single altsetting, older ones have two */ +@@ -255,20 +247,28 @@ done: + } + } + +- /* Set serial->private if not returning error */ +- if (retval == 0) +- usb_set_serial_data(serial, data); +- else +- kfree(data); +- + return retval; + } + ++static int qc_attach(struct usb_serial *serial) ++{ ++ struct usb_wwan_intf_private *data; ++ ++ data = kzalloc(sizeof(*data), GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; ++ ++ spin_lock_init(&data->susp_lock); ++ ++ usb_set_serial_data(serial, data); ++ ++ return 0; ++} ++ + static void qc_release(struct usb_serial *serial) + { + struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); + +- /* Free the private data allocated in qcprobe */ + usb_set_serial_data(serial, NULL); + kfree(priv); + } +@@ -287,8 +287,9 @@ static struct usb_serial_driver qcdevice = { + .write = usb_wwan_write, + .write_room = usb_wwan_write_room, + .chars_in_buffer = usb_wwan_chars_in_buffer, +- .attach = usb_wwan_startup, ++ .attach = qc_attach, + .release = qc_release, ++ .port_probe = usb_wwan_port_probe, + .port_remove = usb_wwan_port_remove, + #ifdef CONFIG_PM + .suspend = usb_wwan_suspend, +diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c +index 151670b..ea69301 100644 +--- a/drivers/usb/serial/quatech2.c ++++ b/drivers/usb/serial/quatech2.c +@@ -145,12 +145,12 @@ static void qt2_read_bulk_callback(struct urb *urb); + + static void qt2_release(struct usb_serial *serial) + { +- int i; ++ struct qt2_serial_private *serial_priv; + +- kfree(usb_get_serial_data(serial)); ++ serial_priv = usb_get_serial_data(serial); + +- for (i = 0; i < serial->num_ports; i++) +- kfree(usb_get_serial_port_data(serial->port[i])); ++ usb_free_urb(serial_priv->read_urb); ++ kfree(serial_priv); + } + + static inline int calc_baud_divisor(int baudrate) +@@ -425,11 +425,16 @@ static void qt2_close(struct usb_serial_port *port) + port_priv->is_open = false; + + spin_lock_irqsave(&port_priv->urb_lock, flags); +- if (port_priv->write_urb->status == -EINPROGRESS) +- usb_kill_urb(port_priv->write_urb); ++ usb_kill_urb(port_priv->write_urb); + port_priv->urb_in_use = false; + spin_unlock_irqrestore(&port_priv->urb_lock, flags); + ++ mutex_lock(&port->serial->disc_mutex); ++ if (port->serial->disconnected) { ++ mutex_unlock(&port->serial->disc_mutex); ++ return; ++ } ++ + /* flush the port transmit buffer */ + i = usb_control_msg(serial->dev, + usb_rcvctrlpipe(serial->dev, 0), +@@ -461,26 +466,14 @@ static void qt2_close(struct usb_serial_port *port) + dev_err(&port->dev, "%s - close port failed %i\n", + __func__, i); + ++ mutex_unlock(&port->serial->disc_mutex); + } + + static void qt2_disconnect(struct usb_serial *serial) + { + struct qt2_serial_private *serial_priv = usb_get_serial_data(serial); +- struct qt2_port_private *port_priv; +- int i; +- +- if (serial_priv->read_urb->status == -EINPROGRESS) +- usb_kill_urb(serial_priv->read_urb); +- +- usb_free_urb(serial_priv->read_urb); + +- for (i = 0; i < serial->num_ports; i++) { +- port_priv = usb_get_serial_port_data(serial->port[i]); +- +- if (port_priv->write_urb->status == -EINPROGRESS) +- usb_kill_urb(port_priv->write_urb); +- usb_free_urb(port_priv->write_urb); +- } ++ usb_kill_urb(serial_priv->read_urb); + } + + static int get_serial_info(struct usb_serial_port *port, +@@ -775,11 +768,9 @@ static void qt2_read_bulk_callback(struct urb *urb) + + static int qt2_setup_urbs(struct usb_serial *serial) + { +- struct usb_serial_port *port; + struct usb_serial_port *port0; + struct qt2_serial_private *serial_priv; +- struct qt2_port_private *port_priv; +- int pcount, status; ++ int status; + + port0 = serial->port[0]; + +@@ -797,46 +788,21 @@ static int qt2_setup_urbs(struct usb_serial *serial) + sizeof(serial_priv->read_buffer), + qt2_read_bulk_callback, serial); + +- /* setup write_urb for each port */ +- for (pcount = 0; pcount < serial->num_ports; pcount++) { +- +- port = serial->port[pcount]; +- port_priv = usb_get_serial_port_data(port); +- +- port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL); +- if (!port_priv->write_urb) { +- dev_err(&serial->dev->dev, +- "failed to alloc write_urb for port %i\n", +- pcount); +- return -ENOMEM; +- } +- +- usb_fill_bulk_urb(port_priv->write_urb, +- serial->dev, +- usb_sndbulkpipe(serial->dev, +- port0-> +- bulk_out_endpointAddress), +- port_priv->write_buffer, +- sizeof(port_priv->write_buffer), +- qt2_write_bulk_callback, port); +- } +- + status = usb_submit_urb(serial_priv->read_urb, GFP_KERNEL); + if (status != 0) { + dev_err(&serial->dev->dev, + "%s - submit read urb failed %i\n", __func__, status); ++ usb_free_urb(serial_priv->read_urb); + return status; + } + + return 0; +- + } + + static int qt2_attach(struct usb_serial *serial) + { + struct qt2_serial_private *serial_priv; +- struct qt2_port_private *port_priv; +- int status, pcount; ++ int status; + + /* power on unit */ + status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), +@@ -856,26 +822,6 @@ static int qt2_attach(struct usb_serial *serial) + + usb_set_serial_data(serial, serial_priv); + +- for (pcount = 0; pcount < serial->num_ports; pcount++) { +- port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); +- if (!port_priv) { +- dev_err(&serial->dev->dev, +- "%s- kmalloc(%Zd) failed.\n", __func__, +- sizeof(*port_priv)); +- pcount--; +- status = -ENOMEM; +- goto attach_failed; +- } +- +- spin_lock_init(&port_priv->lock); +- spin_lock_init(&port_priv->urb_lock); +- init_waitqueue_head(&port_priv->delta_msr_wait); +- +- port_priv->port = serial->port[pcount]; +- +- usb_set_serial_port_data(serial->port[pcount], port_priv); +- } +- + status = qt2_setup_urbs(serial); + if (status != 0) + goto attach_failed; +@@ -883,14 +829,53 @@ static int qt2_attach(struct usb_serial *serial) + return 0; + + attach_failed: +- for (/* empty */; pcount >= 0; pcount--) { +- port_priv = usb_get_serial_port_data(serial->port[pcount]); +- kfree(port_priv); +- } + kfree(serial_priv); + return status; + } + ++static int qt2_port_probe(struct usb_serial_port *port) ++{ ++ struct usb_serial *serial = port->serial; ++ struct qt2_port_private *port_priv; ++ u8 bEndpointAddress; ++ ++ port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); ++ if (!port_priv) ++ return -ENOMEM; ++ ++ spin_lock_init(&port_priv->lock); ++ spin_lock_init(&port_priv->urb_lock); ++ init_waitqueue_head(&port_priv->delta_msr_wait); ++ port_priv->port = port; ++ ++ port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!port_priv->write_urb) { ++ kfree(port_priv); ++ return -ENOMEM; ++ } ++ bEndpointAddress = serial->port[0]->bulk_out_endpointAddress; ++ usb_fill_bulk_urb(port_priv->write_urb, serial->dev, ++ usb_sndbulkpipe(serial->dev, bEndpointAddress), ++ port_priv->write_buffer, ++ sizeof(port_priv->write_buffer), ++ qt2_write_bulk_callback, port); ++ ++ usb_set_serial_port_data(port, port_priv); ++ ++ return 0; ++} ++ ++static int qt2_port_remove(struct usb_serial_port *port) ++{ ++ struct qt2_port_private *port_priv; ++ ++ port_priv = usb_get_serial_port_data(port); ++ usb_free_urb(port_priv->write_urb); ++ kfree(port_priv); ++ ++ return 0; ++} ++ + static int qt2_tiocmget(struct tty_struct *tty) + { + struct usb_serial_port *port = tty->driver_data; +@@ -1129,6 +1114,8 @@ static struct usb_serial_driver qt2_device = { + .attach = qt2_attach, + .release = qt2_release, + .disconnect = qt2_disconnect, ++ .port_probe = qt2_port_probe, ++ .port_remove = qt2_port_remove, + .dtr_rts = qt2_dtr_rts, + .break_ctl = qt2_break_ctl, + .tiocmget = qt2_tiocmget, +diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c +index 0274710..cf6d149 100644 +--- a/drivers/usb/serial/sierra.c ++++ b/drivers/usb/serial/sierra.c +@@ -162,7 +162,6 @@ static int sierra_probe(struct usb_serial *serial, + { + int result = 0; + struct usb_device *udev; +- struct sierra_intf_private *data; + u8 ifnum; + + udev = serial->dev; +@@ -189,11 +188,6 @@ static int sierra_probe(struct usb_serial *serial, + return -ENODEV; + } + +- data = serial->private = kzalloc(sizeof(struct sierra_intf_private), GFP_KERNEL); +- if (!data) +- return -ENOMEM; +- spin_lock_init(&data->susp_lock); +- + return result; + } + +@@ -886,11 +880,15 @@ static void sierra_dtr_rts(struct usb_serial_port *port, int on) + + static int sierra_startup(struct usb_serial *serial) + { +- struct usb_serial_port *port; +- struct sierra_port_private *portdata; +- struct sierra_iface_info *himemoryp = NULL; +- int i; +- u8 ifnum; ++ struct sierra_intf_private *intfdata; ++ ++ intfdata = kzalloc(sizeof(*intfdata), GFP_KERNEL); ++ if (!intfdata) ++ return -ENOMEM; ++ ++ spin_lock_init(&intfdata->susp_lock); ++ ++ usb_set_serial_data(serial, intfdata); + + /* Set Device mode to D0 */ + sierra_set_power_state(serial->dev, 0x0000); +@@ -899,68 +897,71 @@ static int sierra_startup(struct usb_serial *serial) + if (nmea) + sierra_vsc_set_nmea(serial->dev, 1); + +- /* Now setup per port private data */ +- for (i = 0; i < serial->num_ports; i++) { +- port = serial->port[i]; +- portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); +- if (!portdata) { +- dev_dbg(&port->dev, "%s: kmalloc for " +- "sierra_port_private (%d) failed!\n", +- __func__, i); +- return -ENOMEM; +- } +- spin_lock_init(&portdata->lock); +- init_usb_anchor(&portdata->active); +- init_usb_anchor(&portdata->delayed); +- ifnum = i; +- /* Assume low memory requirements */ +- portdata->num_out_urbs = N_OUT_URB; +- portdata->num_in_urbs = N_IN_URB; +- +- /* Determine actual memory requirements */ +- if (serial->num_ports == 1) { +- /* Get interface number for composite device */ +- ifnum = sierra_calc_interface(serial); +- himemoryp = +- (struct sierra_iface_info *)&typeB_interface_list; +- if (is_himemory(ifnum, himemoryp)) { +- portdata->num_out_urbs = N_OUT_URB_HM; +- portdata->num_in_urbs = N_IN_URB_HM; +- } +- } +- else { +- himemoryp = +- (struct sierra_iface_info *)&typeA_interface_list; +- if (is_himemory(i, himemoryp)) { +- portdata->num_out_urbs = N_OUT_URB_HM; +- portdata->num_in_urbs = N_IN_URB_HM; +- } +- } +- dev_dbg(&serial->dev->dev, +- "Memory usage (urbs) interface #%d, in=%d, out=%d\n", +- ifnum,portdata->num_in_urbs, portdata->num_out_urbs ); +- /* Set the port private data pointer */ +- usb_set_serial_port_data(port, portdata); +- } +- + return 0; + } + + static void sierra_release(struct usb_serial *serial) + { +- int i; +- struct usb_serial_port *port; ++ struct sierra_intf_private *intfdata; ++ ++ intfdata = usb_get_serial_data(serial); ++ kfree(intfdata); ++} ++ ++static int sierra_port_probe(struct usb_serial_port *port) ++{ ++ struct usb_serial *serial = port->serial; + struct sierra_port_private *portdata; ++ const struct sierra_iface_info *himemoryp; ++ u8 ifnum; + +- for (i = 0; i < serial->num_ports; ++i) { +- port = serial->port[i]; +- if (!port) +- continue; +- portdata = usb_get_serial_port_data(port); +- if (!portdata) +- continue; +- kfree(portdata); ++ portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); ++ if (!portdata) ++ return -ENOMEM; ++ ++ spin_lock_init(&portdata->lock); ++ init_usb_anchor(&portdata->active); ++ init_usb_anchor(&portdata->delayed); ++ ++ /* Assume low memory requirements */ ++ portdata->num_out_urbs = N_OUT_URB; ++ portdata->num_in_urbs = N_IN_URB; ++ ++ /* Determine actual memory requirements */ ++ if (serial->num_ports == 1) { ++ /* Get interface number for composite device */ ++ ifnum = sierra_calc_interface(serial); ++ himemoryp = &typeB_interface_list; ++ } else { ++ /* This is really the usb-serial port number of the interface ++ * rather than the interface number. ++ */ ++ ifnum = port->number - serial->minor; ++ himemoryp = &typeA_interface_list; + } ++ ++ if (is_himemory(ifnum, himemoryp)) { ++ portdata->num_out_urbs = N_OUT_URB_HM; ++ portdata->num_in_urbs = N_IN_URB_HM; ++ } ++ ++ dev_dbg(&port->dev, ++ "Memory usage (urbs) interface #%d, in=%d, out=%d\n", ++ ifnum, portdata->num_in_urbs, portdata->num_out_urbs); ++ ++ usb_set_serial_port_data(port, portdata); ++ ++ return 0; ++} ++ ++static int sierra_port_remove(struct usb_serial_port *port) ++{ ++ struct sierra_port_private *portdata; ++ ++ portdata = usb_get_serial_port_data(port); ++ kfree(portdata); ++ ++ return 0; + } + + #ifdef CONFIG_PM +@@ -1064,6 +1065,8 @@ static struct usb_serial_driver sierra_device = { + .tiocmset = sierra_tiocmset, + .attach = sierra_startup, + .release = sierra_release, ++ .port_probe = sierra_port_probe, ++ .port_remove = sierra_port_remove, + .suspend = sierra_suspend, + .resume = sierra_resume, + .read_int_callback = sierra_instat_callback, +diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h +index 1f034d2..684739b 100644 +--- a/drivers/usb/serial/usb-wwan.h ++++ b/drivers/usb/serial/usb-wwan.h +@@ -8,7 +8,7 @@ + extern void usb_wwan_dtr_rts(struct usb_serial_port *port, int on); + extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port); + extern void usb_wwan_close(struct usb_serial_port *port); +-extern int usb_wwan_startup(struct usb_serial *serial); ++extern int usb_wwan_port_probe(struct usb_serial_port *port); + extern int usb_wwan_port_remove(struct usb_serial_port *port); + extern int usb_wwan_write_room(struct tty_struct *tty); + extern void usb_wwan_set_termios(struct tty_struct *tty, +diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c +index 6855d5e..2f2d074 100644 +--- a/drivers/usb/serial/usb_wwan.c ++++ b/drivers/usb/serial/usb_wwan.c +@@ -447,10 +447,12 @@ void usb_wwan_close(struct usb_serial_port *port) + EXPORT_SYMBOL(usb_wwan_close); + + /* Helper functions used by usb_wwan_setup_urbs */ +-static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint, ++static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port, ++ int endpoint, + int dir, void *ctx, char *buf, int len, + void (*callback) (struct urb *)) + { ++ struct usb_serial *serial = port->serial; + struct urb *urb; + + if (endpoint == -1) +@@ -470,100 +472,74 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint, + return urb; + } + +-/* Setup urbs */ +-static void usb_wwan_setup_urbs(struct usb_serial *serial) ++int usb_wwan_port_probe(struct usb_serial_port *port) + { +- int i, j; +- struct usb_serial_port *port; + struct usb_wwan_port_private *portdata; ++ struct urb *urb; ++ u8 *buffer; ++ int err; ++ int i; + +- for (i = 0; i < serial->num_ports; i++) { +- port = serial->port[i]; +- portdata = usb_get_serial_port_data(port); +- +- /* Do indat endpoints first */ +- for (j = 0; j < N_IN_URB; ++j) { +- portdata->in_urbs[j] = usb_wwan_setup_urb(serial, +- port-> +- bulk_in_endpointAddress, +- USB_DIR_IN, +- port, +- portdata-> +- in_buffer[j], +- IN_BUFLEN, +- usb_wwan_indat_callback); +- } +- +- /* outdat endpoints */ +- for (j = 0; j < N_OUT_URB; ++j) { +- portdata->out_urbs[j] = usb_wwan_setup_urb(serial, +- port-> +- bulk_out_endpointAddress, +- USB_DIR_OUT, +- port, +- portdata-> +- out_buffer +- [j], +- OUT_BUFLEN, +- usb_wwan_outdat_callback); +- } +- } +-} ++ portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); ++ if (!portdata) ++ return -ENOMEM; + +-int usb_wwan_startup(struct usb_serial *serial) +-{ +- int i, j, err; +- struct usb_serial_port *port; +- struct usb_wwan_port_private *portdata; +- u8 *buffer; ++ init_usb_anchor(&portdata->delayed); + +- /* Now setup per port private data */ +- for (i = 0; i < serial->num_ports; i++) { +- port = serial->port[i]; +- portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); +- if (!portdata) { +- dbg("%s: kmalloc for usb_wwan_port_private (%d) failed!.", +- __func__, i); +- return 1; +- } +- init_usb_anchor(&portdata->delayed); ++ for (i = 0; i < N_IN_URB; i++) { ++ buffer = (u8 *)__get_free_page(GFP_KERNEL); ++ if (!buffer) ++ goto bail_out_error; ++ portdata->in_buffer[i] = buffer; ++ ++ urb = usb_wwan_setup_urb(port, port->bulk_in_endpointAddress, ++ USB_DIR_IN, port, ++ buffer, IN_BUFLEN, ++ usb_wwan_indat_callback); ++ portdata->in_urbs[i] = urb; ++ } ++ for (i = 0; i < N_OUT_URB; i++) { ++ if (port->bulk_out_endpointAddress == -1) ++ continue; + +- for (j = 0; j < N_IN_URB; j++) { +- buffer = (u8 *) __get_free_page(GFP_KERNEL); +- if (!buffer) +- goto bail_out_error; +- portdata->in_buffer[j] = buffer; +- } ++ buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); ++ if (!buffer) ++ goto bail_out_error2; ++ portdata->out_buffer[i] = buffer; + +- for (j = 0; j < N_OUT_URB; j++) { +- buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); +- if (!buffer) +- goto bail_out_error2; +- portdata->out_buffer[j] = buffer; +- } ++ urb = usb_wwan_setup_urb(port, port->bulk_out_endpointAddress, ++ USB_DIR_OUT, port, ++ buffer, OUT_BUFLEN, ++ usb_wwan_outdat_callback); ++ portdata->out_urbs[i] = urb; ++ } + +- usb_set_serial_port_data(port, portdata); ++ usb_set_serial_port_data(port, portdata); + +- if (!port->interrupt_in_urb) +- continue; ++ if (port->interrupt_in_urb) { + err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); + if (err) +- dbg("%s: submit irq_in urb failed %d", __func__, err); ++ dev_dbg(&port->dev, "%s: submit irq_in urb failed %d\n", ++ __func__, err); + } +- usb_wwan_setup_urbs(serial); ++ + return 0; + + bail_out_error2: +- for (j = 0; j < N_OUT_URB; j++) +- kfree(portdata->out_buffer[j]); ++ for (i = 0; i < N_OUT_URB; i++) { ++ usb_free_urb(portdata->out_urbs[i]); ++ kfree(portdata->out_buffer[i]); ++ } + bail_out_error: +- for (j = 0; j < N_IN_URB; j++) +- if (portdata->in_buffer[j]) +- free_page((unsigned long)portdata->in_buffer[j]); ++ for (i = 0; i < N_IN_URB; i++) { ++ usb_free_urb(portdata->in_urbs[i]); ++ free_page((unsigned long)portdata->in_buffer[i]); ++ } + kfree(portdata); +- return 1; ++ ++ return -ENOMEM; + } +-EXPORT_SYMBOL(usb_wwan_startup); ++EXPORT_SYMBOL_GPL(usb_wwan_port_probe); + + int usb_wwan_port_remove(struct usb_serial_port *port) + { +diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c +index 473635e..bd36321 100644 +--- a/drivers/usb/serial/whiteheat.c ++++ b/drivers/usb/serial/whiteheat.c +@@ -86,6 +86,8 @@ static int whiteheat_firmware_attach(struct usb_serial *serial); + /* function prototypes for the Connect Tech WhiteHEAT serial converter */ + static int whiteheat_attach(struct usb_serial *serial); + static void whiteheat_release(struct usb_serial *serial); ++static int whiteheat_port_probe(struct usb_serial_port *port); ++static int whiteheat_port_remove(struct usb_serial_port *port); + static int whiteheat_open(struct tty_struct *tty, + struct usb_serial_port *port); + static void whiteheat_close(struct usb_serial_port *port); +@@ -120,6 +122,8 @@ static struct usb_serial_driver whiteheat_device = { + .num_ports = 4, + .attach = whiteheat_attach, + .release = whiteheat_release, ++ .port_probe = whiteheat_port_probe, ++ .port_remove = whiteheat_port_remove, + .open = whiteheat_open, + .close = whiteheat_close, + .ioctl = whiteheat_ioctl, +@@ -290,15 +294,12 @@ static int whiteheat_attach(struct usb_serial *serial) + { + struct usb_serial_port *command_port; + struct whiteheat_command_private *command_info; +- struct usb_serial_port *port; +- struct whiteheat_private *info; + struct whiteheat_hw_info *hw_info; + int pipe; + int ret; + int alen; + __u8 *command; + __u8 *result; +- int i; + + command_port = serial->port[COMMAND_PORT]; + +@@ -357,22 +358,6 @@ static int whiteheat_attach(struct usb_serial *serial) + serial->type->description, + hw_info->sw_major_rev, hw_info->sw_minor_rev); + +- for (i = 0; i < serial->num_ports; i++) { +- port = serial->port[i]; +- +- info = kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL); +- if (info == NULL) { +- dev_err(&port->dev, +- "%s: Out of memory for port structures\n", +- serial->type->description); +- goto no_private; +- } +- +- info->mcr = 0; +- +- usb_set_serial_port_data(port, info); +- } +- + command_info = kmalloc(sizeof(struct whiteheat_command_private), + GFP_KERNEL); + if (command_info == NULL) { +@@ -405,16 +390,10 @@ no_firmware: + "%s: please contact support@connecttech.com\n", + serial->type->description); + kfree(result); ++ kfree(command); + return -ENODEV; + + no_command_private: +- for (i = serial->num_ports - 1; i >= 0; i--) { +- port = serial->port[i]; +- info = usb_get_serial_port_data(port); +- kfree(info); +-no_private: +- ; +- } + kfree(result); + no_result_buffer: + kfree(command); +@@ -422,21 +401,36 @@ no_command_buffer: + return -ENOMEM; + } + +- + static void whiteheat_release(struct usb_serial *serial) + { + struct usb_serial_port *command_port; +- struct whiteheat_private *info; +- int i; + + /* free up our private data for our command port */ + command_port = serial->port[COMMAND_PORT]; + kfree(usb_get_serial_port_data(command_port)); ++} + +- for (i = 0; i < serial->num_ports; i++) { +- info = usb_get_serial_port_data(serial->port[i]); +- kfree(info); +- } ++static int whiteheat_port_probe(struct usb_serial_port *port) ++{ ++ struct whiteheat_private *info; ++ ++ info = kzalloc(sizeof(*info), GFP_KERNEL); ++ if (!info) ++ return -ENOMEM; ++ ++ usb_set_serial_port_data(port, info); ++ ++ return 0; ++} ++ ++static int whiteheat_port_remove(struct usb_serial_port *port) ++{ ++ struct whiteheat_private *info; ++ ++ info = usb_get_serial_port_data(port); ++ kfree(info); ++ ++ return 0; + } + + static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port) +diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h +index 62a31be..8f98c9a 100644 +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -1004,6 +1004,12 @@ UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9999, + USB_SC_8070, USB_PR_CB, NULL, + US_FL_NEED_OVERRIDE | US_FL_FIX_INQUIRY ), + ++/* Submitted by Oleksandr Chumachenko <ledest@gmail.com> */ ++UNUSUAL_DEV( 0x07cf, 0x1167, 0x0100, 0x0100, ++ "Casio", ++ "EX-N1 DigitalCamera", ++ USB_SC_8070, USB_PR_DEVICE, NULL, 0), ++ + /* Submitted by Hartmut Wahl <hwahl@hwahl.de>*/ + UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001, + "Samsung", +diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c +index 072cbba..7f93f34 100644 +--- a/drivers/vhost/net.c ++++ b/drivers/vhost/net.c +@@ -379,7 +379,8 @@ static void handle_rx(struct vhost_net *net) + .hdr.gso_type = VIRTIO_NET_HDR_GSO_NONE + }; + size_t total_len = 0; +- int err, headcount, mergeable; ++ int err, mergeable; ++ s16 headcount; + size_t vhost_hlen, sock_hlen; + size_t vhost_len, sock_len; + /* TODO: check that we are running from vhost_worker? */ +diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c +index debdfe0..5d2069f 100644 +--- a/fs/compat_ioctl.c ++++ b/fs/compat_ioctl.c +@@ -210,6 +210,8 @@ static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, + + err = get_user(palp, &up->palette); + err |= get_user(length, &up->length); ++ if (err) ++ return -EFAULT; + + up_native = compat_alloc_user_space(sizeof(struct video_spu_palette)); + err = put_user(compat_ptr(palp), &up_native->palette); +diff --git a/fs/exec.c b/fs/exec.c +index 574cf4d..fab2c6d 100644 +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -1110,7 +1110,8 @@ int flush_old_exec(struct linux_binprm * bprm) + bprm->mm = NULL; /* We're using it now */ + + set_fs(USER_DS); +- current->flags &= ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD); ++ current->flags &= ++ ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD | PF_NOFREEZE); + flush_thread(); + current->personality &= ~bprm->per_clear; + +diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c +index e4fb3ba..3d7e09b 100644 +--- a/fs/lockd/mon.c ++++ b/fs/lockd/mon.c +@@ -85,29 +85,38 @@ static struct rpc_clnt *nsm_create(struct net *net) + return rpc_create(&args); + } + ++static struct rpc_clnt *nsm_client_set(struct lockd_net *ln, ++ struct rpc_clnt *clnt) ++{ ++ spin_lock(&ln->nsm_clnt_lock); ++ if (ln->nsm_users == 0) { ++ if (clnt == NULL) ++ goto out; ++ ln->nsm_clnt = clnt; ++ } ++ clnt = ln->nsm_clnt; ++ ln->nsm_users++; ++out: ++ spin_unlock(&ln->nsm_clnt_lock); ++ return clnt; ++} ++ + static struct rpc_clnt *nsm_client_get(struct net *net) + { +- static DEFINE_MUTEX(nsm_create_mutex); +- struct rpc_clnt *clnt; ++ struct rpc_clnt *clnt, *new; + struct lockd_net *ln = net_generic(net, lockd_net_id); + +- spin_lock(&ln->nsm_clnt_lock); +- if (ln->nsm_users) { +- ln->nsm_users++; +- clnt = ln->nsm_clnt; +- spin_unlock(&ln->nsm_clnt_lock); ++ clnt = nsm_client_set(ln, NULL); ++ if (clnt != NULL) + goto out; +- } +- spin_unlock(&ln->nsm_clnt_lock); + +- mutex_lock(&nsm_create_mutex); +- clnt = nsm_create(net); +- if (!IS_ERR(clnt)) { +- ln->nsm_clnt = clnt; +- smp_wmb(); +- ln->nsm_users = 1; +- } +- mutex_unlock(&nsm_create_mutex); ++ clnt = new = nsm_create(net); ++ if (IS_ERR(clnt)) ++ goto out; ++ ++ clnt = nsm_client_set(ln, new); ++ if (clnt != new) ++ rpc_shutdown_client(new); + out: + return clnt; + } +@@ -115,18 +124,16 @@ out: + static void nsm_client_put(struct net *net) + { + struct lockd_net *ln = net_generic(net, lockd_net_id); +- struct rpc_clnt *clnt = ln->nsm_clnt; +- int shutdown = 0; ++ struct rpc_clnt *clnt = NULL; + + spin_lock(&ln->nsm_clnt_lock); +- if (ln->nsm_users) { +- if (--ln->nsm_users) +- ln->nsm_clnt = NULL; +- shutdown = !ln->nsm_users; ++ ln->nsm_users--; ++ if (ln->nsm_users == 0) { ++ clnt = ln->nsm_clnt; ++ ln->nsm_clnt = NULL; + } + spin_unlock(&ln->nsm_clnt_lock); +- +- if (shutdown) ++ if (clnt != NULL) + rpc_shutdown_client(clnt); + } + +diff --git a/fs/namei.c b/fs/namei.c +index 81bd546..091c4b7 100644 +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -651,8 +651,8 @@ static inline void put_link(struct nameidata *nd, struct path *link, void *cooki + path_put(link); + } + +-int sysctl_protected_symlinks __read_mostly = 1; +-int sysctl_protected_hardlinks __read_mostly = 1; ++int sysctl_protected_symlinks __read_mostly = 0; ++int sysctl_protected_hardlinks __read_mostly = 0; + + /** + * may_follow_link - Check symlink following for unsafe situations +diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c +index f3d16ad..1093968 100644 +--- a/fs/nfs/blocklayout/blocklayout.c ++++ b/fs/nfs/blocklayout/blocklayout.c +@@ -242,14 +242,6 @@ bl_end_par_io_read(void *data, int unused) + schedule_work(&rdata->task.u.tk_work); + } + +-static bool +-bl_check_alignment(u64 offset, u32 len, unsigned long blkmask) +-{ +- if ((offset & blkmask) || (len & blkmask)) +- return false; +- return true; +-} +- + static enum pnfs_try_status + bl_read_pagelist(struct nfs_read_data *rdata) + { +@@ -260,15 +252,15 @@ bl_read_pagelist(struct nfs_read_data *rdata) + sector_t isect, extent_length = 0; + struct parallel_io *par; + loff_t f_offset = rdata->args.offset; ++ size_t bytes_left = rdata->args.count; ++ unsigned int pg_offset, pg_len; + struct page **pages = rdata->args.pages; + int pg_index = rdata->args.pgbase >> PAGE_CACHE_SHIFT; ++ const bool is_dio = (header->dreq != NULL); + + dprintk("%s enter nr_pages %u offset %lld count %u\n", __func__, + rdata->pages.npages, f_offset, (unsigned int)rdata->args.count); + +- if (!bl_check_alignment(f_offset, rdata->args.count, PAGE_CACHE_MASK)) +- goto use_mds; +- + par = alloc_parallel(rdata); + if (!par) + goto use_mds; +@@ -298,36 +290,53 @@ bl_read_pagelist(struct nfs_read_data *rdata) + extent_length = min(extent_length, cow_length); + } + } ++ ++ if (is_dio) { ++ pg_offset = f_offset & ~PAGE_CACHE_MASK; ++ if (pg_offset + bytes_left > PAGE_CACHE_SIZE) ++ pg_len = PAGE_CACHE_SIZE - pg_offset; ++ else ++ pg_len = bytes_left; ++ ++ f_offset += pg_len; ++ bytes_left -= pg_len; ++ isect += (pg_offset >> SECTOR_SHIFT); ++ } else { ++ pg_offset = 0; ++ pg_len = PAGE_CACHE_SIZE; ++ } ++ + hole = is_hole(be, isect); + if (hole && !cow_read) { + bio = bl_submit_bio(READ, bio); + /* Fill hole w/ zeroes w/o accessing device */ + dprintk("%s Zeroing page for hole\n", __func__); +- zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE); ++ zero_user_segment(pages[i], pg_offset, pg_len); + print_page(pages[i]); + SetPageUptodate(pages[i]); + } else { + struct pnfs_block_extent *be_read; + + be_read = (hole && cow_read) ? cow_read : be; +- bio = bl_add_page_to_bio(bio, rdata->pages.npages - i, ++ bio = do_add_page_to_bio(bio, rdata->pages.npages - i, + READ, + isect, pages[i], be_read, +- bl_end_io_read, par); ++ bl_end_io_read, par, ++ pg_offset, pg_len); + if (IS_ERR(bio)) { + header->pnfs_error = PTR_ERR(bio); + bio = NULL; + goto out; + } + } +- isect += PAGE_CACHE_SECTORS; ++ isect += (pg_len >> SECTOR_SHIFT); + extent_length -= PAGE_CACHE_SECTORS; + } + if ((isect << SECTOR_SHIFT) >= header->inode->i_size) { + rdata->res.eof = 1; +- rdata->res.count = header->inode->i_size - f_offset; ++ rdata->res.count = header->inode->i_size - rdata->args.offset; + } else { +- rdata->res.count = (isect << SECTOR_SHIFT) - f_offset; ++ rdata->res.count = (isect << SECTOR_SHIFT) - rdata->args.offset; + } + out: + bl_put_extent(be); +@@ -688,10 +697,13 @@ bl_write_pagelist(struct nfs_write_data *wdata, int sync) + NFS_SERVER(header->inode)->pnfs_blksize >> PAGE_CACHE_SHIFT; + + dprintk("%s enter, %Zu@%lld\n", __func__, count, offset); +- /* Check for alignment first */ +- if (!bl_check_alignment(offset, count, PAGE_CACHE_MASK)) +- goto out_mds; + ++ if (header->dreq != NULL && ++ (!IS_ALIGNED(offset, NFS_SERVER(header->inode)->pnfs_blksize) || ++ !IS_ALIGNED(count, NFS_SERVER(header->inode)->pnfs_blksize))) { ++ dprintk("pnfsblock nonblock aligned DIO writes. Resend MDS\n"); ++ goto out_mds; ++ } + /* At this point, wdata->pages is a (sequential) list of nfs_pages. + * We want to write each, and if there is an error set pnfs_error + * to have it redone using nfs. +@@ -1164,33 +1176,64 @@ bl_clear_layoutdriver(struct nfs_server *server) + return 0; + } + ++static bool ++is_aligned_req(struct nfs_page *req, unsigned int alignment) ++{ ++ return IS_ALIGNED(req->wb_offset, alignment) && ++ IS_ALIGNED(req->wb_bytes, alignment); ++} ++ + static void + bl_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) + { +- if (!bl_check_alignment(req->wb_offset, req->wb_bytes, PAGE_CACHE_MASK)) ++ if (pgio->pg_dreq != NULL && ++ !is_aligned_req(req, SECTOR_SIZE)) + nfs_pageio_reset_read_mds(pgio); + else + pnfs_generic_pg_init_read(pgio, req); + } + +-static void ++static bool ++bl_pg_test_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, ++ struct nfs_page *req) ++{ ++ if (pgio->pg_dreq != NULL && ++ !is_aligned_req(req, SECTOR_SIZE)) ++ return false; ++ ++ return pnfs_generic_pg_test(pgio, prev, req); ++} ++ ++void + bl_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) + { +- if (!bl_check_alignment(req->wb_offset, req->wb_bytes, PAGE_CACHE_MASK)) ++ if (pgio->pg_dreq != NULL && ++ !is_aligned_req(req, PAGE_CACHE_SIZE)) + nfs_pageio_reset_write_mds(pgio); + else + pnfs_generic_pg_init_write(pgio, req); + } + ++static bool ++bl_pg_test_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, ++ struct nfs_page *req) ++{ ++ if (pgio->pg_dreq != NULL && ++ !is_aligned_req(req, PAGE_CACHE_SIZE)) ++ return false; ++ ++ return pnfs_generic_pg_test(pgio, prev, req); ++} ++ + static const struct nfs_pageio_ops bl_pg_read_ops = { + .pg_init = bl_pg_init_read, +- .pg_test = pnfs_generic_pg_test, ++ .pg_test = bl_pg_test_read, + .pg_doio = pnfs_generic_pg_readpages, + }; + + static const struct nfs_pageio_ops bl_pg_write_ops = { + .pg_init = bl_pg_init_write, +- .pg_test = pnfs_generic_pg_test, ++ .pg_test = bl_pg_test_write, + .pg_doio = pnfs_generic_pg_writepages, + }; + +diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c +index 6b0bb00..2fbdff6 100644 +--- a/fs/sysfs/dir.c ++++ b/fs/sysfs/dir.c +@@ -485,20 +485,18 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) + /** + * sysfs_pathname - return full path to sysfs dirent + * @sd: sysfs_dirent whose path we want +- * @path: caller allocated buffer ++ * @path: caller allocated buffer of size PATH_MAX + * + * Gives the name "/" to the sysfs_root entry; any path returned + * is relative to wherever sysfs is mounted. +- * +- * XXX: does no error checking on @path size + */ + static char *sysfs_pathname(struct sysfs_dirent *sd, char *path) + { + if (sd->s_parent) { + sysfs_pathname(sd->s_parent, path); +- strcat(path, "/"); ++ strlcat(path, "/", PATH_MAX); + } +- strcat(path, sd->s_name); ++ strlcat(path, sd->s_name, PATH_MAX); + return path; + } + +@@ -531,9 +529,11 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) + char *path = kzalloc(PATH_MAX, GFP_KERNEL); + WARN(1, KERN_WARNING + "sysfs: cannot create duplicate filename '%s'\n", +- (path == NULL) ? sd->s_name : +- strcat(strcat(sysfs_pathname(acxt->parent_sd, path), "/"), +- sd->s_name)); ++ (path == NULL) ? sd->s_name ++ : (sysfs_pathname(acxt->parent_sd, path), ++ strlcat(path, "/", PATH_MAX), ++ strlcat(path, sd->s_name, PATH_MAX), ++ path)); + kfree(path); + } + +diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h +index c78bb99..af1cbaf 100644 +--- a/include/drm/drm_pciids.h ++++ b/include/drm/drm_pciids.h +@@ -205,6 +205,8 @@ + {0x1002, 0x6788, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x678A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6790, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x6791, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x6792, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6798, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6799, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x679A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ +@@ -217,6 +219,7 @@ + {0x1002, 0x6808, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6809, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6810, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x6811, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6816, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6817, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6818, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ +diff --git a/include/linux/efi.h b/include/linux/efi.h +index ec45ccd..5782114 100644 +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -496,6 +496,11 @@ extern void efi_map_pal_code (void); + extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg); + extern void efi_gettimeofday (struct timespec *ts); + extern void efi_enter_virtual_mode (void); /* switch EFI to virtual mode, if possible */ ++#ifdef CONFIG_X86 ++extern void efi_free_boot_services(void); ++#else ++static inline void efi_free_boot_services(void) {} ++#endif + extern u64 efi_get_iobase (void); + extern u32 efi_mem_type (unsigned long phys_addr); + extern u64 efi_mem_attributes (unsigned long phys_addr); +diff --git a/include/linux/memblock.h b/include/linux/memblock.h +index 19dc455..c948c44 100644 +--- a/include/linux/memblock.h ++++ b/include/linux/memblock.h +@@ -57,6 +57,7 @@ int memblock_add(phys_addr_t base, phys_addr_t size); + int memblock_remove(phys_addr_t base, phys_addr_t size); + int memblock_free(phys_addr_t base, phys_addr_t size); + int memblock_reserve(phys_addr_t base, phys_addr_t size); ++void memblock_trim_memory(phys_addr_t align); + + #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP + void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn, +diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h +index 3d254e1..f10553c 100644 +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -1217,6 +1217,7 @@ struct cfg80211_deauth_request { + const u8 *ie; + size_t ie_len; + u16 reason_code; ++ bool local_state_change; + }; + + /** +diff --git a/init/main.c b/init/main.c +index b286730..d61ec54 100644 +--- a/init/main.c ++++ b/init/main.c +@@ -631,6 +631,9 @@ asmlinkage void __init start_kernel(void) + acpi_early_init(); /* before LAPIC and SMP init */ + sfi_init_late(); + ++ if (efi_enabled) ++ efi_free_boot_services(); ++ + ftrace_init(); + + /* Do the rest non-__init'ed, we're now alive */ +diff --git a/lib/genalloc.c b/lib/genalloc.c +index 6bc04aa..7cb7a5d 100644 +--- a/lib/genalloc.c ++++ b/lib/genalloc.c +@@ -176,7 +176,7 @@ int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phy + struct gen_pool_chunk *chunk; + int nbits = size >> pool->min_alloc_order; + int nbytes = sizeof(struct gen_pool_chunk) + +- (nbits + BITS_PER_BYTE - 1) / BITS_PER_BYTE; ++ BITS_TO_LONGS(nbits) * sizeof(long); + + chunk = kmalloc_node(nbytes, GFP_KERNEL | __GFP_ZERO, nid); + if (unlikely(chunk == NULL)) +diff --git a/mm/memblock.c b/mm/memblock.c +index 82aa349..0e490e8 100644 +--- a/mm/memblock.c ++++ b/mm/memblock.c +@@ -929,6 +929,30 @@ int __init_memblock memblock_is_region_reserved(phys_addr_t base, phys_addr_t si + return memblock_overlaps_region(&memblock.reserved, base, size) >= 0; + } + ++void __init_memblock memblock_trim_memory(phys_addr_t align) ++{ ++ int i; ++ phys_addr_t start, end, orig_start, orig_end; ++ struct memblock_type *mem = &memblock.memory; ++ ++ for (i = 0; i < mem->cnt; i++) { ++ orig_start = mem->regions[i].base; ++ orig_end = mem->regions[i].base + mem->regions[i].size; ++ start = round_up(orig_start, align); ++ end = round_down(orig_end, align); ++ ++ if (start == orig_start && end == orig_end) ++ continue; ++ ++ if (start < end) { ++ mem->regions[i].base = start; ++ mem->regions[i].size = end - start; ++ } else { ++ memblock_remove_region(mem, i); ++ i--; ++ } ++ } ++} + + void __init_memblock memblock_set_current_limit(phys_addr_t limit) + { +diff --git a/mm/rmap.c b/mm/rmap.c +index 0f3b7cd..aa95e59 100644 +--- a/mm/rmap.c ++++ b/mm/rmap.c +@@ -56,6 +56,7 @@ + #include <linux/mmu_notifier.h> + #include <linux/migrate.h> + #include <linux/hugetlb.h> ++#include <linux/backing-dev.h> + + #include <asm/tlbflush.h> + +@@ -971,11 +972,8 @@ int page_mkclean(struct page *page) + + if (page_mapped(page)) { + struct address_space *mapping = page_mapping(page); +- if (mapping) { ++ if (mapping) + ret = page_mkclean_file(mapping, page); +- if (page_test_and_clear_dirty(page_to_pfn(page), 1)) +- ret = 1; +- } + } + + return ret; +@@ -1161,6 +1159,7 @@ void page_add_file_rmap(struct page *page) + */ + void page_remove_rmap(struct page *page) + { ++ struct address_space *mapping = page_mapping(page); + bool anon = PageAnon(page); + bool locked; + unsigned long flags; +@@ -1183,8 +1182,19 @@ void page_remove_rmap(struct page *page) + * this if the page is anon, so about to be freed; but perhaps + * not if it's in swapcache - there might be another pte slot + * containing the swap entry, but page not yet written to swap. ++ * ++ * And we can skip it on file pages, so long as the filesystem ++ * participates in dirty tracking; but need to catch shm and tmpfs ++ * and ramfs pages which have been modified since creation by read ++ * fault. ++ * ++ * Note that mapping must be decided above, before decrementing ++ * mapcount (which luckily provides a barrier): once page is unmapped, ++ * it could be truncated and page->mapping reset to NULL at any moment. ++ * Note also that we are relying on page_mapping(page) to set mapping ++ * to &swapper_space when PageSwapCache(page). + */ +- if ((!anon || PageSwapCache(page)) && ++ if (mapping && !mapping_cap_account_dirty(mapping) && + page_test_and_clear_dirty(page_to_pfn(page), 1)) + set_page_dirty(page); + /* +diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c +index 8c225ef..2ac8d50 100644 +--- a/net/bluetooth/smp.c ++++ b/net/bluetooth/smp.c +@@ -32,6 +32,8 @@ + + #define SMP_TIMEOUT msecs_to_jiffies(30000) + ++#define AUTH_REQ_MASK 0x07 ++ + static inline void swap128(u8 src[16], u8 dst[16]) + { + int i; +@@ -230,7 +232,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn, + req->max_key_size = SMP_MAX_ENC_KEY_SIZE; + req->init_key_dist = 0; + req->resp_key_dist = dist_keys; +- req->auth_req = authreq; ++ req->auth_req = (authreq & AUTH_REQ_MASK); + return; + } + +@@ -239,7 +241,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn, + rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE; + rsp->init_key_dist = 0; + rsp->resp_key_dist = req->resp_key_dist & dist_keys; +- rsp->auth_req = authreq; ++ rsp->auth_req = (authreq & AUTH_REQ_MASK); + } + + static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) +diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c +index bfb57dc..c93d395 100644 +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -822,7 +822,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + if (info->control.vif == &sdata->vif) { + __skb_unlink(skb, &local->pending[i]); +- dev_kfree_skb_irq(skb); ++ ieee80211_free_txskb(&local->hw, skb); + } + } + } +diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c +index f76b833..b71d466 100644 +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -3065,22 +3065,32 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, + ht_cfreq, ht_oper->primary_chan, + cbss->channel->band); + ht_oper = NULL; ++ } else { ++ channel_type = NL80211_CHAN_HT20; + } + } + +- if (ht_oper) { +- channel_type = NL80211_CHAN_HT20; ++ if (ht_oper && sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { ++ /* ++ * cfg80211 already verified that the channel itself can ++ * be used, but it didn't check that we can do the right ++ * HT type, so do that here as well. If HT40 isn't allowed ++ * on this channel, disable 40 MHz operation. ++ */ + +- if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { +- switch (ht_oper->ht_param & +- IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { +- case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: ++ switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { ++ case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: ++ if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40PLUS) ++ ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; ++ else + channel_type = NL80211_CHAN_HT40PLUS; +- break; +- case IEEE80211_HT_PARAM_CHA_SEC_BELOW: ++ break; ++ case IEEE80211_HT_PARAM_CHA_SEC_BELOW: ++ if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40MINUS) ++ ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; ++ else + channel_type = NL80211_CHAN_HT40MINUS; +- break; +- } ++ break; + } + } + +@@ -3457,6 +3467,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, + { + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + u8 frame_buf[DEAUTH_DISASSOC_LEN]; ++ bool tx = !req->local_state_change; + + mutex_lock(&ifmgd->mtx); + +@@ -3473,11 +3484,11 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, + if (ifmgd->associated && + ether_addr_equal(ifmgd->associated->bssid, req->bssid)) + ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, +- req->reason_code, true, frame_buf); ++ req->reason_code, tx, frame_buf); + else + ieee80211_send_deauth_disassoc(sdata, req->bssid, + IEEE80211_STYPE_DEAUTH, +- req->reason_code, true, ++ req->reason_code, tx, + frame_buf); + mutex_unlock(&ifmgd->mtx); + +diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c +index 06fa75c..63882b9 100644 +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -585,7 +585,7 @@ static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, + */ + if (!skb) + break; +- dev_kfree_skb(skb); ++ ieee80211_free_txskb(&local->hw, skb); + } + + /* +@@ -614,7 +614,7 @@ static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, + local->total_ps_buffered--; + ps_dbg(sta->sdata, "Buffered frame expired (STA %pM)\n", + sta->sta.addr); +- dev_kfree_skb(skb); ++ ieee80211_free_txskb(&local->hw, skb); + } + + /* +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index 39b82fe..c9b52f7 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -400,7 +400,7 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local, + int queue = info->hw_queue; + + if (WARN_ON(!info->control.vif)) { +- kfree_skb(skb); ++ ieee80211_free_txskb(&local->hw, skb); + return; + } + +@@ -425,7 +425,7 @@ void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + if (WARN_ON(!info->control.vif)) { +- kfree_skb(skb); ++ ieee80211_free_txskb(&local->hw, skb); + continue; + } + +diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c +index bdb53ab..e72562a 100644 +--- a/net/mac80211/wpa.c ++++ b/net/mac80211/wpa.c +@@ -106,7 +106,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) + if (status->flag & RX_FLAG_MMIC_ERROR) + goto mic_fail; + +- if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key) ++ if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key && ++ rx->key->conf.cipher == WLAN_CIPHER_SUITE_TKIP) + goto update_iv; + + return RX_CONTINUE; +diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c +index 97f8918..6a70db4 100644 +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -254,7 +254,6 @@ struct sock_xprt { + void (*old_data_ready)(struct sock *, int); + void (*old_state_change)(struct sock *); + void (*old_write_space)(struct sock *); +- void (*old_error_report)(struct sock *); + }; + + /* +@@ -737,10 +736,10 @@ static int xs_tcp_send_request(struct rpc_task *task) + dprintk("RPC: sendmsg returned unrecognized error %d\n", + -status); + case -ECONNRESET: +- case -EPIPE: + xs_tcp_shutdown(xprt); + case -ECONNREFUSED: + case -ENOTCONN: ++ case -EPIPE: + clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); + } + +@@ -781,7 +780,6 @@ static void xs_save_old_callbacks(struct sock_xprt *transport, struct sock *sk) + transport->old_data_ready = sk->sk_data_ready; + transport->old_state_change = sk->sk_state_change; + transport->old_write_space = sk->sk_write_space; +- transport->old_error_report = sk->sk_error_report; + } + + static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *sk) +@@ -789,7 +787,6 @@ static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *s + sk->sk_data_ready = transport->old_data_ready; + sk->sk_state_change = transport->old_state_change; + sk->sk_write_space = transport->old_write_space; +- sk->sk_error_report = transport->old_error_report; + } + + static void xs_reset_transport(struct sock_xprt *transport) +@@ -1462,7 +1459,7 @@ static void xs_tcp_cancel_linger_timeout(struct rpc_xprt *xprt) + xprt_clear_connecting(xprt); + } + +-static void xs_sock_mark_closed(struct rpc_xprt *xprt) ++static void xs_sock_reset_connection_flags(struct rpc_xprt *xprt) + { + smp_mb__before_clear_bit(); + clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); +@@ -1470,6 +1467,11 @@ static void xs_sock_mark_closed(struct rpc_xprt *xprt) + clear_bit(XPRT_CLOSE_WAIT, &xprt->state); + clear_bit(XPRT_CLOSING, &xprt->state); + smp_mb__after_clear_bit(); ++} ++ ++static void xs_sock_mark_closed(struct rpc_xprt *xprt) ++{ ++ xs_sock_reset_connection_flags(xprt); + /* Mark transport as closed and wake up all pending tasks */ + xprt_disconnect_done(xprt); + } +@@ -1525,6 +1527,7 @@ static void xs_tcp_state_change(struct sock *sk) + case TCP_CLOSE_WAIT: + /* The server initiated a shutdown of the socket */ + xprt->connect_cookie++; ++ clear_bit(XPRT_CONNECTED, &xprt->state); + xs_tcp_force_close(xprt); + case TCP_CLOSING: + /* +@@ -1549,25 +1552,6 @@ static void xs_tcp_state_change(struct sock *sk) + read_unlock_bh(&sk->sk_callback_lock); + } + +-/** +- * xs_error_report - callback mainly for catching socket errors +- * @sk: socket +- */ +-static void xs_error_report(struct sock *sk) +-{ +- struct rpc_xprt *xprt; +- +- read_lock_bh(&sk->sk_callback_lock); +- if (!(xprt = xprt_from_sock(sk))) +- goto out; +- dprintk("RPC: %s client %p...\n" +- "RPC: error %d\n", +- __func__, xprt, sk->sk_err); +- xprt_wake_pending_tasks(xprt, -EAGAIN); +-out: +- read_unlock_bh(&sk->sk_callback_lock); +-} +- + static void xs_write_space(struct sock *sk) + { + struct socket *sock; +@@ -1867,7 +1851,6 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt, + sk->sk_user_data = xprt; + sk->sk_data_ready = xs_local_data_ready; + sk->sk_write_space = xs_udp_write_space; +- sk->sk_error_report = xs_error_report; + sk->sk_allocation = GFP_ATOMIC; + + xprt_clear_connected(xprt); +@@ -1995,7 +1978,6 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) + sk->sk_user_data = xprt; + sk->sk_data_ready = xs_udp_data_ready; + sk->sk_write_space = xs_udp_write_space; +- sk->sk_error_report = xs_error_report; + sk->sk_no_check = UDP_CSUM_NORCV; + sk->sk_allocation = GFP_ATOMIC; + +@@ -2065,10 +2047,8 @@ static void xs_abort_connection(struct sock_xprt *transport) + any.sa_family = AF_UNSPEC; + result = kernel_connect(transport->sock, &any, sizeof(any), 0); + if (!result) +- xs_sock_mark_closed(&transport->xprt); +- else +- dprintk("RPC: AF_UNSPEC connect return code %d\n", +- result); ++ xs_sock_reset_connection_flags(&transport->xprt); ++ dprintk("RPC: AF_UNSPEC connect return code %d\n", result); + } + + static void xs_tcp_reuse_connection(struct sock_xprt *transport) +@@ -2113,7 +2093,6 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) + sk->sk_data_ready = xs_tcp_data_ready; + sk->sk_state_change = xs_tcp_state_change; + sk->sk_write_space = xs_tcp_write_space; +- sk->sk_error_report = xs_error_report; + sk->sk_allocation = GFP_ATOMIC; + + /* socket options */ +diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c +index 1cdb1d5..9ea174f 100644 +--- a/net/wireless/mlme.c ++++ b/net/wireless/mlme.c +@@ -457,20 +457,14 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, + .reason_code = reason, + .ie = ie, + .ie_len = ie_len, ++ .local_state_change = local_state_change, + }; + + ASSERT_WDEV_LOCK(wdev); + +- if (local_state_change) { +- if (wdev->current_bss && +- ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { +- cfg80211_unhold_bss(wdev->current_bss); +- cfg80211_put_bss(&wdev->current_bss->pub); +- wdev->current_bss = NULL; +- } +- ++ if (local_state_change && (!wdev->current_bss || ++ !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) + return 0; +- } + + return rdev->ops->deauth(&rdev->wiphy, dev, &req); + } +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 155cbd2..70ce60f 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -5704,6 +5704,7 @@ static const struct hda_verb alc268_beep_init_verbs[] = { + + enum { + ALC268_FIXUP_INV_DMIC, ++ ALC268_FIXUP_HP_EAPD, + }; + + static const struct alc_fixup alc268_fixups[] = { +@@ -5711,10 +5712,26 @@ static const struct alc_fixup alc268_fixups[] = { + .type = ALC_FIXUP_FUNC, + .v.func = alc_fixup_inv_dmic_0x12, + }, ++ [ALC268_FIXUP_HP_EAPD] = { ++ .type = ALC_FIXUP_VERBS, ++ .v.verbs = (const struct hda_verb[]) { ++ {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0}, ++ {} ++ } ++ }, + }; + + static const struct alc_model_fixup alc268_fixup_models[] = { + {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"}, ++ {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"}, ++ {} ++}; ++ ++static const struct snd_pci_quirk alc268_fixup_tbl[] = { ++ /* below is codec SSID since multiple Toshiba laptops have the ++ * same PCI SSID 1179:ff00 ++ */ ++ SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD), + {} + }; + +@@ -5749,7 +5766,7 @@ static int patch_alc268(struct hda_codec *codec) + + spec = codec->spec; + +- alc_pick_fixup(codec, alc268_fixup_models, NULL, alc268_fixups); ++ alc_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + + /* automatic parse from the BIOS config */ +@@ -6214,6 +6231,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), + SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK), + SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), ++ SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), + SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), + SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), + SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), +diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c +index af0f22f..aca6edc 100644 +--- a/usr/gen_init_cpio.c ++++ b/usr/gen_init_cpio.c +@@ -303,7 +303,7 @@ static int cpio_mkfile(const char *name, const char *location, + int retval; + int rc = -1; + int namesize; +- int i; ++ unsigned int i; + + mode |= S_IFREG; + +@@ -381,25 +381,28 @@ error: + + static char *cpio_replace_env(char *new_location) + { +- char expanded[PATH_MAX + 1]; +- char env_var[PATH_MAX + 1]; +- char *start; +- char *end; +- +- for (start = NULL; (start = strstr(new_location, "${")); ) { +- end = strchr(start, '}'); +- if (start < end) { +- *env_var = *expanded = '\0'; +- strncat(env_var, start + 2, end - start - 2); +- strncat(expanded, new_location, start - new_location); +- strncat(expanded, getenv(env_var), PATH_MAX); +- strncat(expanded, end + 1, PATH_MAX); +- strncpy(new_location, expanded, PATH_MAX); +- } else +- break; +- } +- +- return new_location; ++ char expanded[PATH_MAX + 1]; ++ char env_var[PATH_MAX + 1]; ++ char *start; ++ char *end; ++ ++ for (start = NULL; (start = strstr(new_location, "${")); ) { ++ end = strchr(start, '}'); ++ if (start < end) { ++ *env_var = *expanded = '\0'; ++ strncat(env_var, start + 2, end - start - 2); ++ strncat(expanded, new_location, start - new_location); ++ strncat(expanded, getenv(env_var), ++ PATH_MAX - strlen(expanded)); ++ strncat(expanded, end + 1, ++ PATH_MAX - strlen(expanded)); ++ strncpy(new_location, expanded, PATH_MAX); ++ new_location[PATH_MAX] = 0; ++ } else ++ break; ++ } ++ ++ return new_location; + } + + diff --git a/3.6.4/4420_grsecurity-2.9.1-3.6.4-201210291446.patch b/3.6.5/4420_grsecurity-2.9.1-3.6.5-201210312121.patch index 08c581d..c2276e8 100644 --- a/3.6.4/4420_grsecurity-2.9.1-3.6.4-201210291446.patch +++ b/3.6.5/4420_grsecurity-2.9.1-3.6.5-201210312121.patch @@ -251,7 +251,7 @@ index ad7e2e5..199f49e 100644 pcd. [PARIDE] diff --git a/Makefile b/Makefile -index dcf132a..db194e3 100644 +index 6e4a00d..4c7aa4f 100644 --- a/Makefile +++ b/Makefile @@ -241,8 +241,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ @@ -19013,7 +19013,7 @@ index 7a6f3b3..bed145d7 100644 1: diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c -index 198e774..e880f29 100644 +index 5cee802..bc22bc3 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -440,7 +440,7 @@ static void __init parse_setup_data(void) @@ -24577,7 +24577,7 @@ index b91e485..d00e7c9 100644 } if (mm->get_unmapped_area == arch_get_unmapped_area) diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c -index ab1f6a9..23030ba 100644 +index d7aea41..f753ad2 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -16,6 +16,8 @@ @@ -24589,16 +24589,16 @@ index ab1f6a9..23030ba 100644 unsigned long __initdata pgt_buf_start; unsigned long __meminitdata pgt_buf_end; -@@ -38,7 +40,7 @@ struct map_range { - static void __init find_early_table_space(struct map_range *mr, unsigned long end, - int use_pse, int use_gbpages) +@@ -44,7 +46,7 @@ static void __init find_early_table_space(struct map_range *mr, int nr_range) { -- unsigned long puds, pmds, ptes, tables, start = 0, good_end = end; -+ unsigned long puds, pmds, ptes, tables, start = 0x100000, good_end = end; + int i; + unsigned long puds = 0, pmds = 0, ptes = 0, tables; +- unsigned long start = 0, good_end; ++ unsigned long start = 0x100000, good_end; phys_addr_t base; - puds = (end + PUD_SIZE - 1) >> PUD_SHIFT; -@@ -317,10 +319,37 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, + for (i = 0; i < nr_range; i++) { +@@ -321,10 +323,37 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, * Access has to be given to non-kernel-ram areas as well, these contain the PCI * mmio resources as well as potential bios/acpi data regions. */ @@ -24637,7 +24637,7 @@ index ab1f6a9..23030ba 100644 if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) return 0; if (!page_is_ram(pagenr)) -@@ -377,8 +406,117 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) +@@ -381,8 +410,117 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) #endif } @@ -25034,7 +25034,7 @@ index 575d86f..4987469 100644 printk(KERN_INFO "Write protecting the kernel text: %luk\n", size >> 10); diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c -index 2b6b4a3..c17210d 100644 +index 3baff25..8b37564 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -74,7 +74,7 @@ early_param("gbpages", parse_direct_gbpages_on); @@ -25151,7 +25151,7 @@ index 2b6b4a3..c17210d 100644 adr = (void *)(((unsigned long)adr) | left); return adr; -@@ -548,7 +562,7 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end, +@@ -553,7 +567,7 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end, unmap_low_page(pmd); spin_lock(&init_mm.page_table_lock); @@ -25160,7 +25160,7 @@ index 2b6b4a3..c17210d 100644 spin_unlock(&init_mm.page_table_lock); } __flush_tlb_all(); -@@ -594,7 +608,7 @@ kernel_physical_mapping_init(unsigned long start, +@@ -599,7 +613,7 @@ kernel_physical_mapping_init(unsigned long start, unmap_low_page(pud); spin_lock(&init_mm.page_table_lock); @@ -25169,7 +25169,7 @@ index 2b6b4a3..c17210d 100644 spin_unlock(&init_mm.page_table_lock); pgd_changed = true; } -@@ -686,6 +700,12 @@ void __init mem_init(void) +@@ -691,6 +705,12 @@ void __init mem_init(void) pci_iommu_alloc(); @@ -25182,7 +25182,7 @@ index 2b6b4a3..c17210d 100644 /* clear_bss() already clear the empty_zero_page */ reservedpages = 0; -@@ -846,8 +866,8 @@ int kern_addr_valid(unsigned long addr) +@@ -851,8 +871,8 @@ int kern_addr_valid(unsigned long addr) static struct vm_area_struct gate_vma = { .vm_start = VSYSCALL_START, .vm_end = VSYSCALL_START + (VSYSCALL_MAPPED_PAGES * PAGE_SIZE), @@ -25193,7 +25193,7 @@ index 2b6b4a3..c17210d 100644 }; struct vm_area_struct *get_gate_vma(struct mm_struct *mm) -@@ -881,7 +901,7 @@ int in_gate_area_no_mm(unsigned long addr) +@@ -886,7 +906,7 @@ int in_gate_area_no_mm(unsigned long addr) const char *arch_vma_name(struct vm_area_struct *vma) { @@ -30813,7 +30813,7 @@ index 73fa3e1..ab2e9b9 100644 iir = I915_READ(IIR); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c -index b634f6f..84bb8ba 100644 +index b634f6f..43c62f5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2182,7 +2182,7 @@ intel_finish_fb(struct drm_framebuffer *old_fb) @@ -30825,16 +30825,17 @@ index b634f6f..84bb8ba 100644 /* Big Hammer, we also need to ensure that any pending * MI_WAIT_FOR_EVENT inside a user batch buffer on the -@@ -6168,7 +6168,7 @@ static void do_intel_finish_page_flip(struct drm_device *dev, +@@ -6168,8 +6168,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); -@@ -6515,7 +6515,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, + schedule_work(&work->work); +@@ -6515,7 +6514,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. */ @@ -30843,7 +30844,7 @@ index b634f6f..84bb8ba 100644 ret = dev_priv->display.queue_flip(dev, crtc, fb, obj); if (ret) -@@ -6530,7 +6530,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, +@@ -6530,7 +6529,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, return 0; cleanup_pending: @@ -31504,10 +31505,10 @@ index 14599e2..711c965 100644 for (i = 0; i < hid->maxcollection; i++) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c -index 4065374..10ed7dc 100644 +index f4c3d28..82f45a9 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c -@@ -400,8 +400,8 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, +@@ -402,8 +402,8 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, int ret = 0; int t; @@ -44624,19 +44625,10 @@ index 112e45a..b59845b 100644 /* diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c -index debdfe0..75d31d4 100644 +index 5d2069f..75d31d4 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c -@@ -210,6 +210,8 @@ static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, - - err = get_user(palp, &up->palette); - err |= get_user(length, &up->length); -+ if (err) -+ return -EFAULT; - - up_native = compat_alloc_user_space(sizeof(struct video_spu_palette)); - err = put_user(compat_ptr(palp), &up_native->palette); -@@ -621,7 +623,7 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd, +@@ -623,7 +623,7 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd, return -EFAULT; if (__get_user(udata, &ss32->iomem_base)) return -EFAULT; @@ -44645,7 +44637,7 @@ index debdfe0..75d31d4 100644 if (__get_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift) || __get_user(ss.port_high, &ss32->port_high)) return -EFAULT; -@@ -796,7 +798,7 @@ static int compat_ioctl_preallocate(struct file *file, +@@ -798,7 +798,7 @@ static int compat_ioctl_preallocate(struct file *file, copy_in_user(&p->l_len, &p32->l_len, sizeof(s64)) || copy_in_user(&p->l_sysid, &p32->l_sysid, sizeof(s32)) || copy_in_user(&p->l_pid, &p32->l_pid, sizeof(u32)) || @@ -44654,7 +44646,7 @@ index debdfe0..75d31d4 100644 return -EFAULT; return ioctl_preallocate(file, p); -@@ -1610,8 +1612,8 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, +@@ -1612,8 +1612,8 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, static int __init init_sys32_ioctl_cmp(const void *p, const void *q) { unsigned int a, b; @@ -44780,7 +44772,7 @@ index b2a34a1..162fa69 100644 return rc; } diff --git a/fs/exec.c b/fs/exec.c -index 574cf4d..dfe774a 100644 +index fab2c6d..4fa20c0 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -55,6 +55,15 @@ @@ -45050,7 +45042,7 @@ index 574cf4d..dfe774a 100644 set_fs(old_fs); return result; } -@@ -1257,7 +1296,7 @@ static int check_unsafe_exec(struct linux_binprm *bprm) +@@ -1258,7 +1297,7 @@ static int check_unsafe_exec(struct linux_binprm *bprm) } rcu_read_unlock(); @@ -45059,7 +45051,7 @@ index 574cf4d..dfe774a 100644 bprm->unsafe |= LSM_UNSAFE_SHARE; } else { res = -EAGAIN; -@@ -1460,6 +1499,28 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) +@@ -1461,6 +1500,28 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) EXPORT_SYMBOL(search_binary_handler); @@ -45088,7 +45080,7 @@ index 574cf4d..dfe774a 100644 /* * sys_execve() executes a new program. */ -@@ -1468,6 +1529,11 @@ static int do_execve_common(const char *filename, +@@ -1469,6 +1530,11 @@ static int do_execve_common(const char *filename, struct user_arg_ptr envp, struct pt_regs *regs) { @@ -45100,7 +45092,7 @@ index 574cf4d..dfe774a 100644 struct linux_binprm *bprm; struct file *file; struct files_struct *displaced; -@@ -1475,6 +1541,8 @@ static int do_execve_common(const char *filename, +@@ -1476,6 +1542,8 @@ static int do_execve_common(const char *filename, int retval; const struct cred *cred = current_cred(); @@ -45109,7 +45101,7 @@ index 574cf4d..dfe774a 100644 /* * We move the actual failure in case of RLIMIT_NPROC excess from * set*uid() to execve() because too many poorly written programs -@@ -1515,12 +1583,27 @@ static int do_execve_common(const char *filename, +@@ -1516,12 +1584,27 @@ static int do_execve_common(const char *filename, if (IS_ERR(file)) goto out_unmark; @@ -45137,7 +45129,7 @@ index 574cf4d..dfe774a 100644 retval = bprm_mm_init(bprm); if (retval) goto out_file; -@@ -1537,24 +1620,65 @@ static int do_execve_common(const char *filename, +@@ -1538,24 +1621,65 @@ static int do_execve_common(const char *filename, if (retval < 0) goto out; @@ -45207,7 +45199,7 @@ index 574cf4d..dfe774a 100644 current->fs->in_exec = 0; current->in_execve = 0; acct_update_integrals(current); -@@ -1563,6 +1687,14 @@ static int do_execve_common(const char *filename, +@@ -1564,6 +1688,14 @@ static int do_execve_common(const char *filename, put_files_struct(displaced); return retval; @@ -45222,7 +45214,7 @@ index 574cf4d..dfe774a 100644 out: if (bprm->mm) { acct_arg_size(bprm, 0); -@@ -1636,7 +1768,7 @@ static int expand_corename(struct core_name *cn) +@@ -1637,7 +1769,7 @@ static int expand_corename(struct core_name *cn) { char *old_corename = cn->corename; @@ -45231,7 +45223,7 @@ index 574cf4d..dfe774a 100644 cn->corename = krealloc(old_corename, cn->size, GFP_KERNEL); if (!cn->corename) { -@@ -1733,7 +1865,7 @@ static int format_corename(struct core_name *cn, long signr) +@@ -1734,7 +1866,7 @@ static int format_corename(struct core_name *cn, long signr) int pid_in_pattern = 0; int err = 0; @@ -45240,7 +45232,7 @@ index 574cf4d..dfe774a 100644 cn->corename = kmalloc(cn->size, GFP_KERNEL); cn->used = 0; -@@ -1830,6 +1962,250 @@ out: +@@ -1831,6 +1963,250 @@ out: return ispipe; } @@ -45491,7 +45483,7 @@ index 574cf4d..dfe774a 100644 static int zap_process(struct task_struct *start, int exit_code) { struct task_struct *t; -@@ -2040,17 +2416,17 @@ static void wait_for_dump_helpers(struct file *file) +@@ -2041,17 +2417,17 @@ static void wait_for_dump_helpers(struct file *file) pipe = file->f_path.dentry->d_inode->i_pipe; pipe_lock(pipe); @@ -45514,7 +45506,7 @@ index 574cf4d..dfe774a 100644 pipe_unlock(pipe); } -@@ -2105,7 +2481,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) +@@ -2106,7 +2482,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) int flag = 0; int ispipe; bool need_nonrelative = false; @@ -45523,7 +45515,7 @@ index 574cf4d..dfe774a 100644 struct coredump_params cprm = { .signr = signr, .regs = regs, -@@ -2120,6 +2496,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) +@@ -2121,6 +2497,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) audit_core_dumps(signr); @@ -45533,7 +45525,7 @@ index 574cf4d..dfe774a 100644 binfmt = mm->binfmt; if (!binfmt || !binfmt->core_dump) goto fail; -@@ -2190,7 +2569,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) +@@ -2191,7 +2570,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) } cprm.limit = RLIM_INFINITY; @@ -45542,7 +45534,7 @@ index 574cf4d..dfe774a 100644 if (core_pipe_limit && (core_pipe_limit < dump_count)) { printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\n", task_tgid_vnr(current), current->comm); -@@ -2217,6 +2596,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) +@@ -2218,6 +2597,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) } else { struct inode *inode; @@ -45551,7 +45543,7 @@ index 574cf4d..dfe774a 100644 if (cprm.limit < binfmt->min_coredump) goto fail_unlock; -@@ -2268,7 +2649,7 @@ close_fail: +@@ -2269,7 +2650,7 @@ close_fail: filp_close(cprm.file, NULL); fail_dropcount: if (ispipe) @@ -45560,7 +45552,7 @@ index 574cf4d..dfe774a 100644 fail_unlock: kfree(cn.corename); fail_corename: -@@ -2287,7 +2668,7 @@ fail: +@@ -2288,7 +2669,7 @@ fail: */ int dump_write(struct file *file, const void *addr, int nr) { @@ -47551,7 +47543,7 @@ index 7e81bfc..c3649aa 100644 lock_flocks(); diff --git a/fs/namei.c b/fs/namei.c -index 81bd546..80149d9 100644 +index 091c4b7..c6d7e26 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -265,16 +265,32 @@ int generic_permission(struct inode *inode, int mask) @@ -50292,7 +50284,7 @@ index 41514dd..6564a93 100644 pipe_unlock(ipipe); diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c -index 6b0bb00..75db2fe 100644 +index 2fbdff6..5530a61 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -685,6 +685,18 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd, @@ -61439,10 +61431,10 @@ index 9c02a45..89fdd73 100644 unsigned int offset, size_t len); diff --git a/include/linux/efi.h b/include/linux/efi.h -index ec45ccd..9923c32 100644 +index 5782114..e9b1ba1 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h -@@ -635,7 +635,7 @@ struct efivar_operations { +@@ -640,7 +640,7 @@ struct efivar_operations { efi_get_variable_t *get_variable; efi_get_next_variable_t *get_next_variable; efi_set_variable_t *set_variable; @@ -66039,7 +66031,7 @@ index 84c6bf1..8899338 100644 next_state = Reset; return 0; diff --git a/init/main.c b/init/main.c -index b286730..9ff6135 100644 +index d61ec54..bd3144f 100644 --- a/init/main.c +++ b/init/main.c @@ -96,6 +96,8 @@ static inline void mark_rodata_ro(void) { } @@ -66113,7 +66105,7 @@ index b286730..9ff6135 100644 static const char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, }; const char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, }; static const char *panic_later, *panic_param; -@@ -675,6 +732,7 @@ int __init_or_module do_one_initcall(initcall_t fn) +@@ -678,6 +735,7 @@ int __init_or_module do_one_initcall(initcall_t fn) { int count = preempt_count(); int ret; @@ -66121,7 +66113,7 @@ index b286730..9ff6135 100644 if (initcall_debug) ret = do_one_initcall_debug(fn); -@@ -687,15 +745,15 @@ int __init_or_module do_one_initcall(initcall_t fn) +@@ -690,15 +748,15 @@ int __init_or_module do_one_initcall(initcall_t fn) sprintf(msgbuf, "error code %d ", ret); if (preempt_count() != count) { @@ -66141,7 +66133,7 @@ index b286730..9ff6135 100644 } return ret; -@@ -749,8 +807,14 @@ static void __init do_initcall_level(int level) +@@ -752,8 +810,14 @@ static void __init do_initcall_level(int level) level, level, &repair_env_string); @@ -66157,7 +66149,7 @@ index b286730..9ff6135 100644 } static void __init do_initcalls(void) -@@ -784,8 +848,14 @@ static void __init do_pre_smp_initcalls(void) +@@ -787,8 +851,14 @@ static void __init do_pre_smp_initcalls(void) { initcall_t *fn; @@ -66173,7 +66165,7 @@ index b286730..9ff6135 100644 } static void run_init_process(const char *init_filename) -@@ -867,7 +937,7 @@ static int __init kernel_init(void * unused) +@@ -870,7 +940,7 @@ static int __init kernel_init(void * unused) do_basic_setup(); /* Open the /dev/console on the rootfs, this should never fail */ @@ -66182,7 +66174,7 @@ index b286730..9ff6135 100644 printk(KERN_WARNING "Warning: unable to open an initial console.\n"); (void) sys_dup(0); -@@ -880,11 +950,13 @@ static int __init kernel_init(void * unused) +@@ -883,11 +953,13 @@ static int __init kernel_init(void * unused) if (!ramdisk_execute_command) ramdisk_execute_command = "/init"; @@ -72430,7 +72422,7 @@ index 5736170..8e04800 100644 return 0; } diff --git a/mm/mempolicy.c b/mm/mempolicy.c -index 3d64b36..dbab433 100644 +index 3d64b36..c6ab69c 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -655,6 +655,10 @@ static int mbind_range(struct mm_struct *mm, unsigned long start, @@ -72444,7 +72436,7 @@ index 3d64b36..dbab433 100644 vma = find_vma(mm, start); if (!vma || vma->vm_start > start) return -EFAULT; -@@ -691,9 +695,18 @@ static int mbind_range(struct mm_struct *mm, unsigned long start, +@@ -691,9 +695,20 @@ static int mbind_range(struct mm_struct *mm, unsigned long start, if (err) goto out; } @@ -72455,15 +72447,17 @@ index 3d64b36..dbab433 100644 + +#ifdef CONFIG_PAX_SEGMEXEC + vma_m = pax_find_mirror_vma(vma); -+ err = vma_replace_policy(vma_m, new_pol); -+ if (err) -+ goto out; ++ if (vma_m) { ++ err = vma_replace_policy(vma_m, new_pol); ++ if (err) ++ goto out; ++ } +#endif + } out: -@@ -1147,6 +1160,17 @@ static long do_mbind(unsigned long start, unsigned long len, +@@ -1147,6 +1162,17 @@ static long do_mbind(unsigned long start, unsigned long len, if (end < start) return -EINVAL; @@ -72481,7 +72475,7 @@ index 3d64b36..dbab433 100644 if (end == start) return 0; -@@ -1370,8 +1394,7 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode, +@@ -1370,8 +1396,7 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode, */ tcred = __task_cred(task); if (!uid_eq(cred->euid, tcred->suid) && !uid_eq(cred->euid, tcred->uid) && @@ -72491,7 +72485,7 @@ index 3d64b36..dbab433 100644 rcu_read_unlock(); err = -EPERM; goto out_put; -@@ -1402,6 +1425,15 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode, +@@ -1402,6 +1427,15 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode, goto out; } @@ -74365,10 +74359,10 @@ index 926b466..b23df53 100644 if (!mm || IS_ERR(mm)) { rc = IS_ERR(mm) ? PTR_ERR(mm) : -ESRCH; diff --git a/mm/rmap.c b/mm/rmap.c -index 0f3b7cd..c5652b6 100644 +index aa95e59..b681a63 100644 --- a/mm/rmap.c +++ b/mm/rmap.c -@@ -167,6 +167,10 @@ int anon_vma_prepare(struct vm_area_struct *vma) +@@ -168,6 +168,10 @@ int anon_vma_prepare(struct vm_area_struct *vma) struct anon_vma *anon_vma = vma->anon_vma; struct anon_vma_chain *avc; @@ -74379,7 +74373,7 @@ index 0f3b7cd..c5652b6 100644 might_sleep(); if (unlikely(!anon_vma)) { struct mm_struct *mm = vma->vm_mm; -@@ -176,6 +180,12 @@ int anon_vma_prepare(struct vm_area_struct *vma) +@@ -177,6 +181,12 @@ int anon_vma_prepare(struct vm_area_struct *vma) if (!avc) goto out_enomem; @@ -74392,7 +74386,7 @@ index 0f3b7cd..c5652b6 100644 anon_vma = find_mergeable_anon_vma(vma); allocated = NULL; if (!anon_vma) { -@@ -189,6 +199,18 @@ int anon_vma_prepare(struct vm_area_struct *vma) +@@ -190,6 +200,18 @@ int anon_vma_prepare(struct vm_area_struct *vma) /* page_table_lock to protect against threads */ spin_lock(&mm->page_table_lock); if (likely(!vma->anon_vma)) { @@ -74411,7 +74405,7 @@ index 0f3b7cd..c5652b6 100644 vma->anon_vma = anon_vma; anon_vma_chain_link(vma, avc, anon_vma); allocated = NULL; -@@ -199,12 +221,24 @@ int anon_vma_prepare(struct vm_area_struct *vma) +@@ -200,12 +222,24 @@ int anon_vma_prepare(struct vm_area_struct *vma) if (unlikely(allocated)) put_anon_vma(allocated); @@ -74436,7 +74430,7 @@ index 0f3b7cd..c5652b6 100644 anon_vma_chain_free(avc); out_enomem: return -ENOMEM; -@@ -240,7 +274,7 @@ static inline void unlock_anon_vma_root(struct anon_vma *root) +@@ -241,7 +275,7 @@ static inline void unlock_anon_vma_root(struct anon_vma *root) * Attach the anon_vmas from src to dst. * Returns 0 on success, -ENOMEM on failure. */ @@ -74445,7 +74439,7 @@ index 0f3b7cd..c5652b6 100644 { struct anon_vma_chain *avc, *pavc; struct anon_vma *root = NULL; -@@ -318,7 +352,7 @@ void anon_vma_moveto_tail(struct vm_area_struct *dst) +@@ -319,7 +353,7 @@ void anon_vma_moveto_tail(struct vm_area_struct *dst) * the corresponding VMA in the parent process is attached to. * Returns 0 on success, non-zero on failure. */ @@ -77901,7 +77895,7 @@ index bb61f77..3788d63 100644 /* number of interfaces with corresponding FIF_ flags */ int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll, diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c -index bfb57dc..77c4b81 100644 +index c93d395..a305570 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -454,7 +454,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) @@ -78038,7 +78032,7 @@ index c97a065..ff61928 100644 return p; diff --git a/net/mac80211/util.c b/net/mac80211/util.c -index 39b82fe..5469ef4 100644 +index c9b52f7..4da1014 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1251,7 +1251,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) @@ -89442,32 +89436,6 @@ index 6789d78..4afd019e 100644 + .endm + #endif -diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c -index af0f22f..9a7d479 100644 ---- a/usr/gen_init_cpio.c -+++ b/usr/gen_init_cpio.c -@@ -303,7 +303,7 @@ static int cpio_mkfile(const char *name, const char *location, - int retval; - int rc = -1; - int namesize; -- int i; -+ unsigned int i; - - mode |= S_IFREG; - -@@ -392,9 +392,10 @@ static char *cpio_replace_env(char *new_location) - *env_var = *expanded = '\0'; - strncat(env_var, start + 2, end - start - 2); - strncat(expanded, new_location, start - new_location); -- strncat(expanded, getenv(env_var), PATH_MAX); -- strncat(expanded, end + 1, PATH_MAX); -+ strncat(expanded, getenv(env_var), PATH_MAX - strlen(expanded)); -+ strncat(expanded, end + 1, PATH_MAX - strlen(expanded)); - strncpy(new_location, expanded, PATH_MAX); -+ new_location[PATH_MAX] = 0; - } else - break; - } diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index d617f69..6b445d2 100644 --- a/virt/kvm/kvm_main.c diff --git a/3.6.4/4430_grsec-remove-localversion-grsec.patch b/3.6.5/4430_grsec-remove-localversion-grsec.patch index 31cf878..31cf878 100644 --- a/3.6.4/4430_grsec-remove-localversion-grsec.patch +++ b/3.6.5/4430_grsec-remove-localversion-grsec.patch diff --git a/3.6.4/4435_grsec-mute-warnings.patch b/3.6.5/4435_grsec-mute-warnings.patch index e1a7a3c..e1a7a3c 100644 --- a/3.6.4/4435_grsec-mute-warnings.patch +++ b/3.6.5/4435_grsec-mute-warnings.patch diff --git a/3.6.4/4440_grsec-remove-protected-paths.patch b/3.6.5/4440_grsec-remove-protected-paths.patch index 637934a..637934a 100644 --- a/3.6.4/4440_grsec-remove-protected-paths.patch +++ b/3.6.5/4440_grsec-remove-protected-paths.patch diff --git a/3.6.4/4450_grsec-kconfig-default-gids.patch b/3.6.5/4450_grsec-kconfig-default-gids.patch index d4b0b7e..d4b0b7e 100644 --- a/3.6.4/4450_grsec-kconfig-default-gids.patch +++ b/3.6.5/4450_grsec-kconfig-default-gids.patch diff --git a/3.6.4/4465_selinux-avc_audit-log-curr_ip.patch b/3.6.5/4465_selinux-avc_audit-log-curr_ip.patch index 4fb50f4..4fb50f4 100644 --- a/3.6.4/4465_selinux-avc_audit-log-curr_ip.patch +++ b/3.6.5/4465_selinux-avc_audit-log-curr_ip.patch diff --git a/3.6.4/4470_disable-compat_vdso.patch b/3.6.5/4470_disable-compat_vdso.patch index 4a1947b..4a1947b 100644 --- a/3.6.4/4470_disable-compat_vdso.patch +++ b/3.6.5/4470_disable-compat_vdso.patch |