summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2013-10-29 13:29:31 -0400
committerAnthony G. Basile <blueness@gentoo.org>2013-10-29 13:29:31 -0400
commit73961b305f24ed999e4af414afb420f14ca0252b (patch)
tree345c5e43dadc168ae0f8f628e89a457902b86d7b
parentGrsec/PaX: 2.9.1-{3.2.51,3.11.6}-201310260850 (diff)
downloadhardened-patchset-73961b305f24ed999e4af414afb420f14ca0252b.tar.gz
hardened-patchset-73961b305f24ed999e4af414afb420f14ca0252b.tar.bz2
hardened-patchset-73961b305f24ed999e4af414afb420f14ca0252b.zip
Grsec/PaX: 2.9.1-{2.6.32.61,3.2.52,3.11.6}-20131027155220131027
-rw-r--r--2.6.32/0000_README2
-rw-r--r--2.6.32/4420_grsecurity-2.9.1-2.6.32.61-201310271545.patch (renamed from 2.6.32/4420_grsecurity-2.9.1-2.6.32.61-201309281101.patch)22
-rw-r--r--3.11.6/0000_README2
-rw-r--r--3.11.6/4420_grsecurity-2.9.1-3.11.6-201310271552.patch (renamed from 3.11.6/4420_grsecurity-2.9.1-3.11.6-201310260850.patch)258
-rw-r--r--3.2.52/0000_README (renamed from 3.2.51/0000_README)6
-rw-r--r--3.2.52/1021_linux-3.2.22.patch (renamed from 3.2.51/1021_linux-3.2.22.patch)0
-rw-r--r--3.2.52/1022_linux-3.2.23.patch (renamed from 3.2.51/1022_linux-3.2.23.patch)0
-rw-r--r--3.2.52/1023_linux-3.2.24.patch (renamed from 3.2.51/1023_linux-3.2.24.patch)0
-rw-r--r--3.2.52/1024_linux-3.2.25.patch (renamed from 3.2.51/1024_linux-3.2.25.patch)0
-rw-r--r--3.2.52/1025_linux-3.2.26.patch (renamed from 3.2.51/1025_linux-3.2.26.patch)0
-rw-r--r--3.2.52/1026_linux-3.2.27.patch (renamed from 3.2.51/1026_linux-3.2.27.patch)0
-rw-r--r--3.2.52/1027_linux-3.2.28.patch (renamed from 3.2.51/1027_linux-3.2.28.patch)0
-rw-r--r--3.2.52/1028_linux-3.2.29.patch (renamed from 3.2.51/1028_linux-3.2.29.patch)0
-rw-r--r--3.2.52/1029_linux-3.2.30.patch (renamed from 3.2.51/1029_linux-3.2.30.patch)0
-rw-r--r--3.2.52/1030_linux-3.2.31.patch (renamed from 3.2.51/1030_linux-3.2.31.patch)0
-rw-r--r--3.2.52/1031_linux-3.2.32.patch (renamed from 3.2.51/1031_linux-3.2.32.patch)0
-rw-r--r--3.2.52/1032_linux-3.2.33.patch (renamed from 3.2.51/1032_linux-3.2.33.patch)0
-rw-r--r--3.2.52/1033_linux-3.2.34.patch (renamed from 3.2.51/1033_linux-3.2.34.patch)0
-rw-r--r--3.2.52/1034_linux-3.2.35.patch (renamed from 3.2.51/1034_linux-3.2.35.patch)0
-rw-r--r--3.2.52/1035_linux-3.2.36.patch (renamed from 3.2.51/1035_linux-3.2.36.patch)0
-rw-r--r--3.2.52/1036_linux-3.2.37.patch (renamed from 3.2.51/1036_linux-3.2.37.patch)0
-rw-r--r--3.2.52/1037_linux-3.2.38.patch (renamed from 3.2.51/1037_linux-3.2.38.patch)0
-rw-r--r--3.2.52/1038_linux-3.2.39.patch (renamed from 3.2.51/1038_linux-3.2.39.patch)0
-rw-r--r--3.2.52/1039_linux-3.2.40.patch (renamed from 3.2.51/1039_linux-3.2.40.patch)0
-rw-r--r--3.2.52/1040_linux-3.2.41.patch (renamed from 3.2.51/1040_linux-3.2.41.patch)0
-rw-r--r--3.2.52/1041_linux-3.2.42.patch (renamed from 3.2.51/1041_linux-3.2.42.patch)0
-rw-r--r--3.2.52/1042_linux-3.2.43.patch (renamed from 3.2.51/1042_linux-3.2.43.patch)0
-rw-r--r--3.2.52/1043_linux-3.2.44.patch (renamed from 3.2.51/1043_linux-3.2.44.patch)0
-rw-r--r--3.2.52/1044_linux-3.2.45.patch (renamed from 3.2.51/1044_linux-3.2.45.patch)0
-rw-r--r--3.2.52/1045_linux-3.2.46.patch (renamed from 3.2.51/1045_linux-3.2.46.patch)0
-rw-r--r--3.2.52/1046_linux-3.2.47.patch (renamed from 3.2.51/1046_linux-3.2.47.patch)0
-rw-r--r--3.2.52/1047_linux-3.2.48.patch (renamed from 3.2.51/1047_linux-3.2.48.patch)0
-rw-r--r--3.2.52/1048_linux-3.2.49.patch (renamed from 3.2.51/1048_linux-3.2.49.patch)0
-rw-r--r--3.2.52/1049_linux-3.2.50.patch (renamed from 3.2.51/1049_linux-3.2.50.patch)0
-rw-r--r--3.2.52/1050_linux-3.2.51.patch (renamed from 3.2.51/1050_linux-3.2.51.patch)0
-rw-r--r--3.2.52/1051_linux-3.2.52.patch5221
-rw-r--r--3.2.52/4420_grsecurity-2.9.1-3.2.52-201310271550.patch (renamed from 3.2.51/4420_grsecurity-2.9.1-3.2.51-201310260849.patch)1135
-rw-r--r--3.2.52/4425_grsec_remove_EI_PAX.patch (renamed from 3.2.51/4425_grsec_remove_EI_PAX.patch)0
-rw-r--r--3.2.52/4427_force_XATTR_PAX_tmpfs.patch (renamed from 3.2.51/4427_force_XATTR_PAX_tmpfs.patch)0
-rw-r--r--3.2.52/4430_grsec-remove-localversion-grsec.patch (renamed from 3.2.51/4430_grsec-remove-localversion-grsec.patch)0
-rw-r--r--3.2.52/4435_grsec-mute-warnings.patch (renamed from 3.2.51/4435_grsec-mute-warnings.patch)0
-rw-r--r--3.2.52/4440_grsec-remove-protected-paths.patch (renamed from 3.2.51/4440_grsec-remove-protected-paths.patch)0
-rw-r--r--3.2.52/4450_grsec-kconfig-default-gids.patch (renamed from 3.2.51/4450_grsec-kconfig-default-gids.patch)0
-rw-r--r--3.2.52/4465_selinux-avc_audit-log-curr_ip.patch (renamed from 3.2.51/4465_selinux-avc_audit-log-curr_ip.patch)0
-rw-r--r--3.2.52/4470_disable-compat_vdso.patch (renamed from 3.2.51/4470_disable-compat_vdso.patch)0
-rw-r--r--3.2.52/4475_emutramp_default_on.patch (renamed from 3.2.51/4475_emutramp_default_on.patch)0
46 files changed, 5774 insertions, 872 deletions
diff --git a/2.6.32/0000_README b/2.6.32/0000_README
index 381f8d3..3fdf601 100644
--- a/2.6.32/0000_README
+++ b/2.6.32/0000_README
@@ -38,7 +38,7 @@ Patch: 1060_linux-2.6.32.61.patch
From: http://www.kernel.org
Desc: Linux 2.6.32.61
-Patch: 4420_grsecurity-2.9.1-2.6.32.61-201309281101.patch
+Patch: 4420_grsecurity-2.9.1-2.6.32.61-201310271545.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.61-201309281101.patch b/2.6.32/4420_grsecurity-2.9.1-2.6.32.61-201310271545.patch
index 80f4104..995d206 100644
--- a/2.6.32/4420_grsecurity-2.9.1-2.6.32.61-201309281101.patch
+++ b/2.6.32/4420_grsecurity-2.9.1-2.6.32.61-201310271545.patch
@@ -115800,7 +115800,7 @@ index dba56d2..acee5d6 100644
tmo = req->expires - jiffies;
if (tmo < 0)
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
-index d717267..56de7e7 100644
+index d717267..f9707ae 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -18,12 +18,15 @@
@@ -115819,6 +115819,15 @@ index d717267..56de7e7 100644
/*
* Allocate and initialize a new local port bind bucket.
* The bindhash mutex for snum's hash chain must be held here.
+@@ -247,7 +250,7 @@ begintw:
+ }
+ if (unlikely(!INET_TW_MATCH(sk, net, hash, acookie,
+ saddr, daddr, ports, dif))) {
+- sock_put(sk);
++ inet_twsk_put(inet_twsk(sk));
+ goto begintw;
+ }
+ goto out;
@@ -491,6 +494,8 @@ ok:
}
spin_unlock(&head->lock);
@@ -116814,9 +116823,18 @@ index cc4797d..7cfdfcc 100644
dst_release(dst);
dst = NULL;
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
-index 093e9b2..f72cddb 100644
+index 093e9b2..d6dbc3f 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
+@@ -104,7 +104,7 @@ begintw:
+ goto out;
+ }
+ if (!INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif)) {
+- sock_put(sk);
++ inet_twsk_put(inet_twsk(sk));
+ goto begintw;
+ }
+ goto out;
@@ -119,7 +119,7 @@ out:
}
EXPORT_SYMBOL(__inet6_lookup_established);
diff --git a/3.11.6/0000_README b/3.11.6/0000_README
index 2d9249d..5611acb 100644
--- a/3.11.6/0000_README
+++ b/3.11.6/0000_README
@@ -2,7 +2,7 @@ README
-----------------------------------------------------------------------------
Individual Patch Descriptions:
-----------------------------------------------------------------------------
-Patch: 4420_grsecurity-2.9.1-3.11.6-201310260850.patch
+Patch: 4420_grsecurity-2.9.1-3.11.6-201310271552.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/3.11.6/4420_grsecurity-2.9.1-3.11.6-201310260850.patch b/3.11.6/4420_grsecurity-2.9.1-3.11.6-201310271552.patch
index 584d2ee..e291fc5 100644
--- a/3.11.6/4420_grsecurity-2.9.1-3.11.6-201310260850.patch
+++ b/3.11.6/4420_grsecurity-2.9.1-3.11.6-201310271552.patch
@@ -44037,6 +44037,19 @@ index 4658f4c..407d155 100644
#include "ftmac100.h"
+diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
+index 85fe7b5..e2da180 100644
+--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
++++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
+@@ -2637,6 +2637,8 @@ static int igb_set_eee(struct net_device *netdev,
+ (hw->phy.media_type != e1000_media_type_copper))
+ return -EOPNOTSUPP;
+
++ memset(&eee_curr, 0, sizeof(struct ethtool_eee));
++
+ ret_val = igb_get_eee(netdev, &eee_curr);
+ if (ret_val)
+ return ret_val;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
index 331987d..3be1135 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -44498,6 +44511,18 @@ index 3f0c4f2..bcfff0d 100644
sync.clock_rate = FST_RDL(card, portConfig[i].lineSpeed);
/* Lucky card and linux use same encoding here */
sync.clock_type = FST_RDB(card, portConfig[i].internalClock) ==
+diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c
+index 6a24a5a..4c0a697 100644
+--- a/drivers/net/wan/wanxl.c
++++ b/drivers/net/wan/wanxl.c
+@@ -355,6 +355,7 @@ static int wanxl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+ ifr->ifr_settings.size = size; /* data size wanted */
+ return -ENOBUFS;
+ }
++ memset(&line, 0, sizeof(line));
+ line.clock_type = get_status(port)->clocking;
+ line.clock_rate = 0;
+ line.loopback = 0;
diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c
index 0b60295..b8bfa5b 100644
--- a/drivers/net/wimax/i2400m/rx.c
@@ -54449,6 +54474,19 @@ index c7c83ff..bda9461 100644
parent, NULL, NULL);
}
EXPORT_SYMBOL_GPL(debugfs_create_dir);
+diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
+index d107576..40db688 100644
+--- a/fs/ecryptfs/crypto.c
++++ b/fs/ecryptfs/crypto.c
+@@ -408,7 +408,7 @@ static loff_t lower_offset_for_page(struct ecryptfs_crypt_stat *crypt_stat,
+ struct page *page)
+ {
+ return ecryptfs_lower_header_size(crypt_stat) +
+- (page->index << PAGE_CACHE_SHIFT);
++ ((loff_t)page->index << PAGE_CACHE_SHIFT);
+ }
+
+ /**
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 67e9b63..a9adb68 100644
--- a/fs/ecryptfs/inode.c
@@ -54471,6 +54509,27 @@ index 67e9b63..a9adb68 100644
if (!IS_ERR(buf)) {
/* Free the char* */
kfree(buf);
+diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
+index 7d52806..4725a07 100644
+--- a/fs/ecryptfs/keystore.c
++++ b/fs/ecryptfs/keystore.c
+@@ -1149,7 +1149,7 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
+ struct ecryptfs_msg_ctx *msg_ctx;
+ struct ecryptfs_message *msg = NULL;
+ char *auth_tok_sig;
+- char *payload;
++ char *payload = NULL;
+ size_t payload_len = 0;
+ int rc;
+
+@@ -1203,6 +1203,7 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
+ }
+ out:
+ kfree(msg);
++ kfree(payload);
+ return rc;
+ }
+
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c
index e4141f2..d8263e8 100644
--- a/fs/ecryptfs/miscdev.c
@@ -76402,7 +76461,7 @@ index 429c199..4d42e38 100644
/* shm_mode upper byte flags */
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
-index 3b71a4e..5c9f309 100644
+index 3b71a4e..4823435 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -648,7 +648,7 @@ extern bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
@@ -76441,7 +76500,19 @@ index 3b71a4e..5c9f309 100644
}
/**
-@@ -1750,7 +1750,7 @@ static inline int pskb_network_may_pull(struct sk_buff *skb, unsigned int len)
+@@ -1316,6 +1316,11 @@ static inline int skb_pagelen(const struct sk_buff *skb)
+ return len + skb_headlen(skb);
+ }
+
++static inline bool skb_has_frags(const struct sk_buff *skb)
++{
++ return skb_shinfo(skb)->nr_frags;
++}
++
+ /**
+ * __skb_fill_page_desc - initialise a paged fragment in an skb
+ * @skb: buffer containing fragment to be initialised
+@@ -1750,7 +1755,7 @@ static inline int pskb_network_may_pull(struct sk_buff *skb, unsigned int len)
* NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8)
*/
#ifndef NET_SKB_PAD
@@ -76450,7 +76521,7 @@ index 3b71a4e..5c9f309 100644
#endif
extern int ___pskb_trim(struct sk_buff *skb, unsigned int len);
-@@ -2345,7 +2345,7 @@ extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
+@@ -2345,7 +2350,7 @@ extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
int noblock, int *err);
extern unsigned int datagram_poll(struct file *file, struct socket *sock,
struct poll_table_struct *wait);
@@ -76459,7 +76530,7 @@ index 3b71a4e..5c9f309 100644
int offset, struct iovec *to,
int size);
extern int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
-@@ -2636,6 +2636,9 @@ static inline void nf_reset(struct sk_buff *skb)
+@@ -2636,6 +2641,9 @@ static inline void nf_reset(struct sk_buff *skb)
nf_bridge_put(skb->nf_bridge);
skb->nf_bridge = NULL;
#endif
@@ -88631,30 +88702,10 @@ index 94722a4..e661e29 100644
if (nstart < prev->vm_end)
diff --git a/mm/mremap.c b/mm/mremap.c
-index 0843feb..5607f47 100644
+index 0843feb..4f5b2e6 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
-@@ -25,6 +25,7 @@
- #include <asm/uaccess.h>
- #include <asm/cacheflush.h>
- #include <asm/tlbflush.h>
-+#include <asm/pgalloc.h>
-
- #include "internal.h"
-
-@@ -62,8 +63,10 @@ static pmd_t *alloc_new_pmd(struct mm_struct *mm, struct vm_area_struct *vma,
- return NULL;
-
- pmd = pmd_alloc(mm, pud, addr);
-- if (!pmd)
-+ if (!pmd) {
-+ pud_free(mm, pud);
- return NULL;
-+ }
-
- VM_BUG_ON(pmd_trans_huge(*pmd));
-
-@@ -144,6 +147,12 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
+@@ -144,6 +144,12 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
continue;
pte = ptep_get_and_clear(mm, old_addr, old_pte);
pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
@@ -88667,7 +88718,7 @@ index 0843feb..5607f47 100644
pte = move_soft_dirty_pte(pte);
set_pte_at(mm, new_addr, new_pte, pte);
}
-@@ -337,6 +346,11 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr,
+@@ -337,6 +343,11 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr,
if (is_vm_hugetlb_page(vma))
goto Einval;
@@ -88679,7 +88730,7 @@ index 0843feb..5607f47 100644
/* We can't remap across vm area boundaries */
if (old_len > vma->vm_end - addr)
goto Efault;
-@@ -392,20 +406,25 @@ static unsigned long mremap_to(unsigned long addr, unsigned long old_len,
+@@ -392,20 +403,25 @@ static unsigned long mremap_to(unsigned long addr, unsigned long old_len,
unsigned long ret = -EINVAL;
unsigned long charged = 0;
unsigned long map_flags;
@@ -88710,7 +88761,7 @@ index 0843feb..5607f47 100644
goto out;
ret = do_munmap(mm, new_addr, new_len);
-@@ -474,6 +493,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
+@@ -474,6 +490,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
unsigned long ret = -EINVAL;
unsigned long charged = 0;
bool locked = false;
@@ -88718,7 +88769,7 @@ index 0843feb..5607f47 100644
if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
return ret;
-@@ -495,6 +515,17 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
+@@ -495,6 +512,17 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
if (!new_len)
return ret;
@@ -88736,7 +88787,7 @@ index 0843feb..5607f47 100644
down_write(&current->mm->mmap_sem);
if (flags & MREMAP_FIXED) {
-@@ -545,6 +576,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
+@@ -545,6 +573,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
new_addr = addr;
}
ret = addr;
@@ -88744,7 +88795,7 @@ index 0843feb..5607f47 100644
goto out;
}
}
-@@ -568,7 +600,12 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
+@@ -568,7 +597,12 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
goto out;
}
@@ -91150,23 +91201,25 @@ index eb0a46a..5f3bae8 100644
switch (ss->ss_family) {
diff --git a/net/compat.c b/net/compat.c
-index f0a1ba6..0541331 100644
+index f0a1ba6..24e30e5 100644
--- a/net/compat.c
+++ b/net/compat.c
-@@ -71,9 +71,9 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg)
+@@ -71,9 +71,11 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg)
__get_user(kmsg->msg_controllen, &umsg->msg_controllen) ||
__get_user(kmsg->msg_flags, &umsg->msg_flags))
return -EFAULT;
- kmsg->msg_name = compat_ptr(tmp1);
- kmsg->msg_iov = compat_ptr(tmp2);
- kmsg->msg_control = compat_ptr(tmp3);
++ if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
++ return -EINVAL;
+ kmsg->msg_name = (void __force_kernel *)compat_ptr(tmp1);
+ kmsg->msg_iov = (void __force_kernel *)compat_ptr(tmp2);
+ kmsg->msg_control = (void __force_kernel *)compat_ptr(tmp3);
return 0;
}
-@@ -85,7 +85,7 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
+@@ -85,7 +87,7 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
if (kern_msg->msg_namelen) {
if (mode == VERIFY_READ) {
@@ -91175,7 +91228,7 @@ index f0a1ba6..0541331 100644
kern_msg->msg_namelen,
kern_address);
if (err < 0)
-@@ -96,7 +96,7 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
+@@ -96,7 +98,7 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
kern_msg->msg_name = NULL;
tot_len = iov_from_user_compat_to_kern(kern_iov,
@@ -91184,7 +91237,7 @@ index f0a1ba6..0541331 100644
kern_msg->msg_iovlen);
if (tot_len >= 0)
kern_msg->msg_iov = kern_iov;
-@@ -116,20 +116,20 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
+@@ -116,20 +118,20 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
#define CMSG_COMPAT_FIRSTHDR(msg) \
(((msg)->msg_controllen) >= sizeof(struct compat_cmsghdr) ? \
@@ -91208,7 +91261,7 @@ index f0a1ba6..0541331 100644
msg->msg_controllen)
return NULL;
return (struct compat_cmsghdr __user *)ptr;
-@@ -219,7 +219,7 @@ Efault:
+@@ -219,7 +221,7 @@ Efault:
int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *data)
{
@@ -91217,7 +91270,7 @@ index f0a1ba6..0541331 100644
struct compat_cmsghdr cmhdr;
struct compat_timeval ctv;
struct compat_timespec cts[3];
-@@ -275,7 +275,7 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat
+@@ -275,7 +277,7 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat
void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm)
{
@@ -91226,7 +91279,7 @@ index f0a1ba6..0541331 100644
int fdmax = (kmsg->msg_controllen - sizeof(struct compat_cmsghdr)) / sizeof(int);
int fdnum = scm->fp->count;
struct file **fp = scm->fp->fp;
-@@ -363,7 +363,7 @@ static int do_set_sock_timeout(struct socket *sock, int level,
+@@ -363,7 +365,7 @@ static int do_set_sock_timeout(struct socket *sock, int level,
return -EFAULT;
old_fs = get_fs();
set_fs(KERNEL_DS);
@@ -91235,7 +91288,7 @@ index f0a1ba6..0541331 100644
set_fs(old_fs);
return err;
-@@ -424,7 +424,7 @@ static int do_get_sock_timeout(struct socket *sock, int level, int optname,
+@@ -424,7 +426,7 @@ static int do_get_sock_timeout(struct socket *sock, int level, int optname,
len = sizeof(ktime);
old_fs = get_fs();
set_fs(KERNEL_DS);
@@ -91244,7 +91297,7 @@ index f0a1ba6..0541331 100644
set_fs(old_fs);
if (!err) {
-@@ -567,7 +567,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
+@@ -567,7 +569,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
case MCAST_JOIN_GROUP:
case MCAST_LEAVE_GROUP:
{
@@ -91253,7 +91306,7 @@ index f0a1ba6..0541331 100644
struct group_req __user *kgr =
compat_alloc_user_space(sizeof(struct group_req));
u32 interface;
-@@ -588,7 +588,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
+@@ -588,7 +590,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
case MCAST_BLOCK_SOURCE:
case MCAST_UNBLOCK_SOURCE:
{
@@ -91262,7 +91315,7 @@ index f0a1ba6..0541331 100644
struct group_source_req __user *kgsr = compat_alloc_user_space(
sizeof(struct group_source_req));
u32 interface;
-@@ -609,7 +609,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
+@@ -609,7 +611,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
}
case MCAST_MSFILTER:
{
@@ -91271,7 +91324,7 @@ index f0a1ba6..0541331 100644
struct group_filter __user *kgf;
u32 interface, fmode, numsrc;
-@@ -647,7 +647,7 @@ int compat_mc_getsockopt(struct sock *sock, int level, int optname,
+@@ -647,7 +649,7 @@ int compat_mc_getsockopt(struct sock *sock, int level, int optname,
char __user *optval, int __user *optlen,
int (*getsockopt)(struct sock *, int, int, char __user *, int __user *))
{
@@ -91280,7 +91333,7 @@ index f0a1ba6..0541331 100644
struct group_filter __user *kgf;
int __user *koptlen;
u32 interface, fmode, numsrc;
-@@ -805,7 +805,7 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args)
+@@ -805,7 +807,7 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args)
if (call < SYS_SOCKET || call > SYS_SENDMMSG)
return -EINVAL;
@@ -92084,7 +92137,7 @@ index 6acb541..9ea617d 100644
void inet_get_local_port_range(int *low, int *high)
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
-index 7bd8983..3abdcf6 100644
+index 7bd8983..b956690 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -18,12 +18,15 @@
@@ -92103,6 +92156,15 @@ index 7bd8983..3abdcf6 100644
/*
* Allocate and initialize a new local port bind bucket.
* The bindhash mutex for snum's hash chain must be held here.
+@@ -287,7 +290,7 @@ begintw:
+ if (unlikely(!INET_TW_MATCH(sk, net, acookie,
+ saddr, daddr, ports,
+ dif))) {
+- sock_put(sk);
++ inet_twsk_put(inet_twsk(sk));
+ goto begintw;
+ }
+ goto out;
@@ -554,6 +557,8 @@ ok:
twrefcnt += inet_twsk_bind_unhash(tw, hinfo);
spin_unlock(&head->lock);
@@ -92209,6 +92271,19 @@ index 8d6939e..19d0a95 100644
.kind = "gretap",
.maxtype = IFLA_GRE_MAX,
.policy = ipgre_policy,
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+index a04d872..7f4ab5d 100644
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -836,7 +836,7 @@ static int __ip_append_data(struct sock *sk,
+ csummode = CHECKSUM_PARTIAL;
+
+ cork->length += length;
+- if (((length > mtu) || (skb && skb_is_gso(skb))) &&
++ if (((length > mtu) || (skb && skb_has_frags(skb))) &&
+ (sk->sk_protocol == IPPROTO_UDP) &&
+ (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) {
+ err = ip_ufo_append_data(sk, queue, getfrag, from, length,
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index d9c4f11..02b82dbc 100644
--- a/net/ipv4/ip_sockglue.c
@@ -93213,6 +93288,19 @@ index 7cfc8d2..c5394b6 100644
table = kmemdup(ipv6_icmp_table_template,
sizeof(ipv6_icmp_table_template),
+diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
+index 32b4a16..066640e 100644
+--- a/net/ipv6/inet6_hashtables.c
++++ b/net/ipv6/inet6_hashtables.c
+@@ -116,7 +116,7 @@ begintw:
+ }
+ if (unlikely(!INET6_TW_MATCH(sk, net, saddr, daddr,
+ ports, dif))) {
+- sock_put(sk);
++ inet_twsk_put(inet_twsk(sk));
+ goto begintw;
+ }
+ goto out;
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 8bc717b..76fbb5d 100644
--- a/net/ipv6/ip6_gre.c
@@ -93253,6 +93341,19 @@ index 8bc717b..76fbb5d 100644
.kind = "ip6gretap",
.maxtype = IFLA_GRE_MAX,
.policy = ip6gre_policy,
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index 44df1c9..2e542d0 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -1252,7 +1252,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
+ skb = skb_peek_tail(&sk->sk_write_queue);
+ cork->length += length;
+ if (((length > mtu) ||
+- (skb && skb_is_gso(skb))) &&
++ (skb && skb_has_frags(skb))) &&
+ (sk->sk_protocol == IPPROTO_UDP) &&
+ (rt->dst.dev->features & NETIF_F_UFO)) {
+ err = ip6_ufo_append_data(sk, getfrag, from, length,
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index cf5d490..30946f0 100644
--- a/net/ipv6/ip6_tunnel.c
@@ -95644,7 +95745,7 @@ index 9a5c4c9..46e4b29 100644
table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
diff --git a/net/socket.c b/net/socket.c
-index b2d7c62..441a7ef 100644
+index b2d7c62..f703b02 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -88,6 +88,7 @@
@@ -95828,7 +95929,38 @@ index b2d7c62..441a7ef 100644
int err, err2;
int fput_needed;
-@@ -2040,7 +2106,7 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
+@@ -1973,6 +2039,16 @@ struct used_address {
+ unsigned int name_len;
+ };
+
++static int copy_msghdr_from_user(struct msghdr *kmsg,
++ struct msghdr __user *umsg)
++{
++ if (copy_from_user(kmsg, umsg, sizeof(struct msghdr)))
++ return -EFAULT;
++ if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
++ return -EINVAL;
++ return 0;
++}
++
+ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
+ struct msghdr *msg_sys, unsigned int flags,
+ struct used_address *used_address)
+@@ -1991,8 +2067,11 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
+ if (MSG_CMSG_COMPAT & flags) {
+ if (get_compat_msghdr(msg_sys, msg_compat))
+ return -EFAULT;
+- } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr)))
+- return -EFAULT;
++ } else {
++ err = copy_msghdr_from_user(msg_sys, msg);
++ if (err)
++ return err;
++ }
+
+ if (msg_sys->msg_iovlen > UIO_FASTIOV) {
+ err = -EMSGSIZE;
+@@ -2040,7 +2119,7 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
* checking falls down on this.
*/
if (copy_from_user(ctl_buf,
@@ -95837,7 +95969,7 @@ index b2d7c62..441a7ef 100644
ctl_len))
goto out_freectl;
msg_sys->msg_control = ctl_buf;
-@@ -2191,7 +2257,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
+@@ -2191,7 +2270,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
int err, total_len, len;
/* kernel mode address */
@@ -95846,7 +95978,21 @@ index b2d7c62..441a7ef 100644
/* user mode address pointers */
struct sockaddr __user *uaddr;
-@@ -2219,7 +2285,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
+@@ -2200,8 +2279,11 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
+ if (MSG_CMSG_COMPAT & flags) {
+ if (get_compat_msghdr(msg_sys, msg_compat))
+ return -EFAULT;
+- } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr)))
+- return -EFAULT;
++ } else {
++ err = copy_msghdr_from_user(msg_sys, msg);
++ if (err)
++ return err;
++ }
+
+ if (msg_sys->msg_iovlen > UIO_FASTIOV) {
+ err = -EMSGSIZE;
+@@ -2219,7 +2301,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
* kernel msghdr to use the kernel address space)
*/
@@ -95855,7 +96001,7 @@ index b2d7c62..441a7ef 100644
uaddr_len = COMPAT_NAMELEN(msg);
if (MSG_CMSG_COMPAT & flags) {
err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
-@@ -2974,7 +3040,7 @@ static int bond_ioctl(struct net *net, unsigned int cmd,
+@@ -2974,7 +3056,7 @@ static int bond_ioctl(struct net *net, unsigned int cmd,
old_fs = get_fs();
set_fs(KERNEL_DS);
err = dev_ioctl(net, cmd,
@@ -95864,7 +96010,7 @@ index b2d7c62..441a7ef 100644
set_fs(old_fs);
return err;
-@@ -3083,7 +3149,7 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
+@@ -3083,7 +3165,7 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
old_fs = get_fs();
set_fs(KERNEL_DS);
@@ -95873,7 +96019,7 @@ index b2d7c62..441a7ef 100644
set_fs(old_fs);
if (cmd == SIOCGIFMAP && !err) {
-@@ -3188,7 +3254,7 @@ static int routing_ioctl(struct net *net, struct socket *sock,
+@@ -3188,7 +3270,7 @@ static int routing_ioctl(struct net *net, struct socket *sock,
ret |= __get_user(rtdev, &(ur4->rt_dev));
if (rtdev) {
ret |= copy_from_user(devname, compat_ptr(rtdev), 15);
@@ -95882,7 +96028,7 @@ index b2d7c62..441a7ef 100644
devname[15] = 0;
} else
r4.rt_dev = NULL;
-@@ -3414,8 +3480,8 @@ int kernel_getsockopt(struct socket *sock, int level, int optname,
+@@ -3414,8 +3496,8 @@ int kernel_getsockopt(struct socket *sock, int level, int optname,
int __user *uoptlen;
int err;
@@ -95893,7 +96039,7 @@ index b2d7c62..441a7ef 100644
set_fs(KERNEL_DS);
if (level == SOL_SOCKET)
-@@ -3435,7 +3501,7 @@ int kernel_setsockopt(struct socket *sock, int level, int optname,
+@@ -3435,7 +3517,7 @@ int kernel_setsockopt(struct socket *sock, int level, int optname,
char __user *uoptval;
int err;
diff --git a/3.2.51/0000_README b/3.2.52/0000_README
index 8ba65d1..ec68a31 100644
--- a/3.2.51/0000_README
+++ b/3.2.52/0000_README
@@ -122,7 +122,11 @@ Patch: 1050_linux-3.2.51.patch
From: http://www.kernel.org
Desc: Linux 3.2.51
-Patch: 4420_grsecurity-2.9.1-3.2.51-201310260849.patch
+Patch: 1051_linux-3.2.52.patch
+From: http://www.kernel.org
+Desc: Linux 3.2.52
+
+Patch: 4420_grsecurity-2.9.1-3.2.52-201310271550.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/3.2.51/1021_linux-3.2.22.patch b/3.2.52/1021_linux-3.2.22.patch
index e6ad93a..e6ad93a 100644
--- a/3.2.51/1021_linux-3.2.22.patch
+++ b/3.2.52/1021_linux-3.2.22.patch
diff --git a/3.2.51/1022_linux-3.2.23.patch b/3.2.52/1022_linux-3.2.23.patch
index 3d796d0..3d796d0 100644
--- a/3.2.51/1022_linux-3.2.23.patch
+++ b/3.2.52/1022_linux-3.2.23.patch
diff --git a/3.2.51/1023_linux-3.2.24.patch b/3.2.52/1023_linux-3.2.24.patch
index 4692eb4..4692eb4 100644
--- a/3.2.51/1023_linux-3.2.24.patch
+++ b/3.2.52/1023_linux-3.2.24.patch
diff --git a/3.2.51/1024_linux-3.2.25.patch b/3.2.52/1024_linux-3.2.25.patch
index e95c213..e95c213 100644
--- a/3.2.51/1024_linux-3.2.25.patch
+++ b/3.2.52/1024_linux-3.2.25.patch
diff --git a/3.2.51/1025_linux-3.2.26.patch b/3.2.52/1025_linux-3.2.26.patch
index 44065b9..44065b9 100644
--- a/3.2.51/1025_linux-3.2.26.patch
+++ b/3.2.52/1025_linux-3.2.26.patch
diff --git a/3.2.51/1026_linux-3.2.27.patch b/3.2.52/1026_linux-3.2.27.patch
index 5878eb4..5878eb4 100644
--- a/3.2.51/1026_linux-3.2.27.patch
+++ b/3.2.52/1026_linux-3.2.27.patch
diff --git a/3.2.51/1027_linux-3.2.28.patch b/3.2.52/1027_linux-3.2.28.patch
index 4dbba4b..4dbba4b 100644
--- a/3.2.51/1027_linux-3.2.28.patch
+++ b/3.2.52/1027_linux-3.2.28.patch
diff --git a/3.2.51/1028_linux-3.2.29.patch b/3.2.52/1028_linux-3.2.29.patch
index 3c65179..3c65179 100644
--- a/3.2.51/1028_linux-3.2.29.patch
+++ b/3.2.52/1028_linux-3.2.29.patch
diff --git a/3.2.51/1029_linux-3.2.30.patch b/3.2.52/1029_linux-3.2.30.patch
index 86aea4b..86aea4b 100644
--- a/3.2.51/1029_linux-3.2.30.patch
+++ b/3.2.52/1029_linux-3.2.30.patch
diff --git a/3.2.51/1030_linux-3.2.31.patch b/3.2.52/1030_linux-3.2.31.patch
index c6accf5..c6accf5 100644
--- a/3.2.51/1030_linux-3.2.31.patch
+++ b/3.2.52/1030_linux-3.2.31.patch
diff --git a/3.2.51/1031_linux-3.2.32.patch b/3.2.52/1031_linux-3.2.32.patch
index 247fc0b..247fc0b 100644
--- a/3.2.51/1031_linux-3.2.32.patch
+++ b/3.2.52/1031_linux-3.2.32.patch
diff --git a/3.2.51/1032_linux-3.2.33.patch b/3.2.52/1032_linux-3.2.33.patch
index c32fb75..c32fb75 100644
--- a/3.2.51/1032_linux-3.2.33.patch
+++ b/3.2.52/1032_linux-3.2.33.patch
diff --git a/3.2.51/1033_linux-3.2.34.patch b/3.2.52/1033_linux-3.2.34.patch
index d647b38..d647b38 100644
--- a/3.2.51/1033_linux-3.2.34.patch
+++ b/3.2.52/1033_linux-3.2.34.patch
diff --git a/3.2.51/1034_linux-3.2.35.patch b/3.2.52/1034_linux-3.2.35.patch
index 76a9c19..76a9c19 100644
--- a/3.2.51/1034_linux-3.2.35.patch
+++ b/3.2.52/1034_linux-3.2.35.patch
diff --git a/3.2.51/1035_linux-3.2.36.patch b/3.2.52/1035_linux-3.2.36.patch
index 5d192a3..5d192a3 100644
--- a/3.2.51/1035_linux-3.2.36.patch
+++ b/3.2.52/1035_linux-3.2.36.patch
diff --git a/3.2.51/1036_linux-3.2.37.patch b/3.2.52/1036_linux-3.2.37.patch
index ad13251..ad13251 100644
--- a/3.2.51/1036_linux-3.2.37.patch
+++ b/3.2.52/1036_linux-3.2.37.patch
diff --git a/3.2.51/1037_linux-3.2.38.patch b/3.2.52/1037_linux-3.2.38.patch
index a3c106f..a3c106f 100644
--- a/3.2.51/1037_linux-3.2.38.patch
+++ b/3.2.52/1037_linux-3.2.38.patch
diff --git a/3.2.51/1038_linux-3.2.39.patch b/3.2.52/1038_linux-3.2.39.patch
index 5639e92..5639e92 100644
--- a/3.2.51/1038_linux-3.2.39.patch
+++ b/3.2.52/1038_linux-3.2.39.patch
diff --git a/3.2.51/1039_linux-3.2.40.patch b/3.2.52/1039_linux-3.2.40.patch
index f26b39c..f26b39c 100644
--- a/3.2.51/1039_linux-3.2.40.patch
+++ b/3.2.52/1039_linux-3.2.40.patch
diff --git a/3.2.51/1040_linux-3.2.41.patch b/3.2.52/1040_linux-3.2.41.patch
index 0d27fcb..0d27fcb 100644
--- a/3.2.51/1040_linux-3.2.41.patch
+++ b/3.2.52/1040_linux-3.2.41.patch
diff --git a/3.2.51/1041_linux-3.2.42.patch b/3.2.52/1041_linux-3.2.42.patch
index 77a08ed..77a08ed 100644
--- a/3.2.51/1041_linux-3.2.42.patch
+++ b/3.2.52/1041_linux-3.2.42.patch
diff --git a/3.2.51/1042_linux-3.2.43.patch b/3.2.52/1042_linux-3.2.43.patch
index a3f878b..a3f878b 100644
--- a/3.2.51/1042_linux-3.2.43.patch
+++ b/3.2.52/1042_linux-3.2.43.patch
diff --git a/3.2.51/1043_linux-3.2.44.patch b/3.2.52/1043_linux-3.2.44.patch
index 3d5e6ff..3d5e6ff 100644
--- a/3.2.51/1043_linux-3.2.44.patch
+++ b/3.2.52/1043_linux-3.2.44.patch
diff --git a/3.2.51/1044_linux-3.2.45.patch b/3.2.52/1044_linux-3.2.45.patch
index 44e1767..44e1767 100644
--- a/3.2.51/1044_linux-3.2.45.patch
+++ b/3.2.52/1044_linux-3.2.45.patch
diff --git a/3.2.51/1045_linux-3.2.46.patch b/3.2.52/1045_linux-3.2.46.patch
index bc10efd..bc10efd 100644
--- a/3.2.51/1045_linux-3.2.46.patch
+++ b/3.2.52/1045_linux-3.2.46.patch
diff --git a/3.2.51/1046_linux-3.2.47.patch b/3.2.52/1046_linux-3.2.47.patch
index b74563c..b74563c 100644
--- a/3.2.51/1046_linux-3.2.47.patch
+++ b/3.2.52/1046_linux-3.2.47.patch
diff --git a/3.2.51/1047_linux-3.2.48.patch b/3.2.52/1047_linux-3.2.48.patch
index 6d55b1f..6d55b1f 100644
--- a/3.2.51/1047_linux-3.2.48.patch
+++ b/3.2.52/1047_linux-3.2.48.patch
diff --git a/3.2.51/1048_linux-3.2.49.patch b/3.2.52/1048_linux-3.2.49.patch
index 2dab0cf..2dab0cf 100644
--- a/3.2.51/1048_linux-3.2.49.patch
+++ b/3.2.52/1048_linux-3.2.49.patch
diff --git a/3.2.51/1049_linux-3.2.50.patch b/3.2.52/1049_linux-3.2.50.patch
index 20b3015..20b3015 100644
--- a/3.2.51/1049_linux-3.2.50.patch
+++ b/3.2.52/1049_linux-3.2.50.patch
diff --git a/3.2.51/1050_linux-3.2.51.patch b/3.2.52/1050_linux-3.2.51.patch
index 5d5832b..5d5832b 100644
--- a/3.2.51/1050_linux-3.2.51.patch
+++ b/3.2.52/1050_linux-3.2.51.patch
diff --git a/3.2.52/1051_linux-3.2.52.patch b/3.2.52/1051_linux-3.2.52.patch
new file mode 100644
index 0000000..94b9359
--- /dev/null
+++ b/3.2.52/1051_linux-3.2.52.patch
@@ -0,0 +1,5221 @@
+diff --git a/Makefile b/Makefile
+index 0f11936..1dd2c09 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 3
+ PATCHLEVEL = 2
+-SUBLEVEL = 51
++SUBLEVEL = 52
+ EXTRAVERSION =
+ NAME = Saber-toothed Squirrel
+
+diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c
+index c898deb..189ed00 100644
+--- a/arch/arm/mach-versatile/pci.c
++++ b/arch/arm/mach-versatile/pci.c
+@@ -43,9 +43,9 @@
+ #define PCI_IMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0)
+ #define PCI_IMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4)
+ #define PCI_IMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8)
+-#define PCI_SMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x10)
+-#define PCI_SMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14)
+-#define PCI_SMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18)
++#define PCI_SMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14)
++#define PCI_SMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18)
++#define PCI_SMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x1c)
+ #define PCI_SELFID __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc)
+
+ #define DEVICE_ID_OFFSET 0x00
+diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
+index fbdd12e..cc3f35d 100644
+--- a/arch/arm/mm/init.c
++++ b/arch/arm/mm/init.c
+@@ -98,6 +98,9 @@ void show_mem(unsigned int filter)
+ printk("Mem-info:\n");
+ show_free_areas(filter);
+
++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT)
++ return;
++
+ for_each_bank (i, mi) {
+ struct membank *bank = &mi->bank[i];
+ unsigned int pfn1, pfn2;
+diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
+index f114a3b..ce6e7a8 100644
+--- a/arch/ia64/mm/contig.c
++++ b/arch/ia64/mm/contig.c
+@@ -46,6 +46,8 @@ void show_mem(unsigned int filter)
+ printk(KERN_INFO "Mem-info:\n");
+ show_free_areas(filter);
+ printk(KERN_INFO "Node memory in pages:\n");
++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT)
++ return;
+ for_each_online_pgdat(pgdat) {
+ unsigned long present;
+ unsigned long flags;
+diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
+index c641333..2230817 100644
+--- a/arch/ia64/mm/discontig.c
++++ b/arch/ia64/mm/discontig.c
+@@ -623,6 +623,8 @@ void show_mem(unsigned int filter)
+
+ printk(KERN_INFO "Mem-info:\n");
+ show_free_areas(filter);
++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT)
++ return;
+ printk(KERN_INFO "Node memory in pages:\n");
+ for_each_online_pgdat(pgdat) {
+ unsigned long present;
+diff --git a/arch/m68k/kernel/vmlinux-nommu.lds b/arch/m68k/kernel/vmlinux-nommu.lds
+new file mode 100644
+index 0000000..40e02d9
+--- /dev/null
++++ b/arch/m68k/kernel/vmlinux-nommu.lds
+@@ -0,0 +1,93 @@
++/*
++ * vmlinux.lds.S -- master linker script for m68knommu arch
++ *
++ * (C) Copyright 2002-2012, Greg Ungerer <gerg@snapgear.com>
++ *
++ * This linker script is equipped to build either ROM loaded or RAM
++ * run kernels.
++ */
++
++#if defined(CONFIG_RAMKERNEL)
++#define KTEXT_ADDR CONFIG_KERNELBASE
++#endif
++#if defined(CONFIG_ROMKERNEL)
++#define KTEXT_ADDR CONFIG_ROMSTART
++#define KDATA_ADDR CONFIG_KERNELBASE
++#define LOAD_OFFSET KDATA_ADDR + (ADDR(.text) + SIZEOF(.text))
++#endif
++
++#include <asm/page.h>
++#include <asm/thread_info.h>
++#include <asm-generic/vmlinux.lds.h>
++
++OUTPUT_ARCH(m68k)
++ENTRY(_start)
++
++jiffies = jiffies_64 + 4;
++
++SECTIONS {
++
++#ifdef CONFIG_ROMVEC
++ . = CONFIG_ROMVEC;
++ .romvec : {
++ __rom_start = .;
++ _romvec = .;
++ *(.romvec)
++ *(.data..initvect)
++ }
++#endif
++
++ . = KTEXT_ADDR;
++
++ _text = .;
++ _stext = .;
++ .text : {
++ HEAD_TEXT
++ TEXT_TEXT
++ SCHED_TEXT
++ LOCK_TEXT
++ *(.fixup)
++ . = ALIGN(16);
++ }
++ _etext = .;
++
++#ifdef KDATA_ADDR
++ . = KDATA_ADDR;
++#endif
++
++ _sdata = .;
++ RO_DATA_SECTION(PAGE_SIZE)
++ RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE)
++ _edata = .;
++
++ EXCEPTION_TABLE(16)
++ NOTES
++
++ . = ALIGN(PAGE_SIZE);
++ __init_begin = .;
++ INIT_TEXT_SECTION(PAGE_SIZE)
++ INIT_DATA_SECTION(16)
++ PERCPU_SECTION(16)
++ .m68k_fixup : {
++ __start_fixup = .;
++ *(.m68k_fixup)
++ __stop_fixup = .;
++ }
++ .init.data : {
++ . = ALIGN(PAGE_SIZE);
++ __init_end = .;
++ }
++
++ _sbss = .;
++ BSS_SECTION(0, 0, 0)
++ _ebss = .;
++
++ _end = .;
++
++ STABS_DEBUG
++ .comment 0 : { *(.comment) }
++
++ /* Sections to be discarded */
++ DISCARDS
++}
++
+diff --git a/arch/m68k/kernel/vmlinux.lds.S b/arch/m68k/kernel/vmlinux.lds.S
+index 030dabf..69ec796 100644
+--- a/arch/m68k/kernel/vmlinux.lds.S
++++ b/arch/m68k/kernel/vmlinux.lds.S
+@@ -1,5 +1,14 @@
+-#ifdef CONFIG_MMU
+-#include "vmlinux.lds_mm.S"
++#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE)
++PHDRS
++{
++ text PT_LOAD FILEHDR PHDRS FLAGS (7);
++ data PT_LOAD FLAGS (7);
++}
++#ifdef CONFIG_SUN3
++#include "vmlinux-sun3.lds"
+ #else
+-#include "vmlinux.lds_no.S"
++#include "vmlinux-std.lds"
++#endif
++#else
++#include "vmlinux-nommu.lds"
+ #endif
+diff --git a/arch/m68k/kernel/vmlinux.lds_mm.S b/arch/m68k/kernel/vmlinux.lds_mm.S
+deleted file mode 100644
+index 99ba315..0000000
+--- a/arch/m68k/kernel/vmlinux.lds_mm.S
++++ /dev/null
+@@ -1,10 +0,0 @@
+-PHDRS
+-{
+- text PT_LOAD FILEHDR PHDRS FLAGS (7);
+- data PT_LOAD FLAGS (7);
+-}
+-#ifdef CONFIG_SUN3
+-#include "vmlinux-sun3.lds"
+-#else
+-#include "vmlinux-std.lds"
+-#endif
+diff --git a/arch/m68k/kernel/vmlinux.lds_no.S b/arch/m68k/kernel/vmlinux.lds_no.S
+deleted file mode 100644
+index 4e23893..0000000
+--- a/arch/m68k/kernel/vmlinux.lds_no.S
++++ /dev/null
+@@ -1,187 +0,0 @@
+-/*
+- * vmlinux.lds.S -- master linker script for m68knommu arch
+- *
+- * (C) Copyright 2002-2006, Greg Ungerer <gerg@snapgear.com>
+- *
+- * This linker script is equipped to build either ROM loaded or RAM
+- * run kernels.
+- */
+-
+-#include <asm-generic/vmlinux.lds.h>
+-#include <asm/page.h>
+-#include <asm/thread_info.h>
+-
+-#if defined(CONFIG_RAMKERNEL)
+-#define RAM_START CONFIG_KERNELBASE
+-#define RAM_LENGTH (CONFIG_RAMBASE + CONFIG_RAMSIZE - CONFIG_KERNELBASE)
+-#define TEXT ram
+-#define DATA ram
+-#define INIT ram
+-#define BSSS ram
+-#endif
+-#if defined(CONFIG_ROMKERNEL) || defined(CONFIG_HIMEMKERNEL)
+-#define RAM_START CONFIG_RAMBASE
+-#define RAM_LENGTH CONFIG_RAMSIZE
+-#define ROMVEC_START CONFIG_ROMVEC
+-#define ROMVEC_LENGTH CONFIG_ROMVECSIZE
+-#define ROM_START CONFIG_ROMSTART
+-#define ROM_LENGTH CONFIG_ROMSIZE
+-#define TEXT rom
+-#define DATA ram
+-#define INIT ram
+-#define BSSS ram
+-#endif
+-
+-#ifndef DATA_ADDR
+-#define DATA_ADDR
+-#endif
+-
+-
+-OUTPUT_ARCH(m68k)
+-ENTRY(_start)
+-
+-MEMORY {
+- ram : ORIGIN = RAM_START, LENGTH = RAM_LENGTH
+-#ifdef ROM_START
+- romvec : ORIGIN = ROMVEC_START, LENGTH = ROMVEC_LENGTH
+- rom : ORIGIN = ROM_START, LENGTH = ROM_LENGTH
+-#endif
+-}
+-
+-jiffies = jiffies_64 + 4;
+-
+-SECTIONS {
+-
+-#ifdef ROMVEC_START
+- . = ROMVEC_START ;
+- .romvec : {
+- __rom_start = . ;
+- _romvec = .;
+- *(.data..initvect)
+- } > romvec
+-#endif
+-
+- .text : {
+- _text = .;
+- _stext = . ;
+- HEAD_TEXT
+- TEXT_TEXT
+- SCHED_TEXT
+- LOCK_TEXT
+- *(.text..lock)
+-
+- . = ALIGN(16); /* Exception table */
+- __start___ex_table = .;
+- *(__ex_table)
+- __stop___ex_table = .;
+-
+- *(.rodata) *(.rodata.*)
+- *(__vermagic) /* Kernel version magic */
+- *(.rodata1)
+- *(.rodata.str1.1)
+-
+- /* Kernel symbol table: Normal symbols */
+- . = ALIGN(4);
+- __start___ksymtab = .;
+- *(SORT(___ksymtab+*))
+- __stop___ksymtab = .;
+-
+- /* Kernel symbol table: GPL-only symbols */
+- __start___ksymtab_gpl = .;
+- *(SORT(___ksymtab_gpl+*))
+- __stop___ksymtab_gpl = .;
+-
+- /* Kernel symbol table: Normal unused symbols */
+- __start___ksymtab_unused = .;
+- *(SORT(___ksymtab_unused+*))
+- __stop___ksymtab_unused = .;
+-
+- /* Kernel symbol table: GPL-only unused symbols */
+- __start___ksymtab_unused_gpl = .;
+- *(SORT(___ksymtab_unused_gpl+*))
+- __stop___ksymtab_unused_gpl = .;
+-
+- /* Kernel symbol table: GPL-future symbols */
+- __start___ksymtab_gpl_future = .;
+- *(SORT(___ksymtab_gpl_future+*))
+- __stop___ksymtab_gpl_future = .;
+-
+- /* Kernel symbol table: Normal symbols */
+- __start___kcrctab = .;
+- *(SORT(___kcrctab+*))
+- __stop___kcrctab = .;
+-
+- /* Kernel symbol table: GPL-only symbols */
+- __start___kcrctab_gpl = .;
+- *(SORT(___kcrctab_gpl+*))
+- __stop___kcrctab_gpl = .;
+-
+- /* Kernel symbol table: Normal unused symbols */
+- __start___kcrctab_unused = .;
+- *(SORT(___kcrctab_unused+*))
+- __stop___kcrctab_unused = .;
+-
+- /* Kernel symbol table: GPL-only unused symbols */
+- __start___kcrctab_unused_gpl = .;
+- *(SORT(___kcrctab_unused_gpl+*))
+- __stop___kcrctab_unused_gpl = .;
+-
+- /* Kernel symbol table: GPL-future symbols */
+- __start___kcrctab_gpl_future = .;
+- *(SORT(___kcrctab_gpl_future+*))
+- __stop___kcrctab_gpl_future = .;
+-
+- /* Kernel symbol table: strings */
+- *(__ksymtab_strings)
+-
+- /* Built-in module parameters */
+- . = ALIGN(4) ;
+- __start___param = .;
+- *(__param)
+- __stop___param = .;
+-
+- /* Built-in module versions */
+- . = ALIGN(4) ;
+- __start___modver = .;
+- *(__modver)
+- __stop___modver = .;
+-
+- . = ALIGN(4) ;
+- _etext = . ;
+- } > TEXT
+-
+- .data DATA_ADDR : {
+- . = ALIGN(4);
+- _sdata = . ;
+- DATA_DATA
+- CACHELINE_ALIGNED_DATA(32)
+- PAGE_ALIGNED_DATA(PAGE_SIZE)
+- *(.data..shared_aligned)
+- INIT_TASK_DATA(THREAD_SIZE)
+- _edata = . ;
+- } > DATA
+-
+- .init.text : {
+- . = ALIGN(PAGE_SIZE);
+- __init_begin = .;
+- } > INIT
+- INIT_TEXT_SECTION(PAGE_SIZE) > INIT
+- INIT_DATA_SECTION(16) > INIT
+- .init.data : {
+- . = ALIGN(PAGE_SIZE);
+- __init_end = .;
+- } > INIT
+-
+- .bss : {
+- . = ALIGN(4);
+- _sbss = . ;
+- *(.bss)
+- *(COMMON)
+- . = ALIGN(4) ;
+- _ebss = . ;
+- _end = . ;
+- } > BSSS
+-
+- DISCARDS
+-}
+-
+diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
+index 82f364e..0b62162 100644
+--- a/arch/parisc/mm/init.c
++++ b/arch/parisc/mm/init.c
+@@ -685,6 +685,8 @@ void show_mem(unsigned int filter)
+
+ printk(KERN_INFO "Mem-info:\n");
+ show_free_areas(filter);
++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT)
++ return;
+ #ifndef CONFIG_DISCONTIGMEM
+ i = max_mapnr;
+ while (i-- > 0) {
+diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
+index 8184ee9..3fcbae0 100644
+--- a/arch/powerpc/kernel/align.c
++++ b/arch/powerpc/kernel/align.c
+@@ -764,6 +764,16 @@ int fix_alignment(struct pt_regs *regs)
+ nb = aligninfo[instr].len;
+ flags = aligninfo[instr].flags;
+
++ /* ldbrx/stdbrx overlap lfs/stfs in the DSISR unfortunately */
++ if (IS_XFORM(instruction) && ((instruction >> 1) & 0x3ff) == 532) {
++ nb = 8;
++ flags = LD+SW;
++ } else if (IS_XFORM(instruction) &&
++ ((instruction >> 1) & 0x3ff) == 660) {
++ nb = 8;
++ flags = ST+SW;
++ }
++
+ /* Byteswap little endian loads and stores */
+ swiz = 0;
+ if (regs->msr & MSR_LE) {
+diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
+index 0cfcf98..d0b205c 100644
+--- a/arch/powerpc/kernel/iommu.c
++++ b/arch/powerpc/kernel/iommu.c
+@@ -495,7 +495,7 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
+ /* number of bytes needed for the bitmap */
+ sz = (tbl->it_size + 7) >> 3;
+
+- page = alloc_pages_node(nid, GFP_ATOMIC, get_order(sz));
++ page = alloc_pages_node(nid, GFP_KERNEL, get_order(sz));
+ if (!page)
+ panic("iommu_init_table: Can't allocate %ld bytes\n", sz);
+ tbl->it_map = page_address(page);
+diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
+index 826681d..26af24b 100644
+--- a/arch/powerpc/kernel/lparcfg.c
++++ b/arch/powerpc/kernel/lparcfg.c
+@@ -375,6 +375,7 @@ static void parse_system_parameter_string(struct seq_file *m)
+ __pa(rtas_data_buf),
+ RTAS_DATA_BUF_SIZE);
+ memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH);
++ local_buffer[SPLPAR_MAXLENGTH - 1] = '\0';
+ spin_unlock(&rtas_data_buf_lock);
+
+ if (call_status != 0) {
+diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
+index 55be64d..ca683a1 100644
+--- a/arch/powerpc/kernel/sysfs.c
++++ b/arch/powerpc/kernel/sysfs.c
+@@ -18,6 +18,7 @@
+ #include <asm/machdep.h>
+ #include <asm/smp.h>
+ #include <asm/pmc.h>
++#include <asm/firmware.h>
+
+ #include "cacheinfo.h"
+
+@@ -178,14 +179,24 @@ SYSFS_PMCSETUP(purr, SPRN_PURR);
+ SYSFS_PMCSETUP(spurr, SPRN_SPURR);
+ SYSFS_PMCSETUP(dscr, SPRN_DSCR);
+
++/*
++ Lets only enable read for phyp resources and
++ enable write when needed with a separate function.
++ Lets be conservative and default to pseries.
++*/
+ static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra);
+ static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL);
+ static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr);
+-static SYSDEV_ATTR(purr, 0600, show_purr, store_purr);
++static SYSDEV_ATTR(purr, 0400, show_purr, store_purr);
+
+ unsigned long dscr_default = 0;
+ EXPORT_SYMBOL(dscr_default);
+
++static void add_write_permission_dev_attr(struct sysdev_attribute *attr)
++{
++ attr->attr.mode |= 0200;
++}
++
+ static ssize_t show_dscr_default(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr, char *buf)
+ {
+@@ -394,8 +405,11 @@ static void __cpuinit register_cpu_online(unsigned int cpu)
+ if (cpu_has_feature(CPU_FTR_MMCRA))
+ sysdev_create_file(s, &attr_mmcra);
+
+- if (cpu_has_feature(CPU_FTR_PURR))
++ if (cpu_has_feature(CPU_FTR_PURR)) {
++ if (!firmware_has_feature(FW_FEATURE_LPAR))
++ add_write_permission_dev_attr(&attr_purr);
+ sysdev_create_file(s, &attr_purr);
++ }
+
+ if (cpu_has_feature(CPU_FTR_SPURR))
+ sysdev_create_file(s, &attr_spurr);
+diff --git a/arch/powerpc/lib/checksum_64.S b/arch/powerpc/lib/checksum_64.S
+index 18245af..3cdbc64 100644
+--- a/arch/powerpc/lib/checksum_64.S
++++ b/arch/powerpc/lib/checksum_64.S
+@@ -229,19 +229,35 @@ _GLOBAL(csum_partial)
+ blr
+
+
+- .macro source
++ .macro srcnr
+ 100:
+ .section __ex_table,"a"
+ .align 3
+- .llong 100b,.Lsrc_error
++ .llong 100b,.Lsrc_error_nr
+ .previous
+ .endm
+
+- .macro dest
++ .macro source
++150:
++ .section __ex_table,"a"
++ .align 3
++ .llong 150b,.Lsrc_error
++ .previous
++ .endm
++
++ .macro dstnr
+ 200:
+ .section __ex_table,"a"
+ .align 3
+- .llong 200b,.Ldest_error
++ .llong 200b,.Ldest_error_nr
++ .previous
++ .endm
++
++ .macro dest
++250:
++ .section __ex_table,"a"
++ .align 3
++ .llong 250b,.Ldest_error
+ .previous
+ .endm
+
+@@ -272,16 +288,16 @@ _GLOBAL(csum_partial_copy_generic)
+ rldicl. r6,r3,64-1,64-2 /* r6 = (r3 & 0x3) >> 1 */
+ beq .Lcopy_aligned
+
+- li r7,4
+- sub r6,r7,r6
++ li r9,4
++ sub r6,r9,r6
+ mtctr r6
+
+ 1:
+-source; lhz r6,0(r3) /* align to doubleword */
++srcnr; lhz r6,0(r3) /* align to doubleword */
+ subi r5,r5,2
+ addi r3,r3,2
+ adde r0,r0,r6
+-dest; sth r6,0(r4)
++dstnr; sth r6,0(r4)
+ addi r4,r4,2
+ bdnz 1b
+
+@@ -395,10 +411,10 @@ dest; std r16,56(r4)
+
+ mtctr r6
+ 3:
+-source; ld r6,0(r3)
++srcnr; ld r6,0(r3)
+ addi r3,r3,8
+ adde r0,r0,r6
+-dest; std r6,0(r4)
++dstnr; std r6,0(r4)
+ addi r4,r4,8
+ bdnz 3b
+
+@@ -408,10 +424,10 @@ dest; std r6,0(r4)
+ srdi. r6,r5,2
+ beq .Lcopy_tail_halfword
+
+-source; lwz r6,0(r3)
++srcnr; lwz r6,0(r3)
+ addi r3,r3,4
+ adde r0,r0,r6
+-dest; stw r6,0(r4)
++dstnr; stw r6,0(r4)
+ addi r4,r4,4
+ subi r5,r5,4
+
+@@ -419,10 +435,10 @@ dest; stw r6,0(r4)
+ srdi. r6,r5,1
+ beq .Lcopy_tail_byte
+
+-source; lhz r6,0(r3)
++srcnr; lhz r6,0(r3)
+ addi r3,r3,2
+ adde r0,r0,r6
+-dest; sth r6,0(r4)
++dstnr; sth r6,0(r4)
+ addi r4,r4,2
+ subi r5,r5,2
+
+@@ -430,10 +446,10 @@ dest; sth r6,0(r4)
+ andi. r6,r5,1
+ beq .Lcopy_finish
+
+-source; lbz r6,0(r3)
++srcnr; lbz r6,0(r3)
+ sldi r9,r6,8 /* Pad the byte out to 16 bits */
+ adde r0,r0,r9
+-dest; stb r6,0(r4)
++dstnr; stb r6,0(r4)
+
+ .Lcopy_finish:
+ addze r0,r0 /* add in final carry */
+@@ -443,6 +459,11 @@ dest; stb r6,0(r4)
+ blr
+
+ .Lsrc_error:
++ ld r14,STK_REG(r14)(r1)
++ ld r15,STK_REG(r15)(r1)
++ ld r16,STK_REG(r16)(r1)
++ addi r1,r1,STACKFRAMESIZE
++.Lsrc_error_nr:
+ cmpdi 0,r7,0
+ beqlr
+ li r6,-EFAULT
+@@ -450,6 +471,11 @@ dest; stb r6,0(r4)
+ blr
+
+ .Ldest_error:
++ ld r14,STK_REG(r14)(r1)
++ ld r15,STK_REG(r15)(r1)
++ ld r16,STK_REG(r16)(r1)
++ addi r1,r1,STACKFRAMESIZE
++.Ldest_error_nr:
+ cmpdi 0,r8,0
+ beqlr
+ li r6,-EFAULT
+diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
+index f445e98..cfabc3d 100644
+--- a/arch/sparc/kernel/entry.S
++++ b/arch/sparc/kernel/entry.S
+@@ -1177,7 +1177,7 @@ sys_sigreturn:
+ nop
+
+ call syscall_trace
+- nop
++ mov 1, %o1
+
+ 1:
+ /* We don't want to muck with user registers like a
+diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S
+index 79f3103..7c00735 100644
+--- a/arch/sparc/kernel/ktlb.S
++++ b/arch/sparc/kernel/ktlb.S
+@@ -25,11 +25,10 @@ kvmap_itlb:
+ */
+ kvmap_itlb_4v:
+
+-kvmap_itlb_nonlinear:
+ /* Catch kernel NULL pointer calls. */
+ sethi %hi(PAGE_SIZE), %g5
+ cmp %g4, %g5
+- bleu,pn %xcc, kvmap_dtlb_longpath
++ blu,pn %xcc, kvmap_itlb_longpath
+ nop
+
+ KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_itlb_load)
+diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
+index 7f5f65d..817187d 100644
+--- a/arch/sparc/kernel/syscalls.S
++++ b/arch/sparc/kernel/syscalls.S
+@@ -147,7 +147,7 @@ linux_syscall_trace32:
+ srl %i4, 0, %o4
+ srl %i1, 0, %o1
+ srl %i2, 0, %o2
+- ba,pt %xcc, 2f
++ ba,pt %xcc, 5f
+ srl %i3, 0, %o3
+
+ linux_syscall_trace:
+@@ -177,13 +177,13 @@ linux_sparc_syscall32:
+ srl %i1, 0, %o1 ! IEU0 Group
+ ldx [%g6 + TI_FLAGS], %l0 ! Load
+
+- srl %i5, 0, %o5 ! IEU1
++ srl %i3, 0, %o3 ! IEU0
+ srl %i2, 0, %o2 ! IEU0 Group
+ andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0
+ bne,pn %icc, linux_syscall_trace32 ! CTI
+ mov %i0, %l5 ! IEU1
+- call %l7 ! CTI Group brk forced
+- srl %i3, 0, %o3 ! IEU0
++5: call %l7 ! CTI Group brk forced
++ srl %i5, 0, %o5 ! IEU1
+ ba,a,pt %xcc, 3f
+
+ /* Linux native system calls enter here... */
+diff --git a/arch/sparc/kernel/trampoline_64.S b/arch/sparc/kernel/trampoline_64.S
+index da1b781..8fa84a3 100644
+--- a/arch/sparc/kernel/trampoline_64.S
++++ b/arch/sparc/kernel/trampoline_64.S
+@@ -131,7 +131,6 @@ startup_continue:
+ clr %l5
+ sethi %hi(num_kernel_image_mappings), %l6
+ lduw [%l6 + %lo(num_kernel_image_mappings)], %l6
+- add %l6, 1, %l6
+
+ mov 15, %l7
+ BRANCH_IF_ANY_CHEETAH(g1,g5,2f)
+@@ -224,7 +223,6 @@ niagara_lock_tlb:
+ clr %l5
+ sethi %hi(num_kernel_image_mappings), %l6
+ lduw [%l6 + %lo(num_kernel_image_mappings)], %l6
+- add %l6, 1, %l6
+
+ 1:
+ mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
+diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c
+index 1b30bb3..fbb8005 100644
+--- a/arch/sparc/lib/ksyms.c
++++ b/arch/sparc/lib/ksyms.c
+@@ -131,15 +131,6 @@ EXPORT_SYMBOL(___copy_from_user);
+ EXPORT_SYMBOL(___copy_in_user);
+ EXPORT_SYMBOL(__clear_user);
+
+-/* RW semaphores */
+-EXPORT_SYMBOL(__down_read);
+-EXPORT_SYMBOL(__down_read_trylock);
+-EXPORT_SYMBOL(__down_write);
+-EXPORT_SYMBOL(__down_write_trylock);
+-EXPORT_SYMBOL(__up_read);
+-EXPORT_SYMBOL(__up_write);
+-EXPORT_SYMBOL(__downgrade_write);
+-
+ /* Atomic counter implementation. */
+ EXPORT_SYMBOL(atomic_add);
+ EXPORT_SYMBOL(atomic_add_ret);
+diff --git a/arch/unicore32/mm/init.c b/arch/unicore32/mm/init.c
+index 3b379cd..d1af4ed 100644
+--- a/arch/unicore32/mm/init.c
++++ b/arch/unicore32/mm/init.c
+@@ -65,6 +65,9 @@ void show_mem(unsigned int filter)
+ printk(KERN_DEFAULT "Mem-info:\n");
+ show_free_areas(filter);
+
++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT)
++ return;
++
+ for_each_bank(i, mi) {
+ struct membank *bank = &mi->bank[i];
+ unsigned int pfn1, pfn2;
+diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
+index 47f4e5f..a4e1b4b 100644
+--- a/arch/x86/kernel/reboot.c
++++ b/arch/x86/kernel/reboot.c
+@@ -468,6 +468,22 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"),
+ },
+ },
++ { /* Handle problems with rebooting on the Dell PowerEdge C6100. */
++ .callback = set_pci_reboot,
++ .ident = "Dell PowerEdge C6100",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "C6100"),
++ },
++ },
++ { /* Some C6100 machines were shipped with vendor being 'Dell'. */
++ .callback = set_pci_reboot,
++ .ident = "Dell PowerEdge C6100",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "C6100"),
++ },
++ },
+ { }
+ };
+
+diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
+index f9537e3..a18d20d 100644
+--- a/arch/x86/platform/efi/efi.c
++++ b/arch/x86/platform/efi/efi.c
+@@ -703,10 +703,13 @@ void __init efi_enter_virtual_mode(void)
+
+ for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
+ md = p;
+- if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
+- md->type != EFI_BOOT_SERVICES_CODE &&
+- md->type != EFI_BOOT_SERVICES_DATA)
+- continue;
++ if (!(md->attribute & EFI_MEMORY_RUNTIME)) {
++#ifdef CONFIG_X86_64
++ if (md->type != EFI_BOOT_SERVICES_CODE &&
++ md->type != EFI_BOOT_SERVICES_DATA)
++#endif
++ continue;
++ }
+
+ size = md->num_pages << EFI_PAGE_SHIFT;
+ end = md->phys_addr + size;
+diff --git a/crypto/api.c b/crypto/api.c
+index 033a714..cea3cf6 100644
+--- a/crypto/api.c
++++ b/crypto/api.c
+@@ -34,6 +34,8 @@ EXPORT_SYMBOL_GPL(crypto_alg_sem);
+ BLOCKING_NOTIFIER_HEAD(crypto_chain);
+ EXPORT_SYMBOL_GPL(crypto_chain);
+
++static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg);
++
+ static inline struct crypto_alg *crypto_alg_get(struct crypto_alg *alg)
+ {
+ atomic_inc(&alg->cra_refcnt);
+@@ -150,8 +152,11 @@ static struct crypto_alg *crypto_larval_add(const char *name, u32 type,
+ }
+ up_write(&crypto_alg_sem);
+
+- if (alg != &larval->alg)
++ if (alg != &larval->alg) {
+ kfree(larval);
++ if (crypto_is_larval(alg))
++ alg = crypto_larval_wait(alg);
++ }
+
+ return alg;
+ }
+diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c
+index f40acef..a6977e1 100644
+--- a/drivers/acpi/acpi_ipmi.c
++++ b/drivers/acpi/acpi_ipmi.c
+@@ -39,6 +39,7 @@
+ #include <linux/ipmi.h>
+ #include <linux/device.h>
+ #include <linux/pnp.h>
++#include <linux/spinlock.h>
+
+ MODULE_AUTHOR("Zhao Yakui");
+ MODULE_DESCRIPTION("ACPI IPMI Opregion driver");
+@@ -57,7 +58,7 @@ struct acpi_ipmi_device {
+ struct list_head head;
+ /* the IPMI request message list */
+ struct list_head tx_msg_list;
+- struct mutex tx_msg_lock;
++ spinlock_t tx_msg_lock;
+ acpi_handle handle;
+ struct pnp_dev *pnp_dev;
+ ipmi_user_t user_interface;
+@@ -147,6 +148,7 @@ static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg,
+ struct kernel_ipmi_msg *msg;
+ struct acpi_ipmi_buffer *buffer;
+ struct acpi_ipmi_device *device;
++ unsigned long flags;
+
+ msg = &tx_msg->tx_message;
+ /*
+@@ -177,10 +179,10 @@ static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg,
+
+ /* Get the msgid */
+ device = tx_msg->device;
+- mutex_lock(&device->tx_msg_lock);
++ spin_lock_irqsave(&device->tx_msg_lock, flags);
+ device->curr_msgid++;
+ tx_msg->tx_msgid = device->curr_msgid;
+- mutex_unlock(&device->tx_msg_lock);
++ spin_unlock_irqrestore(&device->tx_msg_lock, flags);
+ }
+
+ static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg,
+@@ -242,6 +244,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data)
+ int msg_found = 0;
+ struct acpi_ipmi_msg *tx_msg;
+ struct pnp_dev *pnp_dev = ipmi_device->pnp_dev;
++ unsigned long flags;
+
+ if (msg->user != ipmi_device->user_interface) {
+ dev_warn(&pnp_dev->dev, "Unexpected response is returned. "
+@@ -250,7 +253,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data)
+ ipmi_free_recv_msg(msg);
+ return;
+ }
+- mutex_lock(&ipmi_device->tx_msg_lock);
++ spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags);
+ list_for_each_entry(tx_msg, &ipmi_device->tx_msg_list, head) {
+ if (msg->msgid == tx_msg->tx_msgid) {
+ msg_found = 1;
+@@ -258,7 +261,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data)
+ }
+ }
+
+- mutex_unlock(&ipmi_device->tx_msg_lock);
++ spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags);
+ if (!msg_found) {
+ dev_warn(&pnp_dev->dev, "Unexpected response (msg id %ld) is "
+ "returned.\n", msg->msgid);
+@@ -378,6 +381,7 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address,
+ struct acpi_ipmi_device *ipmi_device = handler_context;
+ int err, rem_time;
+ acpi_status status;
++ unsigned long flags;
+ /*
+ * IPMI opregion message.
+ * IPMI message is firstly written to the BMC and system software
+@@ -395,9 +399,9 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address,
+ return AE_NO_MEMORY;
+
+ acpi_format_ipmi_msg(tx_msg, address, value);
+- mutex_lock(&ipmi_device->tx_msg_lock);
++ spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags);
+ list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list);
+- mutex_unlock(&ipmi_device->tx_msg_lock);
++ spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags);
+ err = ipmi_request_settime(ipmi_device->user_interface,
+ &tx_msg->addr,
+ tx_msg->tx_msgid,
+@@ -413,9 +417,9 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address,
+ status = AE_OK;
+
+ end_label:
+- mutex_lock(&ipmi_device->tx_msg_lock);
++ spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags);
+ list_del(&tx_msg->head);
+- mutex_unlock(&ipmi_device->tx_msg_lock);
++ spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags);
+ kfree(tx_msg);
+ return status;
+ }
+@@ -457,7 +461,7 @@ static void acpi_add_ipmi_device(struct acpi_ipmi_device *ipmi_device)
+
+ INIT_LIST_HEAD(&ipmi_device->head);
+
+- mutex_init(&ipmi_device->tx_msg_lock);
++ spin_lock_init(&ipmi_device->tx_msg_lock);
+ INIT_LIST_HEAD(&ipmi_device->tx_msg_list);
+ ipmi_install_space_handler(ipmi_device);
+
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
+index 51de186..8176b82 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -964,6 +964,10 @@ static struct dmi_system_id __initdata ec_dmi_table[] = {
+ ec_enlarge_storm_threshold, "CLEVO hardware", {
+ DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "M720T/M730T"),}, NULL},
++ {
++ ec_validate_ecdt, "ASUS hardware", {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek Computer Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),}, NULL},
+ {},
+ };
+
+diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
+index d3446f6..d7ad865 100644
+--- a/drivers/block/cciss.c
++++ b/drivers/block/cciss.c
+@@ -1186,6 +1186,7 @@ static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode,
+ int err;
+ u32 cp;
+
++ memset(&arg64, 0, sizeof(arg64));
+ err = 0;
+ err |=
+ copy_from_user(&arg64.LUN_info, &arg32->LUN_info,
+diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
+index 9125bbe..504bc16 100644
+--- a/drivers/block/cpqarray.c
++++ b/drivers/block/cpqarray.c
+@@ -1195,6 +1195,7 @@ out_passthru:
+ ida_pci_info_struct pciinfo;
+
+ if (!arg) return -EINVAL;
++ memset(&pciinfo, 0, sizeof(pciinfo));
+ pciinfo.bus = host->pci_dev->bus->number;
+ pciinfo.dev_fn = host->pci_dev->devfn;
+ pciinfo.board_id = host->board_id;
+diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
+index bde72f7..3539f9b 100644
+--- a/drivers/bluetooth/ath3k.c
++++ b/drivers/bluetooth/ath3k.c
+@@ -84,6 +84,7 @@ static struct usb_device_id ath3k_table[] = {
+ { USB_DEVICE(0x04CA, 0x3008) },
+ { USB_DEVICE(0x13d3, 0x3362) },
+ { USB_DEVICE(0x0CF3, 0xE004) },
++ { USB_DEVICE(0x0CF3, 0xE005) },
+ { USB_DEVICE(0x0930, 0x0219) },
+ { USB_DEVICE(0x0489, 0xe057) },
+ { USB_DEVICE(0x13d3, 0x3393) },
+@@ -125,6 +126,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {
+ { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
++ { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 1bd3924..f18b5a2 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -108,6 +108,7 @@ static struct usb_device_id btusb_table[] = {
+
+ /* Broadcom BCM20702A0 */
+ { USB_DEVICE(0x0b05, 0x17b5) },
++ { USB_DEVICE(0x0b05, 0x17cb) },
+ { USB_DEVICE(0x04ca, 0x2003) },
+ { USB_DEVICE(0x0489, 0xe042) },
+ { USB_DEVICE(0x413c, 0x8197) },
+@@ -154,6 +155,7 @@ static struct usb_device_id blacklist_table[] = {
+ { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
++ { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
+diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
+index 7211f67..72f460e 100644
+--- a/drivers/gpu/drm/drm_edid.c
++++ b/drivers/gpu/drm/drm_edid.c
+@@ -125,6 +125,9 @@ static struct edid_quirk {
+
+ /* ViewSonic VA2026w */
+ { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING },
++
++ /* Medion MD 30217 PG */
++ { "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 },
+ };
+
+ /*** DDC fetch and block validation ***/
+diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
+index a07ccab..72163e8 100644
+--- a/drivers/gpu/drm/i915/intel_dp.c
++++ b/drivers/gpu/drm/i915/intel_dp.c
+@@ -621,7 +621,18 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
+ DRM_DEBUG_KMS("aux_ch native nack\n");
+ return -EREMOTEIO;
+ case AUX_NATIVE_REPLY_DEFER:
+- udelay(100);
++ /*
++ * For now, just give more slack to branch devices. We
++ * could check the DPCD for I2C bit rate capabilities,
++ * and if available, adjust the interval. We could also
++ * be more careful with DP-to-Legacy adapters where a
++ * long legacy cable may force very low I2C bit rates.
++ */
++ if (intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
++ DP_DWN_STRM_PORT_PRESENT)
++ usleep_range(500, 600);
++ else
++ usleep_range(300, 400);
+ continue;
+ default:
+ DRM_ERROR("aux_ch invalid native reply 0x%02x\n",
+diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
+index cffb007..356a252 100644
+--- a/drivers/gpu/drm/i915/intel_opregion.c
++++ b/drivers/gpu/drm/i915/intel_opregion.c
+@@ -161,7 +161,7 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
+
+ max = intel_panel_get_max_backlight(dev);
+ intel_panel_set_backlight(dev, bclp * max / 255);
+- asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID;
++ asle->cblv = DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID;
+
+ return 0;
+ }
+diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
+index f0dc04b..3171294 100644
+--- a/drivers/gpu/drm/radeon/atombios_encoders.c
++++ b/drivers/gpu/drm/radeon/atombios_encoders.c
+@@ -1385,8 +1385,12 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
+ atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0);
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
+- /* some early dce3.2 boards have a bug in their transmitter control table */
+- if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730))
++ /* some dce3.x boards have a bug in their transmitter control table.
++ * ACTION_ENABLE_OUTPUT can probably be dropped since ACTION_ENABLE
++ * does the same thing and more.
++ */
++ if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730) &&
++ (rdev->family != CHIP_RS880))
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
+ }
+ if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
+diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
+index f5962a0..a68057a 100644
+--- a/drivers/gpu/drm/radeon/evergreen.c
++++ b/drivers/gpu/drm/radeon/evergreen.c
+@@ -501,7 +501,8 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *other_mode)
+ {
+- u32 tmp;
++ u32 tmp, buffer_alloc, i;
++ u32 pipe_offset = radeon_crtc->crtc_id * 0x20;
+ /*
+ * Line Buffer Setup
+ * There are 3 line buffers, each one shared by 2 display controllers.
+@@ -524,18 +525,34 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev,
+ * non-linked crtcs for maximum line buffer allocation.
+ */
+ if (radeon_crtc->base.enabled && mode) {
+- if (other_mode)
++ if (other_mode) {
+ tmp = 0; /* 1/2 */
+- else
++ buffer_alloc = 1;
++ } else {
+ tmp = 2; /* whole */
+- } else
++ buffer_alloc = 2;
++ }
++ } else {
+ tmp = 0;
++ buffer_alloc = 0;
++ }
+
+ /* second controller of the pair uses second half of the lb */
+ if (radeon_crtc->crtc_id % 2)
+ tmp += 4;
+ WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, tmp);
+
++ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
++ WREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset,
++ DMIF_BUFFERS_ALLOCATED(buffer_alloc));
++ for (i = 0; i < rdev->usec_timeout; i++) {
++ if (RREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset) &
++ DMIF_BUFFERS_ALLOCATED_COMPLETED)
++ break;
++ udelay(1);
++ }
++ }
++
+ if (radeon_crtc->base.enabled && mode) {
+ switch (tmp) {
+ case 0:
+diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
+index fe44a95..47f3bd2 100644
+--- a/drivers/gpu/drm/radeon/evergreend.h
++++ b/drivers/gpu/drm/radeon/evergreend.h
+@@ -459,6 +459,10 @@
+ # define LATENCY_LOW_WATERMARK(x) ((x) << 0)
+ # define LATENCY_HIGH_WATERMARK(x) ((x) << 16)
+
++#define PIPE0_DMIF_BUFFER_CONTROL 0x0ca0
++# define DMIF_BUFFERS_ALLOCATED(x) ((x) << 0)
++# define DMIF_BUFFERS_ALLOCATED_COMPLETED (1 << 4)
++
+ #define IH_RB_CNTL 0x3e00
+ # define IH_RB_ENABLE (1 << 0)
+ # define IH_IB_SIZE(x) ((x) << 1) /* log2 */
+diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
+index 383b38e..cda89c6b 100644
+--- a/drivers/gpu/drm/radeon/radeon_atombios.c
++++ b/drivers/gpu/drm/radeon/radeon_atombios.c
+@@ -709,13 +709,16 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
+ (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *)
+ (ctx->bios + data_offset +
+ le16_to_cpu(router_obj->asObjects[k].usSrcDstTableOffset));
++ u8 *num_dst_objs = (u8 *)
++ ((u8 *)router_src_dst_table + 1 +
++ (router_src_dst_table->ucNumberOfSrc * 2));
++ u16 *dst_objs = (u16 *)(num_dst_objs + 1);
+ int enum_id;
+
+ router.router_id = router_obj_id;
+- for (enum_id = 0; enum_id < router_src_dst_table->ucNumberOfDst;
+- enum_id++) {
++ for (enum_id = 0; enum_id < (*num_dst_objs); enum_id++) {
+ if (le16_to_cpu(path->usConnObjectId) ==
+- le16_to_cpu(router_src_dst_table->usDstObjectID[enum_id]))
++ le16_to_cpu(dst_objs[enum_id]))
+ break;
+ }
+
+@@ -1616,7 +1619,9 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
+ kfree(edid);
+ }
+ }
+- record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
++ record += fake_edid_record->ucFakeEDIDLength ?
++ fake_edid_record->ucFakeEDIDLength + 2 :
++ sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
+ break;
+ case LCD_PANEL_RESOLUTION_RECORD_TYPE:
+ panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;
+diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
+index 6fd53b6..b101843 100644
+--- a/drivers/gpu/drm/radeon/radeon_connectors.c
++++ b/drivers/gpu/drm/radeon/radeon_connectors.c
+@@ -1387,6 +1387,24 @@ struct drm_connector_funcs radeon_dp_connector_funcs = {
+ .force = radeon_dvi_force,
+ };
+
++static const struct drm_connector_funcs radeon_edp_connector_funcs = {
++ .dpms = drm_helper_connector_dpms,
++ .detect = radeon_dp_detect,
++ .fill_modes = drm_helper_probe_single_connector_modes,
++ .set_property = radeon_lvds_set_property,
++ .destroy = radeon_dp_connector_destroy,
++ .force = radeon_dvi_force,
++};
++
++static const struct drm_connector_funcs radeon_lvds_bridge_connector_funcs = {
++ .dpms = drm_helper_connector_dpms,
++ .detect = radeon_dp_detect,
++ .fill_modes = drm_helper_probe_single_connector_modes,
++ .set_property = radeon_lvds_set_property,
++ .destroy = radeon_dp_connector_destroy,
++ .force = radeon_dvi_force,
++};
++
+ void
+ radeon_add_atom_connector(struct drm_device *dev,
+ uint32_t connector_id,
+@@ -1478,8 +1496,6 @@ radeon_add_atom_connector(struct drm_device *dev,
+ goto failed;
+ radeon_dig_connector->igp_lane_info = igp_lane_info;
+ radeon_connector->con_priv = radeon_dig_connector;
+- drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
+- drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
+ if (i2c_bus->valid) {
+ /* add DP i2c bus */
+ if (connector_type == DRM_MODE_CONNECTOR_eDP)
+@@ -1496,6 +1512,10 @@ radeon_add_atom_connector(struct drm_device *dev,
+ case DRM_MODE_CONNECTOR_VGA:
+ case DRM_MODE_CONNECTOR_DVIA:
+ default:
++ drm_connector_init(dev, &radeon_connector->base,
++ &radeon_dp_connector_funcs, connector_type);
++ drm_connector_helper_add(&radeon_connector->base,
++ &radeon_dp_connector_helper_funcs);
+ connector->interlace_allowed = true;
+ connector->doublescan_allowed = true;
+ radeon_connector->dac_load_detect = true;
+@@ -1508,6 +1528,10 @@ radeon_add_atom_connector(struct drm_device *dev,
+ case DRM_MODE_CONNECTOR_HDMIA:
+ case DRM_MODE_CONNECTOR_HDMIB:
+ case DRM_MODE_CONNECTOR_DisplayPort:
++ drm_connector_init(dev, &radeon_connector->base,
++ &radeon_dp_connector_funcs, connector_type);
++ drm_connector_helper_add(&radeon_connector->base,
++ &radeon_dp_connector_helper_funcs);
+ drm_connector_attach_property(&radeon_connector->base,
+ rdev->mode_info.underscan_property,
+ UNDERSCAN_OFF);
+@@ -1532,6 +1556,10 @@ radeon_add_atom_connector(struct drm_device *dev,
+ break;
+ case DRM_MODE_CONNECTOR_LVDS:
+ case DRM_MODE_CONNECTOR_eDP:
++ drm_connector_init(dev, &radeon_connector->base,
++ &radeon_lvds_bridge_connector_funcs, connector_type);
++ drm_connector_helper_add(&radeon_connector->base,
++ &radeon_dp_connector_helper_funcs);
+ drm_connector_attach_property(&radeon_connector->base,
+ dev->mode_config.scaling_mode_property,
+ DRM_MODE_SCALE_FULLSCREEN);
+@@ -1695,7 +1723,7 @@ radeon_add_atom_connector(struct drm_device *dev,
+ goto failed;
+ radeon_dig_connector->igp_lane_info = igp_lane_info;
+ radeon_connector->con_priv = radeon_dig_connector;
+- drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
++ drm_connector_init(dev, &radeon_connector->base, &radeon_edp_connector_funcs, connector_type);
+ drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
+ if (i2c_bus->valid) {
+ /* add DP i2c bus */
+diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
+index cd94abb..8cde84b 100644
+--- a/drivers/gpu/drm/radeon/radeon_device.c
++++ b/drivers/gpu/drm/radeon/radeon_device.c
+@@ -818,10 +818,16 @@ int radeon_device_init(struct radeon_device *rdev,
+ return r;
+ }
+ if (radeon_testing) {
+- radeon_test_moves(rdev);
++ if (rdev->accel_working)
++ radeon_test_moves(rdev);
++ else
++ DRM_INFO("radeon: acceleration disabled, skipping move tests\n");
+ }
+ if (radeon_benchmarking) {
+- radeon_benchmark(rdev, radeon_benchmarking);
++ if (rdev->accel_working)
++ radeon_benchmark(rdev, radeon_benchmarking);
++ else
++ DRM_INFO("radeon: acceleration disabled, skipping benchmarks\n");
+ }
+ return 0;
+ }
+diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
+index 4dd9512..c087434 100644
+--- a/drivers/gpu/drm/radeon/rs400.c
++++ b/drivers/gpu/drm/radeon/rs400.c
+@@ -174,10 +174,13 @@ int rs400_gart_enable(struct radeon_device *rdev)
+ /* FIXME: according to doc we should set HIDE_MMCFG_BAR=0,
+ * AGPMODE30=0 & AGP30ENHANCED=0 in NB_CNTL */
+ if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740)) {
+- WREG32_MC(RS480_MC_MISC_CNTL,
+- (RS480_GART_INDEX_REG_EN | RS690_BLOCK_GFX_D3_EN));
++ tmp = RREG32_MC(RS480_MC_MISC_CNTL);
++ tmp |= RS480_GART_INDEX_REG_EN | RS690_BLOCK_GFX_D3_EN;
++ WREG32_MC(RS480_MC_MISC_CNTL, tmp);
+ } else {
+- WREG32_MC(RS480_MC_MISC_CNTL, RS480_GART_INDEX_REG_EN);
++ tmp = RREG32_MC(RS480_MC_MISC_CNTL);
++ tmp |= RS480_GART_INDEX_REG_EN;
++ WREG32_MC(RS480_MC_MISC_CNTL, tmp);
+ }
+ /* Enable gart */
+ WREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | size_reg));
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index 611aafc..9ac4389 100644
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -59,6 +59,8 @@ struct hid_report *hid_register_report(struct hid_device *device, unsigned type,
+ struct hid_report_enum *report_enum = device->report_enum + type;
+ struct hid_report *report;
+
++ if (id >= HID_MAX_IDS)
++ return NULL;
+ if (report_enum->report_id_hash[id])
+ return report_enum->report_id_hash[id];
+
+@@ -216,9 +218,9 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
+ {
+ struct hid_report *report;
+ struct hid_field *field;
+- int usages;
++ unsigned usages;
+ unsigned offset;
+- int i;
++ unsigned i;
+
+ report = hid_register_report(parser->device, report_type, parser->global.report_id);
+ if (!report) {
+@@ -237,7 +239,8 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
+ if (!parser->local.usage_index) /* Ignore padding fields */
+ return 0;
+
+- usages = max_t(int, parser->local.usage_index, parser->global.report_count);
++ usages = max_t(unsigned, parser->local.usage_index,
++ parser->global.report_count);
+
+ field = hid_register_field(report, usages, parser->global.report_count);
+ if (!field)
+@@ -248,7 +251,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
+ field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION);
+
+ for (i = 0; i < usages; i++) {
+- int j = i;
++ unsigned j = i;
+ /* Duplicate the last usage we parsed if we have excess values */
+ if (i >= parser->local.usage_index)
+ j = parser->local.usage_index - 1;
+@@ -380,8 +383,10 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
+
+ case HID_GLOBAL_ITEM_TAG_REPORT_ID:
+ parser->global.report_id = item_udata(item);
+- if (parser->global.report_id == 0) {
+- dbg_hid("report_id 0 is invalid\n");
++ if (parser->global.report_id == 0 ||
++ parser->global.report_id >= HID_MAX_IDS) {
++ dbg_hid("report_id %u is invalid\n",
++ parser->global.report_id);
+ return -1;
+ }
+ return 0;
+@@ -552,7 +557,7 @@ static void hid_device_release(struct device *dev)
+ for (i = 0; i < HID_REPORT_TYPES; i++) {
+ struct hid_report_enum *report_enum = device->report_enum + i;
+
+- for (j = 0; j < 256; j++) {
++ for (j = 0; j < HID_MAX_IDS; j++) {
+ struct hid_report *report = report_enum->report_id_hash[j];
+ if (report)
+ hid_free_report(report);
+@@ -710,6 +715,64 @@ err:
+ }
+ EXPORT_SYMBOL_GPL(hid_parse_report);
+
++static const char * const hid_report_names[] = {
++ "HID_INPUT_REPORT",
++ "HID_OUTPUT_REPORT",
++ "HID_FEATURE_REPORT",
++};
++/**
++ * hid_validate_values - validate existing device report's value indexes
++ *
++ * @device: hid device
++ * @type: which report type to examine
++ * @id: which report ID to examine (0 for first)
++ * @field_index: which report field to examine
++ * @report_counts: expected number of values
++ *
++ * Validate the number of values in a given field of a given report, after
++ * parsing.
++ */
++struct hid_report *hid_validate_values(struct hid_device *hid,
++ unsigned int type, unsigned int id,
++ unsigned int field_index,
++ unsigned int report_counts)
++{
++ struct hid_report *report;
++
++ if (type > HID_FEATURE_REPORT) {
++ hid_err(hid, "invalid HID report type %u\n", type);
++ return NULL;
++ }
++
++ if (id >= HID_MAX_IDS) {
++ hid_err(hid, "invalid HID report id %u\n", id);
++ return NULL;
++ }
++
++ /*
++ * Explicitly not using hid_get_report() here since it depends on
++ * ->numbered being checked, which may not always be the case when
++ * drivers go to access report values.
++ */
++ report = hid->report_enum[type].report_id_hash[id];
++ if (!report) {
++ hid_err(hid, "missing %s %u\n", hid_report_names[type], id);
++ return NULL;
++ }
++ if (report->maxfield <= field_index) {
++ hid_err(hid, "not enough fields in %s %u\n",
++ hid_report_names[type], id);
++ return NULL;
++ }
++ if (report->field[field_index]->report_count < report_counts) {
++ hid_err(hid, "not enough values in %s %u field %u\n",
++ hid_report_names[type], id, field_index);
++ return NULL;
++ }
++ return report;
++}
++EXPORT_SYMBOL_GPL(hid_validate_values);
++
+ /*
+ * Convert a signed n-bit integer to signed 32-bit integer. Common
+ * cases are done through the compiler, the screwed things has to be
+@@ -990,7 +1053,12 @@ EXPORT_SYMBOL_GPL(hid_output_report);
+
+ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
+ {
+- unsigned size = field->report_size;
++ unsigned size;
++
++ if (!field)
++ return -1;
++
++ size = field->report_size;
+
+ hid_dump_input(field->report->device, field->usage + offset, value);
+
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 08075f2..ca2b3e6 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -581,6 +581,7 @@
+ #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16 0x0012
+ #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17 0x0013
+ #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18 0x0014
++#define USB_DEVICE_ID_NTRIG_DUOSENSE 0x1500
+
+ #define USB_VENDOR_ID_ONTRAK 0x0a07
+ #define USB_DEVICE_ID_ONTRAK_ADU100 0x0064
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index f333139..95c79a3 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -284,6 +284,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
+ if (field->flags & HID_MAIN_ITEM_CONSTANT)
+ goto ignore;
+
++ /* Ignore if report count is out of bounds. */
++ if (field->report_count < 1)
++ goto ignore;
++
+ /* only LED usages are supported in output fields */
+ if (field->report_type == HID_OUTPUT_REPORT &&
+ (usage->hid & HID_USAGE_PAGE) != HID_UP_LED) {
+@@ -887,10 +891,15 @@ static void report_features(struct hid_device *hid)
+
+ rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
+ list_for_each_entry(rep, &rep_enum->report_list, list)
+- for (i = 0; i < rep->maxfield; i++)
++ for (i = 0; i < rep->maxfield; i++) {
++ /* Ignore if report count is out of bounds. */
++ if (rep->field[i]->report_count < 1)
++ continue;
++
+ for (j = 0; j < rep->field[i]->maxusage; j++)
+ drv->feature_mapping(hid, rep->field[i],
+ rep->field[i]->usage + j);
++ }
+ }
+
+ /*
+diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c
+index 3c31bc6..128f011 100644
+--- a/drivers/hid/hid-lg2ff.c
++++ b/drivers/hid/hid-lg2ff.c
+@@ -66,26 +66,13 @@ int lg2ff_init(struct hid_device *hid)
+ struct hid_report *report;
+ struct hid_input *hidinput = list_entry(hid->inputs.next,
+ struct hid_input, list);
+- struct list_head *report_list =
+- &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct input_dev *dev = hidinput->input;
+ int error;
+
+- if (list_empty(report_list)) {
+- hid_err(hid, "no output report found\n");
++ /* Check that the report looks ok */
++ report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7);
++ if (!report)
+ return -ENODEV;
+- }
+-
+- report = list_entry(report_list->next, struct hid_report, list);
+-
+- if (report->maxfield < 1) {
+- hid_err(hid, "output report is empty\n");
+- return -ENODEV;
+- }
+- if (report->field[0]->report_count < 7) {
+- hid_err(hid, "not enough values in the field\n");
+- return -ENODEV;
+- }
+
+ lg2ff = kmalloc(sizeof(struct lg2ff_device), GFP_KERNEL);
+ if (!lg2ff)
+diff --git a/drivers/hid/hid-lg3ff.c b/drivers/hid/hid-lg3ff.c
+index f98644c..91f981f 100644
+--- a/drivers/hid/hid-lg3ff.c
++++ b/drivers/hid/hid-lg3ff.c
+@@ -68,10 +68,11 @@ static int hid_lg3ff_play(struct input_dev *dev, void *data,
+ int x, y;
+
+ /*
+- * Maxusage should always be 63 (maximum fields)
+- * likely a better way to ensure this data is clean
++ * Available values in the field should always be 63, but we only use up to
++ * 35. Instead, clear the entire area, however big it is.
+ */
+- memset(report->field[0]->value, 0, sizeof(__s32)*report->field[0]->maxusage);
++ memset(report->field[0]->value, 0,
++ sizeof(__s32) * report->field[0]->report_count);
+
+ switch (effect->type) {
+ case FF_CONSTANT:
+@@ -131,32 +132,14 @@ static const signed short ff3_joystick_ac[] = {
+ int lg3ff_init(struct hid_device *hid)
+ {
+ struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
+- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct input_dev *dev = hidinput->input;
+- struct hid_report *report;
+- struct hid_field *field;
+ const signed short *ff_bits = ff3_joystick_ac;
+ int error;
+ int i;
+
+- /* Find the report to use */
+- if (list_empty(report_list)) {
+- hid_err(hid, "No output report found\n");
+- return -1;
+- }
+-
+ /* Check that the report looks ok */
+- report = list_entry(report_list->next, struct hid_report, list);
+- if (!report) {
+- hid_err(hid, "NULL output report\n");
+- return -1;
+- }
+-
+- field = report->field[0];
+- if (!field) {
+- hid_err(hid, "NULL field\n");
+- return -1;
+- }
++ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 35))
++ return -ENODEV;
+
+ /* Assume single fixed device G940 */
+ for (i = 0; ff_bits[i] >= 0; i++)
+diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
+index 103f30d..5c6bf4b 100644
+--- a/drivers/hid/hid-lg4ff.c
++++ b/drivers/hid/hid-lg4ff.c
+@@ -339,33 +339,15 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at
+ int lg4ff_init(struct hid_device *hid)
+ {
+ struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
+- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct input_dev *dev = hidinput->input;
+- struct hid_report *report;
+- struct hid_field *field;
+ struct lg4ff_device_entry *entry;
+ struct usb_device_descriptor *udesc;
+ int error, i, j;
+ __u16 bcdDevice, rev_maj, rev_min;
+
+- /* Find the report to use */
+- if (list_empty(report_list)) {
+- hid_err(hid, "No output report found\n");
+- return -1;
+- }
+-
+ /* Check that the report looks ok */
+- report = list_entry(report_list->next, struct hid_report, list);
+- if (!report) {
+- hid_err(hid, "NULL output report\n");
++ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7))
+ return -1;
+- }
+-
+- field = report->field[0];
+- if (!field) {
+- hid_err(hid, "NULL field\n");
+- return -1;
+- }
+
+ /* Check what wheel has been connected */
+ for (i = 0; i < ARRAY_SIZE(lg4ff_devices); i++) {
+diff --git a/drivers/hid/hid-lgff.c b/drivers/hid/hid-lgff.c
+index 27bc54f..1d978daa 100644
+--- a/drivers/hid/hid-lgff.c
++++ b/drivers/hid/hid-lgff.c
+@@ -130,27 +130,14 @@ static void hid_lgff_set_autocenter(struct input_dev *dev, u16 magnitude)
+ int lgff_init(struct hid_device* hid)
+ {
+ struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
+- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct input_dev *dev = hidinput->input;
+- struct hid_report *report;
+- struct hid_field *field;
+ const signed short *ff_bits = ff_joystick;
+ int error;
+ int i;
+
+- /* Find the report to use */
+- if (list_empty(report_list)) {
+- hid_err(hid, "No output report found\n");
+- return -1;
+- }
+-
+ /* Check that the report looks ok */
+- report = list_entry(report_list->next, struct hid_report, list);
+- field = report->field[0];
+- if (!field) {
+- hid_err(hid, "NULL field\n");
+- return -1;
+- }
++ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7))
++ return -ENODEV;
+
+ for (i = 0; i < ARRAY_SIZE(devices); i++) {
+ if (dev->id.vendor == devices[i].idVendor &&
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 8821ecc..828a0dd 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -791,6 +791,12 @@ static int logi_dj_probe(struct hid_device *hdev,
+ goto hid_parse_fail;
+ }
+
++ if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, REPORT_ID_DJ_SHORT,
++ 0, DJREPORT_SHORT_LENGTH - 1)) {
++ retval = -ENODEV;
++ goto hid_parse_fail;
++ }
++
+ /* Starts the usb device and connects to upper interfaces hiddev and
+ * hidraw */
+ retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
+index 9fae2eb..48cba85 100644
+--- a/drivers/hid/hid-ntrig.c
++++ b/drivers/hid/hid-ntrig.c
+@@ -115,7 +115,8 @@ static inline int ntrig_get_mode(struct hid_device *hdev)
+ struct hid_report *report = hdev->report_enum[HID_FEATURE_REPORT].
+ report_id_hash[0x0d];
+
+- if (!report)
++ if (!report || report->maxfield < 1 ||
++ report->field[0]->report_count < 1)
+ return -EINVAL;
+
+ usbhid_submit_report(hdev, report, USB_DIR_IN);
+diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c
+index 01e7d2c..1daeaca 100644
+--- a/drivers/hid/hid-picolcd.c
++++ b/drivers/hid/hid-picolcd.c
+@@ -1424,7 +1424,7 @@ static ssize_t picolcd_operation_mode_store(struct device *dev,
+ buf += 10;
+ cnt -= 10;
+ }
+- if (!report)
++ if (!report || report->maxfield != 1)
+ return -EINVAL;
+
+ while (cnt > 0 && (buf[cnt-1] == '\n' || buf[cnt-1] == '\r'))
+diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c
+index 070f93a..12786cd 100644
+--- a/drivers/hid/hid-pl.c
++++ b/drivers/hid/hid-pl.c
+@@ -129,8 +129,14 @@ static int plff_init(struct hid_device *hid)
+ strong = &report->field[0]->value[2];
+ weak = &report->field[0]->value[3];
+ debug("detected single-field device");
+- } else if (report->maxfield >= 4 && report->field[0]->maxusage == 1 &&
+- report->field[0]->usage[0].hid == (HID_UP_LED | 0x43)) {
++ } else if (report->field[0]->maxusage == 1 &&
++ report->field[0]->usage[0].hid ==
++ (HID_UP_LED | 0x43) &&
++ report->maxfield >= 4 &&
++ report->field[0]->report_count >= 1 &&
++ report->field[1]->report_count >= 1 &&
++ report->field[2]->report_count >= 1 &&
++ report->field[3]->report_count >= 1) {
+ report->field[0]->value[0] = 0x00;
+ report->field[1]->value[0] = 0x00;
+ strong = &report->field[2]->value[0];
+diff --git a/drivers/hid/hid-speedlink.c b/drivers/hid/hid-speedlink.c
+index 6020137..2b03c9b 100644
+--- a/drivers/hid/hid-speedlink.c
++++ b/drivers/hid/hid-speedlink.c
+@@ -3,7 +3,7 @@
+ * Fixes "jumpy" cursor and removes nonexistent keyboard LEDS from
+ * the HID descriptor.
+ *
+- * Copyright (c) 2011 Stefan Kriwanek <mail@stefankriwanek.de>
++ * Copyright (c) 2011, 2013 Stefan Kriwanek <dev@stefankriwanek.de>
+ */
+
+ /*
+@@ -48,8 +48,13 @@ static int speedlink_event(struct hid_device *hdev, struct hid_field *field,
+ struct hid_usage *usage, __s32 value)
+ {
+ /* No other conditions due to usage_table. */
+- /* Fix "jumpy" cursor (invalid events sent by device). */
+- if (value == 256)
++
++ /* This fixes the "jumpy" cursor occuring due to invalid events sent
++ * by the device. Some devices only send them with value==+256, others
++ * don't. However, catching abs(value)>=256 is restrictive enough not
++ * to interfere with devices that were bug-free (has been tested).
++ */
++ if (abs(value) >= 256)
+ return 1;
+ /* Drop useless distance 0 events (on button clicks etc.) as well */
+ if (value == 0)
+diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c
+index f6ba81d..f348f7f 100644
+--- a/drivers/hid/hid-zpff.c
++++ b/drivers/hid/hid-zpff.c
+@@ -70,21 +70,13 @@ static int zpff_init(struct hid_device *hid)
+ struct hid_report *report;
+ struct hid_input *hidinput = list_entry(hid->inputs.next,
+ struct hid_input, list);
+- struct list_head *report_list =
+- &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct input_dev *dev = hidinput->input;
+- int error;
++ int i, error;
+
+- if (list_empty(report_list)) {
+- hid_err(hid, "no output report found\n");
+- return -ENODEV;
+- }
+-
+- report = list_entry(report_list->next, struct hid_report, list);
+-
+- if (report->maxfield < 4) {
+- hid_err(hid, "not enough fields in report\n");
+- return -ENODEV;
++ for (i = 0; i < 4; i++) {
++ report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, i, 1);
++ if (!report)
++ return -ENODEV;
+ }
+
+ zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL);
+diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
+index 17d15bb..9e50f61 100644
+--- a/drivers/hid/hidraw.c
++++ b/drivers/hid/hidraw.c
+@@ -42,7 +42,6 @@ static struct cdev hidraw_cdev;
+ static struct class *hidraw_class;
+ static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES];
+ static DEFINE_MUTEX(minors_lock);
+-static void drop_ref(struct hidraw *hid, int exists_bit);
+
+ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
+ {
+@@ -296,14 +295,37 @@ out:
+
+ }
+
++static void drop_ref(struct hidraw *hidraw, int exists_bit)
++{
++ if (exists_bit) {
++ hid_hw_close(hidraw->hid);
++ hidraw->exist = 0;
++ if (hidraw->open)
++ wake_up_interruptible(&hidraw->wait);
++ } else {
++ --hidraw->open;
++ }
++
++ if (!hidraw->open && !hidraw->exist) {
++ device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
++ hidraw_table[hidraw->minor] = NULL;
++ kfree(hidraw);
++ }
++}
++
+ static int hidraw_release(struct inode * inode, struct file * file)
+ {
+ unsigned int minor = iminor(inode);
+ struct hidraw_list *list = file->private_data;
+
+- drop_ref(hidraw_table[minor], 0);
++ mutex_lock(&minors_lock);
++
+ list_del(&list->node);
+ kfree(list);
++
++ drop_ref(hidraw_table[minor], 0);
++
++ mutex_unlock(&minors_lock);
+ return 0;
+ }
+
+@@ -506,7 +528,12 @@ EXPORT_SYMBOL_GPL(hidraw_connect);
+ void hidraw_disconnect(struct hid_device *hid)
+ {
+ struct hidraw *hidraw = hid->hidraw;
++
++ mutex_lock(&minors_lock);
++
+ drop_ref(hidraw, 1);
++
++ mutex_unlock(&minors_lock);
+ }
+ EXPORT_SYMBOL_GPL(hidraw_disconnect);
+
+@@ -555,23 +582,3 @@ void hidraw_exit(void)
+ unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES);
+
+ }
+-
+-static void drop_ref(struct hidraw *hidraw, int exists_bit)
+-{
+- mutex_lock(&minors_lock);
+- if (exists_bit) {
+- hid_hw_close(hidraw->hid);
+- hidraw->exist = 0;
+- if (hidraw->open)
+- wake_up_interruptible(&hidraw->wait);
+- } else {
+- --hidraw->open;
+- }
+-
+- if (!hidraw->open && !hidraw->exist) {
+- device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
+- hidraw_table[hidraw->minor] = NULL;
+- kfree(hidraw);
+- }
+- mutex_unlock(&minors_lock);
+-}
+diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
+index 96a1e0f..f98fbad 100644
+--- a/drivers/hid/usbhid/hid-quirks.c
++++ b/drivers/hid/usbhid/hid-quirks.c
+@@ -99,6 +99,8 @@ static const struct hid_blacklist {
+ { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS },
++ { USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS },
++
+ { 0, 0 }
+ };
+
+diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
+index d99aa84..30cac58 100644
+--- a/drivers/hwmon/applesmc.c
++++ b/drivers/hwmon/applesmc.c
+@@ -344,8 +344,10 @@ static int applesmc_get_lower_bound(unsigned int *lo, const char *key)
+ while (begin != end) {
+ int middle = begin + (end - begin) / 2;
+ entry = applesmc_get_entry_by_index(middle);
+- if (IS_ERR(entry))
++ if (IS_ERR(entry)) {
++ *lo = 0;
+ return PTR_ERR(entry);
++ }
+ if (strcmp(entry->key, key) < 0)
+ begin = middle + 1;
+ else
+@@ -364,8 +366,10 @@ static int applesmc_get_upper_bound(unsigned int *hi, const char *key)
+ while (begin != end) {
+ int middle = begin + (end - begin) / 2;
+ entry = applesmc_get_entry_by_index(middle);
+- if (IS_ERR(entry))
++ if (IS_ERR(entry)) {
++ *hi = smcreg.key_count;
+ return PTR_ERR(entry);
++ }
+ if (strcmp(key, entry->key) < 0)
+ end = middle;
+ else
+@@ -485,16 +489,25 @@ static int applesmc_init_smcreg_try(void)
+ {
+ struct applesmc_registers *s = &smcreg;
+ bool left_light_sensor, right_light_sensor;
++ unsigned int count;
+ u8 tmp[1];
+ int ret;
+
+ if (s->init_complete)
+ return 0;
+
+- ret = read_register_count(&s->key_count);
++ ret = read_register_count(&count);
+ if (ret)
+ return ret;
+
++ if (s->cache && s->key_count != count) {
++ pr_warn("key count changed from %d to %d\n",
++ s->key_count, count);
++ kfree(s->cache);
++ s->cache = NULL;
++ }
++ s->key_count = count;
++
+ if (!s->cache)
+ s->cache = kcalloc(s->key_count, sizeof(*s->cache), GFP_KERNEL);
+ if (!s->cache)
+diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
+index f44a067..b4a4aaf 100644
+--- a/drivers/iommu/intel-iommu.c
++++ b/drivers/iommu/intel-iommu.c
+@@ -861,56 +861,54 @@ static int dma_pte_clear_range(struct dmar_domain *domain,
+ return order;
+ }
+
++static void dma_pte_free_level(struct dmar_domain *domain, int level,
++ struct dma_pte *pte, unsigned long pfn,
++ unsigned long start_pfn, unsigned long last_pfn)
++{
++ pfn = max(start_pfn, pfn);
++ pte = &pte[pfn_level_offset(pfn, level)];
++
++ do {
++ unsigned long level_pfn;
++ struct dma_pte *level_pte;
++
++ if (!dma_pte_present(pte) || dma_pte_superpage(pte))
++ goto next;
++
++ level_pfn = pfn & level_mask(level - 1);
++ level_pte = phys_to_virt(dma_pte_addr(pte));
++
++ if (level > 2)
++ dma_pte_free_level(domain, level - 1, level_pte,
++ level_pfn, start_pfn, last_pfn);
++
++ /* If range covers entire pagetable, free it */
++ if (!(start_pfn > level_pfn ||
++ last_pfn < level_pfn + level_size(level))) {
++ dma_clear_pte(pte);
++ domain_flush_cache(domain, pte, sizeof(*pte));
++ free_pgtable_page(level_pte);
++ }
++next:
++ pfn += level_size(level);
++ } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
++}
++
+ /* free page table pages. last level pte should already be cleared */
+ static void dma_pte_free_pagetable(struct dmar_domain *domain,
+ unsigned long start_pfn,
+ unsigned long last_pfn)
+ {
+ int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
+- struct dma_pte *first_pte, *pte;
+- int total = agaw_to_level(domain->agaw);
+- int level;
+- unsigned long tmp;
+- int large_page = 2;
+
+ BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width);
+ BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width);
+ BUG_ON(start_pfn > last_pfn);
+
+ /* We don't need lock here; nobody else touches the iova range */
+- level = 2;
+- while (level <= total) {
+- tmp = align_to_level(start_pfn, level);
+-
+- /* If we can't even clear one PTE at this level, we're done */
+- if (tmp + level_size(level) - 1 > last_pfn)
+- return;
+-
+- do {
+- large_page = level;
+- first_pte = pte = dma_pfn_level_pte(domain, tmp, level, &large_page);
+- if (large_page > level)
+- level = large_page + 1;
+- if (!pte) {
+- tmp = align_to_level(tmp + 1, level + 1);
+- continue;
+- }
+- do {
+- if (dma_pte_present(pte)) {
+- free_pgtable_page(phys_to_virt(dma_pte_addr(pte)));
+- dma_clear_pte(pte);
+- }
+- pte++;
+- tmp += level_size(level);
+- } while (!first_pte_in_page(pte) &&
+- tmp + level_size(level) - 1 <= last_pfn);
++ dma_pte_free_level(domain, agaw_to_level(domain->agaw),
++ domain->pgd, 0, start_pfn, last_pfn);
+
+- domain_flush_cache(domain, first_pte,
+- (void *)pte - (void *)first_pte);
+-
+- } while (tmp && tmp + level_size(level) - 1 <= last_pfn);
+- level++;
+- }
+ /* free pgd */
+ if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
+ free_pgtable_page(domain->pgd);
+diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
+index b4aaa7b..5c30316 100644
+--- a/drivers/md/dm-snap.c
++++ b/drivers/md/dm-snap.c
+@@ -721,17 +721,16 @@ static int calc_max_buckets(void)
+ */
+ static int init_hash_tables(struct dm_snapshot *s)
+ {
+- sector_t hash_size, cow_dev_size, origin_dev_size, max_buckets;
++ sector_t hash_size, cow_dev_size, max_buckets;
+
+ /*
+ * Calculate based on the size of the original volume or
+ * the COW volume...
+ */
+ cow_dev_size = get_dev_size(s->cow->bdev);
+- origin_dev_size = get_dev_size(s->origin->bdev);
+ max_buckets = calc_max_buckets();
+
+- hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift;
++ hash_size = cow_dev_size >> s->store->chunk_shift;
+ hash_size = min(hash_size, max_buckets);
+
+ if (hash_size < 64)
+diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
+index 441dacf..060353e 100644
+--- a/drivers/media/video/hdpvr/hdpvr-core.c
++++ b/drivers/media/video/hdpvr/hdpvr-core.c
+@@ -297,6 +297,11 @@ static int hdpvr_probe(struct usb_interface *interface,
+
+ dev->workqueue = 0;
+
++ /* init video transfer queues first of all */
++ /* to prevent oops in hdpvr_delete() on error paths */
++ INIT_LIST_HEAD(&dev->free_buff_list);
++ INIT_LIST_HEAD(&dev->rec_buff_list);
++
+ /* register v4l2_device early so it can be used for printks */
+ if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
+ err("v4l2_device_register failed");
+@@ -319,10 +324,6 @@ static int hdpvr_probe(struct usb_interface *interface,
+ if (!dev->workqueue)
+ goto error;
+
+- /* init video transfer queues */
+- INIT_LIST_HEAD(&dev->free_buff_list);
+- INIT_LIST_HEAD(&dev->rec_buff_list);
+-
+ dev->options = hdpvr_default_options;
+
+ if (default_video_input < HDPVR_VIDEO_INPUTS)
+@@ -373,12 +374,6 @@ static int hdpvr_probe(struct usb_interface *interface,
+ }
+ mutex_unlock(&dev->io_mutex);
+
+- if (hdpvr_register_videodev(dev, &interface->dev,
+- video_nr[atomic_inc_return(&dev_nr)])) {
+- v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
+- goto error;
+- }
+-
+ #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ retval = hdpvr_register_i2c_adapter(dev);
+ if (retval < 0) {
+@@ -399,6 +394,13 @@ static int hdpvr_probe(struct usb_interface *interface,
+ }
+ #endif
+
++ retval = hdpvr_register_videodev(dev, &interface->dev,
++ video_nr[atomic_inc_return(&dev_nr)]);
++ if (retval < 0) {
++ v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
++ goto reg_fail;
++ }
++
+ /* let the user know what node this device is now attached to */
+ v4l2_info(&dev->v4l2_dev, "device now attached to %s\n",
+ video_device_node_name(dev->video_dev));
+diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c
+index 86f259c..be9e74d 100644
+--- a/drivers/mmc/host/tmio_mmc_dma.c
++++ b/drivers/mmc/host/tmio_mmc_dma.c
+@@ -92,6 +92,7 @@ static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host)
+ pio:
+ if (!desc) {
+ /* DMA failed, fall back to PIO */
++ tmio_mmc_enable_dma(host, false);
+ if (ret >= 0)
+ ret = -EIO;
+ host->chan_rx = NULL;
+@@ -104,7 +105,6 @@ pio:
+ }
+ dev_warn(&host->pdev->dev,
+ "DMA failed: %d, falling back to PIO\n", ret);
+- tmio_mmc_enable_dma(host, false);
+ }
+
+ dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__,
+@@ -173,6 +173,7 @@ static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host)
+ pio:
+ if (!desc) {
+ /* DMA failed, fall back to PIO */
++ tmio_mmc_enable_dma(host, false);
+ if (ret >= 0)
+ ret = -EIO;
+ host->chan_tx = NULL;
+@@ -185,7 +186,6 @@ pio:
+ }
+ dev_warn(&host->pdev->dev,
+ "DMA failed: %d, falling back to PIO\n", ret);
+- tmio_mmc_enable_dma(host, false);
+ }
+
+ dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d\n", __func__,
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index b436b84..1bf36ac 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -1911,6 +1911,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave, *oldcurrent;
+ struct sockaddr addr;
++ int old_flags = bond_dev->flags;
+ u32 old_features = bond_dev->features;
+
+ /* slave is not a slave or master is not master of this slave */
+@@ -2041,12 +2042,18 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
+ * already taken care of above when we detached the slave
+ */
+ if (!USES_PRIMARY(bond->params.mode)) {
+- /* unset promiscuity level from slave */
+- if (bond_dev->flags & IFF_PROMISC)
++ /* unset promiscuity level from slave
++ * NOTE: The NETDEV_CHANGEADDR call above may change the value
++ * of the IFF_PROMISC flag in the bond_dev, but we need the
++ * value of that flag before that change, as that was the value
++ * when this slave was attached, so we cache at the start of the
++ * function and use it here. Same goes for ALLMULTI below
++ */
++ if (old_flags & IFF_PROMISC)
+ dev_set_promiscuity(slave_dev, -1);
+
+ /* unset allmulti level from slave */
+- if (bond_dev->flags & IFF_ALLMULTI)
++ if (old_flags & IFF_ALLMULTI)
+ dev_set_allmulti(slave_dev, -1);
+
+ /* flush master's mc_list from slave */
+diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
+index e59d006..bb828c2 100644
+--- a/drivers/net/can/flexcan.c
++++ b/drivers/net/can/flexcan.c
+@@ -60,7 +60,7 @@
+ #define FLEXCAN_MCR_BCC BIT(16)
+ #define FLEXCAN_MCR_LPRIO_EN BIT(13)
+ #define FLEXCAN_MCR_AEN BIT(12)
+-#define FLEXCAN_MCR_MAXMB(x) ((x) & 0xf)
++#define FLEXCAN_MCR_MAXMB(x) ((x) & 0x1f)
+ #define FLEXCAN_MCR_IDAM_A (0 << 8)
+ #define FLEXCAN_MCR_IDAM_B (1 << 8)
+ #define FLEXCAN_MCR_IDAM_C (2 << 8)
+@@ -666,7 +666,6 @@ static int flexcan_chip_start(struct net_device *dev)
+ {
+ struct flexcan_priv *priv = netdev_priv(dev);
+ struct flexcan_regs __iomem *regs = priv->base;
+- unsigned int i;
+ int err;
+ u32 reg_mcr, reg_ctrl;
+
+@@ -700,9 +699,11 @@ static int flexcan_chip_start(struct net_device *dev)
+ *
+ */
+ reg_mcr = flexcan_read(&regs->mcr);
++ reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
+ reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT |
+ FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN |
+- FLEXCAN_MCR_IDAM_C;
++ FLEXCAN_MCR_IDAM_C |
++ FLEXCAN_MCR_MAXMB(FLEXCAN_TX_BUF_ID);
+ dev_dbg(dev->dev.parent, "%s: writing mcr=0x%08x", __func__, reg_mcr);
+ flexcan_write(reg_mcr, &regs->mcr);
+
+@@ -732,16 +733,9 @@ static int flexcan_chip_start(struct net_device *dev)
+ dev_dbg(dev->dev.parent, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
+ flexcan_write(reg_ctrl, &regs->ctrl);
+
+- for (i = 0; i < ARRAY_SIZE(regs->cantxfg); i++) {
+- flexcan_write(0, &regs->cantxfg[i].can_ctrl);
+- flexcan_write(0, &regs->cantxfg[i].can_id);
+- flexcan_write(0, &regs->cantxfg[i].data[0]);
+- flexcan_write(0, &regs->cantxfg[i].data[1]);
+-
+- /* put MB into rx queue */
+- flexcan_write(FLEXCAN_MB_CNT_CODE(0x4),
+- &regs->cantxfg[i].can_ctrl);
+- }
++ /* Abort any pending TX, mark Mailbox as INACTIVE */
++ flexcan_write(FLEXCAN_MB_CNT_CODE(0x4),
++ &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
+
+ /* acceptance mask/acceptance code (accept everything) */
+ flexcan_write(0x0, &regs->rxgmask);
+diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
+index d0722a7..fb9e7d3 100644
+--- a/drivers/net/ethernet/freescale/gianfar.c
++++ b/drivers/net/ethernet/freescale/gianfar.c
+@@ -397,7 +397,13 @@ static void gfar_init_mac(struct net_device *ndev)
+ if (ndev->features & NETIF_F_IP_CSUM)
+ tctrl |= TCTRL_INIT_CSUM;
+
+- tctrl |= TCTRL_TXSCHED_PRIO;
++ if (priv->prio_sched_en)
++ tctrl |= TCTRL_TXSCHED_PRIO;
++ else {
++ tctrl |= TCTRL_TXSCHED_WRRS;
++ gfar_write(&regs->tr03wt, DEFAULT_WRRS_WEIGHT);
++ gfar_write(&regs->tr47wt, DEFAULT_WRRS_WEIGHT);
++ }
+
+ gfar_write(&regs->tctrl, tctrl);
+
+@@ -1157,6 +1163,9 @@ static int gfar_probe(struct platform_device *ofdev)
+ priv->rx_filer_enable = 1;
+ /* Enable most messages by default */
+ priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
++ /* use pritority h/w tx queue scheduling for single queue devices */
++ if (priv->num_tx_queues == 1)
++ priv->prio_sched_en = 1;
+
+ /* Carrier starts down, phylib will bring it up */
+ netif_carrier_off(dev);
+diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h
+index 9aa4377..abeb79a 100644
+--- a/drivers/net/ethernet/freescale/gianfar.h
++++ b/drivers/net/ethernet/freescale/gianfar.h
+@@ -304,8 +304,16 @@ extern const char gfar_driver_version[];
+ #define TCTRL_TFCPAUSE 0x00000008
+ #define TCTRL_TXSCHED_MASK 0x00000006
+ #define TCTRL_TXSCHED_INIT 0x00000000
++/* priority scheduling */
+ #define TCTRL_TXSCHED_PRIO 0x00000002
++/* weighted round-robin scheduling (WRRS) */
+ #define TCTRL_TXSCHED_WRRS 0x00000004
++/* default WRRS weight and policy setting,
++ * tailored to the tr03wt and tr47wt registers:
++ * equal weight for all Tx Qs, measured in 64byte units
++ */
++#define DEFAULT_WRRS_WEIGHT 0x18181818
++
+ #define TCTRL_INIT_CSUM (TCTRL_TUCSEN | TCTRL_IPCSEN)
+
+ #define IEVENT_INIT_CLEAR 0xffffffff
+@@ -1101,7 +1109,8 @@ struct gfar_private {
+ extended_hash:1,
+ bd_stash_en:1,
+ rx_filer_enable:1,
+- wol_en:1; /* Wake-on-LAN enabled */
++ wol_en:1, /* Wake-on-LAN enabled */
++ prio_sched_en:1; /* Enable priorty based Tx scheduling in Hw */
+ unsigned short padding;
+
+ /* PHY stuff */
+diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
+index 8f47907..4236b82 100644
+--- a/drivers/net/ethernet/realtek/8139cp.c
++++ b/drivers/net/ethernet/realtek/8139cp.c
+@@ -478,7 +478,7 @@ rx_status_loop:
+
+ while (1) {
+ u32 status, len;
+- dma_addr_t mapping;
++ dma_addr_t mapping, new_mapping;
+ struct sk_buff *skb, *new_skb;
+ struct cp_desc *desc;
+ const unsigned buflen = cp->rx_buf_sz;
+@@ -520,6 +520,14 @@ rx_status_loop:
+ goto rx_next;
+ }
+
++ new_mapping = dma_map_single(&cp->pdev->dev, new_skb->data, buflen,
++ PCI_DMA_FROMDEVICE);
++ if (dma_mapping_error(&cp->pdev->dev, new_mapping)) {
++ dev->stats.rx_dropped++;
++ kfree_skb(new_skb);
++ goto rx_next;
++ }
++
+ dma_unmap_single(&cp->pdev->dev, mapping,
+ buflen, PCI_DMA_FROMDEVICE);
+
+@@ -531,12 +539,11 @@ rx_status_loop:
+
+ skb_put(skb, len);
+
+- mapping = dma_map_single(&cp->pdev->dev, new_skb->data, buflen,
+- PCI_DMA_FROMDEVICE);
+ cp->rx_skb[rx_tail] = new_skb;
+
+ cp_rx_skb(cp, skb, desc);
+ rx++;
++ mapping = new_mapping;
+
+ rx_next:
+ cp->rx_ring[rx_tail].opts2 = 0;
+@@ -704,6 +711,22 @@ static inline u32 cp_tx_vlan_tag(struct sk_buff *skb)
+ TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00;
+ }
+
++static void unwind_tx_frag_mapping(struct cp_private *cp, struct sk_buff *skb,
++ int first, int entry_last)
++{
++ int frag, index;
++ struct cp_desc *txd;
++ skb_frag_t *this_frag;
++ for (frag = 0; frag+first < entry_last; frag++) {
++ index = first+frag;
++ cp->tx_skb[index] = NULL;
++ txd = &cp->tx_ring[index];
++ this_frag = &skb_shinfo(skb)->frags[frag];
++ dma_unmap_single(&cp->pdev->dev, le64_to_cpu(txd->addr),
++ skb_frag_size(this_frag), PCI_DMA_TODEVICE);
++ }
++}
++
+ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
+ struct net_device *dev)
+ {
+@@ -737,6 +760,9 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
+
+ len = skb->len;
+ mapping = dma_map_single(&cp->pdev->dev, skb->data, len, PCI_DMA_TODEVICE);
++ if (dma_mapping_error(&cp->pdev->dev, mapping))
++ goto out_dma_error;
++
+ txd->opts2 = opts2;
+ txd->addr = cpu_to_le64(mapping);
+ wmb();
+@@ -774,6 +800,9 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
+ first_len = skb_headlen(skb);
+ first_mapping = dma_map_single(&cp->pdev->dev, skb->data,
+ first_len, PCI_DMA_TODEVICE);
++ if (dma_mapping_error(&cp->pdev->dev, first_mapping))
++ goto out_dma_error;
++
+ cp->tx_skb[entry] = skb;
+ entry = NEXT_TX(entry);
+
+@@ -787,6 +816,11 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
+ mapping = dma_map_single(&cp->pdev->dev,
+ skb_frag_address(this_frag),
+ len, PCI_DMA_TODEVICE);
++ if (dma_mapping_error(&cp->pdev->dev, mapping)) {
++ unwind_tx_frag_mapping(cp, skb, first_entry, entry);
++ goto out_dma_error;
++ }
++
+ eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
+
+ ctrl = eor | len | DescOwn;
+@@ -845,11 +879,16 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
+ if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1))
+ netif_stop_queue(dev);
+
++out_unlock:
+ spin_unlock_irqrestore(&cp->lock, intr_flags);
+
+ cpw8(TxPoll, NormalTxPoll);
+
+ return NETDEV_TX_OK;
++out_dma_error:
++ kfree_skb(skb);
++ cp->dev->stats.tx_dropped++;
++ goto out_unlock;
+ }
+
+ /* Set or clear the multicast filter for this adaptor.
+@@ -1023,6 +1062,10 @@ static int cp_refill_rx(struct cp_private *cp)
+
+ mapping = dma_map_single(&cp->pdev->dev, skb->data,
+ cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
++ if (dma_mapping_error(&cp->pdev->dev, mapping)) {
++ kfree_skb(skb);
++ goto err_out;
++ }
+ cp->rx_skb[i] = skb;
+
+ cp->rx_ring[i].opts2 = 0;
+diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
+index 9ce8665..c231b3f 100644
+--- a/drivers/net/ethernet/sfc/rx.c
++++ b/drivers/net/ethernet/sfc/rx.c
+@@ -312,8 +312,9 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue,
+
+ index = rx_queue->added_count & rx_queue->ptr_mask;
+ new_buf = efx_rx_buffer(rx_queue, index);
+- new_buf->dma_addr = rx_buf->dma_addr ^ (PAGE_SIZE >> 1);
+ new_buf->u.page = rx_buf->u.page;
++ new_buf->page_offset = rx_buf->page_offset ^ (PAGE_SIZE >> 1);
++ new_buf->dma_addr = state->dma_addr + new_buf->page_offset;
+ new_buf->len = rx_buf->len;
+ new_buf->is_page = true;
+ ++rx_queue->added_count;
+diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
+index f34dd99..f37e0ae 100644
+--- a/drivers/net/ethernet/via/via-rhine.c
++++ b/drivers/net/ethernet/via/via-rhine.c
+@@ -32,7 +32,7 @@
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+ #define DRV_NAME "via-rhine"
+-#define DRV_VERSION "1.5.0"
++#define DRV_VERSION "1.5.1"
+ #define DRV_RELDATE "2010-10-09"
+
+
+@@ -1518,7 +1518,12 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
+ cpu_to_le32(TXDESC | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN));
+
+ if (unlikely(vlan_tx_tag_present(skb))) {
+- rp->tx_ring[entry].tx_status = cpu_to_le32((vlan_tx_tag_get(skb)) << 16);
++ u16 vid_pcp = vlan_tx_tag_get(skb);
++
++ /* drop CFI/DEI bit, register needs VID and PCP */
++ vid_pcp = (vid_pcp & VLAN_VID_MASK) |
++ ((vid_pcp & VLAN_PRIO_MASK) >> 1);
++ rp->tx_ring[entry].tx_status = cpu_to_le32((vid_pcp) << 16);
+ /* request tagging */
+ rp->tx_ring[entry].desc_length |= cpu_to_le32(0x020000);
+ }
+diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
+index 2681b53..e26945d 100644
+--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
+@@ -308,6 +308,12 @@ static int temac_dma_bd_init(struct net_device *ndev)
+ lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1)));
+ lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p);
+
++ /* Init descriptor indexes */
++ lp->tx_bd_ci = 0;
++ lp->tx_bd_next = 0;
++ lp->tx_bd_tail = 0;
++ lp->rx_bd_ci = 0;
++
+ return 0;
+
+ out:
+diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
+index 96b9e3c..b0f9015 100644
+--- a/drivers/net/macvtap.c
++++ b/drivers/net/macvtap.c
+@@ -641,6 +641,28 @@ static int macvtap_skb_to_vnet_hdr(const struct sk_buff *skb,
+ return 0;
+ }
+
++static unsigned long iov_pages(const struct iovec *iv, int offset,
++ unsigned long nr_segs)
++{
++ unsigned long seg, base;
++ int pages = 0, len, size;
++
++ while (nr_segs && (offset >= iv->iov_len)) {
++ offset -= iv->iov_len;
++ ++iv;
++ --nr_segs;
++ }
++
++ for (seg = 0; seg < nr_segs; seg++) {
++ base = (unsigned long)iv[seg].iov_base + offset;
++ len = iv[seg].iov_len - offset;
++ size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT;
++ pages += size;
++ offset = 0;
++ }
++
++ return pages;
++}
+
+ /* Get packet from user space buffer */
+ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
+@@ -687,31 +709,15 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
+ if (unlikely(count > UIO_MAXIOV))
+ goto err;
+
+- if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY))
+- zerocopy = true;
+-
+- if (zerocopy) {
+- /* Userspace may produce vectors with count greater than
+- * MAX_SKB_FRAGS, so we need to linearize parts of the skb
+- * to let the rest of data to be fit in the frags.
+- */
+- if (count > MAX_SKB_FRAGS) {
+- copylen = iov_length(iv, count - MAX_SKB_FRAGS);
+- if (copylen < vnet_hdr_len)
+- copylen = 0;
+- else
+- copylen -= vnet_hdr_len;
+- }
+- /* There are 256 bytes to be copied in skb, so there is enough
+- * room for skb expand head in case it is used.
+- * The rest buffer is mapped from userspace.
+- */
+- if (copylen < vnet_hdr.hdr_len)
+- copylen = vnet_hdr.hdr_len;
+- if (!copylen)
+- copylen = GOODCOPY_LEN;
++ if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) {
++ copylen = vnet_hdr.hdr_len ? vnet_hdr.hdr_len : GOODCOPY_LEN;
+ linear = copylen;
+- } else {
++ if (iov_pages(iv, vnet_hdr_len + copylen, count)
++ <= MAX_SKB_FRAGS)
++ zerocopy = true;
++ }
++
++ if (!zerocopy) {
+ copylen = len;
+ linear = vnet_hdr.hdr_len;
+ }
+@@ -723,9 +729,15 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
+
+ if (zerocopy)
+ err = zerocopy_sg_from_iovec(skb, iv, vnet_hdr_len, count);
+- else
++ else {
+ err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len,
+ len);
++ if (!err && m && m->msg_control) {
++ struct ubuf_info *uarg = m->msg_control;
++ uarg->callback(uarg);
++ }
++ }
++
+ if (err)
+ goto err_kfree;
+
+diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
+index ad6a9d9..2b349d3 100644
+--- a/drivers/net/ppp/pptp.c
++++ b/drivers/net/ppp/pptp.c
+@@ -281,7 +281,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
+ nf_reset(skb);
+
+ skb->ip_summed = CHECKSUM_NONE;
+- ip_select_ident(iph, &rt->dst, NULL);
++ ip_select_ident(skb, &rt->dst, NULL);
+ ip_send_check(iph);
+
+ ip_local_out(skb);
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index f4c5de6..ee1aab0 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -614,8 +614,9 @@ static ssize_t tun_get_user(struct tun_struct *tun,
+ int offset = 0;
+
+ if (!(tun->flags & TUN_NO_PI)) {
+- if ((len -= sizeof(pi)) > count)
++ if (len < sizeof(pi))
+ return -EINVAL;
++ len -= sizeof(pi);
+
+ if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi)))
+ return -EFAULT;
+@@ -623,8 +624,9 @@ static ssize_t tun_get_user(struct tun_struct *tun,
+ }
+
+ if (tun->flags & TUN_VNET_HDR) {
+- if ((len -= tun->vnet_hdr_sz) > count)
++ if (len < tun->vnet_hdr_sz)
+ return -EINVAL;
++ len -= tun->vnet_hdr_sz;
+
+ if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso)))
+ return -EFAULT;
+diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
+index 2ba40cf..43aa06b 100644
+--- a/drivers/net/usb/cdc_ether.c
++++ b/drivers/net/usb/cdc_ether.c
+@@ -615,6 +615,11 @@ static const struct usb_device_id products [] = {
+ .bInterfaceProtocol = USB_CDC_PROTO_NONE,
+ .driver_info = (unsigned long)&wwan_info,
+ }, {
++ /* Telit modules */
++ USB_VENDOR_AND_INTERFACE_INFO(0x1bc7, USB_CLASS_COMM,
++ USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
++ .driver_info = (kernel_ulong_t) &wwan_info,
++}, {
+ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
+ USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &cdc_info,
+diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
+index fbc0e4d..136ecf3 100644
+--- a/drivers/net/usb/dm9601.c
++++ b/drivers/net/usb/dm9601.c
+@@ -384,7 +384,7 @@ static void dm9601_set_multicast(struct net_device *net)
+ rx_ctl |= 0x02;
+ } else if (net->flags & IFF_ALLMULTI ||
+ netdev_mc_count(net) > DM_MAX_MCAST) {
+- rx_ctl |= 0x04;
++ rx_ctl |= 0x08;
+ } else if (!netdev_mc_empty(net)) {
+ struct netdev_hw_addr *ha;
+
+diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+index 73be7ff..f146824 100644
+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+@@ -1016,6 +1016,10 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
+ * is_on == 0 means MRC CCK is OFF (more noise imm)
+ */
+ bool is_on = param ? 1 : 0;
++
++ if (ah->caps.rx_chainmask == 1)
++ break;
++
+ REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
+ AR_PHY_MRC_CCK_ENABLE, is_on);
+ REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
+diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
+index 1c269f5..7c70cf2 100644
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -77,10 +77,6 @@ struct ath_config {
+ sizeof(struct ath_buf_state)); \
+ } while (0)
+
+-#define ATH_RXBUF_RESET(_bf) do { \
+- (_bf)->bf_stale = false; \
+- } while (0)
+-
+ /**
+ * enum buffer_type - Buffer type flags
+ *
+@@ -308,6 +304,7 @@ struct ath_rx {
+ struct ath_buf *rx_bufptr;
+ struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX];
+
++ struct ath_buf *buf_hold;
+ struct sk_buff *frag;
+ };
+
+diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
+index d171a72..8326c14 100644
+--- a/drivers/net/wireless/ath/ath9k/recv.c
++++ b/drivers/net/wireless/ath/ath9k/recv.c
+@@ -78,8 +78,6 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
+ struct ath_desc *ds;
+ struct sk_buff *skb;
+
+- ATH_RXBUF_RESET(bf);
+-
+ ds = bf->bf_desc;
+ ds->ds_link = 0; /* link to null */
+ ds->ds_data = bf->bf_buf_addr;
+@@ -106,6 +104,14 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
+ sc->rx.rxlink = &ds->ds_link;
+ }
+
++static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_buf *bf)
++{
++ if (sc->rx.buf_hold)
++ ath_rx_buf_link(sc, sc->rx.buf_hold);
++
++ sc->rx.buf_hold = bf;
++}
++
+ static void ath_setdefantenna(struct ath_softc *sc, u32 antenna)
+ {
+ /* XXX block beacon interrupts */
+@@ -153,7 +159,6 @@ static bool ath_rx_edma_buf_link(struct ath_softc *sc,
+
+ skb = bf->bf_mpdu;
+
+- ATH_RXBUF_RESET(bf);
+ memset(skb->data, 0, ah->caps.rx_status_len);
+ dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
+ ah->caps.rx_status_len, DMA_TO_DEVICE);
+@@ -492,6 +497,7 @@ int ath_startrecv(struct ath_softc *sc)
+ if (list_empty(&sc->rx.rxbuf))
+ goto start_recv;
+
++ sc->rx.buf_hold = NULL;
+ sc->rx.rxlink = NULL;
+ list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) {
+ ath_rx_buf_link(sc, bf);
+@@ -742,6 +748,9 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
+ }
+
+ bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
++ if (bf == sc->rx.buf_hold)
++ return NULL;
++
+ ds = bf->bf_desc;
+
+ /*
+@@ -1974,7 +1983,7 @@ requeue:
+ if (edma) {
+ ath_rx_edma_buf_link(sc, qtype);
+ } else {
+- ath_rx_buf_link(sc, bf);
++ ath_rx_buf_relink(sc, bf);
+ ath9k_hw_rxena(ah);
+ }
+ } while (1);
+diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
+index 18da100..126ed31 100644
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -2423,6 +2423,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
+ for (acno = 0, ac = &an->ac[acno];
+ acno < WME_NUM_AC; acno++, ac++) {
+ ac->sched = false;
++ ac->clear_ps_filter = true;
+ ac->txq = sc->tx.txq_map[acno];
+ INIT_LIST_HEAD(&ac->tid_q);
+ }
+diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
+index 564218c..0784493 100644
+--- a/drivers/net/wireless/p54/p54usb.c
++++ b/drivers/net/wireless/p54/p54usb.c
+@@ -83,6 +83,7 @@ static struct usb_device_id p54u_table[] = {
+ {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */
+ {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */
+ {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
++ {USB_DEVICE(0x07aa, 0x0020)}, /* Corega WLUSB2GTST USB */
+ {USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */
+ {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
+ {USB_DEVICE(0x083a, 0x4531)}, /* T-Com Sinus 154 data II */
+diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
+index 67cbe5a..8fb8c9e 100644
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -2067,6 +2067,13 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev)
+ int i;
+
+ /*
++ * First check if temperature compensation is supported.
++ */
++ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
++ if (!rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_TX_ALC))
++ return 0;
++
++ /*
+ * Read TSSI boundaries for temperature compensation from
+ * the EEPROM.
+ *
+diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
+index deb87e9..82baaa2 100644
+--- a/drivers/net/wireless/rtlwifi/wifi.h
++++ b/drivers/net/wireless/rtlwifi/wifi.h
+@@ -1630,7 +1630,7 @@ struct rtl_priv {
+ that it points to the data allocated
+ beyond this structure like:
+ rtl_pci_priv or rtl_usb_priv */
+- u8 priv[0];
++ u8 priv[0] __aligned(sizeof(void *));
+ };
+
+ #define rtl_priv(hw) (((struct rtl_priv *)(hw)->priv))
+diff --git a/drivers/of/base.c b/drivers/of/base.c
+index 9b6588e..37639a6 100644
+--- a/drivers/of/base.c
++++ b/drivers/of/base.c
+@@ -1189,6 +1189,7 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
+ ap = dt_alloc(sizeof(*ap) + len + 1, 4);
+ if (!ap)
+ continue;
++ memset(ap, 0, sizeof(*ap) + len + 1);
+ ap->alias = start;
+ of_alias_add(ap, np, id, start, len);
+ }
+diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c
+index 394ed9e..4aa30d8 100644
+--- a/drivers/scsi/esp_scsi.c
++++ b/drivers/scsi/esp_scsi.c
+@@ -530,7 +530,7 @@ static int esp_need_to_nego_sync(struct esp_target_data *tp)
+ static int esp_alloc_lun_tag(struct esp_cmd_entry *ent,
+ struct esp_lun_data *lp)
+ {
+- if (!ent->tag[0]) {
++ if (!ent->orig_tag[0]) {
+ /* Non-tagged, slot already taken? */
+ if (lp->non_tagged_cmd)
+ return -EBUSY;
+@@ -564,9 +564,9 @@ static int esp_alloc_lun_tag(struct esp_cmd_entry *ent,
+ return -EBUSY;
+ }
+
+- BUG_ON(lp->tagged_cmds[ent->tag[1]]);
++ BUG_ON(lp->tagged_cmds[ent->orig_tag[1]]);
+
+- lp->tagged_cmds[ent->tag[1]] = ent;
++ lp->tagged_cmds[ent->orig_tag[1]] = ent;
+ lp->num_tagged++;
+
+ return 0;
+@@ -575,9 +575,9 @@ static int esp_alloc_lun_tag(struct esp_cmd_entry *ent,
+ static void esp_free_lun_tag(struct esp_cmd_entry *ent,
+ struct esp_lun_data *lp)
+ {
+- if (ent->tag[0]) {
+- BUG_ON(lp->tagged_cmds[ent->tag[1]] != ent);
+- lp->tagged_cmds[ent->tag[1]] = NULL;
++ if (ent->orig_tag[0]) {
++ BUG_ON(lp->tagged_cmds[ent->orig_tag[1]] != ent);
++ lp->tagged_cmds[ent->orig_tag[1]] = NULL;
+ lp->num_tagged--;
+ } else {
+ BUG_ON(lp->non_tagged_cmd != ent);
+@@ -667,6 +667,8 @@ static struct esp_cmd_entry *find_and_prep_issuable_command(struct esp *esp)
+ ent->tag[0] = 0;
+ ent->tag[1] = 0;
+ }
++ ent->orig_tag[0] = ent->tag[0];
++ ent->orig_tag[1] = ent->tag[1];
+
+ if (esp_alloc_lun_tag(ent, lp) < 0)
+ continue;
+diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h
+index 28e22ac..cd68805 100644
+--- a/drivers/scsi/esp_scsi.h
++++ b/drivers/scsi/esp_scsi.h
+@@ -271,6 +271,7 @@ struct esp_cmd_entry {
+ #define ESP_CMD_FLAG_AUTOSENSE 0x04 /* Doing automatic REQUEST_SENSE */
+
+ u8 tag[2];
++ u8 orig_tag[2];
+
+ u8 status;
+ u8 message;
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index 96029e6..c874458 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -2105,7 +2105,7 @@ iscsi_if_rx(struct sk_buff *skb)
+ break;
+ err = iscsi_if_send_reply(group, nlh->nlmsg_seq,
+ nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
+- } while (err < 0 && err != -ECONNREFUSED);
++ } while (err < 0 && err != -ECONNREFUSED && err != -ESRCH);
+ skb_pull(skb, rlen);
+ }
+ mutex_unlock(&rx_queue_mutex);
+diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
+index 17603da..f6d2b62 100644
+--- a/drivers/scsi/sd.c
++++ b/drivers/scsi/sd.c
+@@ -2136,14 +2136,9 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
+ }
+ }
+
+- if (modepage == 0x3F) {
+- sd_printk(KERN_ERR, sdkp, "No Caching mode page "
+- "present\n");
+- goto defaults;
+- } else if ((buffer[offset] & 0x3f) != modepage) {
+- sd_printk(KERN_ERR, sdkp, "Got wrong page\n");
+- goto defaults;
+- }
++ sd_printk(KERN_ERR, sdkp, "No Caching mode page found\n");
++ goto defaults;
++
+ Page_found:
+ if (modepage == 8) {
+ sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0);
+diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c
+index 95ebc26..e3adb38 100644
+--- a/drivers/staging/comedi/drivers/dt282x.c
++++ b/drivers/staging/comedi/drivers/dt282x.c
+@@ -407,8 +407,9 @@ struct dt282x_private {
+ } \
+ udelay(5); \
+ } \
+- if (_i) \
++ if (_i) { \
+ b \
++ } \
+ } while (0)
+
+ static int dt282x_attach(struct comedi_device *dev,
+diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c
+index 403fc09..8b564ad 100644
+--- a/drivers/staging/comedi/drivers/ni_65xx.c
++++ b/drivers/staging/comedi/drivers/ni_65xx.c
+@@ -411,29 +411,25 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
+ {
+- unsigned base_bitfield_channel;
+- const unsigned max_ports_per_bitfield = 5;
++ int base_bitfield_channel;
+ unsigned read_bits = 0;
+- unsigned j;
++ int last_port_offset = ni_65xx_port_by_channel(s->n_chan - 1);
++ int port_offset;
++
+ if (insn->n != 2)
+ return -EINVAL;
+ base_bitfield_channel = CR_CHAN(insn->chanspec);
+- for (j = 0; j < max_ports_per_bitfield; ++j) {
+- const unsigned port_offset =
+- ni_65xx_port_by_channel(base_bitfield_channel) + j;
+- const unsigned port =
+- sprivate(s)->base_port + port_offset;
+- unsigned base_port_channel;
++ for (port_offset = ni_65xx_port_by_channel(base_bitfield_channel);
++ port_offset <= last_port_offset; port_offset++) {
++ unsigned port = sprivate(s)->base_port + port_offset;
++ int base_port_channel = port_offset * ni_65xx_channels_per_port;
+ unsigned port_mask, port_data, port_read_bits;
+- int bitshift;
+- if (port >= ni_65xx_total_num_ports(board(dev)))
++ int bitshift = base_port_channel - base_bitfield_channel;
++
++ if (bitshift >= 32)
+ break;
+- base_port_channel = port_offset * ni_65xx_channels_per_port;
+ port_mask = data[0];
+ port_data = data[1];
+- bitshift = base_port_channel - base_bitfield_channel;
+- if (bitshift >= 32 || bitshift <= -32)
+- break;
+ if (bitshift > 0) {
+ port_mask >>= bitshift;
+ port_data >>= bitshift;
+diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
+index 754d54e..f680766 100644
+--- a/drivers/staging/vt6656/main_usb.c
++++ b/drivers/staging/vt6656/main_usb.c
+@@ -1221,6 +1221,8 @@ device_release_WPADEV(pDevice);
+ memset(pMgmt->abyCurrBSSID, 0, 6);
+ pMgmt->eCurrState = WMAC_STATE_IDLE;
+
++ pDevice->flags &= ~DEVICE_FLAGS_OPENED;
++
+ device_free_tx_bufs(pDevice);
+ device_free_rx_bufs(pDevice);
+ device_free_int_bufs(pDevice);
+@@ -1232,7 +1234,6 @@ device_release_WPADEV(pDevice);
+ usb_free_urb(pDevice->pInterruptURB);
+
+ BSSvClearNodeDBTable(pDevice, 0);
+- pDevice->flags &=(~DEVICE_FLAGS_OPENED);
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close2 \n");
+
+diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
+index 926d483..d197b3e 100644
+--- a/drivers/staging/zram/zram_drv.c
++++ b/drivers/staging/zram/zram_drv.c
+@@ -709,9 +709,7 @@ static void zram_slot_free_notify(struct block_device *bdev,
+ struct zram *zram;
+
+ zram = bdev->bd_disk->private_data;
+- down_write(&zram->lock);
+ zram_free_page(zram, index);
+- up_write(&zram->lock);
+ zram_stat64_inc(zram, &zram->stats.notify_free);
+ }
+
+diff --git a/drivers/staging/zram/zram_drv.h b/drivers/staging/zram/zram_drv.h
+index 87f2fec..e5cd246 100644
+--- a/drivers/staging/zram/zram_drv.h
++++ b/drivers/staging/zram/zram_drv.h
+@@ -107,9 +107,8 @@ struct zram {
+ void *compress_buffer;
+ struct table *table;
+ spinlock_t stat64_lock; /* protect 64-bit stats */
+- struct rw_semaphore lock; /* protect compression buffers, table,
+- * 32bit stat counters against concurrent
+- * notifications, reads and writes */
++ struct rw_semaphore lock; /* protect compression buffers and table
++ * against concurrent read and writes */
+ struct request_queue *queue;
+ struct gendisk *disk;
+ int init_done;
+diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
+index c0b4872..f5440a7 100644
+--- a/drivers/tty/serial/pch_uart.c
++++ b/drivers/tty/serial/pch_uart.c
+@@ -552,11 +552,12 @@ static int dma_push_rx(struct eg20t_port *priv, int size)
+ dev_warn(port->dev, "Rx overrun: dropping %u bytes\n",
+ size - room);
+ if (!room)
+- return room;
++ goto out;
+
+ tty_insert_flip_string(tty, sg_virt(&priv->sg_rx), size);
+
+ port->icount.rx += room;
++out:
+ tty_kref_put(tty);
+
+ return room;
+@@ -970,6 +971,8 @@ static void pch_uart_err_ir(struct eg20t_port *priv, unsigned int lsr)
+ if (tty == NULL) {
+ for (i = 0; error_msg[i] != NULL; i++)
+ dev_err(&priv->pdev->dev, error_msg[i]);
++ } else {
++ tty_kref_put(tty);
+ }
+ }
+
+diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
+index fe8c04b..06dfb4f 100644
+--- a/drivers/usb/class/cdc-wdm.c
++++ b/drivers/usb/class/cdc-wdm.c
+@@ -187,6 +187,7 @@ skip_error:
+ static void wdm_int_callback(struct urb *urb)
+ {
+ int rv = 0;
++ int responding;
+ int status = urb->status;
+ struct wdm_device *desc;
+ struct usb_ctrlrequest *req;
+@@ -260,8 +261,8 @@ static void wdm_int_callback(struct urb *urb)
+ desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ spin_lock(&desc->iuspin);
+ clear_bit(WDM_READ, &desc->flags);
+- set_bit(WDM_RESPONDING, &desc->flags);
+- if (!test_bit(WDM_DISCONNECTING, &desc->flags)
++ responding = test_and_set_bit(WDM_RESPONDING, &desc->flags);
++ if (!responding && !test_bit(WDM_DISCONNECTING, &desc->flags)
+ && !test_bit(WDM_SUSPENDING, &desc->flags)) {
+ rv = usb_submit_urb(desc->response, GFP_ATOMIC);
+ dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d",
+@@ -658,16 +659,20 @@ static void wdm_rxwork(struct work_struct *work)
+ {
+ struct wdm_device *desc = container_of(work, struct wdm_device, rxwork);
+ unsigned long flags;
+- int rv;
++ int rv = 0;
++ int responding;
+
+ spin_lock_irqsave(&desc->iuspin, flags);
+ if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
+ spin_unlock_irqrestore(&desc->iuspin, flags);
+ } else {
++ responding = test_and_set_bit(WDM_RESPONDING, &desc->flags);
+ spin_unlock_irqrestore(&desc->iuspin, flags);
+- rv = usb_submit_urb(desc->response, GFP_KERNEL);
++ if (!responding)
++ rv = usb_submit_urb(desc->response, GFP_KERNEL);
+ if (rv < 0 && rv != -EPERM) {
+ spin_lock_irqsave(&desc->iuspin, flags);
++ clear_bit(WDM_RESPONDING, &desc->flags);
+ if (!test_bit(WDM_DISCONNECTING, &desc->flags))
+ schedule_work(&desc->rxwork);
+ spin_unlock_irqrestore(&desc->iuspin, flags);
+diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
+index f4bdd0c..78609d3 100644
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -424,7 +424,8 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx,
+
+ memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
+ if (config->desc.bDescriptorType != USB_DT_CONFIG ||
+- config->desc.bLength < USB_DT_CONFIG_SIZE) {
++ config->desc.bLength < USB_DT_CONFIG_SIZE ||
++ config->desc.bLength > size) {
+ dev_err(ddev, "invalid descriptor for config index %d: "
+ "type = 0x%X, length = %d\n", cfgidx,
+ config->desc.bDescriptorType, config->desc.bLength);
+diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
+index 22f770a..49257b3 100644
+--- a/drivers/usb/core/devio.c
++++ b/drivers/usb/core/devio.c
+@@ -646,6 +646,22 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype,
+ if ((index & ~USB_DIR_IN) == 0)
+ return 0;
+ ret = findintfep(ps->dev, index);
++ if (ret < 0) {
++ /*
++ * Some not fully compliant Win apps seem to get
++ * index wrong and have the endpoint number here
++ * rather than the endpoint address (with the
++ * correct direction). Win does let this through,
++ * so we'll not reject it here but leave it to
++ * the device to not break KVM. But we warn.
++ */
++ ret = findintfep(ps->dev, index ^ 0x80);
++ if (ret >= 0)
++ dev_info(&ps->dev->dev,
++ "%s: process %i (%s) requesting ep %02x but needs %02x\n",
++ __func__, task_pid_nr(current),
++ current->comm, index, index ^ 0x80);
++ }
+ if (ret >= 0)
+ ret = checkintf(ps, ret);
+ break;
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 2768a7e..a5ea85f 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -3749,7 +3749,8 @@ static void hub_events(void)
+ hub->hdev->children[i - 1];
+
+ dev_dbg(hub_dev, "warm reset port %d\n", i);
+- if (!udev) {
++ if (!udev || !(portstatus &
++ USB_PORT_STAT_CONNECTION)) {
+ status = hub_port_reset(hub, i,
+ NULL, HUB_BH_RESET_TIME,
+ true);
+@@ -3759,8 +3760,8 @@ static void hub_events(void)
+ usb_lock_device(udev);
+ status = usb_reset_device(udev);
+ usb_unlock_device(udev);
++ connect_change = 0;
+ }
+- connect_change = 0;
+ }
+
+ if (connect_change)
+diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
+index f77c000..9edc582 100644
+--- a/drivers/usb/dwc3/dwc3-pci.c
++++ b/drivers/usb/dwc3/dwc3-pci.c
+@@ -45,6 +45,8 @@
+ /* FIXME define these in <linux/pci_ids.h> */
+ #define PCI_VENDOR_ID_SYNOPSYS 0x16c3
+ #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd
++#define PCI_DEVICE_ID_INTEL_BYT 0x0f37
++#define PCI_DEVICE_ID_INTEL_MRFLD 0x119e
+
+ #define DWC3_PCI_DEVS_POSSIBLE 32
+
+@@ -191,6 +193,8 @@ static DEFINE_PCI_DEVICE_TABLE(dwc3_pci_id_table) = {
+ PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
+ PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3),
+ },
++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), },
++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), },
+ { } /* Terminating Entry */
+ };
+ MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table);
+diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
+index 55978fc..0874473 100644
+--- a/drivers/usb/host/ehci-mxc.c
++++ b/drivers/usb/host/ehci-mxc.c
+@@ -296,7 +296,7 @@ static int __exit ehci_mxc_drv_remove(struct platform_device *pdev)
+ if (pdata && pdata->exit)
+ pdata->exit(pdev);
+
+- if (pdata->otg)
++ if (pdata && pdata->otg)
+ otg_shutdown(pdata->otg);
+
+ usb_remove_hcd(hcd);
+diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
+index b71e22e..29c0421 100644
+--- a/drivers/usb/host/ehci-pci.c
++++ b/drivers/usb/host/ehci-pci.c
+@@ -543,7 +543,7 @@ static struct pci_driver ehci_pci_driver = {
+ .remove = usb_hcd_pci_remove,
+ .shutdown = usb_hcd_pci_shutdown,
+
+-#ifdef CONFIG_PM_SLEEP
++#ifdef CONFIG_PM
+ .driver = {
+ .pm = &usb_hcd_pci_pm_ops
+ },
+diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
+index bc01b06..839cb64 100644
+--- a/drivers/usb/host/ohci-pci.c
++++ b/drivers/usb/host/ohci-pci.c
+@@ -413,7 +413,7 @@ static struct pci_driver ohci_pci_driver = {
+ .remove = usb_hcd_pci_remove,
+ .shutdown = usb_hcd_pci_shutdown,
+
+-#ifdef CONFIG_PM_SLEEP
++#ifdef CONFIG_PM
+ .driver = {
+ .pm = &usb_hcd_pci_pm_ops
+ },
+diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c
+index c300bd2f7..0f228c4 100644
+--- a/drivers/usb/host/uhci-pci.c
++++ b/drivers/usb/host/uhci-pci.c
+@@ -293,7 +293,7 @@ static struct pci_driver uhci_pci_driver = {
+ .remove = usb_hcd_pci_remove,
+ .shutdown = uhci_shutdown,
+
+-#ifdef CONFIG_PM_SLEEP
++#ifdef CONFIG_PM
+ .driver = {
+ .pm = &usb_hcd_pci_pm_ops
+ },
+diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
+index 79d2720..61b0668 100644
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -330,7 +330,7 @@ static struct pci_driver xhci_pci_driver = {
+ /* suspend and resume implemented later */
+
+ .shutdown = usb_hcd_pci_shutdown,
+-#ifdef CONFIG_PM_SLEEP
++#ifdef CONFIG_PM
+ .driver = {
+ .pm = &usb_hcd_pci_pm_ops
+ },
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index 633476e..2b4f42b 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -879,8 +879,12 @@ remove_finished_td:
+ /* Otherwise ring the doorbell(s) to restart queued transfers */
+ ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
+ }
+- ep->stopped_td = NULL;
+- ep->stopped_trb = NULL;
++
++ /* Clear stopped_td and stopped_trb if endpoint is not halted */
++ if (!(ep->ep_state & EP_HALTED)) {
++ ep->stopped_td = NULL;
++ ep->stopped_trb = NULL;
++ }
+
+ /*
+ * Drop the lock and complete the URBs in the cancelled TD list.
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index 6e1c92a..629aa74 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -3484,10 +3484,21 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
+ {
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ struct xhci_virt_device *virt_dev;
++ struct device *dev = hcd->self.controller;
+ unsigned long flags;
+ u32 state;
+ int i, ret;
+
++#ifndef CONFIG_USB_DEFAULT_PERSIST
++ /*
++ * We called pm_runtime_get_noresume when the device was attached.
++ * Decrement the counter here to allow controller to runtime suspend
++ * if no devices remain.
++ */
++ if (xhci->quirks & XHCI_RESET_ON_RESUME)
++ pm_runtime_put_noidle(dev);
++#endif
++
+ ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);
+ /* If the host is halted due to driver unload, we still need to free the
+ * device.
+@@ -3559,6 +3570,7 @@ static int xhci_reserve_host_control_ep_resources(struct xhci_hcd *xhci)
+ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
+ {
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
++ struct device *dev = hcd->self.controller;
+ unsigned long flags;
+ int timeleft;
+ int ret;
+@@ -3611,6 +3623,16 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
+ goto disable_slot;
+ }
+ udev->slot_id = xhci->slot_id;
++
++#ifndef CONFIG_USB_DEFAULT_PERSIST
++ /*
++ * If resetting upon resume, we can't put the controller into runtime
++ * suspend if there is a device attached.
++ */
++ if (xhci->quirks & XHCI_RESET_ON_RESUME)
++ pm_runtime_get_noresume(dev);
++#endif
++
+ /* Is this a LS or FS device under a HS hub? */
+ /* Hub or peripherial? */
+ return 1;
+diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
+index 9270d5c..8e02ff2 100644
+--- a/drivers/usb/serial/mos7720.c
++++ b/drivers/usb/serial/mos7720.c
+@@ -383,7 +383,7 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
+ kfree(urbtrack);
+ return -ENOMEM;
+ }
+- urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL);
++ urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_ATOMIC);
+ if (!urbtrack->setup) {
+ usb_free_urb(urbtrack->urb);
+ kfree(urbtrack);
+@@ -391,8 +391,8 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
+ }
+ urbtrack->setup->bRequestType = (__u8)0x40;
+ urbtrack->setup->bRequest = (__u8)0x0e;
+- urbtrack->setup->wValue = get_reg_value(reg, dummy);
+- urbtrack->setup->wIndex = get_reg_index(reg);
++ urbtrack->setup->wValue = cpu_to_le16(get_reg_value(reg, dummy));
++ urbtrack->setup->wIndex = cpu_to_le16(get_reg_index(reg));
+ urbtrack->setup->wLength = 0;
+ usb_fill_control_urb(urbtrack->urb, usbdev,
+ usb_sndctrlpipe(usbdev, 0),
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index c2103f4..536c4ad 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -81,6 +81,7 @@ static void option_instat_callback(struct urb *urb);
+
+ #define HUAWEI_VENDOR_ID 0x12D1
+ #define HUAWEI_PRODUCT_E173 0x140C
++#define HUAWEI_PRODUCT_E1750 0x1406
+ #define HUAWEI_PRODUCT_K4505 0x1464
+ #define HUAWEI_PRODUCT_K3765 0x1465
+ #define HUAWEI_PRODUCT_K4605 0x14C6
+@@ -581,6 +582,8 @@ static const struct usb_device_id option_ids[] = {
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff),
+ .driver_info = (kernel_ulong_t) &net_intf1_blacklist },
++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1750, 0xff, 0xff, 0xff),
++ .driver_info = (kernel_ulong_t) &net_intf2_blacklist },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1441, USB_CLASS_COMM, 0x02, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1442, USB_CLASS_COMM, 0x02, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff),
+diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
+index bf1c094..b657de6 100644
+--- a/drivers/xen/grant-table.c
++++ b/drivers/xen/grant-table.c
+@@ -355,9 +355,18 @@ void gnttab_request_free_callback(struct gnttab_free_callback *callback,
+ void (*fn)(void *), void *arg, u16 count)
+ {
+ unsigned long flags;
++ struct gnttab_free_callback *cb;
++
+ spin_lock_irqsave(&gnttab_list_lock, flags);
+- if (callback->next)
+- goto out;
++
++ /* Check if the callback is already on the list */
++ cb = gnttab_free_callback_list;
++ while (cb) {
++ if (cb == callback)
++ goto out;
++ cb = cb->next;
++ }
++
+ callback->fn = fn;
+ callback->arg = arg;
+ callback->count = count;
+diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
+index f3a257d..fb001cd 100644
+--- a/fs/debugfs/inode.c
++++ b/fs/debugfs/inode.c
+@@ -380,8 +380,7 @@ EXPORT_SYMBOL_GPL(debugfs_remove);
+ */
+ void debugfs_remove_recursive(struct dentry *dentry)
+ {
+- struct dentry *child;
+- struct dentry *parent;
++ struct dentry *child, *next, *parent;
+
+ if (!dentry)
+ return;
+@@ -391,61 +390,37 @@ void debugfs_remove_recursive(struct dentry *dentry)
+ return;
+
+ parent = dentry;
++ down:
+ mutex_lock(&parent->d_inode->i_mutex);
++ list_for_each_entry_safe(child, next, &parent->d_subdirs, d_u.d_child) {
++ if (!debugfs_positive(child))
++ continue;
+
+- while (1) {
+- /*
+- * When all dentries under "parent" has been removed,
+- * walk up the tree until we reach our starting point.
+- */
+- if (list_empty(&parent->d_subdirs)) {
+- mutex_unlock(&parent->d_inode->i_mutex);
+- if (parent == dentry)
+- break;
+- parent = parent->d_parent;
+- mutex_lock(&parent->d_inode->i_mutex);
+- }
+- child = list_entry(parent->d_subdirs.next, struct dentry,
+- d_u.d_child);
+- next_sibling:
+-
+- /*
+- * If "child" isn't empty, walk down the tree and
+- * remove all its descendants first.
+- */
++ /* perhaps simple_empty(child) makes more sense */
+ if (!list_empty(&child->d_subdirs)) {
+ mutex_unlock(&parent->d_inode->i_mutex);
+ parent = child;
+- mutex_lock(&parent->d_inode->i_mutex);
+- continue;
+- }
+- __debugfs_remove(child, parent);
+- if (parent->d_subdirs.next == &child->d_u.d_child) {
+- /*
+- * Try the next sibling.
+- */
+- if (child->d_u.d_child.next != &parent->d_subdirs) {
+- child = list_entry(child->d_u.d_child.next,
+- struct dentry,
+- d_u.d_child);
+- goto next_sibling;
+- }
+-
+- /*
+- * Avoid infinite loop if we fail to remove
+- * one dentry.
+- */
+- mutex_unlock(&parent->d_inode->i_mutex);
+- break;
++ goto down;
+ }
+- simple_release_fs(&debugfs_mount, &debugfs_mount_count);
++ up:
++ if (!__debugfs_remove(child, parent))
++ simple_release_fs(&debugfs_mount, &debugfs_mount_count);
+ }
+
+- parent = dentry->d_parent;
++ mutex_unlock(&parent->d_inode->i_mutex);
++ child = parent;
++ parent = parent->d_parent;
+ mutex_lock(&parent->d_inode->i_mutex);
+- __debugfs_remove(dentry, parent);
++
++ if (child != dentry) {
++ next = list_entry(child->d_u.d_child.next, struct dentry,
++ d_u.d_child);
++ goto up;
++ }
++
++ if (!__debugfs_remove(child, parent))
++ simple_release_fs(&debugfs_mount, &debugfs_mount_count);
+ mutex_unlock(&parent->d_inode->i_mutex);
+- simple_release_fs(&debugfs_mount, &debugfs_mount_count);
+ }
+ EXPORT_SYMBOL_GPL(debugfs_remove_recursive);
+
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 3ca3b7f..2e0e34f 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -2054,7 +2054,8 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
+ int err = 0;
+
+ /* ext4_handle_valid() assumes a valid handle_t pointer */
+- if (handle && !ext4_handle_valid(handle))
++ if (handle && !ext4_handle_valid(handle) &&
++ !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS))
+ return 0;
+
+ mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock);
+diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
+index 5ef7afb..06e2f73 100644
+--- a/fs/fuse/dir.c
++++ b/fs/fuse/dir.c
+@@ -1063,6 +1063,8 @@ static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
+ return -EIO;
+ if (reclen > nbytes)
+ break;
++ if (memchr(dirent->name, '/', dirent->namelen) != NULL)
++ return -EIO;
+
+ over = filldir(dstbuf, dirent->name, dirent->namelen,
+ file->f_pos, dirent->ino, dirent->type);
+@@ -1282,6 +1284,7 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
+ {
+ struct inode *inode = entry->d_inode;
+ struct fuse_conn *fc = get_fuse_conn(inode);
++ struct fuse_inode *fi = get_fuse_inode(inode);
+ struct fuse_req *req;
+ struct fuse_setattr_in inarg;
+ struct fuse_attr_out outarg;
+@@ -1312,8 +1315,10 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
+ if (IS_ERR(req))
+ return PTR_ERR(req);
+
+- if (is_truncate)
++ if (is_truncate) {
+ fuse_set_nowrite(inode);
++ set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
++ }
+
+ memset(&inarg, 0, sizeof(inarg));
+ memset(&outarg, 0, sizeof(outarg));
+@@ -1375,12 +1380,14 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
+ invalidate_inode_pages2(inode->i_mapping);
+ }
+
++ clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
+ return 0;
+
+ error:
+ if (is_truncate)
+ fuse_release_nowrite(inode);
+
++ clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
+ return err;
+ }
+
+@@ -1439,6 +1446,8 @@ static int fuse_setxattr(struct dentry *entry, const char *name,
+ fc->no_setxattr = 1;
+ err = -EOPNOTSUPP;
+ }
++ if (!err)
++ fuse_invalidate_attr(inode);
+ return err;
+ }
+
+@@ -1568,6 +1577,8 @@ static int fuse_removexattr(struct dentry *entry, const char *name)
+ fc->no_removexattr = 1;
+ err = -EOPNOTSUPP;
+ }
++ if (!err)
++ fuse_invalidate_attr(inode);
+ return err;
+ }
+
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index 5242006..510d4aa 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -519,7 +519,8 @@ static void fuse_read_update_size(struct inode *inode, loff_t size,
+ struct fuse_inode *fi = get_fuse_inode(inode);
+
+ spin_lock(&fc->lock);
+- if (attr_ver == fi->attr_version && size < inode->i_size) {
++ if (attr_ver == fi->attr_version && size < inode->i_size &&
++ !test_bit(FUSE_I_SIZE_UNSTABLE, &fi->state)) {
+ fi->attr_version = ++fc->attr_version;
+ i_size_write(inode, size);
+ }
+@@ -881,12 +882,16 @@ static ssize_t fuse_perform_write(struct file *file,
+ {
+ struct inode *inode = mapping->host;
+ struct fuse_conn *fc = get_fuse_conn(inode);
++ struct fuse_inode *fi = get_fuse_inode(inode);
+ int err = 0;
+ ssize_t res = 0;
+
+ if (is_bad_inode(inode))
+ return -EIO;
+
++ if (inode->i_size < pos + iov_iter_count(ii))
++ set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
++
+ do {
+ struct fuse_req *req;
+ ssize_t count;
+@@ -921,6 +926,7 @@ static ssize_t fuse_perform_write(struct file *file,
+ if (res > 0)
+ fuse_write_update_size(inode, pos);
+
++ clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
+ fuse_invalidate_attr(inode);
+
+ return res > 0 ? res : err;
+@@ -1251,7 +1257,6 @@ static int fuse_writepage_locked(struct page *page)
+
+ inc_bdi_stat(mapping->backing_dev_info, BDI_WRITEBACK);
+ inc_zone_page_state(tmp_page, NR_WRITEBACK_TEMP);
+- end_page_writeback(page);
+
+ spin_lock(&fc->lock);
+ list_add(&req->writepages_entry, &fi->writepages);
+@@ -1259,6 +1264,8 @@ static int fuse_writepage_locked(struct page *page)
+ fuse_flush_writepages(inode);
+ spin_unlock(&fc->lock);
+
++ end_page_writeback(page);
++
+ return 0;
+
+ err_free:
+diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
+index 89c4a58..52ffd24 100644
+--- a/fs/fuse/fuse_i.h
++++ b/fs/fuse/fuse_i.h
+@@ -103,6 +103,15 @@ struct fuse_inode {
+
+ /** List of writepage requestst (pending or sent) */
+ struct list_head writepages;
++
++ /** Miscellaneous bits describing inode state */
++ unsigned long state;
++};
++
++/** FUSE inode state bits */
++enum {
++ /** An operation changing file size is in progress */
++ FUSE_I_SIZE_UNSTABLE,
+ };
+
+ struct fuse_conn;
+diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
+index 1f82d95..912c250 100644
+--- a/fs/fuse/inode.c
++++ b/fs/fuse/inode.c
+@@ -92,6 +92,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
+ fi->attr_version = 0;
+ fi->writectr = 0;
+ fi->orig_ino = 0;
++ fi->state = 0;
+ INIT_LIST_HEAD(&fi->write_files);
+ INIT_LIST_HEAD(&fi->queued_writes);
+ INIT_LIST_HEAD(&fi->writepages);
+@@ -200,7 +201,8 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
+ loff_t oldsize;
+
+ spin_lock(&fc->lock);
+- if (attr_version != 0 && fi->attr_version > attr_version) {
++ if ((attr_version != 0 && fi->attr_version > attr_version) ||
++ test_bit(FUSE_I_SIZE_UNSTABLE, &fi->state)) {
+ spin_unlock(&fc->lock);
+ return;
+ }
+diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
+index f950059..a5f25a7 100644
+--- a/fs/isofs/inode.c
++++ b/fs/isofs/inode.c
+@@ -120,8 +120,8 @@ static void destroy_inodecache(void)
+
+ static int isofs_remount(struct super_block *sb, int *flags, char *data)
+ {
+- /* we probably want a lot more here */
+- *flags |= MS_RDONLY;
++ if (!(*flags & MS_RDONLY))
++ return -EROFS;
+ return 0;
+ }
+
+@@ -770,15 +770,6 @@ root_found:
+ */
+ s->s_maxbytes = 0x80000000000LL;
+
+- /*
+- * The CDROM is read-only, has no nodes (devices) on it, and since
+- * all of the files appear to be owned by root, we really do not want
+- * to allow suid. (suid or devices will not show up unless we have
+- * Rock Ridge extensions)
+- */
+-
+- s->s_flags |= MS_RDONLY /* | MS_NODEV | MS_NOSUID */;
+-
+ /* Set this for reference. Its not currently used except on write
+ which we don't have .. */
+
+@@ -1535,6 +1526,9 @@ struct inode *isofs_iget(struct super_block *sb,
+ static struct dentry *isofs_mount(struct file_system_type *fs_type,
+ int flags, const char *dev_name, void *data)
+ {
++ /* We don't support read-write mounts */
++ if (!(flags & MS_RDONLY))
++ return ERR_PTR(-EACCES);
+ return mount_bdev(fs_type, flags, dev_name, data, isofs_fill_super);
+ }
+
+diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
+index 65221a0..16eacec 100644
+--- a/fs/nilfs2/page.c
++++ b/fs/nilfs2/page.c
+@@ -94,6 +94,7 @@ void nilfs_forget_buffer(struct buffer_head *bh)
+ clear_buffer_nilfs_volatile(bh);
+ clear_buffer_nilfs_checked(bh);
+ clear_buffer_nilfs_redirected(bh);
++ clear_buffer_async_write(bh);
+ clear_buffer_dirty(bh);
+ if (nilfs_page_buffers_clean(page))
+ __nilfs_clear_page_dirty(page);
+@@ -390,6 +391,7 @@ void nilfs_clear_dirty_pages(struct address_space *mapping)
+ bh = head = page_buffers(page);
+ do {
+ lock_buffer(bh);
++ clear_buffer_async_write(bh);
+ clear_buffer_dirty(bh);
+ clear_buffer_nilfs_volatile(bh);
+ clear_buffer_nilfs_checked(bh);
+diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
+index 6f24e67..233d3ed 100644
+--- a/fs/nilfs2/segment.c
++++ b/fs/nilfs2/segment.c
+@@ -662,7 +662,7 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode,
+
+ bh = head = page_buffers(page);
+ do {
+- if (!buffer_dirty(bh))
++ if (!buffer_dirty(bh) || buffer_async_write(bh))
+ continue;
+ get_bh(bh);
+ list_add_tail(&bh->b_assoc_buffers, listp);
+@@ -696,7 +696,8 @@ static void nilfs_lookup_dirty_node_buffers(struct inode *inode,
+ for (i = 0; i < pagevec_count(&pvec); i++) {
+ bh = head = page_buffers(pvec.pages[i]);
+ do {
+- if (buffer_dirty(bh)) {
++ if (buffer_dirty(bh) &&
++ !buffer_async_write(bh)) {
+ get_bh(bh);
+ list_add_tail(&bh->b_assoc_buffers,
+ listp);
+@@ -1576,6 +1577,7 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci)
+
+ list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
+ b_assoc_buffers) {
++ set_buffer_async_write(bh);
+ if (bh->b_page != bd_page) {
+ if (bd_page) {
+ lock_page(bd_page);
+@@ -1589,6 +1591,7 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci)
+
+ list_for_each_entry(bh, &segbuf->sb_payload_buffers,
+ b_assoc_buffers) {
++ set_buffer_async_write(bh);
+ if (bh == segbuf->sb_super_root) {
+ if (bh->b_page != bd_page) {
+ lock_page(bd_page);
+@@ -1674,6 +1677,7 @@ static void nilfs_abort_logs(struct list_head *logs, int err)
+ list_for_each_entry(segbuf, logs, sb_list) {
+ list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
+ b_assoc_buffers) {
++ clear_buffer_async_write(bh);
+ if (bh->b_page != bd_page) {
+ if (bd_page)
+ end_page_writeback(bd_page);
+@@ -1683,6 +1687,7 @@ static void nilfs_abort_logs(struct list_head *logs, int err)
+
+ list_for_each_entry(bh, &segbuf->sb_payload_buffers,
+ b_assoc_buffers) {
++ clear_buffer_async_write(bh);
+ if (bh == segbuf->sb_super_root) {
+ if (bh->b_page != bd_page) {
+ end_page_writeback(bd_page);
+@@ -1752,6 +1757,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
+ b_assoc_buffers) {
+ set_buffer_uptodate(bh);
+ clear_buffer_dirty(bh);
++ clear_buffer_async_write(bh);
+ if (bh->b_page != bd_page) {
+ if (bd_page)
+ end_page_writeback(bd_page);
+@@ -1773,6 +1779,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
+ b_assoc_buffers) {
+ set_buffer_uptodate(bh);
+ clear_buffer_dirty(bh);
++ clear_buffer_async_write(bh);
+ clear_buffer_delay(bh);
+ clear_buffer_nilfs_volatile(bh);
+ clear_buffer_nilfs_redirected(bh);
+diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
+index a506360..0c2f912 100644
+--- a/fs/notify/fanotify/fanotify.c
++++ b/fs/notify/fanotify/fanotify.c
+@@ -18,6 +18,12 @@ static bool should_merge(struct fsnotify_event *old, struct fsnotify_event *new)
+ old->tgid == new->tgid) {
+ switch (old->data_type) {
+ case (FSNOTIFY_EVENT_PATH):
++#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
++ /* dont merge two permission events */
++ if ((old->mask & FAN_ALL_PERM_EVENTS) &&
++ (new->mask & FAN_ALL_PERM_EVENTS))
++ return false;
++#endif
+ if ((old->path.mnt == new->path.mnt) &&
+ (old->path.dentry == new->path.dentry))
+ return true;
+diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c
+index 7eb1c0c..cf22847 100644
+--- a/fs/ocfs2/extent_map.c
++++ b/fs/ocfs2/extent_map.c
+@@ -782,7 +782,6 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+ cpos = map_start >> osb->s_clustersize_bits;
+ mapping_end = ocfs2_clusters_for_bytes(inode->i_sb,
+ map_start + map_len);
+- mapping_end -= cpos;
+ is_last = 0;
+ while (cpos < mapping_end && !is_last) {
+ u32 fe_flags;
+diff --git a/include/linux/hid.h b/include/linux/hid.h
+index 331e2ef..19fe719 100644
+--- a/include/linux/hid.h
++++ b/include/linux/hid.h
+@@ -416,10 +416,12 @@ struct hid_report {
+ struct hid_device *device; /* associated device */
+ };
+
++#define HID_MAX_IDS 256
++
+ struct hid_report_enum {
+ unsigned numbered;
+ struct list_head report_list;
+- struct hid_report *report_id_hash[256];
++ struct hid_report *report_id_hash[HID_MAX_IDS];
+ };
+
+ #define HID_REPORT_TYPES 3
+@@ -716,6 +718,10 @@ void hid_output_report(struct hid_report *report, __u8 *data);
+ struct hid_device *hid_allocate_device(void);
+ struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id);
+ int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
++struct hid_report *hid_validate_values(struct hid_device *hid,
++ unsigned int type, unsigned int id,
++ unsigned int field_index,
++ unsigned int report_counts);
+ int hid_check_keys_pressed(struct hid_device *hid);
+ int hid_connect(struct hid_device *hid, unsigned int connect_mask);
+ void hid_disconnect(struct hid_device *hid);
+diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
+index ba45e6b..f5a21d0 100644
+--- a/include/linux/icmpv6.h
++++ b/include/linux/icmpv6.h
+@@ -123,6 +123,8 @@ static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff *skb)
+ #define ICMPV6_NOT_NEIGHBOUR 2
+ #define ICMPV6_ADDR_UNREACH 3
+ #define ICMPV6_PORT_UNREACH 4
++#define ICMPV6_POLICY_FAIL 5
++#define ICMPV6_REJECT_ROUTE 6
+
+ /*
+ * Codes for Time Exceeded
+diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
+index 0c99776..84b1447 100644
+--- a/include/linux/ipv6.h
++++ b/include/linux/ipv6.h
+@@ -255,6 +255,7 @@ struct inet6_skb_parm {
+ #define IP6SKB_XFRM_TRANSFORMED 1
+ #define IP6SKB_FORWARDED 2
+ #define IP6SKB_REROUTED 4
++#define IP6SKB_FRAGMENTED 16
+ };
+
+ #define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb))
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index d0493f6..305fd75 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -865,7 +865,8 @@ extern void pagefault_out_of_memory(void);
+ * Flags passed to show_mem() and show_free_areas() to suppress output in
+ * various contexts.
+ */
+-#define SHOW_MEM_FILTER_NODES (0x0001u) /* filter disallowed nodes */
++#define SHOW_MEM_FILTER_NODES (0x0001u) /* disallowed nodes */
++#define SHOW_MEM_FILTER_PAGE_COUNT (0x0002u) /* page type count */
+
+ extern void show_free_areas(unsigned int flags);
+ extern bool skip_free_areas_node(unsigned int flags, int nid);
+diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
+index 3cfcfea..eeb6a29 100644
+--- a/include/linux/perf_event.h
++++ b/include/linux/perf_event.h
+@@ -927,7 +927,7 @@ struct perf_cpu_context {
+ int exclusive;
+ struct list_head rotation_list;
+ int jiffies_interval;
+- struct pmu *active_pmu;
++ struct pmu *unique_pmu;
+ struct perf_cgroup *cgrp;
+ };
+
+diff --git a/include/linux/rculist.h b/include/linux/rculist.h
+index 6f95e24..3863352 100644
+--- a/include/linux/rculist.h
++++ b/include/linux/rculist.h
+@@ -254,8 +254,9 @@ static inline void list_splice_init_rcu(struct list_head *list,
+ */
+ #define list_first_or_null_rcu(ptr, type, member) \
+ ({struct list_head *__ptr = (ptr); \
+- struct list_head __rcu *__next = list_next_rcu(__ptr); \
+- likely(__ptr != __next) ? container_of(__next, type, member) : NULL; \
++ struct list_head *__next = ACCESS_ONCE(__ptr->next); \
++ likely(__ptr != __next) ? \
++ list_entry_rcu(__next, type, member) : NULL; \
+ })
+
+ /**
+diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
+index 03354d5..0daa46b 100644
+--- a/include/linux/usb/hcd.h
++++ b/include/linux/usb/hcd.h
+@@ -395,7 +395,7 @@ extern int usb_hcd_pci_probe(struct pci_dev *dev,
+ extern void usb_hcd_pci_remove(struct pci_dev *dev);
+ extern void usb_hcd_pci_shutdown(struct pci_dev *dev);
+
+-#ifdef CONFIG_PM_SLEEP
++#ifdef CONFIG_PM
+ extern const struct dev_pm_ops usb_hcd_pci_pm_ops;
+ #endif
+ #endif /* CONFIG_PCI */
+diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
+index e9ff3fc..34b06da 100644
+--- a/include/net/inetpeer.h
++++ b/include/net/inetpeer.h
+@@ -41,6 +41,10 @@ struct inet_peer {
+ u32 pmtu_orig;
+ u32 pmtu_learned;
+ struct inetpeer_addr_base redirect_learned;
++ union {
++ struct list_head gc_list;
++ struct rcu_head gc_rcu;
++ };
+ /*
+ * Once inet_peer is queued for deletion (refcnt == -1), following fields
+ * are not available: rid, ip_id_count, tcp_ts, tcp_ts_stamp
+@@ -96,6 +100,8 @@ static inline struct inet_peer *inet_getpeer_v6(const struct in6_addr *v6daddr,
+ extern void inet_putpeer(struct inet_peer *p);
+ extern bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout);
+
++extern void inetpeer_invalidate_tree(int family);
++
+ /*
+ * temporary check to make sure we dont access rid, ip_id_count, tcp_ts,
+ * tcp_ts_stamp if no refcount is taken on inet_peer
+diff --git a/include/net/ip.h b/include/net/ip.h
+index eca0ef7..06aed72 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -266,9 +266,11 @@ int ip_dont_fragment(struct sock *sk, struct dst_entry *dst)
+
+ extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more);
+
+-static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, struct sock *sk)
++static inline void ip_select_ident(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk)
+ {
+- if (iph->frag_off & htons(IP_DF)) {
++ struct iphdr *iph = ip_hdr(skb);
++
++ if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) {
+ /* This is only to work around buggy Windows95/2000
+ * VJ compression implementations. If the ID field
+ * does not change, they drop every other packet in
+@@ -280,9 +282,11 @@ static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, str
+ __ip_select_ident(iph, dst, 0);
+ }
+
+-static inline void ip_select_ident_more(struct iphdr *iph, struct dst_entry *dst, struct sock *sk, int more)
++static inline void ip_select_ident_more(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk, int more)
+ {
+- if (iph->frag_off & htons(IP_DF)) {
++ struct iphdr *iph = ip_hdr(skb);
++
++ if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) {
+ if (sk && inet_sk(sk)->inet_daddr) {
+ iph->id = htons(inet_sk(sk)->inet_id);
+ inet_sk(sk)->inet_id += 1 + more;
+diff --git a/include/net/ipip.h b/include/net/ipip.h
+index a32654d..4dccfe3 100644
+--- a/include/net/ipip.h
++++ b/include/net/ipip.h
+@@ -50,7 +50,7 @@ struct ip_tunnel_prl_entry {
+ int pkt_len = skb->len - skb_transport_offset(skb); \
+ \
+ skb->ip_summed = CHECKSUM_NONE; \
+- ip_select_ident(iph, &rt->dst, NULL); \
++ ip_select_ident(skb, &rt->dst, NULL); \
+ \
+ err = ip_local_out(skb); \
+ if (likely(net_xmit_eval(err) == 0)) { \
+diff --git a/kernel/cgroup.c b/kernel/cgroup.c
+index d2a01fe..2a1ffb7 100644
+--- a/kernel/cgroup.c
++++ b/kernel/cgroup.c
+@@ -3504,6 +3504,7 @@ static int cgroup_write_event_control(struct cgroup *cgrp, struct cftype *cft,
+ const char *buffer)
+ {
+ struct cgroup_event *event = NULL;
++ struct cgroup *cgrp_cfile;
+ unsigned int efd, cfd;
+ struct file *efile = NULL;
+ struct file *cfile = NULL;
+@@ -3559,6 +3560,16 @@ static int cgroup_write_event_control(struct cgroup *cgrp, struct cftype *cft,
+ goto fail;
+ }
+
++ /*
++ * The file to be monitored must be in the same cgroup as
++ * cgroup.event_control is.
++ */
++ cgrp_cfile = __d_cgrp(cfile->f_dentry->d_parent);
++ if (cgrp_cfile != cgrp) {
++ ret = -EINVAL;
++ goto fail;
++ }
++
+ if (!event->cft->register_event || !event->cft->unregister_event) {
+ ret = -EINVAL;
+ goto fail;
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 5bbe443..83d5621 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -242,9 +242,9 @@ perf_cgroup_match(struct perf_event *event)
+ return !event->cgrp || event->cgrp == cpuctx->cgrp;
+ }
+
+-static inline void perf_get_cgroup(struct perf_event *event)
++static inline bool perf_tryget_cgroup(struct perf_event *event)
+ {
+- css_get(&event->cgrp->css);
++ return css_tryget(&event->cgrp->css);
+ }
+
+ static inline void perf_put_cgroup(struct perf_event *event)
+@@ -360,6 +360,8 @@ void perf_cgroup_switch(struct task_struct *task, int mode)
+
+ list_for_each_entry_rcu(pmu, &pmus, entry) {
+ cpuctx = this_cpu_ptr(pmu->pmu_cpu_context);
++ if (cpuctx->unique_pmu != pmu)
++ continue; /* ensure we process each cpuctx once */
+
+ /*
+ * perf_cgroup_events says at least one
+@@ -383,9 +385,10 @@ void perf_cgroup_switch(struct task_struct *task, int mode)
+
+ if (mode & PERF_CGROUP_SWIN) {
+ WARN_ON_ONCE(cpuctx->cgrp);
+- /* set cgrp before ctxsw in to
+- * allow event_filter_match() to not
+- * have to pass task around
++ /*
++ * set cgrp before ctxsw in to allow
++ * event_filter_match() to not have to pass
++ * task around
+ */
+ cpuctx->cgrp = perf_cgroup_from_task(task);
+ cpu_ctx_sched_in(cpuctx, EVENT_ALL, task);
+@@ -473,7 +476,11 @@ static inline int perf_cgroup_connect(int fd, struct perf_event *event,
+ event->cgrp = cgrp;
+
+ /* must be done before we fput() the file */
+- perf_get_cgroup(event);
++ if (!perf_tryget_cgroup(event)) {
++ event->cgrp = NULL;
++ ret = -ENOENT;
++ goto out;
++ }
+
+ /*
+ * all events in a group must monitor
+@@ -4377,7 +4384,7 @@ static void perf_event_task_event(struct perf_task_event *task_event)
+ rcu_read_lock();
+ list_for_each_entry_rcu(pmu, &pmus, entry) {
+ cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
+- if (cpuctx->active_pmu != pmu)
++ if (cpuctx->unique_pmu != pmu)
+ goto next;
+ perf_event_task_ctx(&cpuctx->ctx, task_event);
+
+@@ -4523,7 +4530,7 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event)
+ rcu_read_lock();
+ list_for_each_entry_rcu(pmu, &pmus, entry) {
+ cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
+- if (cpuctx->active_pmu != pmu)
++ if (cpuctx->unique_pmu != pmu)
+ goto next;
+ perf_event_comm_ctx(&cpuctx->ctx, comm_event);
+
+@@ -4719,7 +4726,7 @@ got_name:
+ rcu_read_lock();
+ list_for_each_entry_rcu(pmu, &pmus, entry) {
+ cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
+- if (cpuctx->active_pmu != pmu)
++ if (cpuctx->unique_pmu != pmu)
+ goto next;
+ perf_event_mmap_ctx(&cpuctx->ctx, mmap_event,
+ vma->vm_flags & VM_EXEC);
+@@ -5741,8 +5748,8 @@ static void update_pmu_context(struct pmu *pmu, struct pmu *old_pmu)
+
+ cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu);
+
+- if (cpuctx->active_pmu == old_pmu)
+- cpuctx->active_pmu = pmu;
++ if (cpuctx->unique_pmu == old_pmu)
++ cpuctx->unique_pmu = pmu;
+ }
+ }
+
+@@ -5877,7 +5884,7 @@ skip_type:
+ cpuctx->ctx.pmu = pmu;
+ cpuctx->jiffies_interval = 1;
+ INIT_LIST_HEAD(&cpuctx->rotation_list);
+- cpuctx->active_pmu = pmu;
++ cpuctx->unique_pmu = pmu;
+ }
+
+ got_cpu_context:
+diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
+index 59474c5..c261da7 100644
+--- a/kernel/sched_fair.c
++++ b/kernel/sched_fair.c
+@@ -4890,11 +4890,15 @@ static void task_fork_fair(struct task_struct *p)
+
+ update_rq_clock(rq);
+
+- if (unlikely(task_cpu(p) != this_cpu)) {
+- rcu_read_lock();
+- __set_task_cpu(p, this_cpu);
+- rcu_read_unlock();
+- }
++ /*
++ * Not only the cpu but also the task_group of the parent might have
++ * been changed after parent->se.parent,cfs_rq were copied to
++ * child->se.parent,cfs_rq. So call __set_task_cpu() to make those
++ * of child point to valid ones.
++ */
++ rcu_read_lock();
++ __set_task_cpu(p, this_cpu);
++ rcu_read_unlock();
+
+ update_curr(cfs_rq);
+
+diff --git a/lib/show_mem.c b/lib/show_mem.c
+index 4407f8c..b7c7231 100644
+--- a/lib/show_mem.c
++++ b/lib/show_mem.c
+@@ -18,6 +18,9 @@ void show_mem(unsigned int filter)
+ printk("Mem-Info:\n");
+ show_free_areas(filter);
+
++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT)
++ return;
++
+ for_each_online_pgdat(pgdat) {
+ unsigned long i, flags;
+
+diff --git a/mm/huge_memory.c b/mm/huge_memory.c
+index d80ac4b..ed0ed8a 100644
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -1882,6 +1882,8 @@ static void collapse_huge_page(struct mm_struct *mm,
+ goto out;
+
+ vma = find_vma(mm, address);
++ if (!vma)
++ goto out;
+ hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK;
+ hend = vma->vm_end & HPAGE_PMD_MASK;
+ if (address < hstart || address + HPAGE_PMD_SIZE > hend)
+diff --git a/mm/memcontrol.c b/mm/memcontrol.c
+index d027a24..204de6a 100644
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -4385,7 +4385,13 @@ static int compare_thresholds(const void *a, const void *b)
+ const struct mem_cgroup_threshold *_a = a;
+ const struct mem_cgroup_threshold *_b = b;
+
+- return _a->threshold - _b->threshold;
++ if (_a->threshold > _b->threshold)
++ return 1;
++
++ if (_a->threshold < _b->threshold)
++ return -1;
++
++ return 0;
+ }
+
+ static int mem_cgroup_oom_notify_cb(struct mem_cgroup *memcg)
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index b5afea2..d8762b2 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -1760,6 +1760,13 @@ void warn_alloc_failed(gfp_t gfp_mask, int order, const char *fmt, ...)
+ return;
+
+ /*
++ * Walking all memory to count page types is very expensive and should
++ * be inhibited in non-blockable contexts.
++ */
++ if (!(gfp_mask & __GFP_WAIT))
++ filter |= SHOW_MEM_FILTER_PAGE_COUNT;
++
++ /*
+ * This documents exceptions given to allocations in certain
+ * contexts that are allowed to allocate outside current's set
+ * of allowed nodes.
+diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
+index b81500c..a06deca 100644
+--- a/net/bridge/br_multicast.c
++++ b/net/bridge/br_multicast.c
+@@ -1155,7 +1155,8 @@ static int br_ip6_multicast_query(struct net_bridge *br,
+ mld2q = (struct mld2_query *)icmp6_hdr(skb);
+ if (!mld2q->mld2q_nsrcs)
+ group = &mld2q->mld2q_mca;
+- max_delay = mld2q->mld2q_mrc ? MLDV2_MRC(mld2q->mld2q_mrc) : 1;
++
++ max_delay = max(msecs_to_jiffies(MLDV2_MRC(ntohs(mld2q->mld2q_mrc))), 1UL);
+ }
+
+ if (!group)
+diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
+index dd147d7..8ac946f 100644
+--- a/net/bridge/br_stp.c
++++ b/net/bridge/br_stp.c
+@@ -189,7 +189,7 @@ static void br_record_config_information(struct net_bridge_port *p,
+ p->designated_age = jiffies + bpdu->message_age;
+
+ mod_timer(&p->message_age_timer, jiffies
+- + (p->br->max_age - bpdu->message_age));
++ + (bpdu->max_age - bpdu->message_age));
+ }
+
+ /* called under bridge lock */
+diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c
+index 5cf5222..84efbe4 100644
+--- a/net/caif/cfctrl.c
++++ b/net/caif/cfctrl.c
+@@ -288,9 +288,10 @@ int cfctrl_linkup_request(struct cflayer *layer,
+
+ count = cfctrl_cancel_req(&cfctrl->serv.layer,
+ user_layer);
+- if (count != 1)
++ if (count != 1) {
+ pr_err("Could not remove request (%d)", count);
+ return -ENODEV;
++ }
+ }
+ return 0;
+ }
+diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
+index f4f3f58..a70f426 100644
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -1719,6 +1719,8 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc,
+ dout("osdc_start_request failed map, "
+ " will retry %lld\n", req->r_tid);
+ rc = 0;
++ } else {
++ __unregister_request(osdc, req);
+ }
+ goto out_unlock;
+ }
+diff --git a/net/core/netpoll.c b/net/core/netpoll.c
+index db4bb7a..9649cea 100644
+--- a/net/core/netpoll.c
++++ b/net/core/netpoll.c
+@@ -923,15 +923,14 @@ EXPORT_SYMBOL_GPL(__netpoll_cleanup);
+
+ void netpoll_cleanup(struct netpoll *np)
+ {
+- if (!np->dev)
+- return;
+-
+ rtnl_lock();
++ if (!np->dev)
++ goto out;
+ __netpoll_cleanup(np);
+- rtnl_unlock();
+-
+ dev_put(np->dev);
+ np->dev = NULL;
++out:
++ rtnl_unlock();
+ }
+ EXPORT_SYMBOL(netpoll_cleanup);
+
+diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
+index 77a65f0..f0bdd36 100644
+--- a/net/core/sysctl_net_core.c
++++ b/net/core/sysctl_net_core.c
+@@ -19,6 +19,9 @@
+ #include <net/sock.h>
+ #include <net/net_ratelimit.h>
+
++static int zero = 0;
++static int ushort_max = USHRT_MAX;
++
+ #ifdef CONFIG_RPS
+ static int rps_sock_flow_sysctl(ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+@@ -192,7 +195,9 @@ static struct ctl_table netns_core_table[] = {
+ .data = &init_net.core.sysctl_somaxconn,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+- .proc_handler = proc_dointvec
++ .extra1 = &zero,
++ .extra2 = &ushort_max,
++ .proc_handler = proc_dointvec_minmax
+ },
+ { }
+ };
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
+index cd2d639..c7c6724 100644
+--- a/net/ipv4/fib_trie.c
++++ b/net/ipv4/fib_trie.c
+@@ -72,7 +72,6 @@
+ #include <linux/init.h>
+ #include <linux/list.h>
+ #include <linux/slab.h>
+-#include <linux/prefetch.h>
+ #include <linux/export.h>
+ #include <net/net_namespace.h>
+ #include <net/ip.h>
+@@ -1773,10 +1772,8 @@ static struct leaf *leaf_walk_rcu(struct tnode *p, struct rt_trie_node *c)
+ if (!c)
+ continue;
+
+- if (IS_LEAF(c)) {
+- prefetch(rcu_dereference_rtnl(p->child[idx]));
++ if (IS_LEAF(c))
+ return (struct leaf *) c;
+- }
+
+ /* Rescan start scanning in new node */
+ p = (struct tnode *) c;
+diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
+index c8989a7..75b0860 100644
+--- a/net/ipv4/igmp.c
++++ b/net/ipv4/igmp.c
+@@ -342,7 +342,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
+ pip->saddr = fl4.saddr;
+ pip->protocol = IPPROTO_IGMP;
+ pip->tot_len = 0; /* filled in later */
+- ip_select_ident(pip, &rt->dst, NULL);
++ ip_select_ident(skb, &rt->dst, NULL);
+ ((u8*)&pip[1])[0] = IPOPT_RA;
+ ((u8*)&pip[1])[1] = 4;
+ ((u8*)&pip[1])[2] = 0;
+@@ -683,7 +683,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
+ iph->daddr = dst;
+ iph->saddr = fl4.saddr;
+ iph->protocol = IPPROTO_IGMP;
+- ip_select_ident(iph, &rt->dst, NULL);
++ ip_select_ident(skb, &rt->dst, NULL);
+ ((u8*)&iph[1])[0] = IPOPT_RA;
+ ((u8*)&iph[1])[1] = 4;
+ ((u8*)&iph[1])[2] = 0;
+@@ -705,7 +705,7 @@ static void igmp_gq_timer_expire(unsigned long data)
+
+ in_dev->mr_gq_running = 0;
+ igmpv3_send_report(in_dev, NULL);
+- __in_dev_put(in_dev);
++ in_dev_put(in_dev);
+ }
+
+ static void igmp_ifc_timer_expire(unsigned long data)
+@@ -717,7 +717,7 @@ static void igmp_ifc_timer_expire(unsigned long data)
+ in_dev->mr_ifc_count--;
+ igmp_ifc_start_timer(in_dev, IGMP_Unsolicited_Report_Interval);
+ }
+- __in_dev_put(in_dev);
++ in_dev_put(in_dev);
+ }
+
+ static void igmp_ifc_event(struct in_device *in_dev)
+diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
+index 86f13c67..58c4e696 100644
+--- a/net/ipv4/inetpeer.c
++++ b/net/ipv4/inetpeer.c
+@@ -17,6 +17,7 @@
+ #include <linux/kernel.h>
+ #include <linux/mm.h>
+ #include <linux/net.h>
++#include <linux/workqueue.h>
+ #include <net/ip.h>
+ #include <net/inetpeer.h>
+ #include <net/secure_seq.h>
+@@ -31,8 +32,8 @@
+ * At the moment of writing this notes identifier of IP packets is generated
+ * to be unpredictable using this code only for packets subjected
+ * (actually or potentially) to defragmentation. I.e. DF packets less than
+- * PMTU in size uses a constant ID and do not use this code (see
+- * ip_select_ident() in include/net/ip.h).
++ * PMTU in size when local fragmentation is disabled use a constant ID and do
++ * not use this code (see ip_select_ident() in include/net/ip.h).
+ *
+ * Route cache entries hold references to our nodes.
+ * New cache entries get references via lookup by destination IP address in
+@@ -66,6 +67,11 @@
+
+ static struct kmem_cache *peer_cachep __read_mostly;
+
++static LIST_HEAD(gc_list);
++static const int gc_delay = 60 * HZ;
++static struct delayed_work gc_work;
++static DEFINE_SPINLOCK(gc_lock);
++
+ #define node_height(x) x->avl_height
+
+ #define peer_avl_empty ((struct inet_peer *)&peer_fake_node)
+@@ -102,6 +108,50 @@ int inet_peer_threshold __read_mostly = 65536 + 128; /* start to throw entries m
+ int inet_peer_minttl __read_mostly = 120 * HZ; /* TTL under high load: 120 sec */
+ int inet_peer_maxttl __read_mostly = 10 * 60 * HZ; /* usual time to live: 10 min */
+
++static void inetpeer_gc_worker(struct work_struct *work)
++{
++ struct inet_peer *p, *n;
++ LIST_HEAD(list);
++
++ spin_lock_bh(&gc_lock);
++ list_replace_init(&gc_list, &list);
++ spin_unlock_bh(&gc_lock);
++
++ if (list_empty(&list))
++ return;
++
++ list_for_each_entry_safe(p, n, &list, gc_list) {
++
++ if(need_resched())
++ cond_resched();
++
++ if (p->avl_left != peer_avl_empty) {
++ list_add_tail(&p->avl_left->gc_list, &list);
++ p->avl_left = peer_avl_empty;
++ }
++
++ if (p->avl_right != peer_avl_empty) {
++ list_add_tail(&p->avl_right->gc_list, &list);
++ p->avl_right = peer_avl_empty;
++ }
++
++ n = list_entry(p->gc_list.next, struct inet_peer, gc_list);
++
++ if (!atomic_read(&p->refcnt)) {
++ list_del(&p->gc_list);
++ kmem_cache_free(peer_cachep, p);
++ }
++ }
++
++ if (list_empty(&list))
++ return;
++
++ spin_lock_bh(&gc_lock);
++ list_splice(&list, &gc_list);
++ spin_unlock_bh(&gc_lock);
++
++ schedule_delayed_work(&gc_work, gc_delay);
++}
+
+ /* Called from ip_output.c:ip_init */
+ void __init inet_initpeers(void)
+@@ -126,6 +176,7 @@ void __init inet_initpeers(void)
+ 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC,
+ NULL);
+
++ INIT_DELAYED_WORK_DEFERRABLE(&gc_work, inetpeer_gc_worker);
+ }
+
+ static int addr_compare(const struct inetpeer_addr *a,
+@@ -448,7 +499,7 @@ relookup:
+ p->pmtu_expires = 0;
+ p->pmtu_orig = 0;
+ memset(&p->redirect_learned, 0, sizeof(p->redirect_learned));
+-
++ INIT_LIST_HEAD(&p->gc_list);
+
+ /* Link the node. */
+ link_to_pool(p, base);
+@@ -508,3 +559,38 @@ bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout)
+ return rc;
+ }
+ EXPORT_SYMBOL(inet_peer_xrlim_allow);
++
++static void inetpeer_inval_rcu(struct rcu_head *head)
++{
++ struct inet_peer *p = container_of(head, struct inet_peer, gc_rcu);
++
++ spin_lock_bh(&gc_lock);
++ list_add_tail(&p->gc_list, &gc_list);
++ spin_unlock_bh(&gc_lock);
++
++ schedule_delayed_work(&gc_work, gc_delay);
++}
++
++void inetpeer_invalidate_tree(int family)
++{
++ struct inet_peer *old, *new, *prev;
++ struct inet_peer_base *base = family_to_base(family);
++
++ write_seqlock_bh(&base->lock);
++
++ old = base->root;
++ if (old == peer_avl_empty_rcu)
++ goto out;
++
++ new = peer_avl_empty_rcu;
++
++ prev = cmpxchg(&base->root, old, new);
++ if (prev == old) {
++ base->total = 0;
++ call_rcu(&prev->gc_rcu, inetpeer_inval_rcu);
++ }
++
++out:
++ write_sequnlock_bh(&base->lock);
++}
++EXPORT_SYMBOL(inetpeer_invalidate_tree);
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+index 0bc95f3..daf408e 100644
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -162,7 +162,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
+ iph->daddr = (opt && opt->opt.srr ? opt->opt.faddr : daddr);
+ iph->saddr = saddr;
+ iph->protocol = sk->sk_protocol;
+- ip_select_ident(iph, &rt->dst, sk);
++ ip_select_ident(skb, &rt->dst, sk);
+
+ if (opt && opt->opt.optlen) {
+ iph->ihl += opt->opt.optlen>>2;
+@@ -390,7 +390,7 @@ packet_routed:
+ ip_options_build(skb, &inet_opt->opt, inet->inet_daddr, rt, 0);
+ }
+
+- ip_select_ident_more(iph, &rt->dst, sk,
++ ip_select_ident_more(skb, &rt->dst, sk,
+ (skb_shinfo(skb)->gso_segs ?: 1) - 1);
+
+ skb->priority = sk->sk_priority;
+@@ -1334,7 +1334,7 @@ struct sk_buff *__ip_make_skb(struct sock *sk,
+ iph->ihl = 5;
+ iph->tos = inet->tos;
+ iph->frag_off = df;
+- ip_select_ident(iph, &rt->dst, sk);
++ ip_select_ident(skb, &rt->dst, sk);
+ iph->ttl = ttl;
+ iph->protocol = sk->sk_protocol;
+ iph->saddr = fl4->saddr;
+diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
+index 0064394..b5e64e4 100644
+--- a/net/ipv4/ipmr.c
++++ b/net/ipv4/ipmr.c
+@@ -1576,7 +1576,7 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr)
+ iph->protocol = IPPROTO_IPIP;
+ iph->ihl = 5;
+ iph->tot_len = htons(skb->len);
+- ip_select_ident(iph, skb_dst(skb), NULL);
++ ip_select_ident(skb, skb_dst(skb), NULL);
+ ip_send_check(iph);
+
+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
+index e1d4f30..2815014 100644
+--- a/net/ipv4/raw.c
++++ b/net/ipv4/raw.c
+@@ -380,7 +380,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
+ iph->check = 0;
+ iph->tot_len = htons(length);
+ if (!iph->id)
+- ip_select_ident(iph, &rt->dst, NULL);
++ ip_select_ident(skb, &rt->dst, NULL);
+
+ iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
+ }
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 94cdbc5..c45a155a3 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -939,6 +939,7 @@ static void rt_cache_invalidate(struct net *net)
+ get_random_bytes(&shuffle, sizeof(shuffle));
+ atomic_add(shuffle + 1U, &net->ipv4.rt_genid);
+ redirect_genid++;
++ inetpeer_invalidate_tree(AF_INET);
+ }
+
+ /*
+diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c
+index f376b05..b78eac2 100644
+--- a/net/ipv4/tcp_cubic.c
++++ b/net/ipv4/tcp_cubic.c
+@@ -204,8 +204,8 @@ static u32 cubic_root(u64 a)
+ */
+ static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
+ {
+- u64 offs;
+- u32 delta, t, bic_target, max_cnt;
++ u32 delta, bic_target, max_cnt;
++ u64 offs, t;
+
+ ca->ack_cnt++; /* count the number of ACKs */
+
+@@ -248,9 +248,11 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
+ * if the cwnd < 1 million packets !!!
+ */
+
++ t = (s32)(tcp_time_stamp - ca->epoch_start);
++ t += msecs_to_jiffies(ca->delay_min >> 3);
+ /* change the unit from HZ to bictcp_HZ */
+- t = ((tcp_time_stamp + msecs_to_jiffies(ca->delay_min>>3)
+- - ca->epoch_start) << BICTCP_HZ) / HZ;
++ t <<= BICTCP_HZ;
++ do_div(t, HZ);
+
+ if (t < ca->bic_K) /* t - K */
+ offs = ca->bic_K - t;
+@@ -412,7 +414,7 @@ static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us)
+ return;
+
+ /* Discard delay samples right after fast recovery */
+- if ((s32)(tcp_time_stamp - ca->epoch_start) < HZ)
++ if (ca->epoch_start && (s32)(tcp_time_stamp - ca->epoch_start) < HZ)
+ return;
+
+ delay = (rtt_us << 3) / USEC_PER_MSEC;
+diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
+index ed4bf11..938553e 100644
+--- a/net/ipv4/xfrm4_mode_tunnel.c
++++ b/net/ipv4/xfrm4_mode_tunnel.c
+@@ -54,7 +54,7 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
+
+ top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?
+ 0 : (XFRM_MODE_SKB_CB(skb)->frag_off & htons(IP_DF));
+- ip_select_ident(top_iph, dst->child, NULL);
++ ip_select_ident(skb, dst->child, NULL);
+
+ top_iph->ttl = ip4_dst_hoplimit(dst->child);
+
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index 314bda2..5d41293 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -913,12 +913,10 @@ retry:
+ if (ifp->flags & IFA_F_OPTIMISTIC)
+ addr_flags |= IFA_F_OPTIMISTIC;
+
+- ift = !max_addresses ||
+- ipv6_count_addresses(idev) < max_addresses ?
+- ipv6_add_addr(idev, &addr, tmp_plen,
+- ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK,
+- addr_flags) : NULL;
+- if (!ift || IS_ERR(ift)) {
++ ift = ipv6_add_addr(idev, &addr, tmp_plen,
++ ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK,
++ addr_flags);
++ if (IS_ERR(ift)) {
+ in6_ifa_put(ifp);
+ in6_dev_put(idev);
+ printk(KERN_INFO
+diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
+index 90868fb..d505453 100644
+--- a/net/ipv6/icmp.c
++++ b/net/ipv6/icmp.c
+@@ -911,6 +911,14 @@ static const struct icmp6_err {
+ .err = ECONNREFUSED,
+ .fatal = 1,
+ },
++ { /* POLICY_FAIL */
++ .err = EACCES,
++ .fatal = 1,
++ },
++ { /* REJECT_ROUTE */
++ .err = EACCES,
++ .fatal = 1,
++ },
+ };
+
+ int icmpv6_err_convert(u8 type, u8 code, int *err)
+@@ -922,7 +930,7 @@ int icmpv6_err_convert(u8 type, u8 code, int *err)
+ switch (type) {
+ case ICMPV6_DEST_UNREACH:
+ fatal = 1;
+- if (code <= ICMPV6_PORT_UNREACH) {
++ if (code < ARRAY_SIZE(tab_unreach)) {
+ *err = tab_unreach[code].err;
+ fatal = tab_unreach[code].fatal;
+ }
+diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
+index 93718f3..443724f 100644
+--- a/net/ipv6/ip6_fib.c
++++ b/net/ipv6/ip6_fib.c
+@@ -862,14 +862,22 @@ static struct fib6_node * fib6_lookup_1(struct fib6_node *root,
+
+ if (ipv6_prefix_equal(&key->addr, args->addr, key->plen)) {
+ #ifdef CONFIG_IPV6_SUBTREES
+- if (fn->subtree)
+- fn = fib6_lookup_1(fn->subtree, args + 1);
++ if (fn->subtree) {
++ struct fib6_node *sfn;
++ sfn = fib6_lookup_1(fn->subtree,
++ args + 1);
++ if (!sfn)
++ goto backtrack;
++ fn = sfn;
++ }
+ #endif
+- if (!fn || fn->fn_flags & RTN_RTINFO)
++ if (fn->fn_flags & RTN_RTINFO)
+ return fn;
+ }
+ }
+-
++#ifdef CONFIG_IPV6_SUBTREES
++backtrack:
++#endif
+ if (fn->fn_flags & RTN_ROOT)
+ break;
+
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index db60043..91d0711 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -1125,6 +1125,8 @@ static inline int ip6_ufo_append_data(struct sock *sk,
+ * udp datagram
+ */
+ if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) {
++ struct frag_hdr fhdr;
++
+ skb = sock_alloc_send_skb(sk,
+ hh_len + fragheaderlen + transhdrlen + 20,
+ (flags & MSG_DONTWAIT), &err);
+@@ -1145,12 +1147,6 @@ static inline int ip6_ufo_append_data(struct sock *sk,
+
+ skb->ip_summed = CHECKSUM_PARTIAL;
+ skb->csum = 0;
+- }
+-
+- err = skb_append_datato_frags(sk,skb, getfrag, from,
+- (length - transhdrlen));
+- if (!err) {
+- struct frag_hdr fhdr;
+
+ /* Specify the length of each IPv6 datagram fragment.
+ * It has to be a multiple of 8.
+@@ -1161,15 +1157,10 @@ static inline int ip6_ufo_append_data(struct sock *sk,
+ ipv6_select_ident(&fhdr, rt);
+ skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
+ __skb_queue_tail(&sk->sk_write_queue, skb);
+-
+- return 0;
+ }
+- /* There is not enough support do UPD LSO,
+- * so follow normal path
+- */
+- kfree_skb(skb);
+
+- return err;
++ return skb_append_datato_frags(sk, skb, getfrag, from,
++ (length - transhdrlen));
+ }
+
+ static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src,
+@@ -1342,27 +1333,27 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
+ * --yoshfuji
+ */
+
+- cork->length += length;
+- if (length > mtu) {
+- int proto = sk->sk_protocol;
+- if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){
+- ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen);
+- return -EMSGSIZE;
+- }
+-
+- if (proto == IPPROTO_UDP &&
+- (rt->dst.dev->features & NETIF_F_UFO)) {
++ if ((length > mtu) && dontfrag && (sk->sk_protocol == IPPROTO_UDP ||
++ sk->sk_protocol == IPPROTO_RAW)) {
++ ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen);
++ return -EMSGSIZE;
++ }
+
+- err = ip6_ufo_append_data(sk, getfrag, from, length,
+- hh_len, fragheaderlen,
+- transhdrlen, mtu, flags, rt);
+- if (err)
+- goto error;
+- return 0;
+- }
++ skb = skb_peek_tail(&sk->sk_write_queue);
++ cork->length += length;
++ if (((length > mtu) ||
++ (skb && skb_is_gso(skb))) &&
++ (sk->sk_protocol == IPPROTO_UDP) &&
++ (rt->dst.dev->features & NETIF_F_UFO)) {
++ err = ip6_ufo_append_data(sk, getfrag, from, length,
++ hh_len, fragheaderlen,
++ transhdrlen, mtu, flags, rt);
++ if (err)
++ goto error;
++ return 0;
+ }
+
+- if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL)
++ if (!skb)
+ goto alloc_new_skb;
+
+ while (length > 0) {
+diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
+index c7ec4bb..d20a9be 100644
+--- a/net/ipv6/mcast.c
++++ b/net/ipv6/mcast.c
+@@ -2159,7 +2159,7 @@ static void mld_gq_timer_expire(unsigned long data)
+
+ idev->mc_gq_running = 0;
+ mld_send_report(idev, NULL);
+- __in6_dev_put(idev);
++ in6_dev_put(idev);
+ }
+
+ static void mld_ifc_timer_expire(unsigned long data)
+@@ -2172,7 +2172,7 @@ static void mld_ifc_timer_expire(unsigned long data)
+ if (idev->mc_ifc_count)
+ mld_ifc_start_timer(idev, idev->mc_maxdelay);
+ }
+- __in6_dev_put(idev);
++ in6_dev_put(idev);
+ }
+
+ static void mld_ifc_event(struct inet6_dev *idev)
+diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
+index 9ffc37f..bc55358 100644
+--- a/net/ipv6/ndisc.c
++++ b/net/ipv6/ndisc.c
+@@ -447,7 +447,6 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev,
+ struct sk_buff *skb;
+ struct icmp6hdr *hdr;
+ int len;
+- int err;
+ u8 *opt;
+
+ if (!dev->addr_len)
+@@ -457,14 +456,12 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev,
+ if (llinfo)
+ len += ndisc_opt_addr_space(dev);
+
+- skb = sock_alloc_send_skb(sk,
+- (MAX_HEADER + sizeof(struct ipv6hdr) +
+- len + LL_ALLOCATED_SPACE(dev)),
+- 1, &err);
++ skb = alloc_skb((MAX_HEADER + sizeof(struct ipv6hdr) +
++ len + LL_ALLOCATED_SPACE(dev)), GFP_ATOMIC);
+ if (!skb) {
+ ND_PRINTK0(KERN_ERR
+- "ICMPv6 ND: %s() failed to allocate an skb, err=%d.\n",
+- __func__, err);
++ "ICMPv6 ND: %s() failed to allocate an skb.\n",
++ __func__);
+ return NULL;
+ }
+
+@@ -492,6 +489,11 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev,
+ csum_partial(hdr,
+ len, 0));
+
++ /* Manually assign socket ownership as we avoid calling
++ * sock_alloc_send_pskb() to bypass wmem buffer limits
++ */
++ skb_set_owner_w(skb, sk);
++
+ return skb;
+ }
+
+diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
+index 411fe2c..eba5deb 100644
+--- a/net/ipv6/reassembly.c
++++ b/net/ipv6/reassembly.c
+@@ -517,6 +517,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
+ head->tstamp = fq->q.stamp;
+ ipv6_hdr(head)->payload_len = htons(payload_len);
+ IP6CB(head)->nhoff = nhoff;
++ IP6CB(head)->flags |= IP6SKB_FRAGMENTED;
+
+ /* Yes, and fold redundant checksum back. 8) */
+ if (head->ip_summed == CHECKSUM_COMPLETE)
+@@ -552,6 +553,9 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
+ const struct ipv6hdr *hdr = ipv6_hdr(skb);
+ struct net *net = dev_net(skb_dst(skb)->dev);
+
++ if (IP6CB(skb)->flags & IP6SKB_FRAGMENTED)
++ goto fail_hdr;
++
+ IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMREQDS);
+
+ /* Jumbo payload inhibits frag. header */
+@@ -572,6 +576,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
+ ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMOKS);
+
+ IP6CB(skb)->nhoff = (u8 *)fhdr - skb_network_header(skb);
++ IP6CB(skb)->flags |= IP6SKB_FRAGMENTED;
+ return 1;
+ }
+
+diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
+index aa2d720..38c0813 100644
+--- a/net/netfilter/ipvs/ip_vs_xmit.c
++++ b/net/netfilter/ipvs/ip_vs_xmit.c
+@@ -853,7 +853,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
+ iph->daddr = cp->daddr.ip;
+ iph->saddr = saddr;
+ iph->ttl = old_iph->ttl;
+- ip_select_ident(iph, &rt->dst, NULL);
++ ip_select_ident(skb, &rt->dst, NULL);
+
+ /* Another hack: avoid icmp_send in ip_fragment */
+ skb->local_df = 1;
+diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
+index f08b9166..caa5aff 100644
+--- a/net/sched/sch_htb.c
++++ b/net/sched/sch_htb.c
+@@ -86,7 +86,7 @@ struct htb_class {
+ unsigned int children;
+ struct htb_class *parent; /* parent class */
+
+- int prio; /* these two are used only by leaves... */
++ u32 prio; /* these two are used only by leaves... */
+ int quantum; /* but stored for parent-to-leaf return */
+
+ union {
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index 8104278..0b6a391 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -205,45 +205,24 @@ out:
+ in6_dev_put(idev);
+ }
+
+-/* Based on tcp_v6_xmit() in tcp_ipv6.c. */
+ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
+ {
+ struct sock *sk = skb->sk;
+ struct ipv6_pinfo *np = inet6_sk(sk);
+- struct flowi6 fl6;
+-
+- memset(&fl6, 0, sizeof(fl6));
+-
+- fl6.flowi6_proto = sk->sk_protocol;
+-
+- /* Fill in the dest address from the route entry passed with the skb
+- * and the source address from the transport.
+- */
+- ipv6_addr_copy(&fl6.daddr, &transport->ipaddr.v6.sin6_addr);
+- ipv6_addr_copy(&fl6.saddr, &transport->saddr.v6.sin6_addr);
+-
+- fl6.flowlabel = np->flow_label;
+- IP6_ECN_flow_xmit(sk, fl6.flowlabel);
+- if (ipv6_addr_type(&fl6.saddr) & IPV6_ADDR_LINKLOCAL)
+- fl6.flowi6_oif = transport->saddr.v6.sin6_scope_id;
+- else
+- fl6.flowi6_oif = sk->sk_bound_dev_if;
+-
+- if (np->opt && np->opt->srcrt) {
+- struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
+- ipv6_addr_copy(&fl6.daddr, rt0->addr);
+- }
++ struct flowi6 *fl6 = &transport->fl.u.ip6;
+
+ SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n",
+ __func__, skb, skb->len,
+- &fl6.saddr, &fl6.daddr);
++ &fl6->saddr, &fl6->daddr);
+
+- SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
++ IP6_ECN_flow_xmit(sk, fl6->flowlabel);
+
+ if (!(transport->param_flags & SPP_PMTUD_ENABLE))
+ skb->local_df = 1;
+
+- return ip6_xmit(sk, skb, &fl6, np->opt, np->tclass);
++ SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
++
++ return ip6_xmit(sk, skb, fl6, np->opt, np->tclass);
+ }
+
+ /* Returns the dst cache entry for the given source and destination ip
+@@ -256,10 +235,12 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
+ struct dst_entry *dst = NULL;
+ struct flowi6 *fl6 = &fl->u.ip6;
+ struct sctp_bind_addr *bp;
++ struct ipv6_pinfo *np = inet6_sk(sk);
+ struct sctp_sockaddr_entry *laddr;
+ union sctp_addr *baddr = NULL;
+ union sctp_addr *daddr = &t->ipaddr;
+ union sctp_addr dst_saddr;
++ struct in6_addr *final_p, final;
+ __u8 matchlen = 0;
+ __u8 bmatchlen;
+ sctp_scope_t scope;
+@@ -282,7 +263,8 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
+ SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6->saddr);
+ }
+
+- dst = ip6_dst_lookup_flow(sk, fl6, NULL, false);
++ final_p = fl6_update_dst(fl6, np->opt, &final);
++ dst = ip6_dst_lookup_flow(sk, fl6, final_p, false);
+ if (!asoc || saddr)
+ goto out;
+
+@@ -333,10 +315,12 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
+ }
+ }
+ rcu_read_unlock();
++
+ if (baddr) {
+ ipv6_addr_copy(&fl6->saddr, &baddr->v6.sin6_addr);
+ fl6->fl6_sport = baddr->v6.sin6_port;
+- dst = ip6_dst_lookup_flow(sk, fl6, NULL, false);
++ final_p = fl6_update_dst(fl6, np->opt, &final);
++ dst = ip6_dst_lookup_flow(sk, fl6, final_p, false);
+ }
+
+ out:
+diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
+index 9032d50..76388b0 100644
+--- a/net/sctp/sm_sideeffect.c
++++ b/net/sctp/sm_sideeffect.c
+@@ -1604,9 +1604,8 @@ 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_CHUNK(chunk));
++ SCTP_SACKH(&sackh));
+ break;
+
+ case SCTP_CMD_DISCARD_PACKET:
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index ba0108f..c53d01e 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -814,6 +814,9 @@ static int sctp_send_asconf_del_ip(struct sock *sk,
+ goto skip_mkasconf;
+ }
+
++ if (laddr == NULL)
++ return -EINVAL;
++
+ /* We do not need RCU protection throughout this loop
+ * because this is done under a socket lock from the
+ * setsockopt call.
+diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
+index e728d4c..a224a38 100644
+--- a/net/tipc/eth_media.c
++++ b/net/tipc/eth_media.c
+@@ -53,6 +53,7 @@ struct eth_bearer {
+ struct tipc_bearer *bearer;
+ struct net_device *dev;
+ struct packet_type tipc_packet_type;
++ struct work_struct setup;
+ };
+
+ static struct eth_bearer eth_bearers[MAX_ETH_BEARERS];
+@@ -121,6 +122,17 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev,
+ }
+
+ /**
++ * setup_bearer - setup association between Ethernet bearer and interface
++ */
++static void setup_bearer(struct work_struct *work)
++{
++ struct eth_bearer *eb_ptr =
++ container_of(work, struct eth_bearer, setup);
++
++ dev_add_pack(&eb_ptr->tipc_packet_type);
++}
++
++/**
+ * enable_bearer - attach TIPC bearer to an Ethernet interface
+ */
+
+@@ -164,7 +176,8 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
+ eb_ptr->tipc_packet_type.func = recv_msg;
+ eb_ptr->tipc_packet_type.af_packet_priv = eb_ptr;
+ INIT_LIST_HEAD(&(eb_ptr->tipc_packet_type.list));
+- dev_add_pack(&eb_ptr->tipc_packet_type);
++ INIT_WORK(&eb_ptr->setup, setup_bearer);
++ schedule_work(&eb_ptr->setup);
+
+ /* Associate TIPC bearer with Ethernet bearer */
+
+diff --git a/scripts/kernel-doc b/scripts/kernel-doc
+index d793001..ba3d9df 100755
+--- a/scripts/kernel-doc
++++ b/scripts/kernel-doc
+@@ -2044,6 +2044,9 @@ sub process_file($) {
+
+ $section_counter = 0;
+ while (<IN>) {
++ while (s/\\\s*$//) {
++ $_ .= <IN>;
++ }
+ if ($state == 0) {
+ if (/$doc_start/o) {
+ $state = 1; # next line is always the function name
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index a166a85..7ebe4b7 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -2621,6 +2621,7 @@ static struct snd_pci_quirk msi_black_list[] __devinitdata = {
+ SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */
+ SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
+ SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */
++ SND_PCI_QUIRK(0x1179, 0xfb44, "Toshiba Satellite C870", 0), /* AMD Hudson */
+ SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */
+ SND_PCI_QUIRK(0xa0a0, 0x0575, "Aopen MZ915-M", 0), /* ICH6 */
+ {}
+diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
+index 55d9b30..05f097a 100644
+--- a/sound/pci/hda/patch_hdmi.c
++++ b/sound/pci/hda/patch_hdmi.c
+@@ -512,6 +512,17 @@ static int hdmi_channel_allocation(struct hdmi_eld *eld, int channels)
+ }
+ }
+
++ if (!ca) {
++ /* if there was no match, select the regular ALSA channel
++ * allocation with the matching number of channels */
++ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
++ if (channels == channel_allocations[i].channels) {
++ ca = channel_allocations[i].ca_index;
++ break;
++ }
++ }
++ }
++
+ snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
+ snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n",
+ ca, channels, buf);
+diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
+index 5ca122e..290f4d3 100644
+--- a/sound/soc/codecs/88pm860x-codec.c
++++ b/sound/soc/codecs/88pm860x-codec.c
+@@ -351,6 +351,9 @@ static int snd_soc_put_volsw_2r_st(struct snd_kcontrol *kcontrol,
+ val = ucontrol->value.integer.value[0];
+ val2 = ucontrol->value.integer.value[1];
+
++ if (val >= ARRAY_SIZE(st_table) || val2 >= ARRAY_SIZE(st_table))
++ return -EINVAL;
++
+ err = snd_soc_update_bits(codec, reg, 0x3f, st_table[val].m);
+ if (err < 0)
+ return err;
+diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
+index 26d7b08..a52c15b 100644
+--- a/sound/soc/codecs/max98095.c
++++ b/sound/soc/codecs/max98095.c
+@@ -1861,7 +1861,7 @@ static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol,
+ struct max98095_pdata *pdata = max98095->pdata;
+ int channel = max98095_get_eq_channel(kcontrol->id.name);
+ struct max98095_cdata *cdata;
+- int sel = ucontrol->value.integer.value[0];
++ unsigned int sel = ucontrol->value.integer.value[0];
+ struct max98095_eq_cfg *coef_set;
+ int fs, best, best_val, i;
+ int regmask, regsave;
+@@ -2014,7 +2014,7 @@ static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol,
+ struct max98095_pdata *pdata = max98095->pdata;
+ int channel = max98095_get_bq_channel(codec, kcontrol->id.name);
+ struct max98095_cdata *cdata;
+- int sel = ucontrol->value.integer.value[0];
++ unsigned int sel = ucontrol->value.integer.value[0];
+ struct max98095_biquad_cfg *coef_set;
+ int fs, best, best_val, i;
+ int regmask, regsave;
+diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
+index 2df253c..ef96ca6 100644
+--- a/sound/soc/codecs/wm8960.c
++++ b/sound/soc/codecs/wm8960.c
+@@ -805,9 +805,9 @@ static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
+ if (pll_div.k) {
+ reg |= 0x20;
+
+- snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 18) & 0x3f);
+- snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 9) & 0x1ff);
+- snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0x1ff);
++ snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 16) & 0xff);
++ snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 8) & 0xff);
++ snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0xff);
+ }
+ snd_soc_write(codec, WM8960_PLL1, reg);
+
+diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
+index 42dffa0..f7a7b9d 100644
+--- a/tools/perf/util/map.c
++++ b/tools/perf/util/map.c
+@@ -16,6 +16,7 @@ const char *map_type__name[MAP__NR_TYPES] = {
+ static inline int is_anon_memory(const char *filename)
+ {
+ return !strcmp(filename, "//anon") ||
++ !strcmp(filename, "/dev/zero (deleted)") ||
+ !strcmp(filename, "/anon_hugepage (deleted)");
+ }
+
diff --git a/3.2.51/4420_grsecurity-2.9.1-3.2.51-201310260849.patch b/3.2.52/4420_grsecurity-2.9.1-3.2.52-201310271550.patch
index 0ea9ee0..82cc38f 100644
--- a/3.2.51/4420_grsecurity-2.9.1-3.2.51-201310260849.patch
+++ b/3.2.52/4420_grsecurity-2.9.1-3.2.52-201310271550.patch
@@ -270,7 +270,7 @@ index 88fd7f5..b318a78 100644
==============================================================
diff --git a/Makefile b/Makefile
-index 0f11936..8f1b567 100644
+index 1dd2c09..6f850c4 100644
--- a/Makefile
+++ b/Makefile
@@ -245,8 +245,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -4997,10 +4997,10 @@ index f2496f2..4e3cc47 100644
}
#endif
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
-index 55be64d..94d8783 100644
+index ca683a1..ab912dd 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
-@@ -517,7 +517,7 @@ static int __cpuinit sysfs_cpu_notify(struct notifier_block *self,
+@@ -531,7 +531,7 @@ static int __cpuinit sysfs_cpu_notify(struct notifier_block *self,
return NOTIFY_OK;
}
@@ -6979,7 +6979,7 @@ index 5e4252b..379f84f 100644
mm->unmap_area = arch_unmap_area_topdown;
}
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
-index 7f5f65d..3308382 100644
+index 817187d..1d4541e 100644
--- a/arch/sparc/kernel/syscalls.S
+++ b/arch/sparc/kernel/syscalls.S
@@ -62,7 +62,7 @@ sys32_rt_sigreturn:
@@ -6993,13 +6993,13 @@ index 7f5f65d..3308382 100644
call syscall_trace_leave
@@ -179,7 +179,7 @@ linux_sparc_syscall32:
- srl %i5, 0, %o5 ! IEU1
+ srl %i3, 0, %o3 ! IEU0
srl %i2, 0, %o2 ! IEU0 Group
- andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0
+ andcc %l0, _TIF_WORK_SYSCALL, %g0
bne,pn %icc, linux_syscall_trace32 ! CTI
mov %i0, %l5 ! IEU1
- call %l7 ! CTI Group brk forced
+ 5: call %l7 ! CTI Group brk forced
@@ -202,7 +202,7 @@ linux_sparc_syscall:
mov %i3, %o3 ! IEU1
@@ -7628,10 +7628,10 @@ index 59186e0..f747d7a 100644
cmp %g1, %g7
bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c
-index 1b30bb3..b4a16c7 100644
+index fbb8005..984a269 100644
--- a/arch/sparc/lib/ksyms.c
+++ b/arch/sparc/lib/ksyms.c
-@@ -142,12 +142,18 @@ EXPORT_SYMBOL(__downgrade_write);
+@@ -133,12 +133,18 @@ EXPORT_SYMBOL(__clear_user);
/* Atomic counter implementation. */
EXPORT_SYMBOL(atomic_add);
@@ -20837,7 +20837,7 @@ index 42eb330..139955c 100644
return ret;
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
-index 47f4e5f..849a8a6 100644
+index a4e1b4b..0460044 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -35,7 +35,7 @@ void (*pm_power_off)(void);
@@ -20922,7 +20922,7 @@ index 47f4e5f..849a8a6 100644
}
#ifdef CONFIG_APM_MODULE
EXPORT_SYMBOL(machine_real_restart);
-@@ -548,7 +580,7 @@ void __attribute__((weak)) mach_reboot_fixups(void)
+@@ -564,7 +596,7 @@ void __attribute__((weak)) mach_reboot_fixups(void)
* try to force a triple fault and then cycle between hitting the keyboard
* controller and doing that
*/
@@ -20931,7 +20931,7 @@ index 47f4e5f..849a8a6 100644
{
int i;
int attempt = 0;
-@@ -672,13 +704,13 @@ void native_machine_shutdown(void)
+@@ -688,13 +720,13 @@ void native_machine_shutdown(void)
#endif
}
@@ -20947,7 +20947,7 @@ index 47f4e5f..849a8a6 100644
{
printk("machine restart\n");
-@@ -687,7 +719,7 @@ static void native_machine_restart(char *__unused)
+@@ -703,7 +735,7 @@ static void native_machine_restart(char *__unused)
__machine_emergency_restart(0);
}
@@ -20956,7 +20956,7 @@ index 47f4e5f..849a8a6 100644
{
/* stop other cpus and apics */
machine_shutdown();
-@@ -698,7 +730,7 @@ static void native_machine_halt(void)
+@@ -714,7 +746,7 @@ static void native_machine_halt(void)
stop_this_cpu(NULL);
}
@@ -20965,7 +20965,7 @@ index 47f4e5f..849a8a6 100644
{
if (pm_power_off) {
if (!reboot_force)
-@@ -707,9 +739,10 @@ static void native_machine_power_off(void)
+@@ -723,9 +755,10 @@ static void native_machine_power_off(void)
}
/* a fallback in case there is no PM info available */
tboot_shutdown(TB_SHUTDOWN_HALT);
@@ -30374,10 +30374,10 @@ index 9e76a32..48d7145 100644
goto error;
diff --git a/crypto/api.c b/crypto/api.c
-index 033a714..4f98dd5 100644
+index cea3cf6..86a0f6f 100644
--- a/crypto/api.c
+++ b/crypto/api.c
-@@ -40,6 +40,8 @@ static inline struct crypto_alg *crypto_alg_get(struct crypto_alg *alg)
+@@ -42,6 +42,8 @@ static inline struct crypto_alg *crypto_alg_get(struct crypto_alg *alg)
return alg;
}
@@ -30386,19 +30386,6 @@ index 033a714..4f98dd5 100644
struct crypto_alg *crypto_mod_get(struct crypto_alg *alg)
{
return try_module_get(alg->cra_module) ? crypto_alg_get(alg) : NULL;
-@@ -150,8 +152,11 @@ static struct crypto_alg *crypto_larval_add(const char *name, u32 type,
- }
- up_write(&crypto_alg_sem);
-
-- if (alg != &larval->alg)
-+ if (alg != &larval->alg) {
- kfree(larval);
-+ if (crypto_is_larval(alg))
-+ alg = crypto_larval_wait(alg);
-+ }
-
- return alg;
- }
diff --git a/crypto/cryptd.c b/crypto/cryptd.c
index 7bdd61b..afec999 100644
--- a/crypto/cryptd.c
@@ -31884,18 +31871,10 @@ index e8d11b6..7b1b36f 100644
}
EXPORT_SYMBOL_GPL(unregister_syscore_ops);
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
-index d3446f6..61ddf2c 100644
+index d7ad865..61ddf2c 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
-@@ -1186,6 +1186,7 @@ static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode,
- int err;
- u32 cp;
-
-+ memset(&arg64, 0, sizeof(arg64));
- err = 0;
- err |=
- copy_from_user(&arg64.LUN_info, &arg32->LUN_info,
-@@ -3007,7 +3008,7 @@ static void start_io(ctlr_info_t *h)
+@@ -3008,7 +3008,7 @@ static void start_io(ctlr_info_t *h)
while (!list_empty(&h->reqQ)) {
c = list_entry(h->reqQ.next, CommandList_struct, list);
/* can't do anything if fifo is full */
@@ -31904,7 +31883,7 @@ index d3446f6..61ddf2c 100644
dev_warn(&h->pdev->dev, "fifo full\n");
break;
}
-@@ -3017,7 +3018,7 @@ static void start_io(ctlr_info_t *h)
+@@ -3018,7 +3018,7 @@ static void start_io(ctlr_info_t *h)
h->Qdepth--;
/* Tell the controller execute command */
@@ -31913,7 +31892,7 @@ index d3446f6..61ddf2c 100644
/* Put job onto the completed Q */
addQ(&h->cmpQ, c);
-@@ -3443,17 +3444,17 @@ startio:
+@@ -3444,17 +3444,17 @@ startio:
static inline unsigned long get_next_completion(ctlr_info_t *h)
{
@@ -31934,7 +31913,7 @@ index d3446f6..61ddf2c 100644
(h->interrupts_enabled == 0));
}
-@@ -3486,7 +3487,7 @@ static inline u32 next_command(ctlr_info_t *h)
+@@ -3487,7 +3487,7 @@ static inline u32 next_command(ctlr_info_t *h)
u32 a;
if (unlikely(!(h->transMethod & CFGTBL_Trans_Performant)))
@@ -31943,7 +31922,7 @@ index d3446f6..61ddf2c 100644
if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) {
a = *(h->reply_pool_head); /* Next cmd in ring buffer */
-@@ -4044,7 +4045,7 @@ static void __devinit cciss_put_controller_into_performant_mode(ctlr_info_t *h)
+@@ -4045,7 +4045,7 @@ static void __devinit cciss_put_controller_into_performant_mode(ctlr_info_t *h)
trans_support & CFGTBL_Trans_use_short_tags);
/* Change the access methods to the performant access methods */
@@ -31952,7 +31931,7 @@ index d3446f6..61ddf2c 100644
h->transMethod = CFGTBL_Trans_Performant;
return;
-@@ -4316,7 +4317,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *h)
+@@ -4317,7 +4317,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *h)
if (prod_index < 0)
return -ENODEV;
h->product_name = products[prod_index].product_name;
@@ -31961,7 +31940,7 @@ index d3446f6..61ddf2c 100644
if (cciss_board_disabled(h)) {
dev_warn(&h->pdev->dev, "controller appears to be disabled\n");
-@@ -5041,7 +5042,7 @@ reinit_after_soft_reset:
+@@ -5042,7 +5042,7 @@ reinit_after_soft_reset:
}
/* make sure the board interrupts are off */
@@ -31970,7 +31949,7 @@ index d3446f6..61ddf2c 100644
rc = cciss_request_irq(h, do_cciss_msix_intr, do_cciss_intx);
if (rc)
goto clean2;
-@@ -5093,7 +5094,7 @@ reinit_after_soft_reset:
+@@ -5094,7 +5094,7 @@ reinit_after_soft_reset:
* fake ones to scoop up any residual completions.
*/
spin_lock_irqsave(&h->lock, flags);
@@ -31979,7 +31958,7 @@ index d3446f6..61ddf2c 100644
spin_unlock_irqrestore(&h->lock, flags);
free_irq(h->intr[h->intr_mode], h);
rc = cciss_request_irq(h, cciss_msix_discard_completions,
-@@ -5113,9 +5114,9 @@ reinit_after_soft_reset:
+@@ -5114,9 +5114,9 @@ reinit_after_soft_reset:
dev_info(&h->pdev->dev, "Board READY.\n");
dev_info(&h->pdev->dev,
"Waiting for stale completions to drain.\n");
@@ -31991,7 +31970,7 @@ index d3446f6..61ddf2c 100644
rc = controller_reset_failed(h->cfgtable);
if (rc)
-@@ -5138,7 +5139,7 @@ reinit_after_soft_reset:
+@@ -5139,7 +5139,7 @@ reinit_after_soft_reset:
cciss_scsi_setup(h);
/* Turn the interrupts on so we can service requests */
@@ -32000,7 +31979,7 @@ index d3446f6..61ddf2c 100644
/* Get the firmware version */
inq_buff = kzalloc(sizeof(InquiryData_struct), GFP_KERNEL);
-@@ -5211,7 +5212,7 @@ static void cciss_shutdown(struct pci_dev *pdev)
+@@ -5212,7 +5212,7 @@ static void cciss_shutdown(struct pci_dev *pdev)
kfree(flush_buf);
if (return_code != IO_OK)
dev_warn(&h->pdev->dev, "Error flushing cache\n");
@@ -32023,7 +32002,7 @@ index 7fda30e..eb5dfe0 100644
/* queue and queue Info */
struct list_head reqQ;
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
-index 9125bbe..eede5c8 100644
+index 504bc16..e13b631 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -404,7 +404,7 @@ static int __devinit cpqarray_register_ctlr( int i, struct pci_dev *pdev)
@@ -32098,7 +32077,7 @@ index 9125bbe..eede5c8 100644
a1 = a; a &= ~3;
if ((c = h->cmpQ) == NULL)
{
-@@ -1449,11 +1449,11 @@ static int sendcmd(
+@@ -1450,11 +1450,11 @@ static int sendcmd(
/*
* Disable interrupt
*/
@@ -32112,7 +32091,7 @@ index 9125bbe..eede5c8 100644
if (temp != 0) {
break;
}
-@@ -1466,7 +1466,7 @@ DBG(
+@@ -1467,7 +1467,7 @@ DBG(
/*
* Send the cmd
*/
@@ -32121,7 +32100,7 @@ index 9125bbe..eede5c8 100644
complete = pollcomplete(ctlr);
pci_unmap_single(info_p->pci_dev, (dma_addr_t) c->req.sg[0].addr,
-@@ -1549,9 +1549,9 @@ static int revalidate_allvol(ctlr_info_t *host)
+@@ -1550,9 +1550,9 @@ static int revalidate_allvol(ctlr_info_t *host)
* we check the new geometry. Then turn interrupts back on when
* we're done.
*/
@@ -32133,7 +32112,7 @@ index 9125bbe..eede5c8 100644
for(i=0; i<NWD; i++) {
struct gendisk *disk = ida_gendisk[ctlr][i];
-@@ -1591,7 +1591,7 @@ static int pollcomplete(int ctlr)
+@@ -1592,7 +1592,7 @@ static int pollcomplete(int ctlr)
/* Wait (up to 2 seconds) for a command to complete */
for (i = 200000; i > 0; i--) {
@@ -35263,10 +35242,10 @@ index a9e33ce..09edd4b 100644
#endif
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
-index f5962a0..a542c90 100644
+index a68057a..f3e26dd 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
-@@ -3077,7 +3077,9 @@ static int evergreen_startup(struct radeon_device *rdev)
+@@ -3094,7 +3094,9 @@ static int evergreen_startup(struct radeon_device *rdev)
r = evergreen_blit_init(rdev);
if (r) {
r600_blit_fini(rdev);
@@ -35444,7 +35423,7 @@ index a2e1eae..8e4a0ec 100644
return 0;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
-index cd94abb..5a6052d 100644
+index 8cde84b..0d3f11f 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -687,7 +687,7 @@ static bool radeon_switcheroo_can_switch(struct pci_dev *pdev)
@@ -35961,112 +35940,10 @@ index 8a8725c2..afed796 100644
marker = list_first_entry(&queue->head,
struct vmw_marker, head);
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
-index 611aafc..3f9bbc0 100644
+index 9ac4389..5c05af3 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
-@@ -59,6 +59,8 @@ struct hid_report *hid_register_report(struct hid_device *device, unsigned type,
- struct hid_report_enum *report_enum = device->report_enum + type;
- struct hid_report *report;
-
-+ if (id >= HID_MAX_IDS)
-+ return NULL;
- if (report_enum->report_id_hash[id])
- return report_enum->report_id_hash[id];
-
-@@ -380,8 +382,10 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
-
- case HID_GLOBAL_ITEM_TAG_REPORT_ID:
- parser->global.report_id = item_udata(item);
-- if (parser->global.report_id == 0) {
-- dbg_hid("report_id 0 is invalid\n");
-+ if (parser->global.report_id == 0 ||
-+ parser->global.report_id >= HID_MAX_IDS) {
-+ dbg_hid("report_id %u is invalid\n",
-+ parser->global.report_id);
- return -1;
- }
- return 0;
-@@ -552,7 +556,7 @@ static void hid_device_release(struct device *dev)
- for (i = 0; i < HID_REPORT_TYPES; i++) {
- struct hid_report_enum *report_enum = device->report_enum + i;
-
-- for (j = 0; j < 256; j++) {
-+ for (j = 0; j < HID_MAX_IDS; j++) {
- struct hid_report *report = report_enum->report_id_hash[j];
- if (report)
- hid_free_report(report);
-@@ -710,6 +714,56 @@ err:
- }
- EXPORT_SYMBOL_GPL(hid_parse_report);
-
-+static const char * const hid_report_names[] = {
-+ "HID_INPUT_REPORT",
-+ "HID_OUTPUT_REPORT",
-+ "HID_FEATURE_REPORT",
-+};
-+/**
-+ * hid_validate_report - validate existing device report
-+ *
-+ * @device: hid device
-+ * @type: which report type to examine
-+ * @id: which report ID to examine (0 for first)
-+ * @fields: expected number of fields
-+ * @report_counts: expected number of values per field
-+ *
-+ * Validate the report details after parsing.
-+ */
-+struct hid_report *hid_validate_report(struct hid_device *hid,
-+ unsigned int type, unsigned int id,
-+ unsigned int fields,
-+ unsigned int report_counts)
-+{
-+ struct hid_report *report;
-+ unsigned int i;
-+
-+ if (type > HID_FEATURE_REPORT) {
-+ hid_err(hid, "invalid HID report %u\n", type);
-+ return NULL;
-+ }
-+
-+ report = hid->report_enum[type].report_id_hash[id];
-+ if (!report) {
-+ hid_err(hid, "missing %s %u\n", hid_report_names[type], id);
-+ return NULL;
-+ }
-+ if (report->maxfield < fields) {
-+ hid_err(hid, "not enough fields in %s %u\n",
-+ hid_report_names[type], id);
-+ return NULL;
-+ }
-+ for (i = 0; i < fields; i++) {
-+ if (report->field[i]->report_count < report_counts) {
-+ hid_err(hid, "not enough values in %s %u fields\n",
-+ hid_report_names[type], id);
-+ return NULL;
-+ }
-+ }
-+ return report;
-+}
-+EXPORT_SYMBOL_GPL(hid_validate_report);
-+
- /*
- * Convert a signed n-bit integer to signed 32-bit integer. Common
- * cases are done through the compiler, the screwed things has to be
-@@ -990,7 +1044,12 @@ EXPORT_SYMBOL_GPL(hid_output_report);
-
- int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
- {
-- unsigned size = field->report_size;
-+ unsigned size;
-+
-+ if (!field)
-+ return -1;
-+
-+ size = field->report_size;
-
- hid_dump_input(field->report->device, field->usage + offset, value);
-
-@@ -2034,7 +2093,7 @@ static bool hid_ignore(struct hid_device *hdev)
+@@ -2102,7 +2102,7 @@ static bool hid_ignore(struct hid_device *hdev)
int hid_add_device(struct hid_device *hdev)
{
@@ -36075,7 +35952,7 @@ index 611aafc..3f9bbc0 100644
int ret;
if (WARN_ON(hdev->status & HID_STAT_ADDED))
-@@ -2049,7 +2108,7 @@ int hid_add_device(struct hid_device *hdev)
+@@ -2117,7 +2117,7 @@ int hid_add_device(struct hid_device *hdev)
/* XXX hack, any other cleaner solution after the driver core
* is converted to allow more than 20 bytes as the device name? */
dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
@@ -36084,167 +35961,6 @@ index 611aafc..3f9bbc0 100644
hid_debug_register(hdev, dev_name(&hdev->dev));
ret = device_add(&hdev->dev);
-diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c
-index 3c31bc6..f7b432a 100644
---- a/drivers/hid/hid-lg2ff.c
-+++ b/drivers/hid/hid-lg2ff.c
-@@ -66,26 +66,13 @@ int lg2ff_init(struct hid_device *hid)
- struct hid_report *report;
- struct hid_input *hidinput = list_entry(hid->inputs.next,
- struct hid_input, list);
-- struct list_head *report_list =
-- &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct input_dev *dev = hidinput->input;
- int error;
-
-- if (list_empty(report_list)) {
-- hid_err(hid, "no output report found\n");
-+ /* Check that the report looks ok */
-+ report = hid_validate_report(hid, HID_OUTPUT_REPORT, 0, 1, 7);
-+ if (!report)
- return -ENODEV;
-- }
--
-- report = list_entry(report_list->next, struct hid_report, list);
--
-- if (report->maxfield < 1) {
-- hid_err(hid, "output report is empty\n");
-- return -ENODEV;
-- }
-- if (report->field[0]->report_count < 7) {
-- hid_err(hid, "not enough values in the field\n");
-- return -ENODEV;
-- }
-
- lg2ff = kmalloc(sizeof(struct lg2ff_device), GFP_KERNEL);
- if (!lg2ff)
-diff --git a/drivers/hid/hid-lg3ff.c b/drivers/hid/hid-lg3ff.c
-index f98644c..8590851 100644
---- a/drivers/hid/hid-lg3ff.c
-+++ b/drivers/hid/hid-lg3ff.c
-@@ -68,10 +68,11 @@ static int hid_lg3ff_play(struct input_dev *dev, void *data,
- int x, y;
-
- /*
-- * Maxusage should always be 63 (maximum fields)
-- * likely a better way to ensure this data is clean
-+ * Available values in the field should always be 63, but we only use up to
-+ * 35. Instead, clear the entire area, however big it is.
- */
-- memset(report->field[0]->value, 0, sizeof(__s32)*report->field[0]->maxusage);
-+ memset(report->field[0]->value, 0,
-+ sizeof(__s32) * report->field[0]->report_count);
-
- switch (effect->type) {
- case FF_CONSTANT:
-@@ -131,32 +132,14 @@ static const signed short ff3_joystick_ac[] = {
- int lg3ff_init(struct hid_device *hid)
- {
- struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
-- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct input_dev *dev = hidinput->input;
-- struct hid_report *report;
-- struct hid_field *field;
- const signed short *ff_bits = ff3_joystick_ac;
- int error;
- int i;
-
-- /* Find the report to use */
-- if (list_empty(report_list)) {
-- hid_err(hid, "No output report found\n");
-- return -1;
-- }
--
- /* Check that the report looks ok */
-- report = list_entry(report_list->next, struct hid_report, list);
-- if (!report) {
-- hid_err(hid, "NULL output report\n");
-- return -1;
-- }
--
-- field = report->field[0];
-- if (!field) {
-- hid_err(hid, "NULL field\n");
-- return -1;
-- }
-+ if (!hid_validate_report(hid, HID_OUTPUT_REPORT, 0, 1, 35))
-+ return -ENODEV;
-
- /* Assume single fixed device G940 */
- for (i = 0; ff_bits[i] >= 0; i++)
-diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
-index 103f30d..b9a39e5 100644
---- a/drivers/hid/hid-lg4ff.c
-+++ b/drivers/hid/hid-lg4ff.c
-@@ -339,33 +339,15 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at
- int lg4ff_init(struct hid_device *hid)
- {
- struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
-- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct input_dev *dev = hidinput->input;
-- struct hid_report *report;
-- struct hid_field *field;
- struct lg4ff_device_entry *entry;
- struct usb_device_descriptor *udesc;
- int error, i, j;
- __u16 bcdDevice, rev_maj, rev_min;
-
-- /* Find the report to use */
-- if (list_empty(report_list)) {
-- hid_err(hid, "No output report found\n");
-- return -1;
-- }
--
- /* Check that the report looks ok */
-- report = list_entry(report_list->next, struct hid_report, list);
-- if (!report) {
-- hid_err(hid, "NULL output report\n");
-+ if (!hid_validate_report(hid, HID_OUTPUT_REPORT, 0, 1, 7))
- return -1;
-- }
--
-- field = report->field[0];
-- if (!field) {
-- hid_err(hid, "NULL field\n");
-- return -1;
-- }
-
- /* Check what wheel has been connected */
- for (i = 0; i < ARRAY_SIZE(lg4ff_devices); i++) {
-diff --git a/drivers/hid/hid-lgff.c b/drivers/hid/hid-lgff.c
-index 27bc54f..6d25789 100644
---- a/drivers/hid/hid-lgff.c
-+++ b/drivers/hid/hid-lgff.c
-@@ -130,27 +130,14 @@ static void hid_lgff_set_autocenter(struct input_dev *dev, u16 magnitude)
- int lgff_init(struct hid_device* hid)
- {
- struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
-- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct input_dev *dev = hidinput->input;
-- struct hid_report *report;
-- struct hid_field *field;
- const signed short *ff_bits = ff_joystick;
- int error;
- int i;
-
-- /* Find the report to use */
-- if (list_empty(report_list)) {
-- hid_err(hid, "No output report found\n");
-- return -1;
-- }
--
- /* Check that the report looks ok */
-- report = list_entry(report_list->next, struct hid_report, list);
-- field = report->field[0];
-- if (!field) {
-- hid_err(hid, "NULL field\n");
-- return -1;
-- }
-+ if (!hid_validate_report(hid, HID_OUTPUT_REPORT, 0, 1, 7))
-+ return -ENODEV;
-
- for (i = 0; i < ARRAY_SIZE(devices); i++) {
- if (dev->id.vendor == devices[i].idVendor &&
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 13af0f1..dc797c9 100644
--- a/drivers/hid/hid-multitouch.c
@@ -36267,70 +35983,6 @@ index 13af0f1..dc797c9 100644
}
/* we have handled the hidinput part, now remains hiddev */
-diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
-index 9fae2eb..48cba85 100644
---- a/drivers/hid/hid-ntrig.c
-+++ b/drivers/hid/hid-ntrig.c
-@@ -115,7 +115,8 @@ static inline int ntrig_get_mode(struct hid_device *hdev)
- struct hid_report *report = hdev->report_enum[HID_FEATURE_REPORT].
- report_id_hash[0x0d];
-
-- if (!report)
-+ if (!report || report->maxfield < 1 ||
-+ report->field[0]->report_count < 1)
- return -EINVAL;
-
- usbhid_submit_report(hdev, report, USB_DIR_IN);
-diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c
-index 070f93a..12786cd 100644
---- a/drivers/hid/hid-pl.c
-+++ b/drivers/hid/hid-pl.c
-@@ -129,8 +129,14 @@ static int plff_init(struct hid_device *hid)
- strong = &report->field[0]->value[2];
- weak = &report->field[0]->value[3];
- debug("detected single-field device");
-- } else if (report->maxfield >= 4 && report->field[0]->maxusage == 1 &&
-- report->field[0]->usage[0].hid == (HID_UP_LED | 0x43)) {
-+ } else if (report->field[0]->maxusage == 1 &&
-+ report->field[0]->usage[0].hid ==
-+ (HID_UP_LED | 0x43) &&
-+ report->maxfield >= 4 &&
-+ report->field[0]->report_count >= 1 &&
-+ report->field[1]->report_count >= 1 &&
-+ report->field[2]->report_count >= 1 &&
-+ report->field[3]->report_count >= 1) {
- report->field[0]->value[0] = 0x00;
- report->field[1]->value[0] = 0x00;
- strong = &report->field[2]->value[0];
-diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c
-index f6ba81d..f7e37f7 100644
---- a/drivers/hid/hid-zpff.c
-+++ b/drivers/hid/hid-zpff.c
-@@ -70,22 +70,12 @@ static int zpff_init(struct hid_device *hid)
- struct hid_report *report;
- struct hid_input *hidinput = list_entry(hid->inputs.next,
- struct hid_input, list);
-- struct list_head *report_list =
-- &hid->report_enum[HID_OUTPUT_REPORT].report_list;
- struct input_dev *dev = hidinput->input;
- int error;
-
-- if (list_empty(report_list)) {
-- hid_err(hid, "no output report found\n");
-+ report = hid_validate_report(hid, HID_OUTPUT_REPORT, 0, 4, 1);
-+ if (!report)
- return -ENODEV;
-- }
--
-- report = list_entry(report_list->next, struct hid_report, list);
--
-- if (report->maxfield < 4) {
-- hid_err(hid, "not enough fields in report\n");
-- return -ENODEV;
-- }
-
- zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL);
- if (!zpff)
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 4ef02b2..8a96831 100644
--- a/drivers/hid/usbhid/hiddev.c
@@ -36443,10 +36095,10 @@ index 66f6729..4de8c4a 100644
int res = 0;
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
-index d99aa84..c977790 100644
+index 30cac58..f6406b3 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
-@@ -1056,7 +1056,7 @@ static int applesmc_create_nodes(struct applesmc_node_group *groups, int num)
+@@ -1069,7 +1069,7 @@ static int applesmc_create_nodes(struct applesmc_node_group *groups, int num)
{
struct applesmc_node_group *grp;
struct applesmc_dev_attr *node;
@@ -40263,10 +39915,10 @@ index a9ff89ff..461d313 100644
struct sm_sysfs_attribute *vendor_attribute;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
-index b436b84..d3cecc5 100644
+index 1bf36ac..55c534e 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
-@@ -4796,7 +4796,7 @@ static int bond_get_tx_queues(struct net *net, struct nlattr *tb[],
+@@ -4803,7 +4803,7 @@ static int bond_get_tx_queues(struct net *net, struct nlattr *tb[],
return 0;
}
@@ -40275,7 +39927,7 @@ index b436b84..d3cecc5 100644
.kind = "bond",
.priv_size = sizeof(struct bonding),
.setup = bond_setup,
-@@ -4921,8 +4921,8 @@ static void __exit bonding_exit(void)
+@@ -4928,8 +4928,8 @@ static void __exit bonding_exit(void)
bond_destroy_debugfs();
@@ -40958,10 +40610,10 @@ index 301b39e..345c414 100644
};
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
-index 96b9e3c..d9cfb75 100644
+index b0f9015..93da3cf 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
-@@ -1073,7 +1073,7 @@ static int macvtap_device_event(struct notifier_block *unused,
+@@ -1085,7 +1085,7 @@ static int macvtap_device_event(struct notifier_block *unused,
return NOTIFY_DONE;
}
@@ -41095,7 +40747,7 @@ index 46db5c5..37c1536 100644
err = platform_driver_register(&sk_isa_driver);
if (err)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
-index f4c5de6..31aa71c 100644
+index ee1aab0..31aa71c 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -359,7 +359,7 @@ static void tun_free_netdev(struct net_device *dev)
@@ -41107,29 +40759,7 @@ index f4c5de6..31aa71c 100644
}
/* Net device open. */
-@@ -614,8 +614,9 @@ static ssize_t tun_get_user(struct tun_struct *tun,
- int offset = 0;
-
- if (!(tun->flags & TUN_NO_PI)) {
-- if ((len -= sizeof(pi)) > count)
-+ if (len < sizeof(pi))
- return -EINVAL;
-+ len -= sizeof(pi);
-
- if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi)))
- return -EFAULT;
-@@ -623,8 +624,9 @@ static ssize_t tun_get_user(struct tun_struct *tun,
- }
-
- if (tun->flags & TUN_VNET_HDR) {
-- if ((len -= tun->vnet_hdr_sz) > count)
-+ if (len < tun->vnet_hdr_sz)
- return -EINVAL;
-+ len -= tun->vnet_hdr_sz;
-
- if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso)))
- return -EFAULT;
-@@ -981,10 +983,18 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock,
+@@ -983,10 +983,18 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock,
return ret;
}
@@ -41148,7 +40778,7 @@ index f4c5de6..31aa71c 100644
};
static struct proto tun_proto = {
-@@ -1111,10 +1121,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
+@@ -1113,10 +1121,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr);
err = -ENOMEM;
@@ -41161,7 +40791,7 @@ index f4c5de6..31aa71c 100644
tun->socket.wq = &tun->wq;
init_waitqueue_head(&tun->wq.wait);
tun->socket.ops = &tun_socket_ops;
-@@ -1175,7 +1186,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
+@@ -1177,7 +1186,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
return 0;
err_free_sk:
@@ -41170,7 +40800,7 @@ index f4c5de6..31aa71c 100644
err_free_dev:
free_netdev(dev);
failed:
-@@ -1234,7 +1245,7 @@ static int set_offload(struct tun_struct *tun, unsigned long arg)
+@@ -1236,7 +1245,7 @@ static int set_offload(struct tun_struct *tun, unsigned long arg)
}
static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
@@ -41179,7 +40809,7 @@ index f4c5de6..31aa71c 100644
{
struct tun_file *tfile = file->private_data;
struct tun_struct *tun;
-@@ -1245,6 +1256,9 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
+@@ -1247,6 +1256,9 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
int vnet_hdr_sz;
int ret;
@@ -41394,6 +41024,18 @@ index ebb9f24..7a4c491 100644
sync.clock_rate = FST_RDL(card, portConfig[i].lineSpeed);
/* Lucky card and linux use same encoding here */
sync.clock_type = FST_RDB(card, portConfig[i].internalClock) ==
+diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c
+index 44b7071..c643d77 100644
+--- a/drivers/net/wan/wanxl.c
++++ b/drivers/net/wan/wanxl.c
+@@ -355,6 +355,7 @@ static int wanxl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+ ifr->ifr_settings.size = size; /* data size wanted */
+ return -ENOBUFS;
+ }
++ memset(&line, 0, sizeof(line));
+ line.clock_type = get_status(port)->clocking;
+ line.clock_rate = 0;
+ line.loopback = 0;
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 4045e5a..506f1cf 100644
--- a/drivers/net/wireless/at76c50x-usb.c
@@ -43674,7 +43316,7 @@ index 1b21491..1b7f60e 100644
/*
* Check for overflow; dev_loss_tmo is u32
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
-index 96029e6..4d77fa0 100644
+index c874458..568a977 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -79,7 +79,7 @@ struct iscsi_internal {
@@ -43736,10 +43378,10 @@ index 21a045e..ec89e03 100644
transport_setup_device(&rport->dev);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
-index 17603da..332e23a 100644
+index f6d2b62..d9aa1a4 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
-@@ -2637,7 +2637,7 @@ static int sd_probe(struct device *dev)
+@@ -2632,7 +2632,7 @@ static int sd_probe(struct device *dev)
device_initialize(&sdkp->dev);
sdkp->dev.parent = dev;
sdkp->dev.class = &sd_disk_class;
@@ -45276,7 +44918,7 @@ index 032e5a6..bc422e4 100644
wake_up(&usb_kill_urb_queue);
usb_put_urb(urb);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
-index 2768a7e..7b5c7a9 100644
+index a5ea85f..6530989 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -25,6 +25,7 @@
@@ -51444,7 +51086,7 @@ index d322929..9f4b816 100644
dcache_init();
inode_init();
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
-index f3a257d..9235188 100644
+index fb001cd..95129c3 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -145,6 +145,7 @@ static struct file_system_type debug_fs_type = {
@@ -51498,6 +51140,32 @@ index a9be90d..3cf866c 100644
if (!IS_ERR(buf)) {
/* Free the char* */
kfree(buf);
+diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
+index ac1ad48..d80e1db 100644
+--- a/fs/ecryptfs/keystore.c
++++ b/fs/ecryptfs/keystore.c
+@@ -1151,8 +1151,8 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
+ struct ecryptfs_msg_ctx *msg_ctx;
+ struct ecryptfs_message *msg = NULL;
+ char *auth_tok_sig;
+- char *payload;
+- size_t payload_len;
++ char *payload = NULL;
++ size_t payload_len = 0;
+ int rc;
+
+ rc = ecryptfs_get_auth_tok_sig(&auth_tok_sig, auth_tok);
+@@ -1204,8 +1204,8 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
+ crypt_stat->key_size);
+ }
+ out:
+- if (msg)
+- kfree(msg);
++ kfree(msg);
++ kfree(payload);
+ return rc;
+ }
+
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 94afdfd..bdb8854 100644
--- a/fs/ecryptfs/main.c
@@ -54577,10 +54245,10 @@ index 5c029fb..96e676c 100644
if (!ret)
ret = -EPIPE;
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
-index 5ef7afb..5fc7f4f 100644
+index 06e2f73..e6c5fc8 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
-@@ -1148,7 +1148,7 @@ static char *read_link(struct dentry *dentry)
+@@ -1150,7 +1150,7 @@ static char *read_link(struct dentry *dentry)
return link;
}
@@ -54590,10 +54258,10 @@ index 5ef7afb..5fc7f4f 100644
if (!IS_ERR(link))
free_page((unsigned long) link);
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
-index 1f82d95..763ac54 100644
+index 912c250..f0aee59 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
-@@ -1092,6 +1092,7 @@ static struct file_system_type fuse_fs_type = {
+@@ -1094,6 +1094,7 @@ static struct file_system_type fuse_fs_type = {
.mount = fuse_mount,
.kill_sb = fuse_kill_sb_anon,
};
@@ -54601,7 +54269,7 @@ index 1f82d95..763ac54 100644
#ifdef CONFIG_BLOCK
static struct dentry *fuse_mount_blk(struct file_system_type *fs_type,
-@@ -1121,6 +1122,7 @@ static struct file_system_type fuseblk_fs_type = {
+@@ -1123,6 +1124,7 @@ static struct file_system_type fuseblk_fs_type = {
.kill_sb = fuse_kill_sb_blk,
.fs_flags = FS_REQUIRES_DEV | FS_HAS_SUBTYPE,
};
@@ -54811,10 +54479,10 @@ index e2d3633..e6f3833 100644
spin_unlock(&inode->i_lock);
}
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
-index f950059..78748e8 100644
+index a5f25a7..8ac9cc8 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
-@@ -1545,6 +1545,8 @@ static struct file_system_type iso9660_fs_type = {
+@@ -1539,6 +1539,8 @@ static struct file_system_type iso9660_fs_type = {
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
@@ -54823,7 +54491,7 @@ index f950059..78748e8 100644
static int __init init_iso9660_fs(void)
{
-@@ -1582,5 +1584,3 @@ static void __exit exit_iso9660_fs(void)
+@@ -1576,5 +1578,3 @@ static void __exit exit_iso9660_fs(void)
module_init(init_iso9660_fs)
module_exit(exit_iso9660_fs)
MODULE_LICENSE("GPL");
@@ -72735,35 +72403,6 @@ index 0000000..e7ffaaf
+ const int protocol);
+
+#endif
-diff --git a/include/linux/hid.h b/include/linux/hid.h
-index 331e2ef..37c06bd 100644
---- a/include/linux/hid.h
-+++ b/include/linux/hid.h
-@@ -416,10 +416,12 @@ struct hid_report {
- struct hid_device *device; /* associated device */
- };
-
-+#define HID_MAX_IDS 256
-+
- struct hid_report_enum {
- unsigned numbered;
- struct list_head report_list;
-- struct hid_report *report_id_hash[256];
-+ struct hid_report *report_id_hash[HID_MAX_IDS];
- };
-
- #define HID_REPORT_TYPES 3
-@@ -716,6 +718,10 @@ void hid_output_report(struct hid_report *report, __u8 *data);
- struct hid_device *hid_allocate_device(void);
- struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id);
- int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
-+struct hid_report *hid_validate_report(struct hid_device *hid,
-+ unsigned int type, unsigned int id,
-+ unsigned int fields,
-+ unsigned int report_counts);
- int hid_check_keys_pressed(struct hid_device *hid);
- int hid_connect(struct hid_device *hid, unsigned int connect_mask);
- void hid_disconnect(struct hid_device *hid);
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index 52e9620..26c34b1 100644
--- a/include/linux/highmem.h
@@ -73308,7 +72947,7 @@ index 3797270..7765ede 100644
struct mca_bus {
u64 default_dma_mask;
diff --git a/include/linux/mm.h b/include/linux/mm.h
-index d0493f6..ce3ea0b 100644
+index 305fd75..f0db13d 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -115,7 +115,14 @@ extern unsigned int kobjsize(const void *objp);
@@ -73345,7 +72984,7 @@ index d0493f6..ce3ea0b 100644
struct mmu_gather;
struct inode;
-@@ -940,8 +948,8 @@ int follow_pfn(struct vm_area_struct *vma, unsigned long address,
+@@ -941,8 +949,8 @@ int follow_pfn(struct vm_area_struct *vma, unsigned long address,
unsigned long *pfn);
int follow_phys(struct vm_area_struct *vma, unsigned long address,
unsigned int flags, unsigned long *prot, resource_size_t *phys);
@@ -73356,7 +72995,7 @@ index d0493f6..ce3ea0b 100644
static inline void unmap_shared_mapping_range(struct address_space *mapping,
loff_t const holebegin, loff_t const holelen)
-@@ -983,10 +991,10 @@ static inline int fixup_user_fault(struct task_struct *tsk,
+@@ -984,10 +992,10 @@ static inline int fixup_user_fault(struct task_struct *tsk,
}
#endif
@@ -73371,7 +73010,7 @@ index d0493f6..ce3ea0b 100644
int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
unsigned long start, int len, unsigned int foll_flags,
-@@ -1012,34 +1020,6 @@ int set_page_dirty(struct page *page);
+@@ -1013,34 +1021,6 @@ int set_page_dirty(struct page *page);
int set_page_dirty_lock(struct page *page);
int clear_page_dirty_for_io(struct page *page);
@@ -73406,7 +73045,7 @@ index d0493f6..ce3ea0b 100644
extern unsigned long move_page_tables(struct vm_area_struct *vma,
unsigned long old_addr, struct vm_area_struct *new_vma,
unsigned long new_addr, unsigned long len);
-@@ -1134,6 +1114,15 @@ static inline void sync_mm_rss(struct task_struct *task, struct mm_struct *mm)
+@@ -1135,6 +1115,15 @@ static inline void sync_mm_rss(struct task_struct *task, struct mm_struct *mm)
}
#endif
@@ -73422,7 +73061,7 @@ index d0493f6..ce3ea0b 100644
int vma_wants_writenotify(struct vm_area_struct *vma);
extern pte_t *__get_locked_pte(struct mm_struct *mm, unsigned long addr,
-@@ -1152,8 +1141,15 @@ static inline int __pud_alloc(struct mm_struct *mm, pgd_t *pgd,
+@@ -1153,8 +1142,15 @@ static inline int __pud_alloc(struct mm_struct *mm, pgd_t *pgd,
{
return 0;
}
@@ -73438,7 +73077,7 @@ index d0493f6..ce3ea0b 100644
#endif
#ifdef __PAGETABLE_PMD_FOLDED
-@@ -1162,8 +1158,15 @@ static inline int __pmd_alloc(struct mm_struct *mm, pud_t *pud,
+@@ -1163,8 +1159,15 @@ static inline int __pmd_alloc(struct mm_struct *mm, pud_t *pud,
{
return 0;
}
@@ -73454,7 +73093,7 @@ index d0493f6..ce3ea0b 100644
#endif
int __pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
-@@ -1181,11 +1184,23 @@ static inline pud_t *pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long a
+@@ -1182,11 +1185,23 @@ static inline pud_t *pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long a
NULL: pud_offset(pgd, address);
}
@@ -73478,7 +73117,7 @@ index d0493f6..ce3ea0b 100644
#endif /* CONFIG_MMU && !__ARCH_HAS_4LEVEL_HACK */
#if USE_SPLIT_PTLOCKS
-@@ -1419,6 +1434,7 @@ out:
+@@ -1420,6 +1435,7 @@ out:
}
extern int do_munmap(struct mm_struct *, unsigned long, size_t);
@@ -73486,7 +73125,7 @@ index d0493f6..ce3ea0b 100644
extern unsigned long do_brk(unsigned long, unsigned long);
-@@ -1476,6 +1492,10 @@ extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long add
+@@ -1477,6 +1493,10 @@ extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long add
extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
struct vm_area_struct **pprev);
@@ -73497,7 +73136,7 @@ index d0493f6..ce3ea0b 100644
/* Look up the first VMA which intersects the interval start_addr..end_addr-1,
NULL if none. Assume start_addr < end_addr. */
static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
-@@ -1492,15 +1512,6 @@ static inline unsigned long vma_pages(struct vm_area_struct *vma)
+@@ -1493,15 +1513,6 @@ static inline unsigned long vma_pages(struct vm_area_struct *vma)
return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
}
@@ -73513,7 +73152,7 @@ index d0493f6..ce3ea0b 100644
struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
unsigned long pfn, unsigned long size, pgprot_t);
-@@ -1536,6 +1547,12 @@ void vm_stat_account(struct mm_struct *, unsigned long, struct file *, long);
+@@ -1537,6 +1548,12 @@ void vm_stat_account(struct mm_struct *, unsigned long, struct file *, long);
static inline void vm_stat_account(struct mm_struct *mm,
unsigned long flags, struct file *file, long pages)
{
@@ -73526,7 +73165,7 @@ index d0493f6..ce3ea0b 100644
}
#endif /* CONFIG_PROC_FS */
-@@ -1616,7 +1633,7 @@ extern int unpoison_memory(unsigned long pfn);
+@@ -1617,7 +1634,7 @@ extern int unpoison_memory(unsigned long pfn);
extern int sysctl_memory_failure_early_kill;
extern int sysctl_memory_failure_recovery;
extern void shake_page(struct page *p, int access);
@@ -73535,7 +73174,7 @@ index d0493f6..ce3ea0b 100644
extern int soft_offline_page(struct page *page, int flags);
extern void dump_page(struct page *page);
-@@ -1630,5 +1647,11 @@ extern void copy_user_huge_page(struct page *dst, struct page *src,
+@@ -1631,5 +1648,11 @@ extern void copy_user_huge_page(struct page *dst, struct page *src,
unsigned int pages_per_huge_page);
#endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */
@@ -74041,7 +73680,7 @@ index 45fc162..01a4068 100644
/**
* struct hotplug_slot_info - used to notify the hotplug pci core of the state of the slot
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
-index 3cfcfea..0227030 100644
+index eeb6a29..6eb2b52 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -748,8 +748,8 @@ struct perf_event {
@@ -74327,7 +73966,7 @@ index 29e217a..a76bcd0 100644
/**
diff --git a/include/linux/rculist.h b/include/linux/rculist.h
-index 6f95e24..68fe817 100644
+index 3863352..4ec4bfb 100644
--- a/include/linux/rculist.h
+++ b/include/linux/rculist.h
@@ -39,6 +39,9 @@ static inline void __list_add_rcu(struct list_head *new,
@@ -74876,7 +74515,7 @@ index 92808b8..c28cac4 100644
/* shm_mode upper byte flags */
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
-index efe50af..0d0b145 100644
+index efe50af..9a039e5 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -538,7 +538,7 @@ extern void consume_skb(struct sk_buff *skb);
@@ -74915,7 +74554,19 @@ index efe50af..0d0b145 100644
}
/**
-@@ -1546,7 +1546,7 @@ static inline int pskb_network_may_pull(struct sk_buff *skb, unsigned int len)
+@@ -1157,6 +1157,11 @@ static inline int skb_pagelen(const struct sk_buff *skb)
+ return len + skb_headlen(skb);
+ }
+
++static inline bool skb_has_frags(const struct sk_buff *skb)
++{
++ return skb_shinfo(skb)->nr_frags;
++}
++
+ /**
+ * __skb_fill_page_desc - initialise a paged fragment in an skb
+ * @skb: buffer containing fragment to be initialised
+@@ -1546,7 +1551,7 @@ static inline int pskb_network_may_pull(struct sk_buff *skb, unsigned int len)
* NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8)
*/
#ifndef NET_SKB_PAD
@@ -74924,7 +74575,7 @@ index efe50af..0d0b145 100644
#endif
extern int ___pskb_trim(struct sk_buff *skb, unsigned int len);
-@@ -2085,7 +2085,7 @@ extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
+@@ -2085,7 +2090,7 @@ extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
int noblock, int *err);
extern unsigned int datagram_poll(struct file *file, struct socket *sock,
struct poll_table_struct *wait);
@@ -74933,7 +74584,7 @@ index efe50af..0d0b145 100644
int offset, struct iovec *to,
int size);
extern int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
-@@ -2365,6 +2365,9 @@ static inline void nf_reset(struct sk_buff *skb)
+@@ -2365,6 +2370,9 @@ static inline void nf_reset(struct sk_buff *skb)
nf_bridge_put(skb->nf_bridge);
skb->nf_bridge = NULL;
#endif
@@ -76139,10 +75790,10 @@ index ca2755f..85ec88c 100644
/** inet_connection_sock - INET connection oriented sock
*
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
-index e9ff3fc..c19998a 100644
+index 34b06da..03b1d34 100644
--- a/include/net/inetpeer.h
+++ b/include/net/inetpeer.h
-@@ -48,8 +48,8 @@ struct inet_peer {
+@@ -52,8 +52,8 @@ struct inet_peer {
*/
union {
struct {
@@ -76153,7 +75804,7 @@ index e9ff3fc..c19998a 100644
__u32 tcp_ts;
__u32 tcp_ts_stamp;
};
-@@ -109,16 +109,13 @@ static inline void inet_peer_refcheck(const struct inet_peer *p)
+@@ -115,16 +115,13 @@ static inline void inet_peer_refcheck(const struct inet_peer *p)
/* can be called with or without local BH being disabled */
static inline int inet_getid(struct inet_peer *p, int more)
{
@@ -76176,7 +75827,7 @@ index e9ff3fc..c19998a 100644
#endif /* _NET_INETPEER_H */
diff --git a/include/net/ip.h b/include/net/ip.h
-index eca0ef7..88118cb 100644
+index 06aed72..54fbf5b 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -214,7 +214,7 @@ extern struct local_ports {
@@ -77808,10 +77459,10 @@ index b463871..59495fd 100644
* nsown_capable - Check superior capability to one's own user_ns
* @cap: The capability in question
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
-index d2a01fe..493cba0 100644
+index 2a1ffb7..b99a595 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
-@@ -5153,7 +5153,7 @@ static int cgroup_css_links_read(struct cgroup *cont,
+@@ -5164,7 +5164,7 @@ static int cgroup_css_links_read(struct cgroup *cont,
struct css_set *cg = link->cg;
struct task_struct *task;
int count = 0;
@@ -78229,7 +77880,7 @@ index 63786e7..0780cac 100644
#ifdef CONFIG_MODULE_UNLOAD
{
diff --git a/kernel/events/core.c b/kernel/events/core.c
-index 5bbe443..c8b6b81 100644
+index 83d5621..8c6738d 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -145,8 +145,15 @@ static struct srcu_struct pmus_srcu;
@@ -78258,7 +77909,7 @@ index 5bbe443..c8b6b81 100644
static void cpu_ctx_sched_out(struct perf_cpu_context *cpuctx,
enum event_type_t event_type);
-@@ -2568,7 +2575,7 @@ static void __perf_event_read(void *info)
+@@ -2575,7 +2582,7 @@ static void __perf_event_read(void *info)
static inline u64 perf_event_count(struct perf_event *event)
{
@@ -78267,7 +77918,7 @@ index 5bbe443..c8b6b81 100644
}
static u64 perf_event_read(struct perf_event *event)
-@@ -3114,9 +3121,9 @@ u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running)
+@@ -3121,9 +3128,9 @@ u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running)
mutex_lock(&event->child_mutex);
total += perf_event_read(event);
*enabled += event->total_time_enabled +
@@ -78279,7 +77930,7 @@ index 5bbe443..c8b6b81 100644
list_for_each_entry(child, &event->child_list, child_list) {
total += perf_event_read(child);
-@@ -3508,10 +3515,10 @@ void perf_event_update_userpage(struct perf_event *event)
+@@ -3515,10 +3522,10 @@ void perf_event_update_userpage(struct perf_event *event)
userpg->offset -= local64_read(&event->hw.prev_count);
userpg->time_enabled = enabled +
@@ -78292,7 +77943,7 @@ index 5bbe443..c8b6b81 100644
barrier();
++userpg->lock;
-@@ -4019,11 +4026,11 @@ static void perf_output_read_one(struct perf_output_handle *handle,
+@@ -4026,11 +4033,11 @@ static void perf_output_read_one(struct perf_output_handle *handle,
values[n++] = perf_event_count(event);
if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
values[n++] = enabled +
@@ -78306,7 +77957,7 @@ index 5bbe443..c8b6b81 100644
}
if (read_format & PERF_FORMAT_ID)
values[n++] = primary_event_id(event);
-@@ -4674,12 +4681,12 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
+@@ -4681,12 +4688,12 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
* need to add enough zero bytes after the string to handle
* the 64bit alignment we do later.
*/
@@ -78321,7 +77972,7 @@ index 5bbe443..c8b6b81 100644
if (IS_ERR(name)) {
name = strncpy(tmp, "//toolong", sizeof(tmp));
goto got_name;
-@@ -6036,7 +6043,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
+@@ -6043,7 +6050,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
event->parent = parent_event;
event->ns = get_pid_ns(current->nsproxy->pid_ns);
@@ -78330,7 +77981,7 @@ index 5bbe443..c8b6b81 100644
event->state = PERF_EVENT_STATE_INACTIVE;
-@@ -6282,6 +6289,11 @@ SYSCALL_DEFINE5(perf_event_open,
+@@ -6289,6 +6296,11 @@ SYSCALL_DEFINE5(perf_event_open,
if (flags & ~PERF_FLAG_ALL)
return -EINVAL;
@@ -78342,7 +77993,7 @@ index 5bbe443..c8b6b81 100644
err = perf_copy_attr(attr_uptr, &attr);
if (err)
return err;
-@@ -6577,10 +6589,10 @@ static void sync_child_event(struct perf_event *child_event,
+@@ -6584,10 +6596,10 @@ static void sync_child_event(struct perf_event *child_event,
/*
* Add back the child's count to the parent's count:
*/
@@ -81632,7 +81283,7 @@ index f280df1..da1281d 100644
#ifdef CONFIG_RT_GROUP_SCHED
/*
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
-index 59474c5..efcae8d 100644
+index c261da7..4e5221ad 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -4801,7 +4801,7 @@ static void nohz_idle_balance(int this_cpu, enum cpu_idle_type idle) { }
@@ -84248,7 +83899,7 @@ index 2a07f97..2cdc054 100644
set_page_address(page, (void *)vaddr);
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
-index d80ac4b..9fd73bc 100644
+index ed0ed8a..cc835b9 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -704,7 +704,7 @@ out:
@@ -87238,7 +86889,7 @@ index 5a688a2..fffb9f6 100644
if (nstart < prev->vm_end)
diff --git a/mm/mremap.c b/mm/mremap.c
-index d6959cb..51051b9 100644
+index d6959cb..7bc76da 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -23,6 +23,7 @@
@@ -87249,19 +86900,7 @@ index d6959cb..51051b9 100644
#include "internal.h"
-@@ -60,8 +61,10 @@ static pmd_t *alloc_new_pmd(struct mm_struct *mm, struct vm_area_struct *vma,
- return NULL;
-
- pmd = pmd_alloc(mm, pud, addr);
-- if (!pmd)
-+ if (!pmd) {
-+ pud_free(mm, pud);
- return NULL;
-+ }
-
- VM_BUG_ON(pmd_trans_huge(*pmd));
-
-@@ -106,6 +109,12 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
+@@ -106,6 +107,12 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
continue;
pte = ptep_get_and_clear(mm, old_addr, old_pte);
pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
@@ -87274,7 +86913,7 @@ index d6959cb..51051b9 100644
set_pte_at(mm, new_addr, new_pte, pte);
}
-@@ -251,7 +260,6 @@ static unsigned long move_vma(struct vm_area_struct *vma,
+@@ -251,7 +258,6 @@ static unsigned long move_vma(struct vm_area_struct *vma,
* If this were a serious issue, we'd add a flag to do_munmap().
*/
hiwater_vm = mm->hiwater_vm;
@@ -87282,7 +86921,7 @@ index d6959cb..51051b9 100644
vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
if (do_munmap(mm, old_addr, old_len) < 0) {
-@@ -290,6 +298,11 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr,
+@@ -290,6 +296,11 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr,
if (is_vm_hugetlb_page(vma))
goto Einval;
@@ -87294,7 +86933,7 @@ index d6959cb..51051b9 100644
/* We can't remap across vm area boundaries */
if (old_len > vma->vm_end - addr)
goto Efault;
-@@ -346,20 +359,25 @@ static unsigned long mremap_to(unsigned long addr,
+@@ -346,20 +357,25 @@ static unsigned long mremap_to(unsigned long addr,
unsigned long ret = -EINVAL;
unsigned long charged = 0;
unsigned long map_flags;
@@ -87325,7 +86964,7 @@ index d6959cb..51051b9 100644
goto out;
ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
-@@ -431,6 +449,7 @@ unsigned long do_mremap(unsigned long addr,
+@@ -431,6 +447,7 @@ unsigned long do_mremap(unsigned long addr,
struct vm_area_struct *vma;
unsigned long ret = -EINVAL;
unsigned long charged = 0;
@@ -87333,7 +86972,7 @@ index d6959cb..51051b9 100644
if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
goto out;
-@@ -449,6 +468,17 @@ unsigned long do_mremap(unsigned long addr,
+@@ -449,6 +466,17 @@ unsigned long do_mremap(unsigned long addr,
if (!new_len)
goto out;
@@ -87351,7 +86990,7 @@ index d6959cb..51051b9 100644
if (flags & MREMAP_FIXED) {
if (flags & MREMAP_MAYMOVE)
ret = mremap_to(addr, old_len, new_addr, new_len);
-@@ -490,7 +520,6 @@ unsigned long do_mremap(unsigned long addr,
+@@ -490,7 +518,6 @@ unsigned long do_mremap(unsigned long addr,
goto out;
}
@@ -87359,7 +86998,7 @@ index d6959cb..51051b9 100644
vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages);
if (vma->vm_flags & VM_LOCKED) {
mm->locked_vm += pages;
-@@ -498,6 +527,7 @@ unsigned long do_mremap(unsigned long addr,
+@@ -498,6 +525,7 @@ unsigned long do_mremap(unsigned long addr,
addr + new_len);
}
ret = addr;
@@ -87367,7 +87006,7 @@ index d6959cb..51051b9 100644
goto out;
}
}
-@@ -524,7 +554,13 @@ unsigned long do_mremap(unsigned long addr,
+@@ -524,7 +552,13 @@ unsigned long do_mremap(unsigned long addr,
ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
if (ret)
goto out;
@@ -87508,7 +87147,7 @@ index ea3f83b..001a216 100644
.next = NULL,
};
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
-index b5afea2..762ffa1 100644
+index d8762b2..8a25d14 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -57,6 +57,7 @@
@@ -89659,10 +89298,10 @@ index 82ce164..00bd057 100644
err = -EFAULT;
break;
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
-index b81500c..92fc8ec 100644
+index a06deca..2269299 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
-@@ -1409,7 +1409,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
+@@ -1410,7 +1410,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
nexthdr = ip6h->nexthdr;
offset = ipv6_skip_exthdr(skb, sizeof(*ip6h), &nexthdr);
@@ -89876,7 +89515,7 @@ index 53a8e37..45c033e 100644
if (!IS_ERR(debugfsdir)) {
diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c
-index 5cf5222..6f704ad 100644
+index 84efbe4..51d47bc 100644
--- a/net/caif/cfctrl.c
+++ b/net/caif/cfctrl.c
@@ -9,6 +9,7 @@
@@ -90037,23 +89676,25 @@ index f78f898..d7aa843 100644
if (__rtnl_register(PF_CAN, RTM_GETROUTE, NULL, cgw_dump_jobs, NULL)) {
diff --git a/net/compat.c b/net/compat.c
-index 8c979cc..5800e81 100644
+index 8c979cc..2b1960c 100644
--- a/net/compat.c
+++ b/net/compat.c
-@@ -71,9 +71,9 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg)
+@@ -71,9 +71,11 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg)
__get_user(kmsg->msg_controllen, &umsg->msg_controllen) ||
__get_user(kmsg->msg_flags, &umsg->msg_flags))
return -EFAULT;
- kmsg->msg_name = compat_ptr(tmp1);
- kmsg->msg_iov = compat_ptr(tmp2);
- kmsg->msg_control = compat_ptr(tmp3);
++ if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
++ return -EINVAL;
+ kmsg->msg_name = (void __force_kernel *)compat_ptr(tmp1);
+ kmsg->msg_iov = (void __force_kernel *)compat_ptr(tmp2);
+ kmsg->msg_control = (void __force_kernel *)compat_ptr(tmp3);
return 0;
}
-@@ -85,7 +85,7 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
+@@ -85,7 +87,7 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
if (kern_msg->msg_namelen) {
if (mode == VERIFY_READ) {
@@ -90062,7 +89703,7 @@ index 8c979cc..5800e81 100644
kern_msg->msg_namelen,
kern_address);
if (err < 0)
-@@ -96,7 +96,7 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
+@@ -96,7 +98,7 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
kern_msg->msg_name = NULL;
tot_len = iov_from_user_compat_to_kern(kern_iov,
@@ -90071,7 +89712,7 @@ index 8c979cc..5800e81 100644
kern_msg->msg_iovlen);
if (tot_len >= 0)
kern_msg->msg_iov = kern_iov;
-@@ -116,20 +116,20 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
+@@ -116,20 +118,20 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
#define CMSG_COMPAT_FIRSTHDR(msg) \
(((msg)->msg_controllen) >= sizeof(struct compat_cmsghdr) ? \
@@ -90095,7 +89736,7 @@ index 8c979cc..5800e81 100644
msg->msg_controllen)
return NULL;
return (struct compat_cmsghdr __user *)ptr;
-@@ -221,7 +221,7 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat
+@@ -221,7 +223,7 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat
{
struct compat_timeval ctv;
struct compat_timespec cts[3];
@@ -90104,7 +89745,7 @@ index 8c979cc..5800e81 100644
struct compat_cmsghdr cmhdr;
int cmlen;
-@@ -273,7 +273,7 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat
+@@ -273,7 +275,7 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat
void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm)
{
@@ -90113,7 +89754,7 @@ index 8c979cc..5800e81 100644
int fdmax = (kmsg->msg_controllen - sizeof(struct compat_cmsghdr)) / sizeof(int);
int fdnum = scm->fp->count;
struct file **fp = scm->fp->fp;
-@@ -370,7 +370,7 @@ static int do_set_sock_timeout(struct socket *sock, int level,
+@@ -370,7 +372,7 @@ static int do_set_sock_timeout(struct socket *sock, int level,
return -EFAULT;
old_fs = get_fs();
set_fs(KERNEL_DS);
@@ -90122,7 +89763,7 @@ index 8c979cc..5800e81 100644
set_fs(old_fs);
return err;
-@@ -431,7 +431,7 @@ static int do_get_sock_timeout(struct socket *sock, int level, int optname,
+@@ -431,7 +433,7 @@ static int do_get_sock_timeout(struct socket *sock, int level, int optname,
len = sizeof(ktime);
old_fs = get_fs();
set_fs(KERNEL_DS);
@@ -90131,7 +89772,7 @@ index 8c979cc..5800e81 100644
set_fs(old_fs);
if (!err) {
-@@ -566,7 +566,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
+@@ -566,7 +568,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
case MCAST_JOIN_GROUP:
case MCAST_LEAVE_GROUP:
{
@@ -90140,7 +89781,7 @@ index 8c979cc..5800e81 100644
struct group_req __user *kgr =
compat_alloc_user_space(sizeof(struct group_req));
u32 interface;
-@@ -587,7 +587,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
+@@ -587,7 +589,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
case MCAST_BLOCK_SOURCE:
case MCAST_UNBLOCK_SOURCE:
{
@@ -90149,7 +89790,7 @@ index 8c979cc..5800e81 100644
struct group_source_req __user *kgsr = compat_alloc_user_space(
sizeof(struct group_source_req));
u32 interface;
-@@ -608,7 +608,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
+@@ -608,7 +610,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname,
}
case MCAST_MSFILTER:
{
@@ -90158,7 +89799,7 @@ index 8c979cc..5800e81 100644
struct group_filter __user *kgf;
u32 interface, fmode, numsrc;
-@@ -646,7 +646,7 @@ int compat_mc_getsockopt(struct sock *sock, int level, int optname,
+@@ -646,7 +648,7 @@ int compat_mc_getsockopt(struct sock *sock, int level, int optname,
char __user *optval, int __user *optlen,
int (*getsockopt)(struct sock *, int, int, char __user *, int __user *))
{
@@ -90167,7 +89808,7 @@ index 8c979cc..5800e81 100644
struct group_filter __user *kgf;
int __user *koptlen;
u32 interface, fmode, numsrc;
-@@ -799,7 +799,7 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args)
+@@ -799,7 +801,7 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args)
if (call < SYS_SOCKET || call > SYS_SENDMMSG)
return -EINVAL;
@@ -90743,10 +90384,10 @@ index 8a2c2dd..3ba3cf1 100644
.exit = proto_exit_net,
};
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
-index 77a65f0..ebd69a8 100644
+index f0bdd36..957fc06 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
-@@ -25,7 +25,7 @@ static int rps_sock_flow_sysctl(ctl_table *table, int write,
+@@ -28,7 +28,7 @@ static int rps_sock_flow_sysctl(ctl_table *table, int write,
{
unsigned int orig_size, size;
int ret, i;
@@ -90755,7 +90396,7 @@ index 77a65f0..ebd69a8 100644
.data = &size,
.maxlen = sizeof(size),
.mode = table->mode
-@@ -205,29 +205,27 @@ __net_initdata struct ctl_path net_core_path[] = {
+@@ -210,29 +210,27 @@ __net_initdata struct ctl_path net_core_path[] = {
static __net_init int sysctl_core_net_init(struct net *net)
{
@@ -90791,7 +90432,7 @@ index 77a65f0..ebd69a8 100644
err_dup:
return -ENOMEM;
}
-@@ -242,7 +240,7 @@ static __net_exit void sysctl_core_net_exit(struct net *net)
+@@ -247,7 +245,7 @@ static __net_exit void sysctl_core_net_exit(struct net *net)
kfree(tbl);
}
@@ -91086,30 +90727,6 @@ index d01f9c6..284c56c 100644
return nh->nh_saddr;
}
-diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
-index cd2d639..c7c6724 100644
---- a/net/ipv4/fib_trie.c
-+++ b/net/ipv4/fib_trie.c
-@@ -72,7 +72,6 @@
- #include <linux/init.h>
- #include <linux/list.h>
- #include <linux/slab.h>
--#include <linux/prefetch.h>
- #include <linux/export.h>
- #include <net/net_namespace.h>
- #include <net/ip.h>
-@@ -1773,10 +1772,8 @@ static struct leaf *leaf_walk_rcu(struct tnode *p, struct rt_trie_node *c)
- if (!c)
- continue;
-
-- if (IS_LEAF(c)) {
-- prefetch(rcu_dereference_rtnl(p->child[idx]));
-+ if (IS_LEAF(c))
- return (struct leaf *) c;
-- }
-
- /* Rescan start scanning in new node */
- p = (struct tnode *) c;
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index ab188ae..662585c 100644
--- a/net/ipv4/icmp.c
@@ -91202,7 +90819,7 @@ index ccee270..db23c3c 100644
tmo = req->expires - jiffies;
if (tmo < 0)
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
-index 984ec65..97ac518 100644
+index 984ec65..392d206 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -18,12 +18,15 @@
@@ -91221,6 +90838,15 @@ index 984ec65..97ac518 100644
/*
* Allocate and initialize a new local port bind bucket.
* The bindhash mutex for snum's hash chain must be held here.
+@@ -268,7 +271,7 @@ begintw:
+ }
+ if (unlikely(!INET_TW_MATCH(sk, net, hash, acookie,
+ saddr, daddr, ports, dif))) {
+- sock_put(sk);
++ inet_twsk_put(inet_twsk(sk));
+ goto begintw;
+ }
+ goto out;
@@ -530,6 +533,8 @@ ok:
twrefcnt += inet_twsk_bind_unhash(tw, hinfo);
spin_unlock(&head->lock);
@@ -91231,10 +90857,10 @@ index 984ec65..97ac518 100644
inet_twsk_deschedule(tw, death_row);
while (twrefcnt) {
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
-index 86f13c67..59a35b5 100644
+index 58c4e696..4f025f0 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
-@@ -436,8 +436,8 @@ relookup:
+@@ -487,8 +487,8 @@ relookup:
if (p) {
p->daddr = *daddr;
atomic_set(&p->refcnt, 1);
@@ -91326,6 +90952,19 @@ index 5f28fab..ebd7a97 100644
.kind = "gretap",
.maxtype = IFLA_GRE_MAX,
.policy = ipgre_policy,
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+index daf408e..16191f0 100644
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -833,7 +833,7 @@ static int __ip_append_data(struct sock *sk,
+ csummode = CHECKSUM_PARTIAL;
+
+ cork->length += length;
+- if (((length > mtu) || (skb && skb_is_gso(skb))) &&
++ if (((length > mtu) || (skb && skb_has_frags(skb))) &&
+ (sk->sk_protocol == IPPROTO_UDP) &&
+ (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) {
+ err = ip_ufo_append_data(sk, queue, getfrag, from, length,
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 3b36002..27e6634 100644
--- a/net/ipv4/ip_sockglue.c
@@ -91381,7 +91020,7 @@ index 99ec116..c5628fe 100644
return res;
}
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
-index 0064394..2d993a0 100644
+index b5e64e4..4a9a5c4 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1320,6 +1320,10 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
@@ -91555,7 +91194,7 @@ index f7fdbe9..63740b7 100644
.exit = ip_proc_exit_net,
};
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
-index e1d4f30..5e8918e 100644
+index 2815014..1d39ae6 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -305,7 +305,7 @@ static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb)
@@ -91625,7 +91264,7 @@ index e1d4f30..5e8918e 100644
.exit = raw_exit_net,
};
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
-index 94cdbc5..01d3a77 100644
+index c45a155a3..dadea8d 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -313,7 +313,7 @@ static inline unsigned int rt_hash(__be32 daddr, __be32 saddr, int idx,
@@ -91653,9 +91292,9 @@ index 94cdbc5..01d3a77 100644
- atomic_add(shuffle + 1U, &net->ipv4.rt_genid);
+ atomic_add_unchecked(shuffle + 1U, &net->ipv4.rt_genid);
redirect_genid++;
+ inetpeer_invalidate_tree(AF_INET);
}
-
-@@ -3022,7 +3022,7 @@ static int rt_fill_info(struct net *net,
+@@ -3023,7 +3023,7 @@ static int rt_fill_info(struct net *net,
error = rt->dst.error;
if (peer) {
inet_peer_refcheck(rt->peer);
@@ -91664,7 +91303,7 @@ index 94cdbc5..01d3a77 100644
if (peer->tcp_ts_stamp) {
ts = peer->tcp_ts;
tsage = get_seconds() - peer->tcp_ts_stamp;
-@@ -3221,7 +3221,7 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
+@@ -3222,7 +3222,7 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
{
if (write) {
int flush_delay;
@@ -91673,7 +91312,7 @@ index 94cdbc5..01d3a77 100644
struct net *net;
memcpy(&ctl, __ctl, sizeof(ctl));
-@@ -3370,6 +3370,7 @@ static struct ctl_table ipv4_route_flush_table[] = {
+@@ -3371,6 +3371,7 @@ static struct ctl_table ipv4_route_flush_table[] = {
.maxlen = sizeof(int),
.mode = 0200,
.proc_handler = ipv4_sysctl_rtcache_flush,
@@ -91681,7 +91320,7 @@ index 94cdbc5..01d3a77 100644
},
{ },
};
-@@ -3383,25 +3384,23 @@ static __net_initdata struct ctl_path ipv4_route_path[] = {
+@@ -3384,25 +3385,23 @@ static __net_initdata struct ctl_path ipv4_route_path[] = {
static __net_init int sysctl_route_net_init(struct net *net)
{
@@ -91714,7 +91353,7 @@ index 94cdbc5..01d3a77 100644
err_dup:
return -ENOMEM;
}
-@@ -3416,7 +3415,7 @@ static __net_exit void sysctl_route_net_exit(struct net *net)
+@@ -3417,7 +3416,7 @@ static __net_exit void sysctl_route_net_exit(struct net *net)
kfree(tbl);
}
@@ -91723,7 +91362,7 @@ index 94cdbc5..01d3a77 100644
.init = sysctl_route_net_init,
.exit = sysctl_route_net_exit,
};
-@@ -3431,7 +3430,7 @@ static __net_init int rt_genid_init(struct net *net)
+@@ -3432,7 +3431,7 @@ static __net_init int rt_genid_init(struct net *net)
return 0;
}
@@ -92259,27 +91898,10 @@ index a0b4c5d..a5818a1 100644
}
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
-index 314bda2..19a815f 100644
+index 5d41293..19a815f 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
-@@ -913,12 +913,10 @@ retry:
- if (ifp->flags & IFA_F_OPTIMISTIC)
- addr_flags |= IFA_F_OPTIMISTIC;
-
-- ift = !max_addresses ||
-- ipv6_count_addresses(idev) < max_addresses ?
-- ipv6_add_addr(idev, &addr, tmp_plen,
-- ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK,
-- addr_flags) : NULL;
-- if (!ift || IS_ERR(ift)) {
-+ ift = ipv6_add_addr(idev, &addr, tmp_plen,
-+ ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK,
-+ addr_flags);
-+ if (IS_ERR(ift)) {
- in6_ifa_put(ifp);
- in6_dev_put(idev);
- printk(KERN_INFO
-@@ -2159,7 +2157,7 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg)
+@@ -2157,7 +2157,7 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg)
p.iph.ihl = 5;
p.iph.protocol = IPPROTO_IPV6;
p.iph.ttl = 64;
@@ -92323,10 +91945,10 @@ index 65dd543..e6c6e6d 100644
static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
-index 90868fb..7aeff1e 100644
+index d505453..ff99535 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
-@@ -961,7 +961,7 @@ ctl_table ipv6_icmp_table_template[] = {
+@@ -969,7 +969,7 @@ ctl_table ipv6_icmp_table_template[] = {
struct ctl_table * __net_init ipv6_icmp_sysctl_init(struct net *net)
{
@@ -92357,8 +91979,21 @@ index 1567fb1..29af910 100644
__sk_dst_reset(sk);
dst = NULL;
}
+diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
+index 73f1a00..e38290b 100644
+--- a/net/ipv6/inet6_hashtables.c
++++ b/net/ipv6/inet6_hashtables.c
+@@ -110,7 +110,7 @@ begintw:
+ goto out;
+ }
+ if (!INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif)) {
+- sock_put(sk);
++ inet_twsk_put(inet_twsk(sk));
+ goto begintw;
+ }
+ goto out;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
-index db60043..7f8a2c1 100644
+index 91d0711..7dc5e62 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -600,8 +600,8 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
@@ -92390,92 +92025,15 @@ index db60043..7f8a2c1 100644
}
int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
-@@ -1125,6 +1122,8 @@ static inline int ip6_ufo_append_data(struct sock *sk,
- * udp datagram
- */
- if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) {
-+ struct frag_hdr fhdr;
-+
- skb = sock_alloc_send_skb(sk,
- hh_len + fragheaderlen + transhdrlen + 20,
- (flags & MSG_DONTWAIT), &err);
-@@ -1145,12 +1144,6 @@ static inline int ip6_ufo_append_data(struct sock *sk,
-
- skb->ip_summed = CHECKSUM_PARTIAL;
- skb->csum = 0;
-- }
--
-- err = skb_append_datato_frags(sk,skb, getfrag, from,
-- (length - transhdrlen));
-- if (!err) {
-- struct frag_hdr fhdr;
-
- /* Specify the length of each IPv6 datagram fragment.
- * It has to be a multiple of 8.
-@@ -1161,15 +1154,10 @@ static inline int ip6_ufo_append_data(struct sock *sk,
- ipv6_select_ident(&fhdr, rt);
- skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
- __skb_queue_tail(&sk->sk_write_queue, skb);
--
-- return 0;
- }
-- /* There is not enough support do UPD LSO,
-- * so follow normal path
-- */
-- kfree_skb(skb);
-
-- return err;
-+ return skb_append_datato_frags(sk, skb, getfrag, from,
-+ (length - transhdrlen));
- }
-
- static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src,
-@@ -1342,27 +1330,27 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
- * --yoshfuji
- */
-
-+ if ((length > mtu) && dontfrag && (sk->sk_protocol == IPPROTO_UDP ||
-+ sk->sk_protocol == IPPROTO_RAW)) {
-+ ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen);
-+ return -EMSGSIZE;
-+ }
-+
-+ skb = skb_peek_tail(&sk->sk_write_queue);
+@@ -1342,7 +1339,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
+ skb = skb_peek_tail(&sk->sk_write_queue);
cork->length += length;
-- if (length > mtu) {
-- int proto = sk->sk_protocol;
-- if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){
-- ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen);
-- return -EMSGSIZE;
-- }
--
-- if (proto == IPPROTO_UDP &&
-- (rt->dst.dev->features & NETIF_F_UFO)) {
--
-- err = ip6_ufo_append_data(sk, getfrag, from, length,
-- hh_len, fragheaderlen,
-- transhdrlen, mtu, flags, rt);
-- if (err)
-- goto error;
-- return 0;
-- }
-+ if (((length > mtu) ||
-+ (skb && skb_is_gso(skb))) &&
-+ (sk->sk_protocol == IPPROTO_UDP) &&
-+ (rt->dst.dev->features & NETIF_F_UFO)) {
-+ err = ip6_ufo_append_data(sk, getfrag, from, length,
-+ hh_len, fragheaderlen,
-+ transhdrlen, mtu, flags, rt);
-+ if (err)
-+ goto error;
-+ return 0;
- }
-
-- if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL)
-+ if (!skb)
- goto alloc_new_skb;
-
- while (length > 0) {
+ if (((length > mtu) ||
+- (skb && skb_is_gso(skb))) &&
++ (skb && skb_has_frags(skb))) &&
+ (sk->sk_protocol == IPPROTO_UDP) &&
+ (rt->dst.dev->features & NETIF_F_UFO)) {
+ err = ip6_ufo_append_data(sk, getfrag, from, length,
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index b204df8..8f274f4 100644
--- a/net/ipv6/ipv6_sockglue.c
@@ -92638,10 +92196,10 @@ index 6e6c2c4..c97891e 100644
static int raw6_seq_show(struct seq_file *seq, void *v)
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
-index 411fe2c..cdea3e4 100644
+index eba5deb..61e026f 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
-@@ -646,21 +646,21 @@ static struct ctl_table ip6_frags_ctl_table[] = {
+@@ -651,21 +651,21 @@ static struct ctl_table ip6_frags_ctl_table[] = {
static int __net_init ip6_frags_ns_sysctl_register(struct net *net)
{
@@ -92668,7 +92226,7 @@ index 411fe2c..cdea3e4 100644
if (hdr == NULL)
goto err_reg;
-@@ -668,8 +668,7 @@ static int __net_init ip6_frags_ns_sysctl_register(struct net *net)
+@@ -673,8 +673,7 @@ static int __net_init ip6_frags_ns_sysctl_register(struct net *net)
return 0;
err_reg:
@@ -93563,7 +93121,7 @@ index 2b6678c0..aaa41fc 100644
cp->old_state = cp->state;
/*
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
-index aa2d720..d8aa111 100644
+index 38c0813..a29519d 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -1151,7 +1151,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
@@ -94721,100 +94279,10 @@ index 7635107..4670276 100644
ret = kernel_sendmsg(conn->trans->local->socket, &msg, iov, 3, len);
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
-index 8104278..c969717 100644
+index 0b6a391..febcef2 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
-@@ -205,45 +205,23 @@ out:
- in6_dev_put(idev);
- }
-
--/* Based on tcp_v6_xmit() in tcp_ipv6.c. */
- static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
- {
- struct sock *sk = skb->sk;
- struct ipv6_pinfo *np = inet6_sk(sk);
-- struct flowi6 fl6;
-+ struct flowi6 *fl6 = &transport->fl.u.ip6;
-
-- memset(&fl6, 0, sizeof(fl6));
-+ pr_debug("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", __func__, skb,
-+ skb->len, &fl6->saddr, &fl6->daddr);
-
-- fl6.flowi6_proto = sk->sk_protocol;
--
-- /* Fill in the dest address from the route entry passed with the skb
-- * and the source address from the transport.
-- */
-- ipv6_addr_copy(&fl6.daddr, &transport->ipaddr.v6.sin6_addr);
-- ipv6_addr_copy(&fl6.saddr, &transport->saddr.v6.sin6_addr);
--
-- fl6.flowlabel = np->flow_label;
-- IP6_ECN_flow_xmit(sk, fl6.flowlabel);
-- if (ipv6_addr_type(&fl6.saddr) & IPV6_ADDR_LINKLOCAL)
-- fl6.flowi6_oif = transport->saddr.v6.sin6_scope_id;
-- else
-- fl6.flowi6_oif = sk->sk_bound_dev_if;
--
-- if (np->opt && np->opt->srcrt) {
-- struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
-- ipv6_addr_copy(&fl6.daddr, rt0->addr);
-- }
--
-- SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n",
-- __func__, skb, skb->len,
-- &fl6.saddr, &fl6.daddr);
--
-- SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
-+ IP6_ECN_flow_xmit(sk, fl6->flowlabel);
-
- if (!(transport->param_flags & SPP_PMTUD_ENABLE))
- skb->local_df = 1;
-
-- return ip6_xmit(sk, skb, &fl6, np->opt, np->tclass);
-+ SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
-+
-+ return ip6_xmit(sk, skb, fl6, np->opt, np->tclass);
- }
-
- /* Returns the dst cache entry for the given source and destination ip
-@@ -256,10 +234,12 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
- struct dst_entry *dst = NULL;
- struct flowi6 *fl6 = &fl->u.ip6;
- struct sctp_bind_addr *bp;
-+ struct ipv6_pinfo *np = inet6_sk(sk);
- struct sctp_sockaddr_entry *laddr;
- union sctp_addr *baddr = NULL;
- union sctp_addr *daddr = &t->ipaddr;
- union sctp_addr dst_saddr;
-+ struct in6_addr *final_p, final;
- __u8 matchlen = 0;
- __u8 bmatchlen;
- sctp_scope_t scope;
-@@ -282,7 +262,8 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
- SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6->saddr);
- }
-
-- dst = ip6_dst_lookup_flow(sk, fl6, NULL, false);
-+ final_p = fl6_update_dst(fl6, np->opt, &final);
-+ dst = ip6_dst_lookup_flow(sk, fl6, final_p, false);
- if (!asoc || saddr)
- goto out;
-
-@@ -333,10 +314,12 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
- }
- }
- rcu_read_unlock();
-+
- if (baddr) {
- ipv6_addr_copy(&fl6->saddr, &baddr->v6.sin6_addr);
- fl6->fl6_sport = baddr->v6.sin6_port;
-- dst = ip6_dst_lookup_flow(sk, fl6, NULL, false);
-+ final_p = fl6_update_dst(fl6, np->opt, &final);
-+ dst = ip6_dst_lookup_flow(sk, fl6, final_p, false);
- }
-
- out:
-@@ -977,7 +960,7 @@ static const struct inet6_protocol sctpv6_protocol = {
+@@ -961,7 +961,7 @@ static const struct inet6_protocol sctpv6_protocol = {
.flags = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL,
};
@@ -94823,7 +94291,7 @@ index 8104278..c969717 100644
.sa_family = AF_INET6,
.sctp_xmit = sctp_v6_xmit,
.setsockopt = ipv6_setsockopt,
-@@ -1009,7 +992,7 @@ static struct sctp_af sctp_af_inet6 = {
+@@ -993,7 +993,7 @@ static struct sctp_af sctp_af_inet6 = {
#endif
};
@@ -94832,7 +94300,7 @@ index 8104278..c969717 100644
.event_msgname = sctp_inet6_event_msgname,
.skb_msgname = sctp_inet6_skb_msgname,
.af_supported = sctp_inet6_af_supported,
-@@ -1034,7 +1017,7 @@ void sctp_v6_pf_init(void)
+@@ -1018,7 +1018,7 @@ void sctp_v6_pf_init(void)
void sctp_v6_pf_exit(void)
{
@@ -94912,7 +94380,7 @@ index 6f6ad86..d52dc47 100644
static int sctp_v4_protosw_init(void)
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
-index 9032d50..49eb875 100644
+index 76388b0..a967f68 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -441,7 +441,7 @@ static void sctp_generate_sack_event(unsigned long data)
@@ -94925,10 +94393,10 @@ index 9032d50..49eb875 100644
sctp_generate_t1_cookie_event,
sctp_generate_t1_init_event,
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
-index ba0108f..f09fd13 100644
+index c53d01e..9659111 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
-@@ -2157,11 +2157,13 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval,
+@@ -2160,11 +2160,13 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval,
{
struct sctp_association *asoc;
struct sctp_ulpevent *event;
@@ -94943,7 +94411,7 @@ index ba0108f..f09fd13 100644
/*
* At the time when a user app subscribes to SCTP_SENDER_DRY_EVENT,
-@@ -4147,13 +4149,16 @@ static int sctp_getsockopt_disable_fragments(struct sock *sk, int len,
+@@ -4150,13 +4152,16 @@ static int sctp_getsockopt_disable_fragments(struct sock *sk, int len,
static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval,
int __user *optlen)
{
@@ -94961,7 +94429,7 @@ index ba0108f..f09fd13 100644
return -EFAULT;
return 0;
}
-@@ -4171,6 +4176,8 @@ static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval,
+@@ -4174,6 +4179,8 @@ static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval,
*/
static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optval, int __user *optlen)
{
@@ -94970,7 +94438,7 @@ index ba0108f..f09fd13 100644
/* Applicable to UDP-style socket only */
if (sctp_style(sk, TCP))
return -EOPNOTSUPP;
-@@ -4179,7 +4186,8 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv
+@@ -4182,7 +4189,8 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv
len = sizeof(int);
if (put_user(len, optlen))
return -EFAULT;
@@ -94980,7 +94448,7 @@ index ba0108f..f09fd13 100644
return -EFAULT;
return 0;
}
-@@ -4543,12 +4551,15 @@ static int sctp_getsockopt_delayed_ack(struct sock *sk, int len,
+@@ -4546,12 +4554,15 @@ static int sctp_getsockopt_delayed_ack(struct sock *sk, int len,
*/
static int sctp_getsockopt_initmsg(struct sock *sk, int len, char __user *optval, int __user *optlen)
{
@@ -94997,7 +94465,7 @@ index ba0108f..f09fd13 100644
return -EFAULT;
return 0;
}
-@@ -4589,6 +4600,8 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
+@@ -4592,6 +4603,8 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
if (space_left < addrlen)
return -ENOMEM;
@@ -95060,7 +94528,7 @@ index 8da4481..d02565e 100644
+ (rtt >> sctp_rto_alpha);
} else {
diff --git a/net/socket.c b/net/socket.c
-index cf546a3..a9b550f 100644
+index cf546a3..3cb0fca 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -88,6 +88,7 @@
@@ -95244,7 +94712,38 @@ index cf546a3..a9b550f 100644
int err, err2;
int fput_needed;
-@@ -1950,7 +2016,7 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
+@@ -1876,6 +1942,16 @@ struct used_address {
+ unsigned int name_len;
+ };
+
++static int copy_msghdr_from_user(struct msghdr *kmsg,
++ struct msghdr __user *umsg)
++{
++ if (copy_from_user(kmsg, umsg, sizeof(struct msghdr)))
++ return -EFAULT;
++ if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
++ return -EINVAL;
++ return 0;
++}
++
+ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
+ struct msghdr *msg_sys, unsigned flags,
+ struct used_address *used_address)
+@@ -1894,8 +1970,11 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
+ if (MSG_CMSG_COMPAT & flags) {
+ if (get_compat_msghdr(msg_sys, msg_compat))
+ return -EFAULT;
+- } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr)))
+- return -EFAULT;
++ } else {
++ err = copy_msghdr_from_user(msg_sys, msg);
++ if (err)
++ return err;
++ }
+
+ /* do not move before msg_sys is valid */
+ err = -EMSGSIZE;
+@@ -1950,7 +2029,7 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
* checking falls down on this.
*/
if (copy_from_user(ctl_buf,
@@ -95253,7 +94752,7 @@ index cf546a3..a9b550f 100644
ctl_len))
goto out_freectl;
msg_sys->msg_control = ctl_buf;
-@@ -2101,7 +2167,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
+@@ -2101,7 +2180,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
int err, iov_size, total_len, len;
/* kernel mode address */
@@ -95262,7 +94761,21 @@ index cf546a3..a9b550f 100644
/* user mode address pointers */
struct sockaddr __user *uaddr;
-@@ -2131,7 +2197,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
+@@ -2110,8 +2189,11 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
+ if (MSG_CMSG_COMPAT & flags) {
+ if (get_compat_msghdr(msg_sys, msg_compat))
+ return -EFAULT;
+- } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr)))
+- return -EFAULT;
++ } else {
++ err = copy_msghdr_from_user(msg_sys, msg);
++ if (err)
++ return err;
++ }
+
+ err = -EMSGSIZE;
+ if (msg_sys->msg_iovlen > UIO_MAXIOV)
+@@ -2131,7 +2213,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
* kernel msghdr to use the kernel address space)
*/
@@ -95271,7 +94784,7 @@ index cf546a3..a9b550f 100644
uaddr_len = COMPAT_NAMELEN(msg);
if (MSG_CMSG_COMPAT & flags) {
err = verify_compat_iovec(msg_sys, iov,
-@@ -2772,7 +2838,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
+@@ -2772,7 +2854,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
}
ifr = compat_alloc_user_space(buf_size);
@@ -95280,7 +94793,7 @@ index cf546a3..a9b550f 100644
if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
return -EFAULT;
-@@ -2796,12 +2862,12 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
+@@ -2796,12 +2878,12 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
offsetof(struct ethtool_rxnfc, fs.ring_cookie));
if (copy_in_user(rxnfc, compat_rxnfc,
@@ -95297,7 +94810,7 @@ index cf546a3..a9b550f 100644
copy_in_user(&rxnfc->rule_cnt, &compat_rxnfc->rule_cnt,
sizeof(rxnfc->rule_cnt)))
return -EFAULT;
-@@ -2813,12 +2879,12 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
+@@ -2813,12 +2895,12 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
if (convert_out) {
if (copy_in_user(compat_rxnfc, rxnfc,
@@ -95314,7 +94827,7 @@ index cf546a3..a9b550f 100644
copy_in_user(&compat_rxnfc->rule_cnt, &rxnfc->rule_cnt,
sizeof(rxnfc->rule_cnt)))
return -EFAULT;
-@@ -2888,7 +2954,7 @@ static int bond_ioctl(struct net *net, unsigned int cmd,
+@@ -2888,7 +2970,7 @@ static int bond_ioctl(struct net *net, unsigned int cmd,
old_fs = get_fs();
set_fs(KERNEL_DS);
err = dev_ioctl(net, cmd,
@@ -95323,7 +94836,7 @@ index cf546a3..a9b550f 100644
set_fs(old_fs);
return err;
-@@ -2997,7 +3063,7 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
+@@ -2997,7 +3079,7 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
old_fs = get_fs();
set_fs(KERNEL_DS);
@@ -95332,7 +94845,7 @@ index cf546a3..a9b550f 100644
set_fs(old_fs);
if (cmd == SIOCGIFMAP && !err) {
-@@ -3102,7 +3168,7 @@ static int routing_ioctl(struct net *net, struct socket *sock,
+@@ -3102,7 +3184,7 @@ static int routing_ioctl(struct net *net, struct socket *sock,
ret |= __get_user(rtdev, &(ur4->rt_dev));
if (rtdev) {
ret |= copy_from_user(devname, compat_ptr(rtdev), 15);
@@ -95341,7 +94854,7 @@ index cf546a3..a9b550f 100644
devname[15] = 0;
} else
r4.rt_dev = NULL;
-@@ -3342,8 +3408,8 @@ int kernel_getsockopt(struct socket *sock, int level, int optname,
+@@ -3342,8 +3424,8 @@ int kernel_getsockopt(struct socket *sock, int level, int optname,
int __user *uoptlen;
int err;
@@ -95352,7 +94865,7 @@ index cf546a3..a9b550f 100644
set_fs(KERNEL_DS);
if (level == SOL_SOCKET)
-@@ -3363,7 +3429,7 @@ int kernel_setsockopt(struct socket *sock, int level, int optname,
+@@ -3363,7 +3445,7 @@ int kernel_setsockopt(struct socket *sock, int level, int optname,
char __user *uoptval;
int err;
@@ -96032,10 +95545,10 @@ index e758139..d29ea47 100644
return (mode << 6) | (mode << 3) | mode;
}
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
-index e728d4c..dffdddf 100644
+index a224a38..c31d40a 100644
--- a/net/tipc/eth_media.c
+++ b/net/tipc/eth_media.c
-@@ -57,7 +57,6 @@ struct eth_bearer {
+@@ -58,7 +58,6 @@ struct eth_bearer {
static struct eth_bearer eth_bearers[MAX_ETH_BEARERS];
static int eth_started;
@@ -96043,7 +95556,7 @@ index e728d4c..dffdddf 100644
/**
* send_msg - send a TIPC message out over an Ethernet interface
-@@ -264,6 +263,11 @@ static char *eth_addr2str(struct tipc_media_addr *a, char *str_buf, int str_size
+@@ -277,6 +276,11 @@ static char *eth_addr2str(struct tipc_media_addr *a, char *str_buf, int str_size
* with OS for notifications about device state changes.
*/
@@ -96055,7 +95568,7 @@ index e728d4c..dffdddf 100644
int tipc_eth_media_start(void)
{
struct tipc_media_addr bcast_addr;
-@@ -284,8 +288,6 @@ int tipc_eth_media_start(void)
+@@ -297,8 +301,6 @@ int tipc_eth_media_start(void)
if (res)
return res;
diff --git a/3.2.51/4425_grsec_remove_EI_PAX.patch b/3.2.52/4425_grsec_remove_EI_PAX.patch
index 7d06ac2..7d06ac2 100644
--- a/3.2.51/4425_grsec_remove_EI_PAX.patch
+++ b/3.2.52/4425_grsec_remove_EI_PAX.patch
diff --git a/3.2.51/4427_force_XATTR_PAX_tmpfs.patch b/3.2.52/4427_force_XATTR_PAX_tmpfs.patch
index 8c7a533..8c7a533 100644
--- a/3.2.51/4427_force_XATTR_PAX_tmpfs.patch
+++ b/3.2.52/4427_force_XATTR_PAX_tmpfs.patch
diff --git a/3.2.51/4430_grsec-remove-localversion-grsec.patch b/3.2.52/4430_grsec-remove-localversion-grsec.patch
index 31cf878..31cf878 100644
--- a/3.2.51/4430_grsec-remove-localversion-grsec.patch
+++ b/3.2.52/4430_grsec-remove-localversion-grsec.patch
diff --git a/3.2.51/4435_grsec-mute-warnings.patch b/3.2.52/4435_grsec-mute-warnings.patch
index f099757..f099757 100644
--- a/3.2.51/4435_grsec-mute-warnings.patch
+++ b/3.2.52/4435_grsec-mute-warnings.patch
diff --git a/3.2.51/4440_grsec-remove-protected-paths.patch b/3.2.52/4440_grsec-remove-protected-paths.patch
index 05710b1..05710b1 100644
--- a/3.2.51/4440_grsec-remove-protected-paths.patch
+++ b/3.2.52/4440_grsec-remove-protected-paths.patch
diff --git a/3.2.51/4450_grsec-kconfig-default-gids.patch b/3.2.52/4450_grsec-kconfig-default-gids.patch
index 4de4ac0..4de4ac0 100644
--- a/3.2.51/4450_grsec-kconfig-default-gids.patch
+++ b/3.2.52/4450_grsec-kconfig-default-gids.patch
diff --git a/3.2.51/4465_selinux-avc_audit-log-curr_ip.patch b/3.2.52/4465_selinux-avc_audit-log-curr_ip.patch
index 687ae4c..687ae4c 100644
--- a/3.2.51/4465_selinux-avc_audit-log-curr_ip.patch
+++ b/3.2.52/4465_selinux-avc_audit-log-curr_ip.patch
diff --git a/3.2.51/4470_disable-compat_vdso.patch b/3.2.52/4470_disable-compat_vdso.patch
index 99c691b..99c691b 100644
--- a/3.2.51/4470_disable-compat_vdso.patch
+++ b/3.2.52/4470_disable-compat_vdso.patch
diff --git a/3.2.51/4475_emutramp_default_on.patch b/3.2.52/4475_emutramp_default_on.patch
index df700e6..df700e6 100644
--- a/3.2.51/4475_emutramp_default_on.patch
+++ b/3.2.52/4475_emutramp_default_on.patch