summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2012-11-27 08:40:39 -0500
committerAnthony G. Basile <blueness@gentoo.org>2012-11-27 08:40:39 -0500
commitb09ce05600fc4d3a5dbb532e7c2d0c20ee67feff (patch)
treef603d71e857a66eaa5741b6a171e19b942e46b04
parentGrsec/PaX: 2.9.1-{2.6.32.60,3.2.34,3.6.7}-201211221000 (diff)
downloadhardened-patchset-b09ce05600fc4d3a5dbb532e7c2d0c20ee67feff.tar.gz
hardened-patchset-b09ce05600fc4d3a5dbb532e7c2d0c20ee67feff.tar.bz2
hardened-patchset-b09ce05600fc4d3a5dbb532e7c2d0c20ee67feff.zip
Grsec/PaX: 2.9.1-{2.6.32.60,3.2.34,3.6.8}-20121126171420121126
-rw-r--r--2.6.32/0000_README2
-rw-r--r--2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201211261713.patch (renamed from 2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201211220959.patch)204
-rw-r--r--3.2.34/0000_README2
-rw-r--r--3.2.34/4420_grsecurity-2.9.1-3.2.34-201211251859.patch (renamed from 3.2.34/4420_grsecurity-2.9.1-3.2.34-201211220959.patch)162
-rw-r--r--3.6.7/1006_linux-3.6.7.patch3082
-rw-r--r--3.6.8/0000_README (renamed from 3.6.7/0000_README)6
-rw-r--r--3.6.8/4420_grsecurity-2.9.1-3.6.8-201211261714.patch (renamed from 3.6.7/4420_grsecurity-2.9.1-3.6.7-201211221000.patch)312
-rw-r--r--3.6.8/4425-tmpfs-user-namespace.patch (renamed from 3.6.7/4425-tmpfs-user-namespace.patch)0
-rw-r--r--3.6.8/4430_grsec-remove-localversion-grsec.patch (renamed from 3.6.7/4430_grsec-remove-localversion-grsec.patch)0
-rw-r--r--3.6.8/4435_grsec-mute-warnings.patch (renamed from 3.6.7/4435_grsec-mute-warnings.patch)0
-rw-r--r--3.6.8/4440_grsec-remove-protected-paths.patch (renamed from 3.6.7/4440_grsec-remove-protected-paths.patch)0
-rw-r--r--3.6.8/4450_grsec-kconfig-default-gids.patch (renamed from 3.6.7/4450_grsec-kconfig-default-gids.patch)0
-rw-r--r--3.6.8/4465_selinux-avc_audit-log-curr_ip.patch (renamed from 3.6.7/4465_selinux-avc_audit-log-curr_ip.patch)0
-rw-r--r--3.6.8/4470_disable-compat_vdso.patch (renamed from 3.6.7/4470_disable-compat_vdso.patch)0
14 files changed, 451 insertions, 3319 deletions
diff --git a/2.6.32/0000_README b/2.6.32/0000_README
index 424bb70..05d6bef 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-201211220959.patch
+Patch: 4420_grsecurity-2.9.1-2.6.32.60-201211261713.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-201211220959.patch b/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201211261713.patch
index 8492134..6c95f6c 100644
--- a/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201211220959.patch
+++ b/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201211261713.patch
@@ -3574,6 +3574,30 @@ index 2120746..8d70a5e 100644
DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
me->arch.unwind_section, table, end, gp);
+diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c
+index fb59852..32d43e7 100644
+--- a/arch/parisc/kernel/signal32.c
++++ b/arch/parisc/kernel/signal32.c
+@@ -68,7 +68,8 @@ put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
+ {
+ compat_sigset_t s;
+
+- if (sz != sizeof *set) panic("put_sigset32()");
++ if (sz != sizeof *set)
++ return -EINVAL;
+ sigset_64to32(&s, set);
+
+ return copy_to_user(up, &s, sizeof s);
+@@ -80,7 +81,8 @@ get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
+ compat_sigset_t s;
+ int r;
+
+- if (sz != sizeof *set) panic("put_sigset32()");
++ if (sz != sizeof *set)
++ return -EINVAL;
+
+ if ((r = copy_from_user(&s, up, sz)) == 0) {
+ sigset_32to64(set, &s);
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 9147391..f3d949a 100644
--- a/arch/parisc/kernel/sys_parisc.c
@@ -76721,7 +76745,7 @@ index ff57421..f65f88a 100644
out_free_fd:
diff --git a/fs/exec.c b/fs/exec.c
-index 86fafc6..25f0d1a 100644
+index 86fafc6..ab06586 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -56,12 +56,33 @@
@@ -76746,7 +76770,7 @@ index 86fafc6..25f0d1a 100644
+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
+void __weak pax_set_initial_flags(struct linux_binprm *bprm)
+{
-+ WARN_ONCE(1, "PAX: PAX_HAVE_ACL_FLAGS was enabled without providing the pax_set_initial_flags callback, this is probably not what you wanted.\n");
++ printk_once(KERN_WARNING "PAX: PAX_HAVE_ACL_FLAGS was enabled without providing the pax_set_initial_flags callback, this is probably not what you wanted.\n");
+}
+#endif
+
@@ -96993,50 +97017,68 @@ index 4c4e57d..f3c5303 100644
and pointers */
#endif
diff --git a/include/linux/init.h b/include/linux/init.h
-index ff8bde5..0296174 100644
+index ff8bde5..c7815d8 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
-@@ -38,9 +38,15 @@
+@@ -38,9 +38,33 @@
* Also note, that this data cannot be "const".
*/
+#ifdef MODULE
-+#define add_latent_entropy
++#define add_init_latent_entropy
++#else
++#define add_init_latent_entropy __latent_entropy
++#endif
++
++#ifdef CONFIG_HOTPLUG
++#define add_devinit_latent_entropy
++#else
++#define add_devinit_latent_entropy __latent_entropy
++#endif
++
++#ifdef CONFIG_HOTPLUG_CPU
++#define add_cpuinit_latent_entropy
++#else
++#define add_cpuinit_latent_entropy __latent_entropy
++#endif
++
++#ifdef CONFIG_MEMORY_HOTPLUG
++#define add_meminit_latent_entropy
+#else
-+#define add_latent_entropy __latent_entropy
++#define add_meminit_latent_entropy __latent_entropy
+#endif
+
/* These are for everybody (although not all archs will actually
discard it in modules) */
-#define __init __section(.init.text) __cold notrace
-+#define __init __section(.init.text) __cold notrace add_latent_entropy
++#define __init __section(.init.text) __cold notrace add_init_latent_entropy
#define __initdata __section(.init.data)
#define __initconst __section(.init.rodata)
#define __exitdata __section(.exit.data)
-@@ -75,7 +81,7 @@
+@@ -75,7 +99,7 @@
#define __exit __section(.exit.text) __exitused __cold
/* Used for HOTPLUG */
-#define __devinit __section(.devinit.text) __cold
-+#define __devinit __section(.devinit.text) __cold add_latent_entropy
++#define __devinit __section(.devinit.text) __cold add_devinit_latent_entropy
#define __devinitdata __section(.devinit.data)
#define __devinitconst __section(.devinit.rodata)
#define __devexit __section(.devexit.text) __exitused __cold
-@@ -83,7 +89,7 @@
+@@ -83,7 +107,7 @@
#define __devexitconst __section(.devexit.rodata)
/* Used for HOTPLUG_CPU */
-#define __cpuinit __section(.cpuinit.text) __cold
-+#define __cpuinit __section(.cpuinit.text) __cold add_latent_entropy
++#define __cpuinit __section(.cpuinit.text) __cold add_cpuinit_latent_entropy
#define __cpuinitdata __section(.cpuinit.data)
#define __cpuinitconst __section(.cpuinit.rodata)
#define __cpuexit __section(.cpuexit.text) __exitused __cold
-@@ -91,7 +97,7 @@
+@@ -91,7 +115,7 @@
#define __cpuexitconst __section(.cpuexit.rodata)
/* Used for MEMORY_HOTPLUG */
-#define __meminit __section(.meminit.text) __cold
-+#define __meminit __section(.meminit.text) __cold add_latent_entropy
++#define __meminit __section(.meminit.text) __cold add_meminit_latent_entropy
#define __meminitdata __section(.meminit.data)
#define __meminitconst __section(.meminit.rodata)
#define __memexit __section(.memexit.text) __exitused __cold
@@ -101969,7 +102011,7 @@ index c28f804..96ea6cb 100644
else
new_fs = fs;
diff --git a/kernel/futex.c b/kernel/futex.c
-index 9c5ffe1..05b7eb1 100644
+index 9c5ffe1..abe0820 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -54,6 +54,7 @@
@@ -101992,7 +102034,105 @@ index 9c5ffe1..05b7eb1 100644
/*
* The futex address must be "naturally" aligned.
*/
-@@ -1831,6 +1837,8 @@ static int futex_wait(u32 __user *uaddr, int fshared,
+@@ -665,8 +671,8 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb,
+ struct futex_pi_state **ps,
+ struct task_struct *task, int set_waiters)
+ {
+- int lock_taken, ret, ownerdied = 0;
+- u32 uval, newval, curval;
++ int lock_taken, ret, force_take = 0;
++ u32 uval, newval, curval, vpid = task_pid_vnr(task);
+
+ retry:
+ ret = lock_taken = 0;
+@@ -676,7 +682,7 @@ retry:
+ * (by doing a 0 -> TID atomic cmpxchg), while holding all
+ * the locks. It will most likely not succeed.
+ */
+- newval = task_pid_vnr(task);
++ newval = vpid;
+ if (set_waiters)
+ newval |= FUTEX_WAITERS;
+
+@@ -688,7 +694,7 @@ retry:
+ /*
+ * Detect deadlocks.
+ */
+- if ((unlikely((curval & FUTEX_TID_MASK) == task_pid_vnr(task))))
++ if ((unlikely((curval & FUTEX_TID_MASK) == vpid)))
+ return -EDEADLK;
+
+ /*
+@@ -706,17 +712,15 @@ retry:
+ newval = curval | FUTEX_WAITERS;
+
+ /*
+- * There are two cases, where a futex might have no owner (the
+- * owner TID is 0): OWNER_DIED. We take over the futex in this
+- * case. We also do an unconditional take over, when the owner
+- * of the futex died.
+- *
+- * This is safe as we are protected by the hash bucket lock !
++ * Should we force take the futex? See below.
+ */
+- if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) {
+- /* Keep the OWNER_DIED bit */
+- newval = (curval & ~FUTEX_TID_MASK) | task_pid_vnr(task);
+- ownerdied = 0;
++ if (unlikely(force_take)) {
++ /*
++ * Keep the OWNER_DIED and the WAITERS bit and set the
++ * new TID value.
++ */
++ newval = (curval & ~FUTEX_TID_MASK) | vpid;
++ force_take = 0;
+ lock_taken = 1;
+ }
+
+@@ -728,7 +732,7 @@ retry:
+ goto retry;
+
+ /*
+- * We took the lock due to owner died take over.
++ * We took the lock due to forced take over.
+ */
+ if (unlikely(lock_taken))
+ return 1;
+@@ -743,20 +747,25 @@ retry:
+ switch (ret) {
+ case -ESRCH:
+ /*
+- * No owner found for this futex. Check if the
+- * OWNER_DIED bit is set to figure out whether
+- * this is a robust futex or not.
++ * We failed to find an owner for this
++ * futex. So we have no pi_state to block
++ * on. This can happen in two cases:
++ *
++ * 1) The owner died
++ * 2) A stale FUTEX_WAITERS bit
++ *
++ * Re-read the futex value.
+ */
+ if (get_futex_value_locked(&curval, uaddr))
+ return -EFAULT;
+
+ /*
+- * We simply start over in case of a robust
+- * futex. The code above will take the futex
+- * and return happy.
++ * If the owner died or we have a stale
++ * WAITERS bit the owner TID in the user space
++ * futex is 0.
+ */
+- if (curval & FUTEX_OWNER_DIED) {
+- ownerdied = 1;
++ if (!(curval & FUTEX_TID_MASK)) {
++ force_take = 1;
+ goto retry;
+ }
+ default:
+@@ -1831,6 +1840,8 @@ static int futex_wait(u32 __user *uaddr, int fshared,
struct futex_q q;
int ret;
@@ -102001,7 +102141,7 @@ index 9c5ffe1..05b7eb1 100644
if (!bitset)
return -EINVAL;
-@@ -1883,7 +1891,7 @@ retry:
+@@ -1883,7 +1894,7 @@ retry:
restart = &current_thread_info()->restart_block;
restart->fn = futex_wait_restart;
@@ -102010,7 +102150,7 @@ index 9c5ffe1..05b7eb1 100644
restart->futex.val = val;
restart->futex.time = abs_time->tv64;
restart->futex.bitset = bitset;
-@@ -2245,6 +2253,8 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, int fshared,
+@@ -2245,6 +2256,8 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, int fshared,
struct futex_q q;
int res, ret;
@@ -102019,7 +102159,7 @@ index 9c5ffe1..05b7eb1 100644
if (uaddr == uaddr2)
return -EINVAL;
-@@ -2438,6 +2448,10 @@ SYSCALL_DEFINE3(get_robust_list, int, pid,
+@@ -2438,6 +2451,10 @@ SYSCALL_DEFINE3(get_robust_list, int, pid,
if (!p)
goto err_unlock;
ret = -EPERM;
@@ -102030,7 +102170,7 @@ index 9c5ffe1..05b7eb1 100644
pcred = __task_cred(p);
if (cred->euid != pcred->euid &&
cred->euid != pcred->uid &&
-@@ -2504,7 +2518,7 @@ retry:
+@@ -2504,7 +2521,7 @@ retry:
*/
static inline int fetch_robust_entry(struct robust_list __user **entry,
struct robust_list __user * __user *head,
@@ -102039,7 +102179,7 @@ index 9c5ffe1..05b7eb1 100644
{
unsigned long uentry;
-@@ -2685,6 +2699,7 @@ static int __init futex_init(void)
+@@ -2685,6 +2702,7 @@ static int __init futex_init(void)
{
u32 curval;
int i;
@@ -102047,7 +102187,7 @@ index 9c5ffe1..05b7eb1 100644
/*
* This will fail and we want it. Some arch implementations do
-@@ -2696,7 +2711,10 @@ static int __init futex_init(void)
+@@ -2696,7 +2714,10 @@ static int __init futex_init(void)
* implementation, the non functional ones will return
* -ENOSYS.
*/
@@ -106312,10 +106452,10 @@ index 9ecd6e8..12c94c1 100644
if (atomic_dec_and_test(&kref->refcount)) {
diff --git a/lib/list_debug.c b/lib/list_debug.c
-index 1a39f4e..c2714ca 100644
+index 1a39f4e..745720b 100644
--- a/lib/list_debug.c
+++ b/lib/list_debug.c
-@@ -20,14 +20,15 @@ void __list_add(struct list_head *new,
+@@ -20,14 +20,18 @@ void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
@@ -106330,12 +106470,15 @@ index 1a39f4e..c2714ca 100644
"list_add corruption. prev->next should be "
"next (%p), but was %p. (prev=%p).\n",
- next, prev->next, prev);
-+ next, prev->next, prev))
++ next, prev->next, prev) ||
++ WARN(new == prev || new == next,
++ "list_add double add: new=%p, prev=%p, next=%p.\n",
++ new, prev, next))
+ return;
next->prev = new;
new->next = next;
new->prev = prev;
-@@ -43,12 +44,13 @@ EXPORT_SYMBOL(__list_add);
+@@ -43,12 +47,13 @@ EXPORT_SYMBOL(__list_add);
*/
void list_del(struct list_head *entry)
{
@@ -118864,10 +119007,10 @@ index 0000000..a86e422
+}
diff --git a/tools/gcc/kernexec_plugin.c b/tools/gcc/kernexec_plugin.c
new file mode 100644
-index 0000000..98011fa
+index 0000000..8856202
--- /dev/null
+++ b/tools/gcc/kernexec_plugin.c
-@@ -0,0 +1,427 @@
+@@ -0,0 +1,432 @@
+/*
+ * Copyright 2011 by the PaX Team <pageexec@freemail.hu>
+ * Licensed under the GPL v2
@@ -118908,6 +119051,10 @@ index 0000000..98011fa
+extern void print_gimple_stmt(FILE *, gimple, int, int);
+extern rtx emit_move_insn(rtx x, rtx y);
+
++#if BUILDING_GCC_VERSION <= 4006
++#define ANY_RETURN_P(rtx) (GET_CODE(rtx) == RETURN)
++#endif
++
+int plugin_is_GPL_compatible;
+
+static struct plugin_info kernexec_plugin_info = {
@@ -119212,6 +119359,7 @@ index 0000000..98011fa
+ for (insn = get_insns(); insn; insn = NEXT_INSN(insn)) {
+ // rtl match: (jump_insn 41 40 42 2 (return) fptr.c:42 634 {return_internal} (nil))
+ // (jump_insn 12 9 11 2 (parallel [ (return) (unspec [ (0) ] UNSPEC_REP) ]) fptr.c:46 635 {return_internal_long} (nil))
++ // (jump_insn 97 96 98 6 (simple_return) fptr.c:50 -1 (nil) -> simple_return)
+ rtx body;
+
+ // is it a retn
@@ -119220,7 +119368,7 @@ index 0000000..98011fa
+ body = PATTERN(insn);
+ if (GET_CODE(body) == PARALLEL)
+ body = XVECEXP(body, 0, 0);
-+ if (GET_CODE(body) != RETURN)
++ if (!ANY_RETURN_P(body))
+ continue;
+ kernexec_instrument_retaddr(insn);
+ }
diff --git a/3.2.34/0000_README b/3.2.34/0000_README
index 5f22bbb..3c72d25 100644
--- a/3.2.34/0000_README
+++ b/3.2.34/0000_README
@@ -54,7 +54,7 @@ Patch: 1033_linux-3.2.34.patch
From: http://www.kernel.org
Desc: Linux 3.2.34
-Patch: 4420_grsecurity-2.9.1-3.2.34-201211220959.patch
+Patch: 4420_grsecurity-2.9.1-3.2.34-201211251859.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/3.2.34/4420_grsecurity-2.9.1-3.2.34-201211220959.patch b/3.2.34/4420_grsecurity-2.9.1-3.2.34-201211251859.patch
index f917c5d..a958ea6 100644
--- a/3.2.34/4420_grsecurity-2.9.1-3.2.34-201211220959.patch
+++ b/3.2.34/4420_grsecurity-2.9.1-3.2.34-201211251859.patch
@@ -3515,6 +3515,30 @@ index 5e34ccf..672bc9c 100644
DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
me->arch.unwind_section, table, end, gp);
+diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c
+index e141324..d0ea054 100644
+--- a/arch/parisc/kernel/signal32.c
++++ b/arch/parisc/kernel/signal32.c
+@@ -67,7 +67,8 @@ put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
+ {
+ compat_sigset_t s;
+
+- if (sz != sizeof *set) panic("put_sigset32()");
++ if (sz != sizeof *set)
++ return -EINVAL;
+ sigset_64to32(&s, set);
+
+ return copy_to_user(up, &s, sizeof s);
+@@ -79,7 +80,8 @@ get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
+ compat_sigset_t s;
+ int r;
+
+- if (sz != sizeof *set) panic("put_sigset32()");
++ if (sz != sizeof *set)
++ return -EINVAL;
+
+ if ((r = copy_from_user(&s, up, sz)) == 0) {
+ sigset_32to64(set, &s);
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index c9b9322..02d8940 100644
--- a/arch/parisc/kernel/sys_parisc.c
@@ -45336,7 +45360,7 @@ index a6f3763..f38ed00 100644
out_free_fd:
diff --git a/fs/exec.c b/fs/exec.c
-index 121ccae..c12bdc7 100644
+index 121ccae..d0404a2 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -55,12 +55,33 @@
@@ -45361,7 +45385,7 @@ index 121ccae..c12bdc7 100644
+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
+void __weak pax_set_initial_flags(struct linux_binprm *bprm)
+{
-+ WARN_ONCE(1, "PAX: PAX_HAVE_ACL_FLAGS was enabled without providing the pax_set_initial_flags callback, this is probably not what you wanted.\n");
++ pr_warn_once("PAX: PAX_HAVE_ACL_FLAGS was enabled without providing the pax_set_initial_flags callback, this is probably not what you wanted.\n");
+}
+#endif
+
@@ -64036,50 +64060,68 @@ index a6deef4..c56a7f2 100644
and pointers */
#endif
diff --git a/include/linux/init.h b/include/linux/init.h
-index 9146f39..5c80baf 100644
+index 9146f39..0963f76 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
-@@ -38,9 +38,15 @@
+@@ -38,9 +38,33 @@
* Also note, that this data cannot be "const".
*/
+#ifdef MODULE
-+#define add_latent_entropy
++#define add_init_latent_entropy
++#else
++#define add_init_latent_entropy __latent_entropy
++#endif
++
++#ifdef CONFIG_HOTPLUG
++#define add_devinit_latent_entropy
+#else
-+#define add_latent_entropy __latent_entropy
++#define add_devinit_latent_entropy __latent_entropy
++#endif
++
++#ifdef CONFIG_HOTPLUG_CPU
++#define add_cpuinit_latent_entropy
++#else
++#define add_cpuinit_latent_entropy __latent_entropy
++#endif
++
++#ifdef CONFIG_MEMORY_HOTPLUG
++#define add_meminit_latent_entropy
++#else
++#define add_meminit_latent_entropy __latent_entropy
+#endif
+
/* These are for everybody (although not all archs will actually
discard it in modules) */
-#define __init __section(.init.text) __cold notrace
-+#define __init __section(.init.text) __cold notrace add_latent_entropy
++#define __init __section(.init.text) __cold notrace add_init_latent_entropy
#define __initdata __section(.init.data)
#define __initconst __section(.init.rodata)
#define __exitdata __section(.exit.data)
-@@ -82,7 +88,7 @@
+@@ -82,7 +106,7 @@
#define __exit __section(.exit.text) __exitused __cold notrace
/* Used for HOTPLUG */
-#define __devinit __section(.devinit.text) __cold notrace
-+#define __devinit __section(.devinit.text) __cold notrace add_latent_entropy
++#define __devinit __section(.devinit.text) __cold notrace add_devinit_latent_entropy
#define __devinitdata __section(.devinit.data)
#define __devinitconst __section(.devinit.rodata)
#define __devexit __section(.devexit.text) __exitused __cold notrace
-@@ -90,7 +96,7 @@
+@@ -90,7 +114,7 @@
#define __devexitconst __section(.devexit.rodata)
/* Used for HOTPLUG_CPU */
-#define __cpuinit __section(.cpuinit.text) __cold notrace
-+#define __cpuinit __section(.cpuinit.text) __cold notrace add_latent_entropy
++#define __cpuinit __section(.cpuinit.text) __cold notrace add_cpuinit_latent_entropy
#define __cpuinitdata __section(.cpuinit.data)
#define __cpuinitconst __section(.cpuinit.rodata)
#define __cpuexit __section(.cpuexit.text) __exitused __cold notrace
-@@ -98,7 +104,7 @@
+@@ -98,7 +122,7 @@
#define __cpuexitconst __section(.cpuexit.rodata)
/* Used for MEMORY_HOTPLUG */
-#define __meminit __section(.meminit.text) __cold notrace
-+#define __meminit __section(.meminit.text) __cold notrace add_latent_entropy
++#define __meminit __section(.meminit.text) __cold notrace add_meminit_latent_entropy
#define __meminitdata __section(.meminit.data)
#define __meminitconst __section(.meminit.rodata)
#define __memexit __section(.memexit.text) __exitused __cold notrace
@@ -68764,7 +68806,7 @@ index 222457a..de637ca 100644
else
new_fs = fs;
diff --git a/kernel/futex.c b/kernel/futex.c
-index 80fb1c6..23d88d8 100644
+index 80fb1c6..2238366 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -54,6 +54,7 @@
@@ -68787,7 +68829,84 @@ index 80fb1c6..23d88d8 100644
/*
* The futex address must be "naturally" aligned.
*/
-@@ -2724,6 +2730,7 @@ static int __init futex_init(void)
+@@ -716,7 +722,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb,
+ struct futex_pi_state **ps,
+ struct task_struct *task, int set_waiters)
+ {
+- int lock_taken, ret, ownerdied = 0;
++ int lock_taken, ret, force_take = 0;
+ u32 uval, newval, curval, vpid = task_pid_vnr(task);
+
+ retry:
+@@ -755,17 +761,15 @@ retry:
+ newval = curval | FUTEX_WAITERS;
+
+ /*
+- * There are two cases, where a futex might have no owner (the
+- * owner TID is 0): OWNER_DIED. We take over the futex in this
+- * case. We also do an unconditional take over, when the owner
+- * of the futex died.
+- *
+- * This is safe as we are protected by the hash bucket lock !
++ * Should we force take the futex? See below.
+ */
+- if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) {
+- /* Keep the OWNER_DIED bit */
++ if (unlikely(force_take)) {
++ /*
++ * Keep the OWNER_DIED and the WAITERS bit and set the
++ * new TID value.
++ */
+ newval = (curval & ~FUTEX_TID_MASK) | vpid;
+- ownerdied = 0;
++ force_take = 0;
+ lock_taken = 1;
+ }
+
+@@ -775,7 +779,7 @@ retry:
+ goto retry;
+
+ /*
+- * We took the lock due to owner died take over.
++ * We took the lock due to forced take over.
+ */
+ if (unlikely(lock_taken))
+ return 1;
+@@ -790,20 +794,25 @@ retry:
+ switch (ret) {
+ case -ESRCH:
+ /*
+- * No owner found for this futex. Check if the
+- * OWNER_DIED bit is set to figure out whether
+- * this is a robust futex or not.
++ * We failed to find an owner for this
++ * futex. So we have no pi_state to block
++ * on. This can happen in two cases:
++ *
++ * 1) The owner died
++ * 2) A stale FUTEX_WAITERS bit
++ *
++ * Re-read the futex value.
+ */
+ if (get_futex_value_locked(&curval, uaddr))
+ return -EFAULT;
+
+ /*
+- * We simply start over in case of a robust
+- * futex. The code above will take the futex
+- * and return happy.
++ * If the owner died or we have a stale
++ * WAITERS bit the owner TID in the user space
++ * futex is 0.
+ */
+- if (curval & FUTEX_OWNER_DIED) {
+- ownerdied = 1;
++ if (!(curval & FUTEX_TID_MASK)) {
++ force_take = 1;
+ goto retry;
+ }
+ default:
+@@ -2724,6 +2733,7 @@ static int __init futex_init(void)
{
u32 curval;
int i;
@@ -68795,7 +68914,7 @@ index 80fb1c6..23d88d8 100644
/*
* This will fail and we want it. Some arch implementations do
-@@ -2735,8 +2742,11 @@ static int __init futex_init(void)
+@@ -2735,8 +2745,11 @@ static int __init futex_init(void)
* implementation, the non-functional ones will return
* -ENOSYS.
*/
@@ -85101,10 +85220,10 @@ index 0000000..a86e422
+}
diff --git a/tools/gcc/kernexec_plugin.c b/tools/gcc/kernexec_plugin.c
new file mode 100644
-index 0000000..98011fa
+index 0000000..8856202
--- /dev/null
+++ b/tools/gcc/kernexec_plugin.c
-@@ -0,0 +1,427 @@
+@@ -0,0 +1,432 @@
+/*
+ * Copyright 2011 by the PaX Team <pageexec@freemail.hu>
+ * Licensed under the GPL v2
@@ -85145,6 +85264,10 @@ index 0000000..98011fa
+extern void print_gimple_stmt(FILE *, gimple, int, int);
+extern rtx emit_move_insn(rtx x, rtx y);
+
++#if BUILDING_GCC_VERSION <= 4006
++#define ANY_RETURN_P(rtx) (GET_CODE(rtx) == RETURN)
++#endif
++
+int plugin_is_GPL_compatible;
+
+static struct plugin_info kernexec_plugin_info = {
@@ -85449,6 +85572,7 @@ index 0000000..98011fa
+ for (insn = get_insns(); insn; insn = NEXT_INSN(insn)) {
+ // rtl match: (jump_insn 41 40 42 2 (return) fptr.c:42 634 {return_internal} (nil))
+ // (jump_insn 12 9 11 2 (parallel [ (return) (unspec [ (0) ] UNSPEC_REP) ]) fptr.c:46 635 {return_internal_long} (nil))
++ // (jump_insn 97 96 98 6 (simple_return) fptr.c:50 -1 (nil) -> simple_return)
+ rtx body;
+
+ // is it a retn
@@ -85457,7 +85581,7 @@ index 0000000..98011fa
+ body = PATTERN(insn);
+ if (GET_CODE(body) == PARALLEL)
+ body = XVECEXP(body, 0, 0);
-+ if (GET_CODE(body) != RETURN)
++ if (!ANY_RETURN_P(body))
+ continue;
+ kernexec_instrument_retaddr(insn);
+ }
diff --git a/3.6.7/1006_linux-3.6.7.patch b/3.6.7/1006_linux-3.6.7.patch
deleted file mode 100644
index 4b496eb..0000000
--- a/3.6.7/1006_linux-3.6.7.patch
+++ /dev/null
@@ -1,3082 +0,0 @@
-diff --git a/Makefile b/Makefile
-index 471b83c..07f2308 100644
---- a/Makefile
-+++ b/Makefile
-@@ -1,6 +1,6 @@
- VERSION = 3
- PATCHLEVEL = 6
--SUBLEVEL = 6
-+SUBLEVEL = 7
- EXTRAVERSION =
- NAME = Terrified Chipmunk
-
-diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
-index 5141d80..dde1a3f 100644
---- a/arch/x86/xen/mmu.c
-+++ b/arch/x86/xen/mmu.c
-@@ -1215,6 +1215,25 @@ unsigned long xen_read_cr2_direct(void)
- return this_cpu_read(xen_vcpu_info.arch.cr2);
- }
-
-+void xen_flush_tlb_all(void)
-+{
-+ struct mmuext_op *op;
-+ struct multicall_space mcs;
-+
-+ trace_xen_mmu_flush_tlb_all(0);
-+
-+ preempt_disable();
-+
-+ mcs = xen_mc_entry(sizeof(*op));
-+
-+ op = mcs.args;
-+ op->cmd = MMUEXT_TLB_FLUSH_ALL;
-+ MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
-+
-+ xen_mc_issue(PARAVIRT_LAZY_MMU);
-+
-+ preempt_enable();
-+}
- static void xen_flush_tlb(void)
- {
- struct mmuext_op *op;
-@@ -2366,7 +2385,7 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
- err = 0;
- out:
-
-- flush_tlb_all();
-+ xen_flush_tlb_all();
-
- return err;
- }
-diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
-index 5062eec..7aff5c7 100644
---- a/drivers/gpu/drm/drm_fops.c
-+++ b/drivers/gpu/drm/drm_fops.c
-@@ -121,6 +121,8 @@ int drm_open(struct inode *inode, struct file *filp)
- int minor_id = iminor(inode);
- struct drm_minor *minor;
- int retcode = 0;
-+ int need_setup = 0;
-+ struct address_space *old_mapping;
-
- minor = idr_find(&drm_minors_idr, minor_id);
- if (!minor)
-@@ -132,23 +134,37 @@ int drm_open(struct inode *inode, struct file *filp)
- if (drm_device_is_unplugged(dev))
- return -ENODEV;
-
-+ if (!dev->open_count++)
-+ need_setup = 1;
-+ mutex_lock(&dev->struct_mutex);
-+ old_mapping = dev->dev_mapping;
-+ if (old_mapping == NULL)
-+ dev->dev_mapping = &inode->i_data;
-+ /* ihold ensures nobody can remove inode with our i_data */
-+ ihold(container_of(dev->dev_mapping, struct inode, i_data));
-+ inode->i_mapping = dev->dev_mapping;
-+ filp->f_mapping = dev->dev_mapping;
-+ mutex_unlock(&dev->struct_mutex);
-+
- retcode = drm_open_helper(inode, filp, dev);
-- if (!retcode) {
-- atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
-- if (!dev->open_count++)
-- retcode = drm_setup(dev);
-- }
-- if (!retcode) {
-- mutex_lock(&dev->struct_mutex);
-- if (dev->dev_mapping == NULL)
-- dev->dev_mapping = &inode->i_data;
-- /* ihold ensures nobody can remove inode with our i_data */
-- ihold(container_of(dev->dev_mapping, struct inode, i_data));
-- inode->i_mapping = dev->dev_mapping;
-- filp->f_mapping = dev->dev_mapping;
-- mutex_unlock(&dev->struct_mutex);
-+ if (retcode)
-+ goto err_undo;
-+ atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
-+ if (need_setup) {
-+ retcode = drm_setup(dev);
-+ if (retcode)
-+ goto err_undo;
- }
-+ return 0;
-
-+err_undo:
-+ mutex_lock(&dev->struct_mutex);
-+ filp->f_mapping = old_mapping;
-+ inode->i_mapping = old_mapping;
-+ iput(container_of(dev->dev_mapping, struct inode, i_data));
-+ dev->dev_mapping = old_mapping;
-+ mutex_unlock(&dev->struct_mutex);
-+ dev->open_count--;
- return retcode;
- }
- EXPORT_SYMBOL(drm_open);
-diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
-index 914c0df..0969a7c 100644
---- a/drivers/gpu/drm/i915/i915_dma.c
-+++ b/drivers/gpu/drm/i915/i915_dma.c
-@@ -1484,7 +1484,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
- goto put_gmch;
- }
-
-- i915_kick_out_firmware_fb(dev_priv);
-+ if (drm_core_check_feature(dev, DRIVER_MODESET))
-+ i915_kick_out_firmware_fb(dev_priv);
-
- pci_set_master(dev->pdev);
-
-diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
-index 830d0dd..cf49a57 100644
---- a/drivers/gpu/drm/i915/intel_overlay.c
-+++ b/drivers/gpu/drm/i915/intel_overlay.c
-@@ -431,9 +431,17 @@ static int intel_overlay_off(struct intel_overlay *overlay)
- intel_ring_emit(ring, flip_addr);
- intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
- /* turn overlay off */
-- intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
-- intel_ring_emit(ring, flip_addr);
-- intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
-+ if (IS_I830(dev)) {
-+ /* Workaround: Don't disable the overlay fully, since otherwise
-+ * it dies on the next OVERLAY_ON cmd. */
-+ intel_ring_emit(ring, MI_NOOP);
-+ intel_ring_emit(ring, MI_NOOP);
-+ intel_ring_emit(ring, MI_NOOP);
-+ } else {
-+ intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
-+ intel_ring_emit(ring, flip_addr);
-+ intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
-+ }
- intel_ring_advance(ring);
-
- return intel_overlay_do_wait_request(overlay, request,
-diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
-index 123afd3..20cb52d 100644
---- a/drivers/gpu/drm/i915/intel_sdvo.c
-+++ b/drivers/gpu/drm/i915/intel_sdvo.c
-@@ -882,6 +882,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo)
- }
- #endif
-
-+static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo,
-+ unsigned if_index, uint8_t tx_rate,
-+ uint8_t *data, unsigned length)
-+{
-+ uint8_t set_buf_index[2] = { if_index, 0 };
-+ uint8_t hbuf_size, tmp[8];
-+ int i;
-+
-+ if (!intel_sdvo_set_value(intel_sdvo,
-+ SDVO_CMD_SET_HBUF_INDEX,
-+ set_buf_index, 2))
-+ return false;
-+
-+ if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO,
-+ &hbuf_size, 1))
-+ return false;
-+
-+ /* Buffer size is 0 based, hooray! */
-+ hbuf_size++;
-+
-+ DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n",
-+ if_index, length, hbuf_size);
-+
-+ for (i = 0; i < hbuf_size; i += 8) {
-+ memset(tmp, 0, 8);
-+ if (i < length)
-+ memcpy(tmp, data + i, min_t(unsigned, 8, length - i));
-+
-+ if (!intel_sdvo_set_value(intel_sdvo,
-+ SDVO_CMD_SET_HBUF_DATA,
-+ tmp, 8))
-+ return false;
-+ }
-+
-+ return intel_sdvo_set_value(intel_sdvo,
-+ SDVO_CMD_SET_HBUF_TXRATE,
-+ &tx_rate, 1);
-+}
-+
- static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
- {
- struct dip_infoframe avi_if = {
-@@ -889,11 +928,7 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
- .ver = DIP_VERSION_AVI,
- .len = DIP_LEN_AVI,
- };
-- uint8_t tx_rate = SDVO_HBUF_TX_VSYNC;
-- uint8_t set_buf_index[2] = { 1, 0 };
- uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)];
-- uint64_t *data = (uint64_t *)sdvo_data;
-- unsigned i;
-
- intel_dip_infoframe_csum(&avi_if);
-
-@@ -903,22 +938,9 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
- sdvo_data[3] = avi_if.checksum;
- memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi));
-
-- if (!intel_sdvo_set_value(intel_sdvo,
-- SDVO_CMD_SET_HBUF_INDEX,
-- set_buf_index, 2))
-- return false;
--
-- for (i = 0; i < sizeof(sdvo_data); i += 8) {
-- if (!intel_sdvo_set_value(intel_sdvo,
-- SDVO_CMD_SET_HBUF_DATA,
-- data, 8))
-- return false;
-- data++;
-- }
--
-- return intel_sdvo_set_value(intel_sdvo,
-- SDVO_CMD_SET_HBUF_TXRATE,
-- &tx_rate, 1);
-+ return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF,
-+ SDVO_HBUF_TX_VSYNC,
-+ sdvo_data, sizeof(sdvo_data));
- }
-
- static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo)
-diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h
-index 9d03014..770bdd6 100644
---- a/drivers/gpu/drm/i915/intel_sdvo_regs.h
-+++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h
-@@ -708,6 +708,8 @@ struct intel_sdvo_enhancements_arg {
- #define SDVO_CMD_SET_AUDIO_STAT 0x91
- #define SDVO_CMD_GET_AUDIO_STAT 0x92
- #define SDVO_CMD_SET_HBUF_INDEX 0x93
-+ #define SDVO_HBUF_INDEX_ELD 0
-+ #define SDVO_HBUF_INDEX_AVI_IF 1
- #define SDVO_CMD_GET_HBUF_INDEX 0x94
- #define SDVO_CMD_GET_HBUF_INFO 0x95
- #define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96
-diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
-index e932810..4a33cdc 100644
---- a/drivers/gpu/drm/radeon/evergreen_cs.c
-+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
-@@ -2725,6 +2725,9 @@ static bool evergreen_vm_reg_valid(u32 reg)
- /* check config regs */
- switch (reg) {
- case GRBM_GFX_INDEX:
-+ case CP_STRMOUT_CNTL:
-+ case CP_COHER_CNTL:
-+ case CP_COHER_SIZE:
- case VGT_VTX_VECT_EJECT_REG:
- case VGT_CACHE_INVALIDATION:
- case VGT_GS_VERTEX_REUSE:
-diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
-index 7934785..302af4f 100644
---- a/drivers/gpu/drm/radeon/evergreend.h
-+++ b/drivers/gpu/drm/radeon/evergreend.h
-@@ -87,6 +87,10 @@
-
- #define CONFIG_MEMSIZE 0x5428
-
-+#define CP_STRMOUT_CNTL 0x84FC
-+
-+#define CP_COHER_CNTL 0x85F0
-+#define CP_COHER_SIZE 0x85F4
- #define CP_COHER_BASE 0x85F8
- #define CP_STALLED_STAT1 0x8674
- #define CP_STALLED_STAT2 0x8678
-diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
-index d16f50f..dd402bb 100644
---- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
-+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
-@@ -651,6 +651,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc
- tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN;
- WREG32(RADEON_DAC_CNTL, tmp);
-
-+ tmp = dac_macro_cntl;
- tmp &= ~(RADEON_DAC_PDWN_R |
- RADEON_DAC_PDWN_G |
- RADEON_DAC_PDWN_B);
-diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
-index 0139e22..6ab4a90 100644
---- a/drivers/gpu/drm/radeon/si.c
-+++ b/drivers/gpu/drm/radeon/si.c
-@@ -2472,6 +2472,7 @@ static bool si_vm_reg_valid(u32 reg)
- /* check config regs */
- switch (reg) {
- case GRBM_GFX_INDEX:
-+ case CP_STRMOUT_CNTL:
- case VGT_VTX_VECT_EJECT_REG:
- case VGT_CACHE_INVALIDATION:
- case VGT_ESGS_RING_SIZE:
-diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h
-index ef4815c..6f0083a 100644
---- a/drivers/gpu/drm/radeon/sid.h
-+++ b/drivers/gpu/drm/radeon/sid.h
-@@ -424,6 +424,7 @@
- # define RDERR_INT_ENABLE (1 << 0)
- # define GUI_IDLE_INT_ENABLE (1 << 19)
-
-+#define CP_STRMOUT_CNTL 0x84FC
- #define SCRATCH_REG0 0x8500
- #define SCRATCH_REG1 0x8504
- #define SCRATCH_REG2 0x8508
-diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
-index fccd361..87aa5f5 100644
---- a/drivers/gpu/drm/udl/udl_drv.h
-+++ b/drivers/gpu/drm/udl/udl_drv.h
-@@ -104,7 +104,7 @@ udl_fb_user_fb_create(struct drm_device *dev,
-
- int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr,
- const char *front, char **urb_buf_ptr,
-- u32 byte_offset, u32 byte_width,
-+ u32 byte_offset, u32 device_byte_offset, u32 byte_width,
- int *ident_ptr, int *sent_ptr);
-
- int udl_dumb_create(struct drm_file *file_priv,
-diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c
-index ce9a611..6f6ca50 100644
---- a/drivers/gpu/drm/udl/udl_fb.c
-+++ b/drivers/gpu/drm/udl/udl_fb.c
-@@ -114,9 +114,10 @@ static void udlfb_dpy_deferred_io(struct fb_info *info,
- list_for_each_entry(cur, &fbdefio->pagelist, lru) {
-
- if (udl_render_hline(dev, (ufbdev->ufb.base.bits_per_pixel / 8),
-- &urb, (char *) info->fix.smem_start,
-- &cmd, cur->index << PAGE_SHIFT,
-- PAGE_SIZE, &bytes_identical, &bytes_sent))
-+ &urb, (char *) info->fix.smem_start,
-+ &cmd, cur->index << PAGE_SHIFT,
-+ cur->index << PAGE_SHIFT,
-+ PAGE_SIZE, &bytes_identical, &bytes_sent))
- goto error;
- bytes_rendered += PAGE_SIZE;
- }
-@@ -187,10 +188,11 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
- for (i = y; i < y + height ; i++) {
- const int line_offset = fb->base.pitches[0] * i;
- const int byte_offset = line_offset + (x * bpp);
--
-+ const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp);
- if (udl_render_hline(dev, bpp, &urb,
- (char *) fb->obj->vmapping,
-- &cmd, byte_offset, width * bpp,
-+ &cmd, byte_offset, dev_byte_offset,
-+ width * bpp,
- &bytes_identical, &bytes_sent))
- goto error;
- }
-diff --git a/drivers/gpu/drm/udl/udl_transfer.c b/drivers/gpu/drm/udl/udl_transfer.c
-index b9320e2..fc11344 100644
---- a/drivers/gpu/drm/udl/udl_transfer.c
-+++ b/drivers/gpu/drm/udl/udl_transfer.c
-@@ -213,11 +213,12 @@ static void udl_compress_hline16(
- */
- int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr,
- const char *front, char **urb_buf_ptr,
-- u32 byte_offset, u32 byte_width,
-+ u32 byte_offset, u32 device_byte_offset,
-+ u32 byte_width,
- int *ident_ptr, int *sent_ptr)
- {
- const u8 *line_start, *line_end, *next_pixel;
-- u32 base16 = 0 + (byte_offset / bpp) * 2;
-+ u32 base16 = 0 + (device_byte_offset / bpp) * 2;
- struct urb *urb = *urb_ptr;
- u8 *cmd = *urb_buf_ptr;
- u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length;
-diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
-index 3fa884d..27151f7 100644
---- a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
-+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
-@@ -306,7 +306,7 @@ void vmw_bo_pin(struct ttm_buffer_object *bo, bool pin)
-
- BUG_ON(!atomic_read(&bo->reserved));
- BUG_ON(old_mem_type != TTM_PL_VRAM &&
-- old_mem_type != VMW_PL_FLAG_GMR);
-+ old_mem_type != VMW_PL_GMR);
-
- pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED;
- if (pin)
-diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
-index ba2c35d..4a04ae0 100644
---- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
-+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
-@@ -1099,6 +1099,11 @@ static void vmw_pm_complete(struct device *kdev)
- struct drm_device *dev = pci_get_drvdata(pdev);
- struct vmw_private *dev_priv = vmw_priv(dev);
-
-+ mutex_lock(&dev_priv->hw_mutex);
-+ vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2);
-+ (void) vmw_read(dev_priv, SVGA_REG_ID);
-+ mutex_unlock(&dev_priv->hw_mutex);
-+
- /**
- * Reclaim 3d reference held by fbdev and potentially
- * start fifo.
-diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
-index 1821b74..de3c7e0 100644
---- a/drivers/hwmon/w83627ehf.c
-+++ b/drivers/hwmon/w83627ehf.c
-@@ -2083,6 +2083,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
- mutex_init(&data->lock);
- mutex_init(&data->update_lock);
- data->name = w83627ehf_device_names[sio_data->kind];
-+ data->bank = 0xff; /* Force initial bank selection */
- platform_set_drvdata(pdev, data);
-
- /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */
-diff --git a/drivers/input/touchscreen/tsc40.c b/drivers/input/touchscreen/tsc40.c
-index 63209aa..eb96f16 100644
---- a/drivers/input/touchscreen/tsc40.c
-+++ b/drivers/input/touchscreen/tsc40.c
-@@ -107,7 +107,6 @@ static int tsc_connect(struct serio *serio, struct serio_driver *drv)
- __set_bit(BTN_TOUCH, input_dev->keybit);
- input_set_abs_params(ptsc->dev, ABS_X, 0, 0x3ff, 0, 0);
- input_set_abs_params(ptsc->dev, ABS_Y, 0, 0x3ff, 0, 0);
-- input_set_abs_params(ptsc->dev, ABS_PRESSURE, 0, 0, 0, 0);
-
- serio_set_drvdata(serio, ptsc);
-
-diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
-index 9a11dc3..b1facf9 100644
---- a/drivers/mmc/host/sdhci.c
-+++ b/drivers/mmc/host/sdhci.c
-@@ -1307,16 +1307,19 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
- */
- if ((host->flags & SDHCI_NEEDS_RETUNING) &&
- !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) {
-- /* eMMC uses cmd21 while sd and sdio use cmd19 */
-- tuning_opcode = mmc->card->type == MMC_TYPE_MMC ?
-- MMC_SEND_TUNING_BLOCK_HS200 :
-- MMC_SEND_TUNING_BLOCK;
-- spin_unlock_irqrestore(&host->lock, flags);
-- sdhci_execute_tuning(mmc, tuning_opcode);
-- spin_lock_irqsave(&host->lock, flags);
--
-- /* Restore original mmc_request structure */
-- host->mrq = mrq;
-+ if (mmc->card) {
-+ /* eMMC uses cmd21 but sd and sdio use cmd19 */
-+ tuning_opcode =
-+ mmc->card->type == MMC_TYPE_MMC ?
-+ MMC_SEND_TUNING_BLOCK_HS200 :
-+ MMC_SEND_TUNING_BLOCK;
-+ spin_unlock_irqrestore(&host->lock, flags);
-+ sdhci_execute_tuning(mmc, tuning_opcode);
-+ spin_lock_irqsave(&host->lock, flags);
-+
-+ /* Restore original mmc_request structure */
-+ host->mrq = mrq;
-+ }
- }
-
- if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23))
-diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
-index ba0e493..9058d21 100644
---- a/drivers/mmc/host/sh_mmcif.c
-+++ b/drivers/mmc/host/sh_mmcif.c
-@@ -1464,9 +1464,9 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
-
- platform_set_drvdata(pdev, NULL);
-
-+ clk_disable(host->hclk);
- mmc_free_host(host->mmc);
- pm_runtime_put_sync(&pdev->dev);
-- clk_disable(host->hclk);
- pm_runtime_disable(&pdev->dev);
-
- return 0;
-diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
-index 56b20d1..116f0e9 100644
---- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
-+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
-@@ -2673,6 +2673,9 @@ static int ixgbe_get_ts_info(struct net_device *dev,
- case ixgbe_mac_X540:
- case ixgbe_mac_82599EB:
- info->so_timestamping =
-+ SOF_TIMESTAMPING_TX_SOFTWARE |
-+ SOF_TIMESTAMPING_RX_SOFTWARE |
-+ SOF_TIMESTAMPING_SOFTWARE |
- SOF_TIMESTAMPING_TX_HARDWARE |
- SOF_TIMESTAMPING_RX_HARDWARE |
- SOF_TIMESTAMPING_RAW_HARDWARE;
-diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
-index 53743f7..af8b414 100644
---- a/drivers/net/ethernet/nxp/lpc_eth.c
-+++ b/drivers/net/ethernet/nxp/lpc_eth.c
-@@ -1524,6 +1524,7 @@ static int lpc_eth_drv_remove(struct platform_device *pdev)
- pldat->dma_buff_base_p);
- free_irq(ndev->irq, ndev);
- iounmap(pldat->net_base);
-+ mdiobus_unregister(pldat->mii_bus);
- mdiobus_free(pldat->mii_bus);
- clk_disable(pldat->clk);
- clk_put(pldat->clk);
-diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
-index fc9f578..9c382b5 100644
---- a/drivers/net/usb/usbnet.c
-+++ b/drivers/net/usb/usbnet.c
-@@ -1158,6 +1158,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
- usb_anchor_urb(urb, &dev->deferred);
- /* no use to process more packets */
- netif_stop_queue(net);
-+ usb_put_urb(urb);
- spin_unlock_irqrestore(&dev->txq.lock, flags);
- netdev_dbg(dev->net, "Delaying transmission for resumption\n");
- goto deferred;
-@@ -1310,6 +1311,8 @@ void usbnet_disconnect (struct usb_interface *intf)
-
- cancel_work_sync(&dev->kevent);
-
-+ usb_scuttle_anchored_urbs(&dev->deferred);
-+
- if (dev->driver_info->unbind)
- dev->driver_info->unbind (dev, intf);
-
-diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
-index 423a9f3..88b6acc 100644
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -312,6 +312,7 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
- }
-
- bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
-+ bf->bf_next = NULL;
- list_del(&bf->list);
-
- spin_unlock_bh(&sc->tx.txbuflock);
-@@ -393,7 +394,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
- u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first;
- u32 ba[WME_BA_BMP_SIZE >> 5];
- int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
-- bool rc_update = true;
-+ bool rc_update = true, isba;
- struct ieee80211_tx_rate rates[4];
- struct ath_frame_info *fi;
- int nframes;
-@@ -437,13 +438,17 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
- tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
- tid = ATH_AN_2_TID(an, tidno);
- seq_first = tid->seq_start;
-+ isba = ts->ts_flags & ATH9K_TX_BA;
-
- /*
- * The hardware occasionally sends a tx status for the wrong TID.
- * In this case, the BA status cannot be considered valid and all
- * subframes need to be retransmitted
-+ *
-+ * Only BlockAcks have a TID and therefore normal Acks cannot be
-+ * checked
- */
-- if (tidno != ts->tid)
-+ if (isba && tidno != ts->tid)
- txok = false;
-
- isaggr = bf_isaggr(bf);
-@@ -1774,6 +1779,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
- list_add_tail(&bf->list, &bf_head);
- bf->bf_state.bf_type = 0;
-
-+ bf->bf_next = NULL;
- bf->bf_lastbf = bf;
- ath_tx_fill_desc(sc, bf, txq, fi->framelen);
- ath_tx_txqaddbuf(sc, txq, &bf_head, false);
-diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
-index b93516d..1345bdd 100644
---- a/drivers/net/wireless/rt2x00/rt2800lib.c
-+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -2395,7 +2395,7 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev)
- /*
- * Check if temperature compensation is supported.
- */
-- if (tssi_bounds[4] == 0xff)
-+ if (tssi_bounds[4] == 0xff || step == 0xff)
- return 0;
-
- /*
-diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
-index dd4fce2..6b6f50a 100644
---- a/drivers/target/iscsi/iscsi_target.c
-+++ b/drivers/target/iscsi/iscsi_target.c
-@@ -3735,7 +3735,9 @@ restart:
- */
- iscsit_thread_check_cpumask(conn, current, 1);
-
-- schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT);
-+ wait_event_interruptible(conn->queues_wq,
-+ !iscsit_conn_all_queues_empty(conn) ||
-+ ts->status == ISCSI_THREAD_SET_RESET);
-
- if ((ts->status == ISCSI_THREAD_SET_RESET) ||
- signal_pending(current))
-diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h
-index a90294f..1d63d56 100644
---- a/drivers/target/iscsi/iscsi_target_core.h
-+++ b/drivers/target/iscsi/iscsi_target_core.h
-@@ -486,6 +486,7 @@ struct iscsi_tmr_req {
- };
-
- struct iscsi_conn {
-+ wait_queue_head_t queues_wq;
- /* Authentication Successful for this connection */
- u8 auth_complete;
- /* State connection is currently in */
-diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
-index 6aba439..7b643ab 100644
---- a/drivers/target/iscsi/iscsi_target_login.c
-+++ b/drivers/target/iscsi/iscsi_target_login.c
-@@ -45,6 +45,7 @@ extern spinlock_t sess_idr_lock;
-
- static int iscsi_login_init_conn(struct iscsi_conn *conn)
- {
-+ init_waitqueue_head(&conn->queues_wq);
- INIT_LIST_HEAD(&conn->conn_list);
- INIT_LIST_HEAD(&conn->conn_cmd_list);
- INIT_LIST_HEAD(&conn->immed_queue_list);
-diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c
-index b42cdeb..552f45a 100644
---- a/drivers/target/iscsi/iscsi_target_util.c
-+++ b/drivers/target/iscsi/iscsi_target_util.c
-@@ -488,7 +488,7 @@ void iscsit_add_cmd_to_immediate_queue(
- atomic_set(&conn->check_immediate_queue, 1);
- spin_unlock_bh(&conn->immed_queue_lock);
-
-- wake_up_process(conn->thread_set->tx_thread);
-+ wake_up(&conn->queues_wq);
- }
-
- struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *conn)
-@@ -562,7 +562,7 @@ void iscsit_add_cmd_to_response_queue(
- atomic_inc(&cmd->response_queue_count);
- spin_unlock_bh(&conn->response_queue_lock);
-
-- wake_up_process(conn->thread_set->tx_thread);
-+ wake_up(&conn->queues_wq);
- }
-
- struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *conn)
-@@ -616,6 +616,24 @@ static void iscsit_remove_cmd_from_response_queue(
- }
- }
-
-+bool iscsit_conn_all_queues_empty(struct iscsi_conn *conn)
-+{
-+ bool empty;
-+
-+ spin_lock_bh(&conn->immed_queue_lock);
-+ empty = list_empty(&conn->immed_queue_list);
-+ spin_unlock_bh(&conn->immed_queue_lock);
-+
-+ if (!empty)
-+ return empty;
-+
-+ spin_lock_bh(&conn->response_queue_lock);
-+ empty = list_empty(&conn->response_queue_list);
-+ spin_unlock_bh(&conn->response_queue_lock);
-+
-+ return empty;
-+}
-+
- void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn)
- {
- struct iscsi_queue_req *qr, *qr_tmp;
-diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h
-index e1c729b..2ff9bbc 100644
---- a/drivers/target/iscsi/iscsi_target_util.h
-+++ b/drivers/target/iscsi/iscsi_target_util.h
-@@ -25,6 +25,7 @@ extern struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_
- extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8);
- extern struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *);
- extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_conn *);
-+extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *);
- extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *);
- extern void iscsit_release_cmd(struct iscsi_cmd *);
- extern void iscsit_free_cmd(struct iscsi_cmd *);
-diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
-index 06aca11..ac0b69f 100644
---- a/drivers/target/target_core_configfs.c
-+++ b/drivers/target/target_core_configfs.c
-@@ -3214,7 +3214,8 @@ static int __init target_core_init_configfs(void)
- if (ret < 0)
- goto out;
-
-- if (core_dev_setup_virtual_lun0() < 0)
-+ ret = core_dev_setup_virtual_lun0();
-+ if (ret < 0)
- goto out;
-
- return 0;
-diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
-index 9fc9a60..68d4c10 100644
---- a/drivers/target/target_core_device.c
-+++ b/drivers/target/target_core_device.c
-@@ -850,20 +850,20 @@ int se_dev_check_shutdown(struct se_device *dev)
-
- static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size)
- {
-- u32 tmp, aligned_max_sectors;
-+ u32 aligned_max_sectors;
-+ u32 alignment;
- /*
- * Limit max_sectors to a PAGE_SIZE aligned value for modern
- * transport_allocate_data_tasks() operation.
- */
-- tmp = rounddown((max_sectors * block_size), PAGE_SIZE);
-- aligned_max_sectors = (tmp / block_size);
-- if (max_sectors != aligned_max_sectors) {
-- printk(KERN_INFO "Rounding down aligned max_sectors from %u"
-- " to %u\n", max_sectors, aligned_max_sectors);
-- return aligned_max_sectors;
-- }
-+ alignment = max(1ul, PAGE_SIZE / block_size);
-+ aligned_max_sectors = rounddown(max_sectors, alignment);
-+
-+ if (max_sectors != aligned_max_sectors)
-+ pr_info("Rounding down aligned max_sectors from %u to %u\n",
-+ max_sectors, aligned_max_sectors);
-
-- return max_sectors;
-+ return aligned_max_sectors;
- }
-
- void se_dev_set_default_attribs(
-diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
-index 9229bd9..6fd434d 100644
---- a/drivers/target/target_core_spc.c
-+++ b/drivers/target/target_core_spc.c
-@@ -605,6 +605,8 @@ static int spc_emulate_inquiry(struct se_cmd *cmd)
- unsigned char buf[SE_INQUIRY_BUF];
- int p, ret;
-
-+ memset(buf, 0, SE_INQUIRY_BUF);
-+
- if (dev == tpg->tpg_virt_lun0.lun_se_dev)
- buf[0] = 0x3f; /* Not connected */
- else
-diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
-index 1c59a3c..be75c43 100644
---- a/drivers/target/target_core_tmr.c
-+++ b/drivers/target/target_core_tmr.c
-@@ -140,15 +140,15 @@ void core_tmr_abort_task(
- printk("ABORT_TASK: Found referenced %s task_tag: %u\n",
- se_cmd->se_tfo->get_fabric_name(), ref_tag);
-
-- spin_lock_irq(&se_cmd->t_state_lock);
-+ spin_lock(&se_cmd->t_state_lock);
- if (se_cmd->transport_state & CMD_T_COMPLETE) {
- printk("ABORT_TASK: ref_tag: %u already complete, skipping\n", ref_tag);
-- spin_unlock_irq(&se_cmd->t_state_lock);
-+ spin_unlock(&se_cmd->t_state_lock);
- spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
- goto out;
- }
- se_cmd->transport_state |= CMD_T_ABORTED;
-- spin_unlock_irq(&se_cmd->t_state_lock);
-+ spin_unlock(&se_cmd->t_state_lock);
-
- list_del_init(&se_cmd->se_cmd_list);
- kref_get(&se_cmd->cmd_kref);
-diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
-index 7f12416..9a113b7 100644
---- a/drivers/xen/gntdev.c
-+++ b/drivers/xen/gntdev.c
-@@ -105,6 +105,21 @@ static void gntdev_print_maps(struct gntdev_priv *priv,
- #endif
- }
-
-+static void gntdev_free_map(struct grant_map *map)
-+{
-+ if (map == NULL)
-+ return;
-+
-+ if (map->pages)
-+ free_xenballooned_pages(map->count, map->pages);
-+ kfree(map->pages);
-+ kfree(map->grants);
-+ kfree(map->map_ops);
-+ kfree(map->unmap_ops);
-+ kfree(map->kmap_ops);
-+ kfree(map);
-+}
-+
- static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
- {
- struct grant_map *add;
-@@ -142,12 +157,7 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
- return add;
-
- err:
-- kfree(add->pages);
-- kfree(add->grants);
-- kfree(add->map_ops);
-- kfree(add->unmap_ops);
-- kfree(add->kmap_ops);
-- kfree(add);
-+ gntdev_free_map(add);
- return NULL;
- }
-
-@@ -198,17 +208,9 @@ static void gntdev_put_map(struct grant_map *map)
- evtchn_put(map->notify.event);
- }
-
-- if (map->pages) {
-- if (!use_ptemod)
-- unmap_grant_pages(map, 0, map->count);
--
-- free_xenballooned_pages(map->count, map->pages);
-- }
-- kfree(map->pages);
-- kfree(map->grants);
-- kfree(map->map_ops);
-- kfree(map->unmap_ops);
-- kfree(map);
-+ if (map->pages && !use_ptemod)
-+ unmap_grant_pages(map, 0, map->count);
-+ gntdev_free_map(map);
- }
-
- /* ------------------------------------------------------------------ */
-diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
-index 8ff95a2..0967d0c 100644
---- a/fs/gfs2/lops.c
-+++ b/fs/gfs2/lops.c
-@@ -393,12 +393,10 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
- struct gfs2_meta_header *mh;
- struct gfs2_trans *tr;
-
-- lock_buffer(bd->bd_bh);
-- gfs2_log_lock(sdp);
- tr = current->journal_info;
- tr->tr_touched = 1;
- if (!list_empty(&bd->bd_list))
-- goto out;
-+ return;
- set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
- set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
- mh = (struct gfs2_meta_header *)bd->bd_bh->b_data;
-@@ -414,9 +412,6 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
- sdp->sd_log_num_buf++;
- list_add(&bd->bd_list, &sdp->sd_log_le_buf);
- tr->tr_num_buf_new++;
--out:
-- gfs2_log_unlock(sdp);
-- unlock_buffer(bd->bd_bh);
- }
-
- static void gfs2_check_magic(struct buffer_head *bh)
-@@ -777,12 +772,10 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
- struct address_space *mapping = bd->bd_bh->b_page->mapping;
- struct gfs2_inode *ip = GFS2_I(mapping->host);
-
-- lock_buffer(bd->bd_bh);
-- gfs2_log_lock(sdp);
- if (tr)
- tr->tr_touched = 1;
- if (!list_empty(&bd->bd_list))
-- goto out;
-+ return;
- set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
- set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
- if (gfs2_is_jdata(ip)) {
-@@ -793,9 +786,6 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
- } else {
- list_add_tail(&bd->bd_list, &sdp->sd_log_le_ordered);
- }
--out:
-- gfs2_log_unlock(sdp);
-- unlock_buffer(bd->bd_bh);
- }
-
- /**
-diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c
-index adbd278..4136270 100644
---- a/fs/gfs2/trans.c
-+++ b/fs/gfs2/trans.c
-@@ -155,14 +155,22 @@ void gfs2_trans_add_bh(struct gfs2_glock *gl, struct buffer_head *bh, int meta)
- struct gfs2_sbd *sdp = gl->gl_sbd;
- struct gfs2_bufdata *bd;
-
-+ lock_buffer(bh);
-+ gfs2_log_lock(sdp);
- bd = bh->b_private;
- if (bd)
- gfs2_assert(sdp, bd->bd_gl == gl);
- else {
-+ gfs2_log_unlock(sdp);
-+ unlock_buffer(bh);
- gfs2_attach_bufdata(gl, bh, meta);
- bd = bh->b_private;
-+ lock_buffer(bh);
-+ gfs2_log_lock(sdp);
- }
- lops_add(sdp, bd);
-+ gfs2_log_unlock(sdp);
-+ unlock_buffer(bh);
- }
-
- void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
-diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c
-index 31c26c4..ca4b11e 100644
---- a/fs/nfs/dns_resolve.c
-+++ b/fs/nfs/dns_resolve.c
-@@ -217,7 +217,7 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen)
- {
- char buf1[NFS_DNS_HOSTNAME_MAXLEN+1];
- struct nfs_dns_ent key, *item;
-- unsigned long ttl;
-+ unsigned int ttl;
- ssize_t len;
- int ret = -EINVAL;
-
-@@ -240,7 +240,8 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen)
- key.namelen = len;
- memset(&key.h, 0, sizeof(key.h));
-
-- ttl = get_expiry(&buf);
-+ if (get_uint(&buf, &ttl) < 0)
-+ goto out;
- if (ttl == 0)
- goto out;
- key.h.expiry_time = ttl + seconds_since_boot();
-diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
-index 31fdb03..e794dee 100644
---- a/fs/nfs/internal.h
-+++ b/fs/nfs/internal.h
-@@ -353,8 +353,9 @@ extern void nfs_sb_active(struct super_block *sb);
- extern void nfs_sb_deactive(struct super_block *sb);
-
- /* namespace.c */
-+#define NFS_PATH_CANONICAL 1
- extern char *nfs_path(char **p, struct dentry *dentry,
-- char *buffer, ssize_t buflen);
-+ char *buffer, ssize_t buflen, unsigned flags);
- extern struct vfsmount *nfs_d_automount(struct path *path);
- struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *,
- struct nfs_fh *, struct nfs_fattr *);
-@@ -491,7 +492,7 @@ static inline char *nfs_devname(struct dentry *dentry,
- char *buffer, ssize_t buflen)
- {
- char *dummy;
-- return nfs_path(&dummy, dentry, buffer, buflen);
-+ return nfs_path(&dummy, dentry, buffer, buflen, NFS_PATH_CANONICAL);
- }
-
- /*
-diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
-index 8e65c7f..015f71f 100644
---- a/fs/nfs/mount_clnt.c
-+++ b/fs/nfs/mount_clnt.c
-@@ -181,7 +181,7 @@ int nfs_mount(struct nfs_mount_request *info)
- else
- msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC_MNT];
-
-- status = rpc_call_sync(mnt_clnt, &msg, 0);
-+ status = rpc_call_sync(mnt_clnt, &msg, RPC_TASK_SOFT|RPC_TASK_TIMEOUT);
- rpc_shutdown_client(mnt_clnt);
-
- if (status < 0)
-diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
-index 6559253..dd057bc 100644
---- a/fs/nfs/namespace.c
-+++ b/fs/nfs/namespace.c
-@@ -33,6 +33,7 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ;
- * @dentry - pointer to dentry
- * @buffer - result buffer
- * @buflen - length of buffer
-+ * @flags - options (see below)
- *
- * Helper function for constructing the server pathname
- * by arbitrary hashed dentry.
-@@ -40,8 +41,14 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ;
- * This is mainly for use in figuring out the path on the
- * server side when automounting on top of an existing partition
- * and in generating /proc/mounts and friends.
-+ *
-+ * Supported flags:
-+ * NFS_PATH_CANONICAL: ensure there is exactly one slash after
-+ * the original device (export) name
-+ * (if unset, the original name is returned verbatim)
- */
--char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen)
-+char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen,
-+ unsigned flags)
- {
- char *end;
- int namelen;
-@@ -74,7 +81,7 @@ rename_retry:
- rcu_read_unlock();
- goto rename_retry;
- }
-- if (*end != '/') {
-+ if ((flags & NFS_PATH_CANONICAL) && *end != '/') {
- if (--buflen < 0) {
- spin_unlock(&dentry->d_lock);
- rcu_read_unlock();
-@@ -91,9 +98,11 @@ rename_retry:
- return end;
- }
- namelen = strlen(base);
-- /* Strip off excess slashes in base string */
-- while (namelen > 0 && base[namelen - 1] == '/')
-- namelen--;
-+ if (flags & NFS_PATH_CANONICAL) {
-+ /* Strip off excess slashes in base string */
-+ while (namelen > 0 && base[namelen - 1] == '/')
-+ namelen--;
-+ }
- buflen -= namelen;
- if (buflen < 0) {
- spin_unlock(&dentry->d_lock);
-diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
-index 017b4b0..c077b25 100644
---- a/fs/nfs/nfs4namespace.c
-+++ b/fs/nfs/nfs4namespace.c
-@@ -81,7 +81,8 @@ static char *nfs_path_component(const char *nfspath, const char *end)
- static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen)
- {
- char *limit;
-- char *path = nfs_path(&limit, dentry, buffer, buflen);
-+ char *path = nfs_path(&limit, dentry, buffer, buflen,
-+ NFS_PATH_CANONICAL);
- if (!IS_ERR(path)) {
- char *path_component = nfs_path_component(path, limit);
- if (path_component)
-diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
-index d5a0cf1..7bff871 100644
---- a/fs/nfs/nfs4proc.c
-+++ b/fs/nfs/nfs4proc.c
-@@ -331,8 +331,7 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
- dprintk("%s ERROR: %d Reset session\n", __func__,
- errorcode);
- nfs4_schedule_session_recovery(clp->cl_session, errorcode);
-- exception->retry = 1;
-- break;
-+ goto wait_on_recovery;
- #endif /* defined(CONFIG_NFS_V4_1) */
- case -NFS4ERR_FILE_OPEN:
- if (exception->timeout > HZ) {
-@@ -1499,9 +1498,11 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
- data->timestamp = jiffies;
- if (nfs4_setup_sequence(data->o_arg.server,
- &data->o_arg.seq_args,
-- &data->o_res.seq_res, task))
-- return;
-- rpc_call_start(task);
-+ &data->o_res.seq_res,
-+ task) != 0)
-+ nfs_release_seqid(data->o_arg.seqid);
-+ else
-+ rpc_call_start(task);
- return;
- unlock_no_action:
- rcu_read_unlock();
-@@ -2182,9 +2183,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
- if (nfs4_setup_sequence(NFS_SERVER(calldata->inode),
- &calldata->arg.seq_args,
- &calldata->res.seq_res,
-- task))
-- goto out;
-- rpc_call_start(task);
-+ task) != 0)
-+ nfs_release_seqid(calldata->arg.seqid);
-+ else
-+ rpc_call_start(task);
- out:
- dprintk("%s: done!\n", __func__);
- }
-@@ -4390,6 +4392,7 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
- if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
- rpc_restart_call_prepare(task);
- }
-+ nfs_release_seqid(calldata->arg.seqid);
- }
-
- static void nfs4_locku_prepare(struct rpc_task *task, void *data)
-@@ -4406,9 +4409,11 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
- calldata->timestamp = jiffies;
- if (nfs4_setup_sequence(calldata->server,
- &calldata->arg.seq_args,
-- &calldata->res.seq_res, task))
-- return;
-- rpc_call_start(task);
-+ &calldata->res.seq_res,
-+ task) != 0)
-+ nfs_release_seqid(calldata->arg.seqid);
-+ else
-+ rpc_call_start(task);
- }
-
- static const struct rpc_call_ops nfs4_locku_ops = {
-@@ -4553,7 +4558,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
- /* Do we need to do an open_to_lock_owner? */
- if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) {
- if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0)
-- return;
-+ goto out_release_lock_seqid;
- data->arg.open_stateid = &state->stateid;
- data->arg.new_lock_owner = 1;
- data->res.open_seqid = data->arg.open_seqid;
-@@ -4562,10 +4567,15 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
- data->timestamp = jiffies;
- if (nfs4_setup_sequence(data->server,
- &data->arg.seq_args,
-- &data->res.seq_res, task))
-+ &data->res.seq_res,
-+ task) == 0) {
-+ rpc_call_start(task);
- return;
-- rpc_call_start(task);
-- dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
-+ }
-+ nfs_release_seqid(data->arg.open_seqid);
-+out_release_lock_seqid:
-+ nfs_release_seqid(data->arg.lock_seqid);
-+ dprintk("%s: done!, ret = %d\n", __func__, task->tk_status);
- }
-
- static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata)
-diff --git a/fs/nfs/super.c b/fs/nfs/super.c
-index b8eda70..d8d7396 100644
---- a/fs/nfs/super.c
-+++ b/fs/nfs/super.c
-@@ -765,7 +765,7 @@ int nfs_show_devname(struct seq_file *m, struct dentry *root)
- int err = 0;
- if (!page)
- return -ENOMEM;
-- devname = nfs_path(&dummy, root, page, PAGE_SIZE);
-+ devname = nfs_path(&dummy, root, page, PAGE_SIZE, 0);
- if (IS_ERR(devname))
- err = PTR_ERR(devname);
- else
-diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
-index a8d0ed9..becf4a9 100644
---- a/fs/xfs/xfs_buf_item.c
-+++ b/fs/xfs/xfs_buf_item.c
-@@ -526,7 +526,25 @@ xfs_buf_item_unpin(
- }
- xfs_buf_relse(bp);
- } else if (freed && remove) {
-+ /*
-+ * There are currently two references to the buffer - the active
-+ * LRU reference and the buf log item. What we are about to do
-+ * here - simulate a failed IO completion - requires 3
-+ * references.
-+ *
-+ * The LRU reference is removed by the xfs_buf_stale() call. The
-+ * buf item reference is removed by the xfs_buf_iodone()
-+ * callback that is run by xfs_buf_do_callbacks() during ioend
-+ * processing (via the bp->b_iodone callback), and then finally
-+ * the ioend processing will drop the IO reference if the buffer
-+ * is marked XBF_ASYNC.
-+ *
-+ * Hence we need to take an additional reference here so that IO
-+ * completion processing doesn't free the buffer prematurely.
-+ */
- xfs_buf_lock(bp);
-+ xfs_buf_hold(bp);
-+ bp->b_flags |= XBF_ASYNC;
- xfs_buf_ioerror(bp, EIO);
- XFS_BUF_UNDONE(bp);
- xfs_buf_stale(bp);
-diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
-index 5da3ace..d308749 100644
---- a/fs/xfs/xfs_log_recover.c
-+++ b/fs/xfs/xfs_log_recover.c
-@@ -3541,7 +3541,7 @@ xlog_do_recovery_pass(
- * - order is important.
- */
- error = xlog_bread_offset(log, 0,
-- bblks - split_bblks, hbp,
-+ bblks - split_bblks, dbp,
- offset + BBTOB(split_bblks));
- if (error)
- goto bread_err2;
-diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index f10553c..fb5204b 100644
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -2633,6 +2633,15 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb);
- unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc);
-
- /**
-+ * ieee80211_get_mesh_hdrlen - get mesh extension header length
-+ * @meshhdr: the mesh extension header, only the flags field
-+ * (first byte) will be accessed
-+ * Returns the length of the extension header, which is always at
-+ * least 6 bytes and at most 18 if address 5 and 6 are present.
-+ */
-+unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);
-+
-+/**
- * DOC: Data path helpers
- *
- * In addition to generic utilities, cfg80211 also offers
-diff --git a/include/sound/core.h b/include/sound/core.h
-index bc05668..93896ad 100644
---- a/include/sound/core.h
-+++ b/include/sound/core.h
-@@ -132,6 +132,7 @@ struct snd_card {
- int shutdown; /* this card is going down */
- int free_on_last_close; /* free in context of file_release */
- wait_queue_head_t shutdown_sleep;
-+ atomic_t refcount; /* refcount for disconnection */
- struct device *dev; /* device assigned to this card */
- struct device *card_dev; /* cardX object for sysfs */
-
-@@ -189,6 +190,7 @@ struct snd_minor {
- const struct file_operations *f_ops; /* file operations */
- void *private_data; /* private data for f_ops->open */
- struct device *dev; /* device for sysfs */
-+ struct snd_card *card_ptr; /* assigned card instance */
- };
-
- /* return a device pointer linked to each sound device as a parent */
-@@ -295,6 +297,7 @@ int snd_card_info_done(void);
- int snd_component_add(struct snd_card *card, const char *component);
- int snd_card_file_add(struct snd_card *card, struct file *file);
- int snd_card_file_remove(struct snd_card *card, struct file *file);
-+void snd_card_unref(struct snd_card *card);
-
- #define snd_card_set_dev(card, devptr) ((card)->dev = (devptr))
-
-diff --git a/include/trace/events/xen.h b/include/trace/events/xen.h
-index 15ba03b..d06b6da 100644
---- a/include/trace/events/xen.h
-+++ b/include/trace/events/xen.h
-@@ -377,6 +377,14 @@ DECLARE_EVENT_CLASS(xen_mmu_pgd,
- DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_pin);
- DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_unpin);
-
-+TRACE_EVENT(xen_mmu_flush_tlb_all,
-+ TP_PROTO(int x),
-+ TP_ARGS(x),
-+ TP_STRUCT__entry(__array(char, x, 0)),
-+ TP_fast_assign((void)x),
-+ TP_printk("%s", "")
-+ );
-+
- TRACE_EVENT(xen_mmu_flush_tlb,
- TP_PROTO(int x),
- TP_ARGS(x),
-diff --git a/kernel/futex.c b/kernel/futex.c
-index 3717e7b..20ef219 100644
---- a/kernel/futex.c
-+++ b/kernel/futex.c
-@@ -716,7 +716,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb,
- struct futex_pi_state **ps,
- struct task_struct *task, int set_waiters)
- {
-- int lock_taken, ret, ownerdied = 0;
-+ int lock_taken, ret, force_take = 0;
- u32 uval, newval, curval, vpid = task_pid_vnr(task);
-
- retry:
-@@ -755,17 +755,15 @@ retry:
- newval = curval | FUTEX_WAITERS;
-
- /*
-- * There are two cases, where a futex might have no owner (the
-- * owner TID is 0): OWNER_DIED. We take over the futex in this
-- * case. We also do an unconditional take over, when the owner
-- * of the futex died.
-- *
-- * This is safe as we are protected by the hash bucket lock !
-+ * Should we force take the futex? See below.
- */
-- if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) {
-- /* Keep the OWNER_DIED bit */
-+ if (unlikely(force_take)) {
-+ /*
-+ * Keep the OWNER_DIED and the WAITERS bit and set the
-+ * new TID value.
-+ */
- newval = (curval & ~FUTEX_TID_MASK) | vpid;
-- ownerdied = 0;
-+ force_take = 0;
- lock_taken = 1;
- }
-
-@@ -775,7 +773,7 @@ retry:
- goto retry;
-
- /*
-- * We took the lock due to owner died take over.
-+ * We took the lock due to forced take over.
- */
- if (unlikely(lock_taken))
- return 1;
-@@ -790,20 +788,25 @@ retry:
- switch (ret) {
- case -ESRCH:
- /*
-- * No owner found for this futex. Check if the
-- * OWNER_DIED bit is set to figure out whether
-- * this is a robust futex or not.
-+ * We failed to find an owner for this
-+ * futex. So we have no pi_state to block
-+ * on. This can happen in two cases:
-+ *
-+ * 1) The owner died
-+ * 2) A stale FUTEX_WAITERS bit
-+ *
-+ * Re-read the futex value.
- */
- if (get_futex_value_locked(&curval, uaddr))
- return -EFAULT;
-
- /*
-- * We simply start over in case of a robust
-- * futex. The code above will take the futex
-- * and return happy.
-+ * If the owner died or we have a stale
-+ * WAITERS bit the owner TID in the user space
-+ * futex is 0.
- */
-- if (curval & FUTEX_OWNER_DIED) {
-- ownerdied = 1;
-+ if (!(curval & FUTEX_TID_MASK)) {
-+ force_take = 1;
- goto retry;
- }
- default:
-diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
-index 6705d35..e7b5777 100644
---- a/net/batman-adv/bridge_loop_avoidance.c
-+++ b/net/batman-adv/bridge_loop_avoidance.c
-@@ -1205,8 +1205,8 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
- /**
- * batadv_bla_check_bcast_duplist
- * @bat_priv: the bat priv with all the soft interface information
-- * @bcast_packet: originator mac address
-- * @hdr_size: maximum length of the frame
-+ * @bcast_packet: encapsulated broadcast frame plus batman header
-+ * @bcast_packet_len: length of encapsulated broadcast frame plus batman header
- *
- * check if it is on our broadcast list. Another gateway might
- * have sent the same packet because it is connected to the same backbone,
-@@ -1219,14 +1219,14 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
- */
- int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
- struct batadv_bcast_packet *bcast_packet,
-- int hdr_size)
-+ int bcast_packet_len)
- {
- int i, length, curr;
- uint8_t *content;
- uint16_t crc;
- struct batadv_bcast_duplist_entry *entry;
-
-- length = hdr_size - sizeof(*bcast_packet);
-+ length = bcast_packet_len - sizeof(*bcast_packet);
- content = (uint8_t *)bcast_packet;
- content += sizeof(*bcast_packet);
-
-diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
-index bc2b88b..f861b7c 100644
---- a/net/batman-adv/routing.c
-+++ b/net/batman-adv/routing.c
-@@ -1136,8 +1136,14 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
-
- spin_unlock_bh(&orig_node->bcast_seqno_lock);
-
-+ /* keep skb linear for crc calculation */
-+ if (skb_linearize(skb) < 0)
-+ goto out;
-+
-+ bcast_packet = (struct batadv_bcast_packet *)skb->data;
-+
- /* check whether this has been sent by another originator before */
-- if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, hdr_size))
-+ if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, skb->len))
- goto out;
-
- /* rebroadcast packet */
-diff --git a/net/core/dev.c b/net/core/dev.c
-index 2fb9f59..aed87a4 100644
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -1644,7 +1644,7 @@ static inline int deliver_skb(struct sk_buff *skb,
-
- static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb)
- {
-- if (ptype->af_packet_priv == NULL)
-+ if (!ptype->af_packet_priv || !skb->sk)
- return false;
-
- if (ptype->id_match)
-diff --git a/net/core/skbuff.c b/net/core/skbuff.c
-index ef172af..9708777 100644
---- a/net/core/skbuff.c
-+++ b/net/core/skbuff.c
-@@ -3384,10 +3384,12 @@ EXPORT_SYMBOL(__skb_warn_lro_forwarding);
-
- void kfree_skb_partial(struct sk_buff *skb, bool head_stolen)
- {
-- if (head_stolen)
-+ if (head_stolen) {
-+ skb_release_head_state(skb);
- kmem_cache_free(skbuff_head_cache, skb);
-- else
-+ } else {
- __kfree_skb(skb);
-+ }
- }
- EXPORT_SYMBOL(kfree_skb_partial);
-
-diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
-index 570e61f..6405a44 100644
---- a/net/ipv4/inet_diag.c
-+++ b/net/ipv4/inet_diag.c
-@@ -883,13 +883,16 @@ static int __inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
- struct inet_diag_req_v2 *r, struct nlattr *bc)
- {
- const struct inet_diag_handler *handler;
-+ int err = 0;
-
- handler = inet_diag_lock_handler(r->sdiag_protocol);
- if (!IS_ERR(handler))
- handler->dump(skb, cb, r, bc);
-+ else
-+ err = PTR_ERR(handler);
- inet_diag_unlock_handler(handler);
-
-- return skb->len;
-+ return err ? : skb->len;
- }
-
- static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
-diff --git a/net/ipv4/route.c b/net/ipv4/route.c
-index 2a1383c..c017cb1 100644
---- a/net/ipv4/route.c
-+++ b/net/ipv4/route.c
-@@ -1166,8 +1166,12 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
- spin_lock_bh(&fnhe_lock);
-
- if (daddr == fnhe->fnhe_daddr) {
-- struct rtable *orig;
--
-+ struct rtable *orig = rcu_dereference(fnhe->fnhe_rth);
-+ if (orig && rt_is_expired(orig)) {
-+ fnhe->fnhe_gw = 0;
-+ fnhe->fnhe_pmtu = 0;
-+ fnhe->fnhe_expires = 0;
-+ }
- if (fnhe->fnhe_pmtu) {
- unsigned long expires = fnhe->fnhe_expires;
- unsigned long diff = expires - jiffies;
-@@ -1184,7 +1188,6 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
- } else if (!rt->rt_gateway)
- rt->rt_gateway = daddr;
-
-- orig = rcu_dereference(fnhe->fnhe_rth);
- rcu_assign_pointer(fnhe->fnhe_rth, rt);
- if (orig)
- rt_free(orig);
-diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
-index 5f64193..49dd993 100644
---- a/net/ipv4/tcp.c
-+++ b/net/ipv4/tcp.c
-@@ -548,14 +548,12 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
- !tp->urg_data ||
- before(tp->urg_seq, tp->copied_seq) ||
- !before(tp->urg_seq, tp->rcv_nxt)) {
-- struct sk_buff *skb;
-
- answ = tp->rcv_nxt - tp->copied_seq;
-
-- /* Subtract 1, if FIN is in queue. */
-- skb = skb_peek_tail(&sk->sk_receive_queue);
-- if (answ && skb)
-- answ -= tcp_hdr(skb)->fin;
-+ /* Subtract 1, if FIN was received */
-+ if (answ && sock_flag(sk, SOCK_DONE))
-+ answ--;
- } else
- answ = tp->urg_seq - tp->copied_seq;
- release_sock(sk);
-diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c
-index 813b43a..834857f 100644
---- a/net/ipv4/tcp_illinois.c
-+++ b/net/ipv4/tcp_illinois.c
-@@ -313,11 +313,13 @@ static void tcp_illinois_info(struct sock *sk, u32 ext,
- .tcpv_rttcnt = ca->cnt_rtt,
- .tcpv_minrtt = ca->base_rtt,
- };
-- u64 t = ca->sum_rtt;
-
-- do_div(t, ca->cnt_rtt);
-- info.tcpv_rtt = t;
-+ if (info.tcpv_rttcnt > 0) {
-+ u64 t = ca->sum_rtt;
-
-+ do_div(t, info.tcpv_rttcnt);
-+ info.tcpv_rtt = t;
-+ }
- nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info);
- }
- }
-diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
-index d377f48..c92c4da 100644
---- a/net/ipv4/tcp_input.c
-+++ b/net/ipv4/tcp_input.c
-@@ -4556,6 +4556,9 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size)
- struct tcphdr *th;
- bool fragstolen;
-
-+ if (size == 0)
-+ return 0;
-+
- skb = alloc_skb(size + sizeof(*th), sk->sk_allocation);
- if (!skb)
- goto err;
-diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
-index ff36194..2edce30 100644
---- a/net/ipv6/ndisc.c
-+++ b/net/ipv6/ndisc.c
-@@ -535,7 +535,7 @@ static void ndisc_send_unsol_na(struct net_device *dev)
- {
- struct inet6_dev *idev;
- struct inet6_ifaddr *ifa;
-- struct in6_addr mcaddr;
-+ struct in6_addr mcaddr = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
-
- idev = in6_dev_get(dev);
- if (!idev)
-@@ -543,7 +543,6 @@ static void ndisc_send_unsol_na(struct net_device *dev)
-
- read_lock_bh(&idev->lock);
- list_for_each_entry(ifa, &idev->addr_list, if_list) {
-- addrconf_addr_solict_mult(&ifa->addr, &mcaddr);
- ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr,
- /*router=*/ !!idev->cnf.forwarding,
- /*solicited=*/ false, /*override=*/ true,
-diff --git a/net/ipv6/route.c b/net/ipv6/route.c
-index 46eff42..070a3ce 100644
---- a/net/ipv6/route.c
-+++ b/net/ipv6/route.c
-@@ -219,7 +219,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
- };
-
- static const u32 ip6_template_metrics[RTAX_MAX] = {
-- [RTAX_HOPLIMIT - 1] = 255,
-+ [RTAX_HOPLIMIT - 1] = 0,
- };
-
- static struct rt6_info ip6_null_entry_template = {
-@@ -1241,7 +1241,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
- rt->rt6i_dst.addr = fl6->daddr;
- rt->rt6i_dst.plen = 128;
- rt->rt6i_idev = idev;
-- dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255);
-+ dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 0);
-
- spin_lock_bh(&icmp6_dst_lock);
- rt->dst.next = icmp6_dst_gc_list;
-diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
-index 3bfb34a..69bf48d 100644
---- a/net/l2tp/l2tp_eth.c
-+++ b/net/l2tp/l2tp_eth.c
-@@ -290,6 +290,7 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p
-
- out_del_dev:
- free_netdev(dev);
-+ spriv->dev = NULL;
- out_del_session:
- l2tp_session_delete(session);
- out:
-diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
-index 5746d62..327aa07 100644
---- a/net/mac80211/ibss.c
-+++ b/net/mac80211/ibss.c
-@@ -1074,7 +1074,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
- sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
- sdata->u.ibss.ibss_join_req = jiffies;
-
-- memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN);
-+ memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len);
- sdata->u.ibss.ssid_len = params->ssid_len;
-
- mutex_unlock(&sdata->u.ibss.mtx);
-diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
-index 0cb4ede..37fe5ce 100644
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -491,6 +491,11 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
-
- if (ieee80211_is_action(hdr->frame_control)) {
- u8 category;
-+
-+ /* make sure category field is present */
-+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE)
-+ return RX_DROP_MONITOR;
-+
- mgmt = (struct ieee80211_mgmt *)hdr;
- category = mgmt->u.action.category;
- if (category != WLAN_CATEGORY_MESH_ACTION &&
-@@ -843,14 +848,16 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
- */
- if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
- ieee80211_is_data_present(hdr->frame_control)) {
-- u16 ethertype;
-- u8 *payload;
--
-- payload = rx->skb->data +
-- ieee80211_hdrlen(hdr->frame_control);
-- ethertype = (payload[6] << 8) | payload[7];
-- if (cpu_to_be16(ethertype) ==
-- rx->sdata->control_port_protocol)
-+ unsigned int hdrlen;
-+ __be16 ethertype;
-+
-+ hdrlen = ieee80211_hdrlen(hdr->frame_control);
-+
-+ if (rx->skb->len < hdrlen + 8)
-+ return RX_DROP_MONITOR;
-+
-+ skb_copy_bits(rx->skb, hdrlen + 6, &ethertype, 2);
-+ if (ethertype == rx->sdata->control_port_protocol)
- return RX_CONTINUE;
- }
-
-@@ -1422,11 +1429,14 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
-
- hdr = (struct ieee80211_hdr *)rx->skb->data;
- fc = hdr->frame_control;
-+
-+ if (ieee80211_is_ctl(fc))
-+ return RX_CONTINUE;
-+
- sc = le16_to_cpu(hdr->seq_ctrl);
- frag = sc & IEEE80211_SCTL_FRAG;
-
- if (likely((!ieee80211_has_morefrags(fc) && frag == 0) ||
-- (rx->skb)->len < 24 ||
- is_multicast_ether_addr(hdr->addr1))) {
- /* not fragmented */
- goto out;
-@@ -1849,6 +1859,20 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
-
- hdr = (struct ieee80211_hdr *) skb->data;
- hdrlen = ieee80211_hdrlen(hdr->frame_control);
-+
-+ /* make sure fixed part of mesh header is there, also checks skb len */
-+ if (!pskb_may_pull(rx->skb, hdrlen + 6))
-+ return RX_DROP_MONITOR;
-+
-+ mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
-+
-+ /* make sure full mesh header is there, also checks skb len */
-+ if (!pskb_may_pull(rx->skb,
-+ hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr)))
-+ return RX_DROP_MONITOR;
-+
-+ /* reload pointers */
-+ hdr = (struct ieee80211_hdr *) skb->data;
- mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
-
- /* frame is in RMC, don't forward */
-@@ -1857,7 +1881,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
- mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata))
- return RX_DROP_MONITOR;
-
-- if (!ieee80211_is_data(hdr->frame_control))
-+ if (!ieee80211_is_data(hdr->frame_control) ||
-+ !(status->rx_flags & IEEE80211_RX_RA_MATCH))
- return RX_CONTINUE;
-
- if (!mesh_hdr->ttl)
-@@ -1871,9 +1896,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
- if (is_multicast_ether_addr(hdr->addr1)) {
- mpp_addr = hdr->addr3;
- proxied_addr = mesh_hdr->eaddr1;
-- } else {
-+ } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) {
-+ /* has_a4 already checked in ieee80211_rx_mesh_check */
- mpp_addr = hdr->addr4;
- proxied_addr = mesh_hdr->eaddr2;
-+ } else {
-+ return RX_DROP_MONITOR;
- }
-
- rcu_read_lock();
-@@ -1901,9 +1929,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
- }
- skb_set_queue_mapping(skb, q);
-
-- if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
-- goto out;
--
- if (!--mesh_hdr->ttl) {
- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
- return RX_DROP_MONITOR;
-@@ -2313,6 +2338,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
- }
- break;
- case WLAN_CATEGORY_SELF_PROTECTED:
-+ if (len < (IEEE80211_MIN_ACTION_SIZE +
-+ sizeof(mgmt->u.action.u.self_prot.action_code)))
-+ break;
-+
- switch (mgmt->u.action.u.self_prot.action_code) {
- case WLAN_SP_MESH_PEERING_OPEN:
- case WLAN_SP_MESH_PEERING_CLOSE:
-@@ -2331,6 +2360,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
- }
- break;
- case WLAN_CATEGORY_MESH_ACTION:
-+ if (len < (IEEE80211_MIN_ACTION_SIZE +
-+ sizeof(mgmt->u.action.u.mesh_action.action_code)))
-+ break;
-+
- if (!ieee80211_vif_is_mesh(&sdata->vif))
- break;
- if (mesh_action_is_path_sel(mgmt) &&
-@@ -2865,10 +2898,15 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
- if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
- local->dot11ReceivedFragmentCount++;
-
-- if (ieee80211_is_mgmt(fc))
-- err = skb_linearize(skb);
-- else
-+ if (ieee80211_is_mgmt(fc)) {
-+ /* drop frame if too short for header */
-+ if (skb->len < ieee80211_hdrlen(fc))
-+ err = -ENOBUFS;
-+ else
-+ err = skb_linearize(skb);
-+ } else {
- err = !pskb_may_pull(skb, ieee80211_hdrlen(fc));
-+ }
-
- if (err) {
- dev_kfree_skb(skb);
-diff --git a/net/mac80211/util.c b/net/mac80211/util.c
-index c9b52f7..1cfe6d5 100644
---- a/net/mac80211/util.c
-+++ b/net/mac80211/util.c
-@@ -637,13 +637,41 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
- break;
- }
-
-- if (id != WLAN_EID_VENDOR_SPECIFIC &&
-- id != WLAN_EID_QUIET &&
-- test_bit(id, seen_elems)) {
-- elems->parse_error = true;
-- left -= elen;
-- pos += elen;
-- continue;
-+ switch (id) {
-+ case WLAN_EID_SSID:
-+ case WLAN_EID_SUPP_RATES:
-+ case WLAN_EID_FH_PARAMS:
-+ case WLAN_EID_DS_PARAMS:
-+ case WLAN_EID_CF_PARAMS:
-+ case WLAN_EID_TIM:
-+ case WLAN_EID_IBSS_PARAMS:
-+ case WLAN_EID_CHALLENGE:
-+ case WLAN_EID_RSN:
-+ case WLAN_EID_ERP_INFO:
-+ case WLAN_EID_EXT_SUPP_RATES:
-+ case WLAN_EID_HT_CAPABILITY:
-+ case WLAN_EID_HT_OPERATION:
-+ case WLAN_EID_VHT_CAPABILITY:
-+ case WLAN_EID_VHT_OPERATION:
-+ case WLAN_EID_MESH_ID:
-+ case WLAN_EID_MESH_CONFIG:
-+ case WLAN_EID_PEER_MGMT:
-+ case WLAN_EID_PREQ:
-+ case WLAN_EID_PREP:
-+ case WLAN_EID_PERR:
-+ case WLAN_EID_RANN:
-+ case WLAN_EID_CHANNEL_SWITCH:
-+ case WLAN_EID_EXT_CHANSWITCH_ANN:
-+ case WLAN_EID_COUNTRY:
-+ case WLAN_EID_PWR_CONSTRAINT:
-+ case WLAN_EID_TIMEOUT_INTERVAL:
-+ if (test_bit(id, seen_elems)) {
-+ elems->parse_error = true;
-+ left -= elen;
-+ pos += elen;
-+ continue;
-+ }
-+ break;
- }
-
- if (calc_crc && id < 64 && (filter & (1ULL << id)))
-diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
-index 9172179..0426b67 100644
---- a/net/netlink/af_netlink.c
-+++ b/net/netlink/af_netlink.c
-@@ -138,6 +138,8 @@ static int netlink_dump(struct sock *sk);
- static DEFINE_RWLOCK(nl_table_lock);
- static atomic_t nl_table_users = ATOMIC_INIT(0);
-
-+#define nl_deref_protected(X) rcu_dereference_protected(X, lockdep_is_held(&nl_table_lock));
-+
- static ATOMIC_NOTIFIER_HEAD(netlink_chain);
-
- static inline u32 netlink_group_mask(u32 group)
-@@ -345,6 +347,11 @@ netlink_update_listeners(struct sock *sk)
- struct hlist_node *node;
- unsigned long mask;
- unsigned int i;
-+ struct listeners *listeners;
-+
-+ listeners = nl_deref_protected(tbl->listeners);
-+ if (!listeners)
-+ return;
-
- for (i = 0; i < NLGRPLONGS(tbl->groups); i++) {
- mask = 0;
-@@ -352,7 +359,7 @@ netlink_update_listeners(struct sock *sk)
- if (i < NLGRPLONGS(nlk_sk(sk)->ngroups))
- mask |= nlk_sk(sk)->groups[i];
- }
-- tbl->listeners->masks[i] = mask;
-+ listeners->masks[i] = mask;
- }
- /* this function is only called with the netlink table "grabbed", which
- * makes sure updates are visible before bind or setsockopt return. */
-@@ -536,7 +543,11 @@ static int netlink_release(struct socket *sock)
- if (netlink_is_kernel(sk)) {
- BUG_ON(nl_table[sk->sk_protocol].registered == 0);
- if (--nl_table[sk->sk_protocol].registered == 0) {
-- kfree(nl_table[sk->sk_protocol].listeners);
-+ struct listeners *old;
-+
-+ old = nl_deref_protected(nl_table[sk->sk_protocol].listeners);
-+ RCU_INIT_POINTER(nl_table[sk->sk_protocol].listeners, NULL);
-+ kfree_rcu(old, rcu);
- nl_table[sk->sk_protocol].module = NULL;
- nl_table[sk->sk_protocol].registered = 0;
- }
-@@ -978,7 +989,7 @@ int netlink_has_listeners(struct sock *sk, unsigned int group)
- rcu_read_lock();
- listeners = rcu_dereference(nl_table[sk->sk_protocol].listeners);
-
-- if (group - 1 < nl_table[sk->sk_protocol].groups)
-+ if (listeners && group - 1 < nl_table[sk->sk_protocol].groups)
- res = test_bit(group - 1, listeners->masks);
-
- rcu_read_unlock();
-@@ -1620,7 +1631,7 @@ int __netlink_change_ngroups(struct sock *sk, unsigned int groups)
- new = kzalloc(sizeof(*new) + NLGRPSZ(groups), GFP_ATOMIC);
- if (!new)
- return -ENOMEM;
-- old = rcu_dereference_protected(tbl->listeners, 1);
-+ old = nl_deref_protected(tbl->listeners);
- memcpy(new->masks, old->masks, NLGRPSZ(tbl->groups));
- rcu_assign_pointer(tbl->listeners, new);
-
-diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
-index fe99628..b1c5be3 100644
---- a/net/sctp/sm_sideeffect.c
-+++ b/net/sctp/sm_sideeffect.c
-@@ -1634,8 +1634,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
- asoc->outqueue.outstanding_bytes;
- sackh.num_gap_ack_blocks = 0;
- sackh.num_dup_tsns = 0;
-+ chunk->subh.sack_hdr = &sackh;
- sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK,
-- SCTP_SACKH(&sackh));
-+ SCTP_CHUNK(chunk));
- break;
-
- case SCTP_CMD_DISCARD_PACKET:
-diff --git a/net/wireless/core.c b/net/wireless/core.c
-index dcd64d5..5797032 100644
---- a/net/wireless/core.c
-+++ b/net/wireless/core.c
-@@ -506,8 +506,7 @@ int wiphy_register(struct wiphy *wiphy)
- for (i = 0; i < sband->n_channels; i++) {
- sband->channels[i].orig_flags =
- sband->channels[i].flags;
-- sband->channels[i].orig_mag =
-- sband->channels[i].max_antenna_gain;
-+ sband->channels[i].orig_mag = INT_MAX;
- sband->channels[i].orig_mpwr =
- sband->channels[i].max_power;
- sband->channels[i].band = band;
-diff --git a/net/wireless/util.c b/net/wireless/util.c
-index 994e2f0..09afde7 100644
---- a/net/wireless/util.c
-+++ b/net/wireless/util.c
-@@ -309,23 +309,21 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)
- }
- EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
-
--static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
-+unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
- {
- int ae = meshhdr->flags & MESH_FLAGS_AE;
-- /* 7.1.3.5a.2 */
-+ /* 802.11-2012, 8.2.4.7.3 */
- switch (ae) {
-+ default:
- case 0:
- return 6;
- case MESH_FLAGS_AE_A4:
- return 12;
- case MESH_FLAGS_AE_A5_A6:
- return 18;
-- case (MESH_FLAGS_AE_A4 | MESH_FLAGS_AE_A5_A6):
-- return 24;
-- default:
-- return 6;
- }
- }
-+EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen);
-
- int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
- enum nl80211_iftype iftype)
-@@ -373,6 +371,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
- /* make sure meshdr->flags is on the linear part */
- if (!pskb_may_pull(skb, hdrlen + 1))
- return -1;
-+ if (meshdr->flags & MESH_FLAGS_AE_A4)
-+ return -1;
- if (meshdr->flags & MESH_FLAGS_AE_A5_A6) {
- skb_copy_bits(skb, hdrlen +
- offsetof(struct ieee80211s_hdr, eaddr1),
-@@ -397,6 +397,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
- /* make sure meshdr->flags is on the linear part */
- if (!pskb_may_pull(skb, hdrlen + 1))
- return -1;
-+ if (meshdr->flags & MESH_FLAGS_AE_A5_A6)
-+ return -1;
- if (meshdr->flags & MESH_FLAGS_AE_A4)
- skb_copy_bits(skb, hdrlen +
- offsetof(struct ieee80211s_hdr, eaddr1),
-diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
-index eb60cb8..d5103f7 100644
---- a/sound/core/compress_offload.c
-+++ b/sound/core/compress_offload.c
-@@ -100,12 +100,15 @@ static int snd_compr_open(struct inode *inode, struct file *f)
-
- if (dirn != compr->direction) {
- pr_err("this device doesn't support this direction\n");
-+ snd_card_unref(compr->card);
- return -EINVAL;
- }
-
- data = kzalloc(sizeof(*data), GFP_KERNEL);
-- if (!data)
-+ if (!data) {
-+ snd_card_unref(compr->card);
- return -ENOMEM;
-+ }
- data->stream.ops = compr->ops;
- data->stream.direction = dirn;
- data->stream.private_data = compr->private_data;
-@@ -113,6 +116,7 @@ static int snd_compr_open(struct inode *inode, struct file *f)
- runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
- if (!runtime) {
- kfree(data);
-+ snd_card_unref(compr->card);
- return -ENOMEM;
- }
- runtime->state = SNDRV_PCM_STATE_OPEN;
-@@ -126,7 +130,8 @@ static int snd_compr_open(struct inode *inode, struct file *f)
- kfree(runtime);
- kfree(data);
- }
-- return ret;
-+ snd_card_unref(compr->card);
-+ return 0;
- }
-
- static int snd_compr_free(struct inode *inode, struct file *f)
-diff --git a/sound/core/control.c b/sound/core/control.c
-index 2487a6b..daa4fc8 100644
---- a/sound/core/control.c
-+++ b/sound/core/control.c
-@@ -86,6 +86,7 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
- write_lock_irqsave(&card->ctl_files_rwlock, flags);
- list_add_tail(&ctl->list, &card->ctl_files);
- write_unlock_irqrestore(&card->ctl_files_rwlock, flags);
-+ snd_card_unref(card);
- return 0;
-
- __error:
-@@ -93,6 +94,8 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
- __error2:
- snd_card_file_remove(card, file);
- __error1:
-+ if (card)
-+ snd_card_unref(card);
- return err;
- }
-
-@@ -1433,6 +1436,8 @@ static ssize_t snd_ctl_read(struct file *file, char __user *buffer,
- spin_unlock_irq(&ctl->read_lock);
- schedule();
- remove_wait_queue(&ctl->change_sleep, &wait);
-+ if (ctl->card->shutdown)
-+ return -ENODEV;
- if (signal_pending(current))
- return -ERESTARTSYS;
- spin_lock_irq(&ctl->read_lock);
-diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
-index 75ea16f..3f7f662 100644
---- a/sound/core/hwdep.c
-+++ b/sound/core/hwdep.c
-@@ -100,8 +100,10 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
- if (hw == NULL)
- return -ENODEV;
-
-- if (!try_module_get(hw->card->module))
-+ if (!try_module_get(hw->card->module)) {
-+ snd_card_unref(hw->card);
- return -EFAULT;
-+ }
-
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&hw->open_wait, &wait);
-@@ -129,6 +131,10 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
- mutex_unlock(&hw->open_mutex);
- schedule();
- mutex_lock(&hw->open_mutex);
-+ if (hw->card->shutdown) {
-+ err = -ENODEV;
-+ break;
-+ }
- if (signal_pending(current)) {
- err = -ERESTARTSYS;
- break;
-@@ -148,6 +154,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
- mutex_unlock(&hw->open_mutex);
- if (err < 0)
- module_put(hw->card->module);
-+ snd_card_unref(hw->card);
- return err;
- }
-
-@@ -459,12 +466,15 @@ static int snd_hwdep_dev_disconnect(struct snd_device *device)
- mutex_unlock(&register_mutex);
- return -EINVAL;
- }
-+ mutex_lock(&hwdep->open_mutex);
-+ wake_up(&hwdep->open_wait);
- #ifdef CONFIG_SND_OSSEMUL
- if (hwdep->ossreg)
- snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device);
- #endif
- snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device);
- list_del_init(&hwdep->list);
-+ mutex_unlock(&hwdep->open_mutex);
- mutex_unlock(&register_mutex);
- return 0;
- }
-diff --git a/sound/core/init.c b/sound/core/init.c
-index d8ec849..7b012d1 100644
---- a/sound/core/init.c
-+++ b/sound/core/init.c
-@@ -213,6 +213,7 @@ int snd_card_create(int idx, const char *xid,
- spin_lock_init(&card->files_lock);
- INIT_LIST_HEAD(&card->files_list);
- init_waitqueue_head(&card->shutdown_sleep);
-+ atomic_set(&card->refcount, 0);
- #ifdef CONFIG_PM
- mutex_init(&card->power_lock);
- init_waitqueue_head(&card->power_sleep);
-@@ -446,21 +447,36 @@ static int snd_card_do_free(struct snd_card *card)
- return 0;
- }
-
-+/**
-+ * snd_card_unref - release the reference counter
-+ * @card: the card instance
-+ *
-+ * Decrements the reference counter. When it reaches to zero, wake up
-+ * the sleeper and call the destructor if needed.
-+ */
-+void snd_card_unref(struct snd_card *card)
-+{
-+ if (atomic_dec_and_test(&card->refcount)) {
-+ wake_up(&card->shutdown_sleep);
-+ if (card->free_on_last_close)
-+ snd_card_do_free(card);
-+ }
-+}
-+EXPORT_SYMBOL(snd_card_unref);
-+
- int snd_card_free_when_closed(struct snd_card *card)
- {
-- int free_now = 0;
-- int ret = snd_card_disconnect(card);
-- if (ret)
-- return ret;
-+ int ret;
-
-- spin_lock(&card->files_lock);
-- if (list_empty(&card->files_list))
-- free_now = 1;
-- else
-- card->free_on_last_close = 1;
-- spin_unlock(&card->files_lock);
-+ atomic_inc(&card->refcount);
-+ ret = snd_card_disconnect(card);
-+ if (ret) {
-+ atomic_dec(&card->refcount);
-+ return ret;
-+ }
-
-- if (free_now)
-+ card->free_on_last_close = 1;
-+ if (atomic_dec_and_test(&card->refcount))
- snd_card_do_free(card);
- return 0;
- }
-@@ -474,7 +490,7 @@ int snd_card_free(struct snd_card *card)
- return ret;
-
- /* wait, until all devices are ready for the free operation */
-- wait_event(card->shutdown_sleep, list_empty(&card->files_list));
-+ wait_event(card->shutdown_sleep, !atomic_read(&card->refcount));
- snd_card_do_free(card);
- return 0;
- }
-@@ -886,6 +902,7 @@ int snd_card_file_add(struct snd_card *card, struct file *file)
- return -ENODEV;
- }
- list_add(&mfile->list, &card->files_list);
-+ atomic_inc(&card->refcount);
- spin_unlock(&card->files_lock);
- return 0;
- }
-@@ -908,7 +925,6 @@ EXPORT_SYMBOL(snd_card_file_add);
- int snd_card_file_remove(struct snd_card *card, struct file *file)
- {
- struct snd_monitor_file *mfile, *found = NULL;
-- int last_close = 0;
-
- spin_lock(&card->files_lock);
- list_for_each_entry(mfile, &card->files_list, list) {
-@@ -923,19 +939,13 @@ int snd_card_file_remove(struct snd_card *card, struct file *file)
- break;
- }
- }
-- if (list_empty(&card->files_list))
-- last_close = 1;
- spin_unlock(&card->files_lock);
-- if (last_close) {
-- wake_up(&card->shutdown_sleep);
-- if (card->free_on_last_close)
-- snd_card_do_free(card);
-- }
- if (!found) {
- snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file);
- return -ENOENT;
- }
- kfree(found);
-+ snd_card_unref(card);
- return 0;
- }
-
-diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
-index 18297f7..c353768 100644
---- a/sound/core/oss/mixer_oss.c
-+++ b/sound/core/oss/mixer_oss.c
-@@ -52,14 +52,19 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file)
- SNDRV_OSS_DEVICE_TYPE_MIXER);
- if (card == NULL)
- return -ENODEV;
-- if (card->mixer_oss == NULL)
-+ if (card->mixer_oss == NULL) {
-+ snd_card_unref(card);
- return -ENODEV;
-+ }
- err = snd_card_file_add(card, file);
-- if (err < 0)
-+ if (err < 0) {
-+ snd_card_unref(card);
- return err;
-+ }
- fmixer = kzalloc(sizeof(*fmixer), GFP_KERNEL);
- if (fmixer == NULL) {
- snd_card_file_remove(card, file);
-+ snd_card_unref(card);
- return -ENOMEM;
- }
- fmixer->card = card;
-@@ -68,8 +73,10 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file)
- if (!try_module_get(card->module)) {
- kfree(fmixer);
- snd_card_file_remove(card, file);
-+ snd_card_unref(card);
- return -EFAULT;
- }
-+ snd_card_unref(card);
- return 0;
- }
-
-diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
-index 08fde00..4c1cc51 100644
---- a/sound/core/oss/pcm_oss.c
-+++ b/sound/core/oss/pcm_oss.c
-@@ -2441,6 +2441,10 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
- mutex_unlock(&pcm->open_mutex);
- schedule();
- mutex_lock(&pcm->open_mutex);
-+ if (pcm->card->shutdown) {
-+ err = -ENODEV;
-+ break;
-+ }
- if (signal_pending(current)) {
- err = -ERESTARTSYS;
- break;
-@@ -2450,6 +2454,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
- mutex_unlock(&pcm->open_mutex);
- if (err < 0)
- goto __error;
-+ snd_card_unref(pcm->card);
- return err;
-
- __error:
-@@ -2457,6 +2462,8 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
- __error2:
- snd_card_file_remove(pcm->card, file);
- __error1:
-+ if (pcm)
-+ snd_card_unref(pcm->card);
- return err;
- }
-
-diff --git a/sound/core/pcm.c b/sound/core/pcm.c
-index 1a3070b..e30e1be 100644
---- a/sound/core/pcm.c
-+++ b/sound/core/pcm.c
-@@ -1086,11 +1086,19 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
- if (list_empty(&pcm->list))
- goto unlock;
-
-+ mutex_lock(&pcm->open_mutex);
-+ wake_up(&pcm->open_wait);
- list_del_init(&pcm->list);
- for (cidx = 0; cidx < 2; cidx++)
-- for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
-- if (substream->runtime)
-+ for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) {
-+ snd_pcm_stream_lock_irq(substream);
-+ if (substream->runtime) {
- substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED;
-+ wake_up(&substream->runtime->sleep);
-+ wake_up(&substream->runtime->tsleep);
-+ }
-+ snd_pcm_stream_unlock_irq(substream);
-+ }
- list_for_each_entry(notify, &snd_pcm_notify_list, list) {
- notify->n_disconnect(pcm);
- }
-@@ -1106,6 +1114,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
- }
- snd_unregister_device(devtype, pcm->card, pcm->device);
- }
-+ mutex_unlock(&pcm->open_mutex);
- unlock:
- mutex_unlock(&register_mutex);
- return 0;
-diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
-index 53b5ada..bf3bf43 100644
---- a/sound/core/pcm_native.c
-+++ b/sound/core/pcm_native.c
-@@ -369,6 +369,14 @@ static int period_to_usecs(struct snd_pcm_runtime *runtime)
- return usecs;
- }
-
-+static void snd_pcm_set_state(struct snd_pcm_substream *substream, int state)
-+{
-+ snd_pcm_stream_lock_irq(substream);
-+ if (substream->runtime->status->state != SNDRV_PCM_STATE_DISCONNECTED)
-+ substream->runtime->status->state = state;
-+ snd_pcm_stream_unlock_irq(substream);
-+}
-+
- static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
- {
-@@ -452,7 +460,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
- runtime->boundary *= 2;
-
- snd_pcm_timer_resolution_change(substream);
-- runtime->status->state = SNDRV_PCM_STATE_SETUP;
-+ snd_pcm_set_state(substream, SNDRV_PCM_STATE_SETUP);
-
- if (pm_qos_request_active(&substream->latency_pm_qos_req))
- pm_qos_remove_request(&substream->latency_pm_qos_req);
-@@ -464,7 +472,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
- /* hardware might be unusable from this time,
- so we force application to retry to set
- the correct hardware parameter settings */
-- runtime->status->state = SNDRV_PCM_STATE_OPEN;
-+ snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
- if (substream->ops->hw_free != NULL)
- substream->ops->hw_free(substream);
- return err;
-@@ -512,7 +520,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
- return -EBADFD;
- if (substream->ops->hw_free)
- result = substream->ops->hw_free(substream);
-- runtime->status->state = SNDRV_PCM_STATE_OPEN;
-+ snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
- pm_qos_remove_request(&substream->latency_pm_qos_req);
- return result;
- }
-@@ -1320,7 +1328,7 @@ static void snd_pcm_post_prepare(struct snd_pcm_substream *substream, int state)
- {
- struct snd_pcm_runtime *runtime = substream->runtime;
- runtime->control->appl_ptr = runtime->status->hw_ptr;
-- runtime->status->state = SNDRV_PCM_STATE_PREPARED;
-+ snd_pcm_set_state(substream, SNDRV_PCM_STATE_PREPARED);
- }
-
- static struct action_ops snd_pcm_action_prepare = {
-@@ -1510,6 +1518,10 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
- down_read(&snd_pcm_link_rwsem);
- snd_pcm_stream_lock_irq(substream);
- remove_wait_queue(&to_check->sleep, &wait);
-+ if (card->shutdown) {
-+ result = -ENODEV;
-+ break;
-+ }
- if (tout == 0) {
- if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
- result = -ESTRPIPE;
-@@ -1633,6 +1645,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
- write_unlock_irq(&snd_pcm_link_rwlock);
- up_write(&snd_pcm_link_rwsem);
- _nolock:
-+ snd_card_unref(substream1->pcm->card);
- fput(file);
- if (res < 0)
- kfree(group);
-@@ -2107,7 +2120,10 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file)
- return err;
- pcm = snd_lookup_minor_data(iminor(inode),
- SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
-- return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK);
-+ err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK);
-+ if (pcm)
-+ snd_card_unref(pcm->card);
-+ return err;
- }
-
- static int snd_pcm_capture_open(struct inode *inode, struct file *file)
-@@ -2118,7 +2134,10 @@ static int snd_pcm_capture_open(struct inode *inode, struct file *file)
- return err;
- pcm = snd_lookup_minor_data(iminor(inode),
- SNDRV_DEVICE_TYPE_PCM_CAPTURE);
-- return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE);
-+ err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE);
-+ if (pcm)
-+ snd_card_unref(pcm->card);
-+ return err;
- }
-
- static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
-@@ -2155,6 +2174,10 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
- mutex_unlock(&pcm->open_mutex);
- schedule();
- mutex_lock(&pcm->open_mutex);
-+ if (pcm->card->shutdown) {
-+ err = -ENODEV;
-+ break;
-+ }
- if (signal_pending(current)) {
- err = -ERESTARTSYS;
- break;
-diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
-index ebf6e49..1bb95ae 100644
---- a/sound/core/rawmidi.c
-+++ b/sound/core/rawmidi.c
-@@ -379,8 +379,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
- if (rmidi == NULL)
- return -ENODEV;
-
-- if (!try_module_get(rmidi->card->module))
-+ if (!try_module_get(rmidi->card->module)) {
-+ snd_card_unref(rmidi->card);
- return -ENXIO;
-+ }
-
- mutex_lock(&rmidi->open_mutex);
- card = rmidi->card;
-@@ -422,6 +424,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
- mutex_unlock(&rmidi->open_mutex);
- schedule();
- mutex_lock(&rmidi->open_mutex);
-+ if (rmidi->card->shutdown) {
-+ err = -ENODEV;
-+ break;
-+ }
- if (signal_pending(current)) {
- err = -ERESTARTSYS;
- break;
-@@ -440,6 +446,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
- #endif
- file->private_data = rawmidi_file;
- mutex_unlock(&rmidi->open_mutex);
-+ snd_card_unref(rmidi->card);
- return 0;
-
- __error:
-@@ -447,6 +454,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
- __error_card:
- mutex_unlock(&rmidi->open_mutex);
- module_put(rmidi->card->module);
-+ snd_card_unref(rmidi->card);
- return err;
- }
-
-@@ -991,6 +999,8 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun
- spin_unlock_irq(&runtime->lock);
- schedule();
- remove_wait_queue(&runtime->sleep, &wait);
-+ if (rfile->rmidi->card->shutdown)
-+ return -ENODEV;
- if (signal_pending(current))
- return result > 0 ? result : -ERESTARTSYS;
- if (!runtime->avail)
-@@ -1234,6 +1244,8 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf,
- spin_unlock_irq(&runtime->lock);
- timeout = schedule_timeout(30 * HZ);
- remove_wait_queue(&runtime->sleep, &wait);
-+ if (rfile->rmidi->card->shutdown)
-+ return -ENODEV;
- if (signal_pending(current))
- return result > 0 ? result : -ERESTARTSYS;
- if (!runtime->avail && !timeout)
-@@ -1609,9 +1621,20 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
- static int snd_rawmidi_dev_disconnect(struct snd_device *device)
- {
- struct snd_rawmidi *rmidi = device->device_data;
-+ int dir;
-
- mutex_lock(&register_mutex);
-+ mutex_lock(&rmidi->open_mutex);
-+ wake_up(&rmidi->open_wait);
- list_del_init(&rmidi->list);
-+ for (dir = 0; dir < 2; dir++) {
-+ struct snd_rawmidi_substream *s;
-+ list_for_each_entry(s, &rmidi->streams[dir].substreams, list) {
-+ if (s->runtime)
-+ wake_up(&s->runtime->sleep);
-+ }
-+ }
-+
- #ifdef CONFIG_SND_OSSEMUL
- if (rmidi->ossreg) {
- if ((int)rmidi->device == midi_map[rmidi->card->number]) {
-@@ -1626,6 +1649,7 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device)
- }
- #endif /* CONFIG_SND_OSSEMUL */
- snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
-+ mutex_unlock(&rmidi->open_mutex);
- mutex_unlock(&register_mutex);
- return 0;
- }
-diff --git a/sound/core/sound.c b/sound/core/sound.c
-index 28f3559..3700d96 100644
---- a/sound/core/sound.c
-+++ b/sound/core/sound.c
-@@ -99,6 +99,10 @@ static void snd_request_other(int minor)
- *
- * Checks that a minor device with the specified type is registered, and returns
- * its user data pointer.
-+ *
-+ * This function increments the reference counter of the card instance
-+ * if an associated instance with the given minor number and type is found.
-+ * The caller must call snd_card_unref() appropriately later.
- */
- void *snd_lookup_minor_data(unsigned int minor, int type)
- {
-@@ -109,9 +113,11 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
- return NULL;
- mutex_lock(&sound_mutex);
- mreg = snd_minors[minor];
-- if (mreg && mreg->type == type)
-+ if (mreg && mreg->type == type) {
- private_data = mreg->private_data;
-- else
-+ if (private_data && mreg->card_ptr)
-+ atomic_inc(&mreg->card_ptr->refcount);
-+ } else
- private_data = NULL;
- mutex_unlock(&sound_mutex);
- return private_data;
-@@ -276,6 +282,7 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
- preg->device = dev;
- preg->f_ops = f_ops;
- preg->private_data = private_data;
-+ preg->card_ptr = card;
- mutex_lock(&sound_mutex);
- #ifdef CONFIG_SND_DYNAMIC_MINORS
- minor = snd_find_free_minor(type);
-diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
-index e952833..726a49a 100644
---- a/sound/core/sound_oss.c
-+++ b/sound/core/sound_oss.c
-@@ -40,6 +40,9 @@
- static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS];
- static DEFINE_MUTEX(sound_oss_mutex);
-
-+/* NOTE: This function increments the refcount of the associated card like
-+ * snd_lookup_minor_data(); the caller must call snd_card_unref() appropriately
-+ */
- void *snd_lookup_oss_minor_data(unsigned int minor, int type)
- {
- struct snd_minor *mreg;
-@@ -49,9 +52,11 @@ void *snd_lookup_oss_minor_data(unsigned int minor, int type)
- return NULL;
- mutex_lock(&sound_oss_mutex);
- mreg = snd_oss_minors[minor];
-- if (mreg && mreg->type == type)
-+ if (mreg && mreg->type == type) {
- private_data = mreg->private_data;
-- else
-+ if (private_data && mreg->card_ptr)
-+ atomic_inc(&mreg->card_ptr->refcount);
-+ } else
- private_data = NULL;
- mutex_unlock(&sound_oss_mutex);
- return private_data;
-@@ -123,6 +128,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
- preg->device = dev;
- preg->f_ops = f_ops;
- preg->private_data = private_data;
-+ preg->card_ptr = card;
- mutex_lock(&sound_oss_mutex);
- snd_oss_minors[minor] = preg;
- minor_unit = SNDRV_MINOR_OSS_DEVICE(minor);
-diff --git a/sound/usb/card.c b/sound/usb/card.c
-index 4a469f0..b3f5ad4 100644
---- a/sound/usb/card.c
-+++ b/sound/usb/card.c
-@@ -339,7 +339,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
- }
-
- mutex_init(&chip->mutex);
-- mutex_init(&chip->shutdown_mutex);
-+ init_rwsem(&chip->shutdown_rwsem);
- chip->index = idx;
- chip->dev = dev;
- chip->card = card;
-@@ -559,9 +559,11 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
- return;
-
- card = chip->card;
-- mutex_lock(&register_mutex);
-- mutex_lock(&chip->shutdown_mutex);
-+ down_write(&chip->shutdown_rwsem);
- chip->shutdown = 1;
-+ up_write(&chip->shutdown_rwsem);
-+
-+ mutex_lock(&register_mutex);
- chip->num_interfaces--;
- if (chip->num_interfaces <= 0) {
- snd_card_disconnect(card);
-@@ -582,11 +584,9 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
- snd_usb_mixer_disconnect(p);
- }
- usb_chip[chip->index] = NULL;
-- mutex_unlock(&chip->shutdown_mutex);
- mutex_unlock(&register_mutex);
- snd_card_free_when_closed(card);
- } else {
-- mutex_unlock(&chip->shutdown_mutex);
- mutex_unlock(&register_mutex);
- }
- }
-@@ -618,16 +618,20 @@ int snd_usb_autoresume(struct snd_usb_audio *chip)
- {
- int err = -ENODEV;
-
-+ down_read(&chip->shutdown_rwsem);
- if (!chip->shutdown && !chip->probing)
- err = usb_autopm_get_interface(chip->pm_intf);
-+ up_read(&chip->shutdown_rwsem);
-
- return err;
- }
-
- void snd_usb_autosuspend(struct snd_usb_audio *chip)
- {
-+ down_read(&chip->shutdown_rwsem);
- if (!chip->shutdown && !chip->probing)
- usb_autopm_put_interface(chip->pm_intf);
-+ up_read(&chip->shutdown_rwsem);
- }
-
- static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
-diff --git a/sound/usb/card.h b/sound/usb/card.h
-index d9d2b5a..6e262c5 100644
---- a/sound/usb/card.h
-+++ b/sound/usb/card.h
-@@ -125,6 +125,7 @@ struct snd_usb_substream {
- struct snd_usb_endpoint *data_endpoint;
- struct snd_usb_endpoint *sync_endpoint;
- unsigned long flags;
-+ unsigned int speed; /* USB_SPEED_XXX */
-
- u64 formats; /* format bitmasks (all or'ed) */
- unsigned int num_formats; /* number of supported audio formats (list) */
-diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
-index fe56c9d..298070e 100644
---- a/sound/usb/mixer.c
-+++ b/sound/usb/mixer.c
-@@ -287,25 +287,32 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v
- unsigned char buf[2];
- int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
- int timeout = 10;
-- int err;
-+ int idx = 0, err;
-
- err = snd_usb_autoresume(cval->mixer->chip);
- if (err < 0)
- return -EIO;
-+ down_read(&chip->shutdown_rwsem);
- while (timeout-- > 0) {
-+ if (chip->shutdown)
-+ break;
-+ idx = snd_usb_ctrl_intf(chip) | (cval->id << 8);
- if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-- validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
-- buf, val_len) >= val_len) {
-+ validx, idx, buf, val_len) >= val_len) {
- *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
-- snd_usb_autosuspend(cval->mixer->chip);
-- return 0;
-+ err = 0;
-+ goto out;
- }
- }
-- snd_usb_autosuspend(cval->mixer->chip);
- snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
-- request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
-- return -EINVAL;
-+ request, validx, idx, cval->val_type);
-+ err = -EINVAL;
-+
-+ out:
-+ up_read(&chip->shutdown_rwsem);
-+ snd_usb_autosuspend(cval->mixer->chip);
-+ return err;
- }
-
- static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
-@@ -313,7 +320,7 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v
- struct snd_usb_audio *chip = cval->mixer->chip;
- unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */
- unsigned char *val;
-- int ret, size;
-+ int idx = 0, ret, size;
- __u8 bRequest;
-
- if (request == UAC_GET_CUR) {
-@@ -330,16 +337,22 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v
- if (ret)
- goto error;
-
-- ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
-+ down_read(&chip->shutdown_rwsem);
-+ if (chip->shutdown)
-+ ret = -ENODEV;
-+ else {
-+ idx = snd_usb_ctrl_intf(chip) | (cval->id << 8);
-+ ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-- validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
-- buf, size);
-+ validx, idx, buf, size);
-+ }
-+ up_read(&chip->shutdown_rwsem);
- snd_usb_autosuspend(chip);
-
- if (ret < 0) {
- error:
- snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
-- request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
-+ request, validx, idx, cval->val_type);
- return ret;
- }
-
-@@ -417,7 +430,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
- {
- struct snd_usb_audio *chip = cval->mixer->chip;
- unsigned char buf[2];
-- int val_len, err, timeout = 10;
-+ int idx = 0, val_len, err, timeout = 10;
-
- if (cval->mixer->protocol == UAC_VERSION_1) {
- val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
-@@ -440,19 +453,27 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
- err = snd_usb_autoresume(chip);
- if (err < 0)
- return -EIO;
-- while (timeout-- > 0)
-+ down_read(&chip->shutdown_rwsem);
-+ while (timeout-- > 0) {
-+ if (chip->shutdown)
-+ break;
-+ idx = snd_usb_ctrl_intf(chip) | (cval->id << 8);
- if (snd_usb_ctl_msg(chip->dev,
- usb_sndctrlpipe(chip->dev, 0), request,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
-- validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
-- buf, val_len) >= 0) {
-- snd_usb_autosuspend(chip);
-- return 0;
-+ validx, idx, buf, val_len) >= 0) {
-+ err = 0;
-+ goto out;
- }
-- snd_usb_autosuspend(chip);
-+ }
- snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
-- request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]);
-- return -EINVAL;
-+ request, validx, idx, cval->val_type, buf[0], buf[1]);
-+ err = -EINVAL;
-+
-+ out:
-+ up_read(&chip->shutdown_rwsem);
-+ snd_usb_autosuspend(chip);
-+ return err;
- }
-
- static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value)
-diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
-index 690000d..ae2b714 100644
---- a/sound/usb/mixer_quirks.c
-+++ b/sound/usb/mixer_quirks.c
-@@ -283,6 +283,11 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
- if (value > 1)
- return -EINVAL;
- changed = value != mixer->audigy2nx_leds[index];
-+ down_read(&mixer->chip->shutdown_rwsem);
-+ if (mixer->chip->shutdown) {
-+ err = -ENODEV;
-+ goto out;
-+ }
- if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042))
- err = snd_usb_ctl_msg(mixer->chip->dev,
- usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
-@@ -299,6 +304,8 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
- usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
- value, index + 2, NULL, 0);
-+ out:
-+ up_read(&mixer->chip->shutdown_rwsem);
- if (err < 0)
- return err;
- mixer->audigy2nx_leds[index] = value;
-@@ -392,11 +399,16 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
-
- for (i = 0; jacks[i].name; ++i) {
- snd_iprintf(buffer, "%s: ", jacks[i].name);
-- err = snd_usb_ctl_msg(mixer->chip->dev,
-+ down_read(&mixer->chip->shutdown_rwsem);
-+ if (mixer->chip->shutdown)
-+ err = 0;
-+ else
-+ err = snd_usb_ctl_msg(mixer->chip->dev,
- usb_rcvctrlpipe(mixer->chip->dev, 0),
- UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
- USB_RECIP_INTERFACE, 0,
- jacks[i].unitid << 8, buf, 3);
-+ up_read(&mixer->chip->shutdown_rwsem);
- if (err == 3 && (buf[0] == 3 || buf[0] == 6))
- snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
- else
-@@ -426,10 +438,15 @@ static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
- else
- new_status = old_status & ~0x02;
- changed = new_status != old_status;
-- err = snd_usb_ctl_msg(mixer->chip->dev,
-+ down_read(&mixer->chip->shutdown_rwsem);
-+ if (mixer->chip->shutdown)
-+ err = -ENODEV;
-+ else
-+ err = snd_usb_ctl_msg(mixer->chip->dev,
- usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
- 50, 0, &new_status, 1);
-+ up_read(&mixer->chip->shutdown_rwsem);
- if (err < 0)
- return err;
- mixer->xonar_u1_status = new_status;
-@@ -468,11 +485,17 @@ static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,
- u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
- u16 wIndex = kcontrol->private_value & 0xffff;
- u8 tmp;
-+ int ret;
-
-- int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
-+ down_read(&mixer->chip->shutdown_rwsem);
-+ if (mixer->chip->shutdown)
-+ ret = -ENODEV;
-+ else
-+ ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
- 0, cpu_to_le16(wIndex),
- &tmp, sizeof(tmp), 1000);
-+ up_read(&mixer->chip->shutdown_rwsem);
-
- if (ret < 0) {
- snd_printk(KERN_ERR
-@@ -493,11 +516,17 @@ static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
- u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
- u16 wIndex = kcontrol->private_value & 0xffff;
- u16 wValue = ucontrol->value.integer.value[0];
-+ int ret;
-
-- int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
-+ down_read(&mixer->chip->shutdown_rwsem);
-+ if (mixer->chip->shutdown)
-+ ret = -ENODEV;
-+ else
-+ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
- cpu_to_le16(wValue), cpu_to_le16(wIndex),
- NULL, 0, 1000);
-+ up_read(&mixer->chip->shutdown_rwsem);
-
- if (ret < 0) {
- snd_printk(KERN_ERR
-@@ -656,11 +685,16 @@ static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl,
- return -EINVAL;
-
-
-- err = snd_usb_ctl_msg(chip->dev,
-+ down_read(&mixer->chip->shutdown_rwsem);
-+ if (mixer->chip->shutdown)
-+ err = -ENODEV;
-+ else
-+ err = snd_usb_ctl_msg(chip->dev,
- usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
- validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
- value, val_len);
-+ up_read(&mixer->chip->shutdown_rwsem);
- if (err < 0)
- return err;
-
-@@ -703,11 +737,16 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
-
- if (!pval->is_cached) {
- /* Read current value */
-- err = snd_usb_ctl_msg(chip->dev,
-+ down_read(&mixer->chip->shutdown_rwsem);
-+ if (mixer->chip->shutdown)
-+ err = -ENODEV;
-+ else
-+ err = snd_usb_ctl_msg(chip->dev,
- usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
- validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
- value, val_len);
-+ up_read(&mixer->chip->shutdown_rwsem);
- if (err < 0)
- return err;
-
-@@ -719,11 +758,16 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
- if (cur_val != new_val) {
- value[0] = new_val;
- value[1] = 0;
-- err = snd_usb_ctl_msg(chip->dev,
-+ down_read(&mixer->chip->shutdown_rwsem);
-+ if (mixer->chip->shutdown)
-+ err = -ENODEV;
-+ else
-+ err = snd_usb_ctl_msg(chip->dev,
- usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
- validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
- value, val_len);
-+ up_read(&mixer->chip->shutdown_rwsem);
- if (err < 0)
- return err;
-
-diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
-index f782ce1..ee3c15c 100644
---- a/sound/usb/pcm.c
-+++ b/sound/usb/pcm.c
-@@ -71,6 +71,8 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream
- unsigned int hwptr_done;
-
- subs = (struct snd_usb_substream *)substream->runtime->private_data;
-+ if (subs->stream->chip->shutdown)
-+ return SNDRV_PCM_POS_XRUN;
- spin_lock(&subs->lock);
- hwptr_done = subs->hwptr_done;
- substream->runtime->delay = snd_usb_pcm_delay(subs,
-@@ -471,8 +473,14 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
- changed = subs->cur_audiofmt != fmt ||
- subs->period_bytes != params_period_bytes(hw_params) ||
- subs->cur_rate != rate;
-+
-+ down_read(&subs->stream->chip->shutdown_rwsem);
-+ if (subs->stream->chip->shutdown) {
-+ ret = -ENODEV;
-+ goto unlock;
-+ }
- if ((ret = set_format(subs, fmt)) < 0)
-- return ret;
-+ goto unlock;
-
- if (subs->cur_rate != rate) {
- struct usb_host_interface *alts;
-@@ -481,12 +489,11 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
- alts = &iface->altsetting[fmt->altset_idx];
- ret = snd_usb_init_sample_rate(subs->stream->chip, fmt->iface, alts, fmt, rate);
- if (ret < 0)
-- return ret;
-+ goto unlock;
- subs->cur_rate = rate;
- }
-
- if (changed) {
-- mutex_lock(&subs->stream->chip->shutdown_mutex);
- /* format changed */
- stop_endpoints(subs, 0, 0, 0);
- ret = snd_usb_endpoint_set_params(subs->data_endpoint, hw_params, fmt,
-@@ -497,8 +504,6 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
- if (subs->sync_endpoint)
- ret = snd_usb_endpoint_set_params(subs->sync_endpoint,
- hw_params, fmt, NULL);
--unlock:
-- mutex_unlock(&subs->stream->chip->shutdown_mutex);
- }
-
- if (ret == 0) {
-@@ -506,6 +511,8 @@ unlock:
- subs->altset_idx = fmt->altset_idx;
- }
-
-+unlock:
-+ up_read(&subs->stream->chip->shutdown_rwsem);
- return ret;
- }
-
-@@ -521,10 +528,12 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
- subs->cur_audiofmt = NULL;
- subs->cur_rate = 0;
- subs->period_bytes = 0;
-- mutex_lock(&subs->stream->chip->shutdown_mutex);
-- stop_endpoints(subs, 0, 1, 1);
-- deactivate_endpoints(subs);
-- mutex_unlock(&subs->stream->chip->shutdown_mutex);
-+ down_read(&subs->stream->chip->shutdown_rwsem);
-+ if (!subs->stream->chip->shutdown) {
-+ stop_endpoints(subs, 0, 1, 1);
-+ deactivate_endpoints(subs);
-+ }
-+ up_read(&subs->stream->chip->shutdown_rwsem);
- return snd_pcm_lib_free_vmalloc_buffer(substream);
- }
-
-@@ -537,14 +546,22 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
- {
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usb_substream *subs = runtime->private_data;
-+ int ret = 0;
-
- if (! subs->cur_audiofmt) {
- snd_printk(KERN_ERR "usbaudio: no format is specified!\n");
- return -ENXIO;
- }
-
-- if (snd_BUG_ON(!subs->data_endpoint))
-- return -EIO;
-+ down_read(&subs->stream->chip->shutdown_rwsem);
-+ if (subs->stream->chip->shutdown) {
-+ ret = -ENODEV;
-+ goto unlock;
-+ }
-+ if (snd_BUG_ON(!subs->data_endpoint)) {
-+ ret = -EIO;
-+ goto unlock;
-+ }
-
- /* some unit conversions in runtime */
- subs->data_endpoint->maxframesize =
-@@ -562,9 +579,11 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
- /* for playback, submit the URBs now; otherwise, the first hwptr_done
- * updates for all URBs would happen at the same time when starting */
- if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
-- return start_endpoints(subs, 1);
-+ ret = start_endpoints(subs, 1);
-
-- return 0;
-+ unlock:
-+ up_read(&subs->stream->chip->shutdown_rwsem);
-+ return ret;
- }
-
- static struct snd_pcm_hardware snd_usb_hardware =
-@@ -617,7 +636,7 @@ static int hw_check_valid_format(struct snd_usb_substream *subs,
- return 0;
- }
- /* check whether the period time is >= the data packet interval */
-- if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) {
-+ if (subs->speed != USB_SPEED_FULL) {
- ptime = 125 * (1 << fp->datainterval);
- if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
- hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max);
-@@ -895,7 +914,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
- return err;
-
- param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
-- if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
-+ if (subs->speed == USB_SPEED_FULL)
- /* full speed devices have fixed data packet interval */
- ptmin = 1000;
- if (ptmin == 1000)
-diff --git a/sound/usb/proc.c b/sound/usb/proc.c
-index ebc1a5b..d218f76 100644
---- a/sound/usb/proc.c
-+++ b/sound/usb/proc.c
-@@ -108,7 +108,7 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s
- }
- snd_iprintf(buffer, "\n");
- }
-- if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL)
-+ if (subs->speed != USB_SPEED_FULL)
- snd_iprintf(buffer, " Data packet interval: %d us\n",
- 125 * (1 << fp->datainterval));
- // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize);
-@@ -124,7 +124,7 @@ static void proc_dump_ep_status(struct snd_usb_substream *subs,
- return;
- snd_iprintf(buffer, " Packet Size = %d\n", ep->curpacksize);
- snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n",
-- snd_usb_get_speed(subs->dev) == USB_SPEED_FULL
-+ subs->speed == USB_SPEED_FULL
- ? get_full_speed_hz(ep->freqm)
- : get_high_speed_hz(ep->freqm),
- ep->freqm >> 16, ep->freqm & 0xffff);
-diff --git a/sound/usb/stream.c b/sound/usb/stream.c
-index 083ed81..1de0c8c 100644
---- a/sound/usb/stream.c
-+++ b/sound/usb/stream.c
-@@ -90,6 +90,7 @@ static void snd_usb_init_substream(struct snd_usb_stream *as,
- subs->direction = stream;
- subs->dev = as->chip->dev;
- subs->txfr_quirk = as->chip->txfr_quirk;
-+ subs->speed = snd_usb_get_speed(subs->dev);
-
- snd_usb_set_pcm_ops(as->pcm, stream);
-
-diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
-index b8233eb..ef42797 100644
---- a/sound/usb/usbaudio.h
-+++ b/sound/usb/usbaudio.h
-@@ -37,7 +37,7 @@ struct snd_usb_audio {
- struct usb_interface *pm_intf;
- u32 usb_id;
- struct mutex mutex;
-- struct mutex shutdown_mutex;
-+ struct rw_semaphore shutdown_rwsem;
- unsigned int shutdown:1;
- unsigned int probing:1;
- unsigned int autosuspended:1;
diff --git a/3.6.7/0000_README b/3.6.8/0000_README
index 05b1561..f24acf7 100644
--- a/3.6.7/0000_README
+++ b/3.6.8/0000_README
@@ -2,11 +2,7 @@ README
-----------------------------------------------------------------------------
Individual Patch Descriptions:
-----------------------------------------------------------------------------
-Patch: 1006_linux-3.6.7.patch
-From: http://www.kernel.org
-Desc: Linux 3.6.7
-
-Patch: 4420_grsecurity-2.9.1-3.6.7-201211221000.patch
+Patch: 4420_grsecurity-2.9.1-3.6.8-201211261714.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/3.6.7/4420_grsecurity-2.9.1-3.6.7-201211221000.patch b/3.6.8/4420_grsecurity-2.9.1-3.6.8-201211261714.patch
index cdc60ce..13615ed 100644
--- a/3.6.7/4420_grsecurity-2.9.1-3.6.7-201211221000.patch
+++ b/3.6.8/4420_grsecurity-2.9.1-3.6.8-201211261714.patch
@@ -251,7 +251,7 @@ index ad7e2e5..199f49e 100644
pcd. [PARIDE]
diff --git a/Makefile b/Makefile
-index 07f2308..7271d99 100644
+index c5cc2f0..6570abb 100644
--- a/Makefile
+++ b/Makefile
@@ -241,8 +241,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -3470,6 +3470,30 @@ index 5e34ccf..672bc9c 100644
DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
me->arch.unwind_section, table, end, gp);
+diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c
+index fd49aed..5dede04 100644
+--- a/arch/parisc/kernel/signal32.c
++++ b/arch/parisc/kernel/signal32.c
+@@ -65,7 +65,8 @@ put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
+ {
+ compat_sigset_t s;
+
+- if (sz != sizeof *set) panic("put_sigset32()");
++ if (sz != sizeof *set)
++ return -EINVAL;
+ sigset_64to32(&s, set);
+
+ return copy_to_user(up, &s, sizeof s);
+@@ -77,7 +78,8 @@ get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
+ compat_sigset_t s;
+ int r;
+
+- if (sz != sizeof *set) panic("put_sigset32()");
++ if (sz != sizeof *set)
++ return -EINVAL;
+
+ if ((r = copy_from_user(&s, up, sz)) == 0) {
+ sigset_32to64(set, &s);
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 7426e40..30c8dbe 100644
--- a/arch/parisc/kernel/sys_parisc.c
@@ -20537,7 +20561,7 @@ index baead95..90feeb4 100644
local_irq_disable();
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
-index b1eb202..254e292 100644
+index ff66a3b..48ad872 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1331,7 +1331,11 @@ static void reload_tss(void)
@@ -28017,7 +28041,7 @@ index 9a87daa..fb17486 100644
goto error;
diff --git a/crypto/cryptd.c b/crypto/cryptd.c
-index 671d4d6..afec999 100644
+index 7bdd61b..afec999 100644
--- a/crypto/cryptd.c
+++ b/crypto/cryptd.c
@@ -63,7 +63,7 @@ struct cryptd_blkcipher_ctx {
@@ -28038,28 +28062,6 @@ index 671d4d6..afec999 100644
static void cryptd_queue_worker(struct work_struct *work);
-@@ -137,13 +137,18 @@ static void cryptd_queue_worker(struct work_struct *work)
- struct crypto_async_request *req, *backlog;
-
- cpu_queue = container_of(work, struct cryptd_cpu_queue, work);
-- /* Only handle one request at a time to avoid hogging crypto
-- * workqueue. preempt_disable/enable is used to prevent
-- * being preempted by cryptd_enqueue_request() */
-+ /*
-+ * Only handle one request at a time to avoid hogging crypto workqueue.
-+ * preempt_disable/enable is used to prevent being preempted by
-+ * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent
-+ * cryptd_enqueue_request() being accessed from software interrupts.
-+ */
-+ local_bh_disable();
- preempt_disable();
- backlog = crypto_get_backlog(&cpu_queue->queue);
- req = crypto_dequeue_request(&cpu_queue->queue);
- preempt_enable();
-+ local_bh_enable();
-
- if (!req)
- return;
diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c
index e6defd8..c26a225 100644
--- a/drivers/acpi/apei/cper.c
@@ -31555,7 +31557,7 @@ index 3b663fc..57850f4 100644
if (rdev->pm.max_bandwidth.full > rdev->pm.k8_bandwidth.full &&
rdev->pm.k8_bandwidth.full)
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c
-index ebc6fac..a8313ed 100644
+index 578207e..1073f25 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
@@ -394,9 +394,9 @@ static int ttm_pool_get_num_unused_pages(void)
@@ -35596,7 +35598,7 @@ index 4a518a3..936b334 100644
#define VXGE_HW_VIRTUAL_PATH_HANDLE(vpath) \
((struct __vxge_hw_vpath_handle *)(vpath)->vpath_handles.next)
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
-index b47d5b3..273a516 100644
+index df7bbba..162f850 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -745,22 +745,22 @@ struct rtl8169_private {
@@ -36581,10 +36583,10 @@ index 61859d0..124539e 100644
/* No printks while decoding is disabled! */
if (!dev->mmio_always_on) {
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
-index 27911b5..5b6db88 100644
+index af028c7..654cdfc 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
-@@ -476,7 +476,16 @@ static const struct file_operations proc_bus_pci_dev_operations = {
+@@ -484,7 +484,16 @@ static const struct file_operations proc_bus_pci_dev_operations = {
static int __init pci_proc_init(void)
{
struct pci_dev *dev = NULL;
@@ -42932,22 +42934,6 @@ index 88714ae..16c2e11 100644
static inline u32 get_pll_internal_frequency(u32 ref_freq,
-diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
-index c3b3f7f..abd47c7 100644
---- a/drivers/virtio/virtio.c
-+++ b/drivers/virtio/virtio.c
-@@ -225,8 +225,10 @@ EXPORT_SYMBOL_GPL(register_virtio_device);
-
- void unregister_virtio_device(struct virtio_device *dev)
- {
-+ int index = dev->index; /* save for after device release */
-+
- device_unregister(&dev->dev);
-- ida_simple_remove(&virtio_index_ida, dev->index);
-+ ida_simple_remove(&virtio_index_ida, index);
- }
- EXPORT_SYMBOL_GPL(unregister_virtio_device);
-
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 453db0c..604973e 100644
--- a/drivers/virtio/virtio_mmio.c
@@ -45203,7 +45189,7 @@ index b2a34a1..162fa69 100644
return rc;
}
diff --git a/fs/exec.c b/fs/exec.c
-index fab2c6d..4fa20c0 100644
+index fab2c6d..6a13dff 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -55,6 +55,15 @@
@@ -45229,7 +45215,7 @@ index fab2c6d..4fa20c0 100644
+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
+void __weak pax_set_initial_flags(struct linux_binprm *bprm)
+{
-+ WARN_ONCE(1, "PAX: PAX_HAVE_ACL_FLAGS was enabled without providing the pax_set_initial_flags callback, this is probably not what you wanted.\n");
++ pr_warn_once("PAX: PAX_HAVE_ACL_FLAGS was enabled without providing the pax_set_initial_flags callback, this is probably not what you wanted.\n");
+}
+#endif
+
@@ -46042,7 +46028,7 @@ index cf18217..8f6b9c3 100644
if (free_clusters >= (nclusters + dirty_clusters))
return 1;
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
-index 5c69f2b..05dec7f 100644
+index b686b43..4b46d01 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1248,19 +1248,19 @@ struct ext4_sb_info {
@@ -48755,18 +48741,6 @@ index a9269f1..5490437 100644
set_fs(oldfs);
if (host_err < 0)
-diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
-index f35794b..a506360 100644
---- a/fs/notify/fanotify/fanotify.c
-+++ b/fs/notify/fanotify/fanotify.c
-@@ -21,6 +21,7 @@ static bool should_merge(struct fsnotify_event *old, struct fsnotify_event *new)
- if ((old->path.mnt == new->path.mnt) &&
- (old->path.dentry == new->path.dentry))
- return true;
-+ break;
- case (FSNOTIFY_EVENT_NONE):
- return true;
- default:
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index d438036..0ecadde 100644
--- a/fs/notify/fanotify/fanotify_user.c
@@ -50397,25 +50371,6 @@ index 1ccfa53..0848f95 100644
} else if (mm) {
pid_t tid = vm_is_stack(priv->task, vma, is_pid);
-diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
-index 29996e8..2d1e0f3 100644
---- a/fs/pstore/platform.c
-+++ b/fs/pstore/platform.c
-@@ -161,12 +161,13 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c)
-
- while (s < e) {
- unsigned long flags;
-+ u64 id;
-
- if (c > psinfo->bufsize)
- c = psinfo->bufsize;
- spin_lock_irqsave(&psinfo->buf_lock, flags);
- memcpy(psinfo->buf, s, c);
-- psinfo->write(PSTORE_TYPE_CONSOLE, 0, NULL, 0, c, psinfo);
-+ psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, c, psinfo);
- spin_unlock_irqrestore(&psinfo->buf_lock, flags);
- s += c;
- c = e - s;
diff --git a/fs/quota/netlink.c b/fs/quota/netlink.c
index d67908b..d13f6a6 100644
--- a/fs/quota/netlink.c
@@ -63486,50 +63441,68 @@ index aa2e167..84024ce 100644
};
diff --git a/include/linux/init.h b/include/linux/init.h
-index 5e664f6..0a1225c 100644
+index 5e664f6..15ae326 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
-@@ -39,9 +39,15 @@
+@@ -39,9 +39,33 @@
* Also note, that this data cannot be "const".
*/
+#ifdef MODULE
-+#define add_latent_entropy
++#define add_init_latent_entropy
+#else
-+#define add_latent_entropy __latent_entropy
++#define add_init_latent_entropy __latent_entropy
++#endif
++
++#ifdef CONFIG_HOTPLUG
++#define add_devinit_latent_entropy
++#else
++#define add_devinit_latent_entropy __latent_entropy
++#endif
++
++#ifdef CONFIG_HOTPLUG_CPU
++#define add_cpuinit_latent_entropy
++#else
++#define add_cpuinit_latent_entropy __latent_entropy
++#endif
++
++#ifdef CONFIG_MEMORY_HOTPLUG
++#define add_meminit_latent_entropy
++#else
++#define add_meminit_latent_entropy __latent_entropy
+#endif
+
/* These are for everybody (although not all archs will actually
discard it in modules) */
-#define __init __section(.init.text) __cold notrace
-+#define __init __section(.init.text) __cold notrace add_latent_entropy
++#define __init __section(.init.text) __cold notrace add_init_latent_entropy
#define __initdata __section(.init.data)
#define __initconst __section(.init.rodata)
#define __exitdata __section(.exit.data)
-@@ -83,7 +89,7 @@
+@@ -83,7 +107,7 @@
#define __exit __section(.exit.text) __exitused __cold notrace
/* Used for HOTPLUG */
-#define __devinit __section(.devinit.text) __cold notrace
-+#define __devinit __section(.devinit.text) __cold notrace add_latent_entropy
++#define __devinit __section(.devinit.text) __cold notrace add_devinit_latent_entropy
#define __devinitdata __section(.devinit.data)
#define __devinitconst __section(.devinit.rodata)
#define __devexit __section(.devexit.text) __exitused __cold notrace
-@@ -91,7 +97,7 @@
+@@ -91,7 +115,7 @@
#define __devexitconst __section(.devexit.rodata)
/* Used for HOTPLUG_CPU */
-#define __cpuinit __section(.cpuinit.text) __cold notrace
-+#define __cpuinit __section(.cpuinit.text) __cold notrace add_latent_entropy
++#define __cpuinit __section(.cpuinit.text) __cold notrace add_cpuinit_latent_entropy
#define __cpuinitdata __section(.cpuinit.data)
#define __cpuinitconst __section(.cpuinit.rodata)
#define __cpuexit __section(.cpuexit.text) __exitused __cold notrace
-@@ -99,7 +105,7 @@
+@@ -99,7 +123,7 @@
#define __cpuexitconst __section(.cpuexit.rodata)
/* Used for MEMORY_HOTPLUG */
-#define __meminit __section(.meminit.text) __cold notrace
-+#define __meminit __section(.meminit.text) __cold notrace add_latent_entropy
++#define __meminit __section(.meminit.text) __cold notrace add_meminit_latent_entropy
#define __meminitdata __section(.meminit.data)
#define __meminitconst __section(.meminit.rodata)
#define __memexit __section(.memexit.text) __exitused __cold notrace
@@ -64011,7 +63984,7 @@ index 1d1b1e1..2a13c78 100644
#define pmdp_clear_flush_notify(__vma, __address, __pmdp) \
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
-index 2daa54f..bfdf2f5 100644
+index a16d929..860ae00 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -414,7 +414,7 @@ struct zone {
@@ -68560,7 +68533,7 @@ index 91c32a0..7b88d63 100644
seq_printf(m, "%40s %14lu %29s %pS\n",
name, stats->contending_point[i],
diff --git a/kernel/module.c b/kernel/module.c
-index 9ad9ee9..731c128 100644
+index 2a15c59..731c128 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -58,6 +58,7 @@
@@ -68849,7 +68822,7 @@ index 9ad9ee9..731c128 100644
}
}
-@@ -2266,28 +2284,33 @@ static void layout_symtab(struct module *mod, struct load_info *info)
+@@ -2266,7 +2284,7 @@ static void layout_symtab(struct module *mod, struct load_info *info)
/* Put symbol section at end of init part of module. */
symsect->sh_flags |= SHF_ALLOC;
@@ -68858,23 +68831,8 @@ index 9ad9ee9..731c128 100644
info->index.sym) | INIT_OFFSET_MASK;
pr_debug("\t%s\n", info->secstrings + symsect->sh_name);
- src = (void *)info->hdr + symsect->sh_offset;
- nsrc = symsect->sh_size / sizeof(*src);
-
-+ /* strtab always starts with a nul, so offset 0 is the empty string. */
-+ strtab_size = 1;
-+
- /* Compute total space required for the core symbols' strtab. */
-- for (ndst = i = strtab_size = 1; i < nsrc; ++i, ++src)
-- if (is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) {
-- strtab_size += strlen(&info->strtab[src->st_name]) + 1;
-+ for (ndst = i = 0; i < nsrc; i++) {
-+ if (i == 0 ||
-+ is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
-+ strtab_size += strlen(&info->strtab[src[i].st_name])+1;
- ndst++;
- }
-+ }
+@@ -2286,13 +2304,13 @@ static void layout_symtab(struct module *mod, struct load_info *info)
+ }
/* Append room for core symbols at end of core part. */
- info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1);
@@ -68891,7 +68849,7 @@ index 9ad9ee9..731c128 100644
info->index.str) | INIT_OFFSET_MASK;
pr_debug("\t%s\n", info->secstrings + strsect->sh_name);
}
-@@ -2305,24 +2328,28 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
+@@ -2310,12 +2328,14 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
/* Make sure we get permanent strtab: don't use info->strtab. */
mod->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
@@ -68906,23 +68864,10 @@ index 9ad9ee9..731c128 100644
+ mod->core_symtab = dst = mod->module_core_rx + info->symoffs;
+ mod->core_strtab = s = mod->module_core_rx + info->stroffs;
src = mod->symtab;
-- *dst = *src;
*s++ = 0;
-- for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) {
-- if (!is_core_symbol(src, info->sechdrs, info->hdr->e_shnum))
-- continue;
--
-- dst[ndst] = *src;
-- dst[ndst++].st_name = s - mod->core_strtab;
-- s += strlcpy(s, &mod->strtab[src->st_name], KSYM_NAME_LEN) + 1;
-+ for (ndst = i = 0; i < mod->num_symtab; i++) {
-+ if (i == 0 ||
-+ is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
-+ dst[ndst] = src[i];
-+ dst[ndst++].st_name = s - mod->core_strtab;
-+ s += strlcpy(s, &mod->strtab[src[i].st_name],
-+ KSYM_NAME_LEN) + 1;
-+ }
+ for (ndst = i = 0; i < mod->num_symtab; i++) {
+@@ -2328,6 +2348,8 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
+ }
}
mod->core_num_syms = ndst;
+
@@ -68930,7 +68875,7 @@ index 9ad9ee9..731c128 100644
}
#else
static inline void layout_symtab(struct module *mod, struct load_info *info)
-@@ -2356,17 +2383,33 @@ void * __weak module_alloc(unsigned long size)
+@@ -2361,17 +2383,33 @@ void * __weak module_alloc(unsigned long size)
return size == 0 ? NULL : vmalloc_exec(size);
}
@@ -68969,7 +68914,7 @@ index 9ad9ee9..731c128 100644
mutex_unlock(&module_mutex);
}
return ret;
-@@ -2544,8 +2587,14 @@ static struct module *setup_load_info(struct load_info *info)
+@@ -2549,8 +2587,14 @@ static struct module *setup_load_info(struct load_info *info)
static int check_modinfo(struct module *mod, struct load_info *info)
{
const char *modmagic = get_modinfo(info, "vermagic");
@@ -68984,7 +68929,7 @@ index 9ad9ee9..731c128 100644
/* This is allowed: modprobe --force will invalidate it. */
if (!modmagic) {
err = try_to_force_load(mod, "bad vermagic");
-@@ -2568,7 +2617,7 @@ static int check_modinfo(struct module *mod, struct load_info *info)
+@@ -2573,7 +2617,7 @@ static int check_modinfo(struct module *mod, struct load_info *info)
}
/* Set up license info based on the info section */
@@ -68993,7 +68938,7 @@ index 9ad9ee9..731c128 100644
return 0;
}
-@@ -2662,7 +2711,7 @@ static int move_module(struct module *mod, struct load_info *info)
+@@ -2667,7 +2711,7 @@ static int move_module(struct module *mod, struct load_info *info)
void *ptr;
/* Do the allocs. */
@@ -69002,7 +68947,7 @@ index 9ad9ee9..731c128 100644
/*
* The pointer to this block is stored in the module structure
* which is inside the block. Just mark it as not being a
-@@ -2672,23 +2721,50 @@ static int move_module(struct module *mod, struct load_info *info)
+@@ -2677,23 +2721,50 @@ static int move_module(struct module *mod, struct load_info *info)
if (!ptr)
return -ENOMEM;
@@ -69061,7 +69006,7 @@ index 9ad9ee9..731c128 100644
/* Transfer each section which specifies SHF_ALLOC */
pr_debug("final section addresses:\n");
-@@ -2699,16 +2775,45 @@ static int move_module(struct module *mod, struct load_info *info)
+@@ -2704,16 +2775,45 @@ static int move_module(struct module *mod, struct load_info *info)
if (!(shdr->sh_flags & SHF_ALLOC))
continue;
@@ -69114,7 +69059,7 @@ index 9ad9ee9..731c128 100644
pr_debug("\t0x%lx %s\n",
(long)shdr->sh_addr, info->secstrings + shdr->sh_name);
}
-@@ -2763,12 +2868,12 @@ static void flush_module_icache(const struct module *mod)
+@@ -2768,12 +2868,12 @@ static void flush_module_icache(const struct module *mod)
* Do it before processing of module parameters, so the module
* can provide parameter accessor functions of its own.
*/
@@ -69133,7 +69078,7 @@ index 9ad9ee9..731c128 100644
set_fs(old_fs);
}
-@@ -2838,8 +2943,10 @@ out:
+@@ -2843,8 +2943,10 @@ out:
static void module_deallocate(struct module *mod, struct load_info *info)
{
percpu_modfree(mod);
@@ -69146,7 +69091,7 @@ index 9ad9ee9..731c128 100644
}
int __weak module_finalize(const Elf_Ehdr *hdr,
-@@ -2852,7 +2959,9 @@ int __weak module_finalize(const Elf_Ehdr *hdr,
+@@ -2857,7 +2959,9 @@ int __weak module_finalize(const Elf_Ehdr *hdr,
static int post_relocation(struct module *mod, const struct load_info *info)
{
/* Sort exception table now relocations are done. */
@@ -69156,7 +69101,7 @@ index 9ad9ee9..731c128 100644
/* Copy relocated percpu area over. */
percpu_modcopy(mod, (void *)info->sechdrs[info->index.pcpu].sh_addr,
-@@ -2903,9 +3012,38 @@ static struct module *load_module(void __user *umod,
+@@ -2908,9 +3012,38 @@ static struct module *load_module(void __user *umod,
if (err)
goto free_unload;
@@ -69195,7 +69140,7 @@ index 9ad9ee9..731c128 100644
/* Fix up syms, so that st_value is a pointer to location. */
err = simplify_symbols(mod, &info);
if (err < 0)
-@@ -2921,13 +3059,6 @@ static struct module *load_module(void __user *umod,
+@@ -2926,13 +3059,6 @@ static struct module *load_module(void __user *umod,
flush_module_icache(mod);
@@ -69209,7 +69154,7 @@ index 9ad9ee9..731c128 100644
/* Mark state as coming so strong_try_module_get() ignores us. */
mod->state = MODULE_STATE_COMING;
-@@ -2985,11 +3116,10 @@ static struct module *load_module(void __user *umod,
+@@ -2990,11 +3116,10 @@ static struct module *load_module(void __user *umod,
unlock:
mutex_unlock(&module_mutex);
synchronize_sched();
@@ -69222,7 +69167,7 @@ index 9ad9ee9..731c128 100644
free_unload:
module_unload_free(mod);
free_module:
-@@ -3030,16 +3160,16 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
+@@ -3035,16 +3160,16 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
MODULE_STATE_COMING, mod);
/* Set RO and NX regions for core */
@@ -69247,7 +69192,7 @@ index 9ad9ee9..731c128 100644
do_mod_ctors(mod);
/* Start the module */
-@@ -3085,11 +3215,12 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
+@@ -3090,11 +3215,12 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
mod->strtab = mod->core_strtab;
#endif
unset_module_init_ro_nx(mod);
@@ -69265,7 +69210,7 @@ index 9ad9ee9..731c128 100644
mutex_unlock(&module_mutex);
return 0;
-@@ -3120,10 +3251,16 @@ static const char *get_ksymbol(struct module *mod,
+@@ -3125,10 +3251,16 @@ static const char *get_ksymbol(struct module *mod,
unsigned long nextval;
/* At worse, next value is at end of module */
@@ -69285,7 +69230,7 @@ index 9ad9ee9..731c128 100644
/* Scan for closest preceding symbol, and next symbol. (ELF
starts real symbols at 1). */
-@@ -3358,7 +3495,7 @@ static int m_show(struct seq_file *m, void *p)
+@@ -3363,7 +3495,7 @@ static int m_show(struct seq_file *m, void *p)
char buf[8];
seq_printf(m, "%s %u",
@@ -69294,7 +69239,7 @@ index 9ad9ee9..731c128 100644
print_unload_info(m, mod);
/* Informative for users. */
-@@ -3367,7 +3504,7 @@ static int m_show(struct seq_file *m, void *p)
+@@ -3372,7 +3504,7 @@ static int m_show(struct seq_file *m, void *p)
mod->state == MODULE_STATE_COMING ? "Loading":
"Live");
/* Used by oprofile and other similar tools. */
@@ -69303,7 +69248,7 @@ index 9ad9ee9..731c128 100644
/* Taints info */
if (mod->taints)
-@@ -3403,7 +3540,17 @@ static const struct file_operations proc_modules_operations = {
+@@ -3408,7 +3540,17 @@ static const struct file_operations proc_modules_operations = {
static int __init proc_modules_init(void)
{
@@ -69321,7 +69266,7 @@ index 9ad9ee9..731c128 100644
return 0;
}
module_init(proc_modules_init);
-@@ -3462,12 +3609,12 @@ struct module *__module_address(unsigned long addr)
+@@ -3467,12 +3609,12 @@ struct module *__module_address(unsigned long addr)
{
struct module *mod;
@@ -69337,7 +69282,7 @@ index 9ad9ee9..731c128 100644
return mod;
return NULL;
}
-@@ -3501,11 +3648,20 @@ bool is_module_text_address(unsigned long addr)
+@@ -3506,11 +3648,20 @@ bool is_module_text_address(unsigned long addr)
*/
struct module *__module_text_address(unsigned long addr)
{
@@ -72090,9 +72035,18 @@ index 9ed4fd4..c42648d 100644
* Make sure the vma is shared, that it supports prefaulting,
* and that the remapped range is valid and fully within
diff --git a/mm/highmem.c b/mm/highmem.c
-index d517cd1..006a1c5 100644
+index d517cd1..9568fec 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
+@@ -98,7 +98,7 @@ struct page *kmap_to_page(void *vaddr)
+ {
+ unsigned long addr = (unsigned long)vaddr;
+
+- if (addr >= PKMAP_ADDR(0) && addr <= PKMAP_ADDR(LAST_PKMAP)) {
++ if (addr >= PKMAP_ADDR(0) && addr < PKMAP_ADDR(LAST_PKMAP)) {
+ int i = (addr - PKMAP_ADDR(0)) >> PAGE_SHIFT;
+ return pte_page(pkmap_page_table[i]);
+ }
@@ -137,9 +137,10 @@ static void flush_all_zero_pkmaps(void)
* So no dangers, even with speculative execution.
*/
@@ -74900,7 +74854,7 @@ index d4b0c10..ed421b5 100644
new->vm_region = region;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
-index c13ea75..081ab2c 100644
+index d2d8f54..be2a87c 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -340,7 +340,7 @@ out:
@@ -75116,7 +75070,7 @@ index aa95e59..b681a63 100644
struct anon_vma_chain *avc;
struct anon_vma *anon_vma;
diff --git a/mm/shmem.c b/mm/shmem.c
-index d2eeca1..92f3123 100644
+index 31e1506..dbf3647 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -31,7 +31,7 @@
@@ -75137,7 +75091,7 @@ index d2eeca1..92f3123 100644
struct shmem_xattr {
struct list_head list; /* anchored by shmem_inode_info->xattr_list */
-@@ -2207,6 +2207,11 @@ static const struct xattr_handler *shmem_xattr_handlers[] = {
+@@ -2219,6 +2219,11 @@ static const struct xattr_handler *shmem_xattr_handlers[] = {
static int shmem_xattr_validate(const char *name)
{
struct { const char *prefix; size_t len; } arr[] = {
@@ -75149,7 +75103,7 @@ index d2eeca1..92f3123 100644
{ XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN },
{ XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN }
};
-@@ -2260,6 +2265,15 @@ static int shmem_setxattr(struct dentry *dentry, const char *name,
+@@ -2272,6 +2277,15 @@ static int shmem_setxattr(struct dentry *dentry, const char *name,
if (err)
return err;
@@ -75165,7 +75119,7 @@ index d2eeca1..92f3123 100644
if (size == 0)
value = ""; /* empty EA, do not remove */
-@@ -2594,8 +2608,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent)
+@@ -2606,8 +2620,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 */
@@ -76354,19 +76308,6 @@ index 2bb90b1..3795e47 100644
v->addr, v->addr + v->size, v->size);
if (v->caller)
-diff --git a/mm/vmscan.c b/mm/vmscan.c
-index 99b434b..a018dfc 100644
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -2953,6 +2953,8 @@ static int kswapd(void *p)
- &balanced_classzone_idx);
- }
- }
-+
-+ current->reclaim_state = NULL;
- return 0;
- }
-
diff --git a/mm/vmstat.c b/mm/vmstat.c
index df7a674..8b4a4f3 100644
--- a/mm/vmstat.c
@@ -77052,7 +76993,7 @@ index 0337e2b..47914a0 100644
return err;
diff --git a/net/core/dev.c b/net/core/dev.c
-index aed87a4..72cc526 100644
+index 1dce5b5..363a522 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1138,9 +1138,13 @@ void dev_load(struct net *net, const char *name)
@@ -77096,7 +77037,7 @@ index aed87a4..72cc526 100644
#define DEV_GSO_CB(skb) ((struct dev_gso_cb *)(skb)->cb)
-@@ -2928,7 +2932,7 @@ enqueue:
+@@ -2930,7 +2934,7 @@ enqueue:
local_irq_restore(flags);
@@ -77105,7 +77046,7 @@ index aed87a4..72cc526 100644
kfree_skb(skb);
return NET_RX_DROP;
}
-@@ -3000,7 +3004,7 @@ int netif_rx_ni(struct sk_buff *skb)
+@@ -3002,7 +3006,7 @@ int netif_rx_ni(struct sk_buff *skb)
}
EXPORT_SYMBOL(netif_rx_ni);
@@ -77114,7 +77055,7 @@ index aed87a4..72cc526 100644
{
struct softnet_data *sd = &__get_cpu_var(softnet_data);
-@@ -3331,7 +3335,7 @@ ncls:
+@@ -3333,7 +3337,7 @@ ncls:
ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
} else {
drop:
@@ -77123,7 +77064,7 @@ index aed87a4..72cc526 100644
kfree_skb(skb);
/* Jamal, now you will not able to escape explaining
* me how you were going to use this. :-)
-@@ -3898,7 +3902,7 @@ void netif_napi_del(struct napi_struct *napi)
+@@ -3900,7 +3904,7 @@ void netif_napi_del(struct napi_struct *napi)
}
EXPORT_SYMBOL(netif_napi_del);
@@ -77132,7 +77073,7 @@ index aed87a4..72cc526 100644
{
struct softnet_data *sd = &__get_cpu_var(softnet_data);
unsigned long time_limit = jiffies + 2;
-@@ -4368,8 +4372,13 @@ static int ptype_seq_show(struct seq_file *seq, void *v)
+@@ -4370,8 +4374,13 @@ static int ptype_seq_show(struct seq_file *seq, void *v)
else
seq_printf(seq, "%04x", ntohs(pt->type));
@@ -77146,7 +77087,7 @@ index aed87a4..72cc526 100644
}
return 0;
-@@ -5922,7 +5931,7 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
+@@ -5924,7 +5933,7 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
} else {
netdev_stats_to_stats64(storage, &dev->stats);
}
@@ -77520,10 +77461,10 @@ index 8d07c97..d0812ef 100644
rc = qp->q.fragments && (end - start) > max;
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
-index 5eea4a8..49819c2 100644
+index 14bbfcf..644f472 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
-@@ -1142,7 +1142,8 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
+@@ -1151,7 +1151,8 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
len = min_t(unsigned int, len, opt->optlen);
if (put_user(len, optlen))
return -EFAULT;
@@ -77533,7 +77474,7 @@ index 5eea4a8..49819c2 100644
return -EFAULT;
return 0;
}
-@@ -1273,7 +1274,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
+@@ -1282,7 +1283,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
if (sk->sk_type != SOCK_STREAM)
return -ENOPROTOOPT;
@@ -78078,10 +78019,10 @@ index b10374d..0baa1f9 100644
if (ops->ndo_do_ioctl) {
mm_segment_t oldfs = get_fs();
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
-index ba6d13d..6899122 100644
+index e02faed..9780f28 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
-@@ -989,7 +989,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
+@@ -990,7 +990,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
if (sk->sk_type != SOCK_STREAM)
return -ENOPROTOOPT;
@@ -78561,7 +78502,7 @@ index 34e4185..8823368 100644
return res;
}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
-index bb61f77..3788d63 100644
+index 642a2a3..9dcc3dd 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -28,6 +28,7 @@
@@ -78719,7 +78660,7 @@ index c97a065..ff61928 100644
return p;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
-index 1cfe6d5..c428ba3 100644
+index 7883449..17c6a9a 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1279,7 +1279,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
@@ -83594,10 +83535,10 @@ index 0000000..a86e422
+}
diff --git a/tools/gcc/kernexec_plugin.c b/tools/gcc/kernexec_plugin.c
new file mode 100644
-index 0000000..98011fa
+index 0000000..8856202
--- /dev/null
+++ b/tools/gcc/kernexec_plugin.c
-@@ -0,0 +1,427 @@
+@@ -0,0 +1,432 @@
+/*
+ * Copyright 2011 by the PaX Team <pageexec@freemail.hu>
+ * Licensed under the GPL v2
@@ -83638,6 +83579,10 @@ index 0000000..98011fa
+extern void print_gimple_stmt(FILE *, gimple, int, int);
+extern rtx emit_move_insn(rtx x, rtx y);
+
++#if BUILDING_GCC_VERSION <= 4006
++#define ANY_RETURN_P(rtx) (GET_CODE(rtx) == RETURN)
++#endif
++
+int plugin_is_GPL_compatible;
+
+static struct plugin_info kernexec_plugin_info = {
@@ -83942,6 +83887,7 @@ index 0000000..98011fa
+ for (insn = get_insns(); insn; insn = NEXT_INSN(insn)) {
+ // rtl match: (jump_insn 41 40 42 2 (return) fptr.c:42 634 {return_internal} (nil))
+ // (jump_insn 12 9 11 2 (parallel [ (return) (unspec [ (0) ] UNSPEC_REP) ]) fptr.c:46 635 {return_internal_long} (nil))
++ // (jump_insn 97 96 98 6 (simple_return) fptr.c:50 -1 (nil) -> simple_return)
+ rtx body;
+
+ // is it a retn
@@ -83950,7 +83896,7 @@ index 0000000..98011fa
+ body = PATTERN(insn);
+ if (GET_CODE(body) == PARALLEL)
+ body = XVECEXP(body, 0, 0);
-+ if (GET_CODE(body) != RETURN)
++ if (!ANY_RETURN_P(body))
+ continue;
+ kernexec_instrument_retaddr(insn);
+ }
diff --git a/3.6.7/4425-tmpfs-user-namespace.patch b/3.6.8/4425-tmpfs-user-namespace.patch
index b48d735..b48d735 100644
--- a/3.6.7/4425-tmpfs-user-namespace.patch
+++ b/3.6.8/4425-tmpfs-user-namespace.patch
diff --git a/3.6.7/4430_grsec-remove-localversion-grsec.patch b/3.6.8/4430_grsec-remove-localversion-grsec.patch
index 31cf878..31cf878 100644
--- a/3.6.7/4430_grsec-remove-localversion-grsec.patch
+++ b/3.6.8/4430_grsec-remove-localversion-grsec.patch
diff --git a/3.6.7/4435_grsec-mute-warnings.patch b/3.6.8/4435_grsec-mute-warnings.patch
index e1a7a3c..e1a7a3c 100644
--- a/3.6.7/4435_grsec-mute-warnings.patch
+++ b/3.6.8/4435_grsec-mute-warnings.patch
diff --git a/3.6.7/4440_grsec-remove-protected-paths.patch b/3.6.8/4440_grsec-remove-protected-paths.patch
index 637934a..637934a 100644
--- a/3.6.7/4440_grsec-remove-protected-paths.patch
+++ b/3.6.8/4440_grsec-remove-protected-paths.patch
diff --git a/3.6.7/4450_grsec-kconfig-default-gids.patch b/3.6.8/4450_grsec-kconfig-default-gids.patch
index d4b0b7e..d4b0b7e 100644
--- a/3.6.7/4450_grsec-kconfig-default-gids.patch
+++ b/3.6.8/4450_grsec-kconfig-default-gids.patch
diff --git a/3.6.7/4465_selinux-avc_audit-log-curr_ip.patch b/3.6.8/4465_selinux-avc_audit-log-curr_ip.patch
index 4fb50f4..4fb50f4 100644
--- a/3.6.7/4465_selinux-avc_audit-log-curr_ip.patch
+++ b/3.6.8/4465_selinux-avc_audit-log-curr_ip.patch
diff --git a/3.6.7/4470_disable-compat_vdso.patch b/3.6.8/4470_disable-compat_vdso.patch
index 4a1947b..4a1947b 100644
--- a/3.6.7/4470_disable-compat_vdso.patch
+++ b/3.6.8/4470_disable-compat_vdso.patch