diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2013-10-29 13:29:31 -0400 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2013-10-29 13:29:31 -0400 |
commit | 73961b305f24ed999e4af414afb420f14ca0252b (patch) | |
tree | 345c5e43dadc168ae0f8f628e89a457902b86d7b | |
parent | Grsec/PaX: 2.9.1-{3.2.51,3.11.6}-201310260850 (diff) | |
download | hardened-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_README | 2 | ||||
-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_README | 2 | ||||
-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.patch | 5221 | ||||
-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(¤t->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(®s->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, ®s->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, ®s->ctrl); + +- for (i = 0; i < ARRAY_SIZE(regs->cantxfg); i++) { +- flexcan_write(0, ®s->cantxfg[i].can_ctrl); +- flexcan_write(0, ®s->cantxfg[i].can_id); +- flexcan_write(0, ®s->cantxfg[i].data[0]); +- flexcan_write(0, ®s->cantxfg[i].data[1]); +- +- /* put MB into rx queue */ +- flexcan_write(FLEXCAN_MB_CNT_CODE(0x4), +- ®s->cantxfg[i].can_ctrl); +- } ++ /* Abort any pending TX, mark Mailbox as INACTIVE */ ++ flexcan_write(FLEXCAN_MB_CNT_CODE(0x4), ++ ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl); + + /* acceptance mask/acceptance code (accept everything) */ + flexcan_write(0x0, ®s->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(®s->tr03wt, DEFAULT_WRRS_WEIGHT); ++ gfar_write(®s->tr47wt, DEFAULT_WRRS_WEIGHT); ++ } + + gfar_write(®s->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 |