From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 7C7AB1381F1 for ; Sun, 20 May 2018 22:21:21 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 5920CE0C53; Sun, 20 May 2018 22:20:51 +0000 (UTC) Received: from smtp.gentoo.org (woodpecker.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 1CF77E0C56 for ; Sun, 20 May 2018 22:20:49 +0000 (UTC) Received: from oystercatcher.gentoo.org (unknown [IPv6:2a01:4f8:202:4333:225:90ff:fed9:fc84]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 0417F335CF9 for ; Sun, 20 May 2018 22:20:48 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id C5AEC27A for ; Sun, 20 May 2018 22:20:46 +0000 (UTC) From: "Mike Pagano" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Mike Pagano" Message-ID: <1526854839.7043d95188bcdfd203c462d80dba964d40d26d06.mpagano@gentoo> Subject: [gentoo-commits] proj/linux-patches:4.9 commit in: / X-VCS-Repository: proj/linux-patches X-VCS-Files: 0000_README 1100_linux-4.9.101.patch X-VCS-Directories: / X-VCS-Committer: mpagano X-VCS-Committer-Name: Mike Pagano X-VCS-Revision: 7043d95188bcdfd203c462d80dba964d40d26d06 X-VCS-Branch: 4.9 Date: Sun, 20 May 2018 22:20:46 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: 5c74ab08-f6c4-4a99-bc44-a3252275a535 X-Archives-Hash: 366086028e7b2c2bb5616bfbf898788f commit: 7043d95188bcdfd203c462d80dba964d40d26d06 Author: Mike Pagano gentoo org> AuthorDate: Sun May 20 22:20:39 2018 +0000 Commit: Mike Pagano gentoo org> CommitDate: Sun May 20 22:20:39 2018 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=7043d951 Linux patch 4.9.101 0000_README | 4 + 1100_linux-4.9.101.patch | 2104 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2108 insertions(+) diff --git a/0000_README b/0000_README index 3281660..e5bef53 100644 --- a/0000_README +++ b/0000_README @@ -443,6 +443,10 @@ Patch: 1099_linux-4.9.100.patch From: http://www.kernel.org Desc: Linux 4.9.100 +Patch: 1100_linux-4.9.101.patch +From: http://www.kernel.org +Desc: Linux 4.9.101 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1100_linux-4.9.101.patch b/1100_linux-4.9.101.patch new file mode 100644 index 0000000..162d7fe --- /dev/null +++ b/1100_linux-4.9.101.patch @@ -0,0 +1,2104 @@ +diff --git a/Makefile b/Makefile +index 52a41396680c..7d7bda23db8f 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 9 +-SUBLEVEL = 100 ++SUBLEVEL = 101 + EXTRAVERSION = + NAME = Roaring Lionus + +diff --git a/arch/alpha/include/asm/futex.h b/arch/alpha/include/asm/futex.h +index f939794363ac..56474690e685 100644 +--- a/arch/alpha/include/asm/futex.h ++++ b/arch/alpha/include/asm/futex.h +@@ -29,18 +29,10 @@ + : "r" (uaddr), "r"(oparg) \ + : "memory") + +-static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) ++static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, ++ u32 __user *uaddr) + { +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- int oparg = (encoded_op << 8) >> 20; +- int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, ret; +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; +- +- if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) +- return -EFAULT; + + pagefault_disable(); + +@@ -66,17 +58,9 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) + + pagefault_enable(); + +- if (!ret) { +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; +- case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; +- case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; +- case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; +- case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; +- case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; +- default: ret = -ENOSYS; +- } +- } ++ if (!ret) ++ *oval = oldval; ++ + return ret; + } + +diff --git a/arch/arc/include/asm/futex.h b/arch/arc/include/asm/futex.h +index 11e1b1f3acda..eb887dd13e74 100644 +--- a/arch/arc/include/asm/futex.h ++++ b/arch/arc/include/asm/futex.h +@@ -73,20 +73,11 @@ + + #endif + +-static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) ++static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, ++ u32 __user *uaddr) + { +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- int oparg = (encoded_op << 8) >> 20; +- int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, ret; + +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; +- +- if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) +- return -EFAULT; +- + #ifndef CONFIG_ARC_HAS_LLSC + preempt_disable(); /* to guarantee atomic r-m-w of futex op */ + #endif +@@ -118,30 +109,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) + preempt_enable(); + #endif + +- if (!ret) { +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: +- ret = (oldval == cmparg); +- break; +- case FUTEX_OP_CMP_NE: +- ret = (oldval != cmparg); +- break; +- case FUTEX_OP_CMP_LT: +- ret = (oldval < cmparg); +- break; +- case FUTEX_OP_CMP_GE: +- ret = (oldval >= cmparg); +- break; +- case FUTEX_OP_CMP_LE: +- ret = (oldval <= cmparg); +- break; +- case FUTEX_OP_CMP_GT: +- ret = (oldval > cmparg); +- break; +- default: +- ret = -ENOSYS; +- } +- } ++ if (!ret) ++ *oval = oldval; ++ + return ret; + } + +diff --git a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi +index 47c955458a77..2b9c2be436f9 100644 +--- a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi +@@ -88,7 +88,6 @@ + clocks = <&clks IMX6QDL_CLK_CKO>; + VDDA-supply = <®_2p5v>; + VDDIO-supply = <®_3p3v>; +- lrclk-strength = <3>; + }; + }; + +diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h +index 6795368ad023..cc414382dab4 100644 +--- a/arch/arm/include/asm/futex.h ++++ b/arch/arm/include/asm/futex.h +@@ -128,20 +128,10 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + #endif /* !SMP */ + + static inline int +-futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) ++arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) + { +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- int oparg = (encoded_op << 8) >> 20; +- int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, ret, tmp; + +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; +- +- if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) +- return -EFAULT; +- + #ifndef CONFIG_SMP + preempt_disable(); + #endif +@@ -172,17 +162,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) + preempt_enable(); + #endif + +- if (!ret) { +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; +- case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; +- case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; +- case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; +- case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; +- case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; +- default: ret = -ENOSYS; +- } +- } ++ if (!ret) ++ *oval = oldval; ++ + return ret; + } + +diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h +index 4e5f36a804b4..2a5090fb9113 100644 +--- a/arch/arm64/include/asm/futex.h ++++ b/arch/arm64/include/asm/futex.h +@@ -51,20 +51,9 @@ + : "memory") + + static inline int +-futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *_uaddr) ++arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) + { +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- int oparg = (int)(encoded_op << 8) >> 20; +- int cmparg = (int)(encoded_op << 20) >> 20; + int oldval = 0, ret, tmp; +- u32 __user *uaddr = __uaccess_mask_ptr(_uaddr); +- +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1U << (oparg & 0x1f); +- +- if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) +- return -EFAULT; + + pagefault_disable(); + +@@ -95,17 +84,9 @@ futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *_uaddr) + + pagefault_enable(); + +- if (!ret) { +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; +- case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; +- case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; +- case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; +- case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; +- case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; +- default: ret = -ENOSYS; +- } +- } ++ if (!ret) ++ *oval = oldval; ++ + return ret; + } + +diff --git a/arch/frv/include/asm/futex.h b/arch/frv/include/asm/futex.h +index 4bea27f50a7a..2702bd802d44 100644 +--- a/arch/frv/include/asm/futex.h ++++ b/arch/frv/include/asm/futex.h +@@ -7,7 +7,8 @@ + #include + #include + +-extern int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr); ++extern int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, ++ u32 __user *uaddr); + + static inline int + futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, +diff --git a/arch/frv/kernel/futex.c b/arch/frv/kernel/futex.c +index d155ca9e5098..37f7b2bf7f73 100644 +--- a/arch/frv/kernel/futex.c ++++ b/arch/frv/kernel/futex.c +@@ -186,20 +186,10 @@ static inline int atomic_futex_op_xchg_xor(int oparg, u32 __user *uaddr, int *_o + /* + * do the futex operations + */ +-int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) ++int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) + { +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- int oparg = (encoded_op << 8) >> 20; +- int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, ret; + +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; +- +- if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) +- return -EFAULT; +- + pagefault_disable(); + + switch (op) { +@@ -225,18 +215,9 @@ int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) + + pagefault_enable(); + +- if (!ret) { +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; +- case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; +- case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; +- case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; +- case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; +- case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; +- default: ret = -ENOSYS; break; +- } +- } ++ if (!ret) ++ *oval = oldval; + + return ret; + +-} /* end futex_atomic_op_inuser() */ ++} /* end arch_futex_atomic_op_inuser() */ +diff --git a/arch/hexagon/include/asm/futex.h b/arch/hexagon/include/asm/futex.h +index 7e597f8434da..c607b77c8215 100644 +--- a/arch/hexagon/include/asm/futex.h ++++ b/arch/hexagon/include/asm/futex.h +@@ -31,18 +31,9 @@ + + + static inline int +-futex_atomic_op_inuser(int encoded_op, int __user *uaddr) ++arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) + { +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- int oparg = (encoded_op << 8) >> 20; +- int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, ret; +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; +- +- if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) +- return -EFAULT; + + pagefault_disable(); + +@@ -72,30 +63,9 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr) + + pagefault_enable(); + +- if (!ret) { +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: +- ret = (oldval == cmparg); +- break; +- case FUTEX_OP_CMP_NE: +- ret = (oldval != cmparg); +- break; +- case FUTEX_OP_CMP_LT: +- ret = (oldval < cmparg); +- break; +- case FUTEX_OP_CMP_GE: +- ret = (oldval >= cmparg); +- break; +- case FUTEX_OP_CMP_LE: +- ret = (oldval <= cmparg); +- break; +- case FUTEX_OP_CMP_GT: +- ret = (oldval > cmparg); +- break; +- default: +- ret = -ENOSYS; +- } +- } ++ if (!ret) ++ *oval = oldval; ++ + return ret; + } + +diff --git a/arch/ia64/include/asm/futex.h b/arch/ia64/include/asm/futex.h +index 76acbcd5c060..6d67dc1eaf2b 100644 +--- a/arch/ia64/include/asm/futex.h ++++ b/arch/ia64/include/asm/futex.h +@@ -45,18 +45,9 @@ do { \ + } while (0) + + static inline int +-futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) ++arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) + { +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- int oparg = (encoded_op << 8) >> 20; +- int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, ret; +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; +- +- if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) +- return -EFAULT; + + pagefault_disable(); + +@@ -84,17 +75,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) + + pagefault_enable(); + +- if (!ret) { +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; +- case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; +- case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; +- case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; +- case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; +- case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; +- default: ret = -ENOSYS; +- } +- } ++ if (!ret) ++ *oval = oldval; ++ + return ret; + } + +diff --git a/arch/microblaze/include/asm/futex.h b/arch/microblaze/include/asm/futex.h +index 01848f056f43..a9dad9e5e132 100644 +--- a/arch/microblaze/include/asm/futex.h ++++ b/arch/microblaze/include/asm/futex.h +@@ -29,18 +29,9 @@ + }) + + static inline int +-futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) ++arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) + { +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- int oparg = (encoded_op << 8) >> 20; +- int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, ret; +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; +- +- if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) +- return -EFAULT; + + pagefault_disable(); + +@@ -66,30 +57,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) + + pagefault_enable(); + +- if (!ret) { +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: +- ret = (oldval == cmparg); +- break; +- case FUTEX_OP_CMP_NE: +- ret = (oldval != cmparg); +- break; +- case FUTEX_OP_CMP_LT: +- ret = (oldval < cmparg); +- break; +- case FUTEX_OP_CMP_GE: +- ret = (oldval >= cmparg); +- break; +- case FUTEX_OP_CMP_LE: +- ret = (oldval <= cmparg); +- break; +- case FUTEX_OP_CMP_GT: +- ret = (oldval > cmparg); +- break; +- default: +- ret = -ENOSYS; +- } +- } ++ if (!ret) ++ *oval = oldval; ++ + return ret; + } + +diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h +index 1de190bdfb9c..a9e61ea54ca9 100644 +--- a/arch/mips/include/asm/futex.h ++++ b/arch/mips/include/asm/futex.h +@@ -83,18 +83,9 @@ + } + + static inline int +-futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) ++arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) + { +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- int oparg = (encoded_op << 8) >> 20; +- int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, ret; +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; +- +- if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) +- return -EFAULT; + + pagefault_disable(); + +@@ -125,17 +116,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) + + pagefault_enable(); + +- if (!ret) { +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; +- case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; +- case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; +- case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; +- case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; +- case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; +- default: ret = -ENOSYS; +- } +- } ++ if (!ret) ++ *oval = oldval; ++ + return ret; + } + +diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h +index ac8bd586ace8..06a1a883c72f 100644 +--- a/arch/parisc/include/asm/futex.h ++++ b/arch/parisc/include/asm/futex.h +@@ -32,22 +32,12 @@ _futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags) + } + + static inline int +-futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) ++arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) + { + unsigned long int flags; +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- int oparg = (encoded_op << 8) >> 20; +- int cmparg = (encoded_op << 20) >> 20; + int oldval, ret; + u32 tmp; + +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; +- +- if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr))) +- return -EFAULT; +- + _futex_spin_lock_irqsave(uaddr, &flags); + pagefault_disable(); + +@@ -85,17 +75,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) + pagefault_enable(); + _futex_spin_unlock_irqrestore(uaddr, &flags); + +- if (ret == 0) { +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; +- case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; +- case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; +- case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; +- case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; +- case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; +- default: ret = -ENOSYS; +- } +- } ++ if (!ret) ++ *oval = oldval; ++ + return ret; + } + +diff --git a/arch/powerpc/include/asm/futex.h b/arch/powerpc/include/asm/futex.h +index 2a9cf845473b..f4c7467f7465 100644 +--- a/arch/powerpc/include/asm/futex.h ++++ b/arch/powerpc/include/asm/futex.h +@@ -31,18 +31,10 @@ + : "b" (uaddr), "i" (-EFAULT), "r" (oparg) \ + : "cr0", "memory") + +-static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) ++static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, ++ u32 __user *uaddr) + { +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- int oparg = (encoded_op << 8) >> 20; +- int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, ret; +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; +- +- if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) +- return -EFAULT; + + pagefault_disable(); + +@@ -68,17 +60,9 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) + + pagefault_enable(); + +- if (!ret) { +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; +- case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; +- case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; +- case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; +- case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; +- case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; +- default: ret = -ENOSYS; +- } +- } ++ if (!ret) ++ *oval = oldval; ++ + return ret; + } + +diff --git a/arch/s390/include/asm/futex.h b/arch/s390/include/asm/futex.h +index a4811aa0304d..8f8eec9e1198 100644 +--- a/arch/s390/include/asm/futex.h ++++ b/arch/s390/include/asm/futex.h +@@ -21,17 +21,12 @@ + : "0" (-EFAULT), "d" (oparg), "a" (uaddr), \ + "m" (*uaddr) : "cc"); + +-static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) ++static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, ++ u32 __user *uaddr) + { +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- int oparg = (encoded_op << 8) >> 20; +- int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, newval, ret; + + load_kernel_asce(); +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; + + pagefault_disable(); + switch (op) { +@@ -60,17 +55,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) + } + pagefault_enable(); + +- if (!ret) { +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; +- case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; +- case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; +- case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; +- case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; +- case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; +- default: ret = -ENOSYS; +- } +- } ++ if (!ret) ++ *oval = oldval; ++ + return ret; + } + +diff --git a/arch/sh/include/asm/futex.h b/arch/sh/include/asm/futex.h +index d0078747d308..8f8cf941a8cd 100644 +--- a/arch/sh/include/asm/futex.h ++++ b/arch/sh/include/asm/futex.h +@@ -27,21 +27,12 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + return atomic_futex_op_cmpxchg_inatomic(uval, uaddr, oldval, newval); + } + +-static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) ++static inline int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, ++ u32 __user *uaddr) + { +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- u32 oparg = (encoded_op << 8) >> 20; +- u32 cmparg = (encoded_op << 20) >> 20; + u32 oldval, newval, prev; + int ret; + +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; +- +- if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) +- return -EFAULT; +- + pagefault_disable(); + + do { +@@ -80,17 +71,8 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) + + pagefault_enable(); + +- if (!ret) { +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; +- case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; +- case FUTEX_OP_CMP_LT: ret = ((int)oldval < (int)cmparg); break; +- case FUTEX_OP_CMP_GE: ret = ((int)oldval >= (int)cmparg); break; +- case FUTEX_OP_CMP_LE: ret = ((int)oldval <= (int)cmparg); break; +- case FUTEX_OP_CMP_GT: ret = ((int)oldval > (int)cmparg); break; +- default: ret = -ENOSYS; +- } +- } ++ if (!ret) ++ *oval = oldval; + + return ret; + } +diff --git a/arch/sparc/include/asm/futex_64.h b/arch/sparc/include/asm/futex_64.h +index 4e899b0dabf7..1cfd89d92208 100644 +--- a/arch/sparc/include/asm/futex_64.h ++++ b/arch/sparc/include/asm/futex_64.h +@@ -29,22 +29,14 @@ + : "r" (uaddr), "r" (oparg), "i" (-EFAULT) \ + : "memory") + +-static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) ++static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, ++ u32 __user *uaddr) + { +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- int oparg = (encoded_op << 8) >> 20; +- int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, ret, tem; + +- if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))) +- return -EFAULT; + if (unlikely((((unsigned long) uaddr) & 0x3UL))) + return -EINVAL; + +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; +- + pagefault_disable(); + + switch (op) { +@@ -69,17 +61,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) + + pagefault_enable(); + +- if (!ret) { +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; +- case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; +- case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; +- case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; +- case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; +- case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; +- default: ret = -ENOSYS; +- } +- } ++ if (!ret) ++ *oval = oldval; ++ + return ret; + } + +diff --git a/arch/tile/include/asm/futex.h b/arch/tile/include/asm/futex.h +index e64a1b75fc38..83c1e639b411 100644 +--- a/arch/tile/include/asm/futex.h ++++ b/arch/tile/include/asm/futex.h +@@ -106,12 +106,9 @@ + lock = __atomic_hashed_lock((int __force *)uaddr) + #endif + +-static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) ++static inline int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, ++ u32 __user *uaddr) + { +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- int oparg = (encoded_op << 8) >> 20; +- int cmparg = (encoded_op << 20) >> 20; + int uninitialized_var(val), ret; + + __futex_prolog(); +@@ -119,12 +116,6 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) + /* The 32-bit futex code makes this assumption, so validate it here. */ + BUILD_BUG_ON(sizeof(atomic_t) != sizeof(int)); + +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; +- +- if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) +- return -EFAULT; +- + pagefault_disable(); + switch (op) { + case FUTEX_OP_SET: +@@ -148,30 +139,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) + } + pagefault_enable(); + +- if (!ret) { +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: +- ret = (val == cmparg); +- break; +- case FUTEX_OP_CMP_NE: +- ret = (val != cmparg); +- break; +- case FUTEX_OP_CMP_LT: +- ret = (val < cmparg); +- break; +- case FUTEX_OP_CMP_GE: +- ret = (val >= cmparg); +- break; +- case FUTEX_OP_CMP_LE: +- ret = (val <= cmparg); +- break; +- case FUTEX_OP_CMP_GT: +- ret = (val > cmparg); +- break; +- default: +- ret = -ENOSYS; +- } +- } ++ if (!ret) ++ *oval = val; ++ + return ret; + } + +diff --git a/arch/x86/include/asm/futex.h b/arch/x86/include/asm/futex.h +index b4c1f5453436..f4dc9b63bdda 100644 +--- a/arch/x86/include/asm/futex.h ++++ b/arch/x86/include/asm/futex.h +@@ -41,20 +41,11 @@ + "+m" (*uaddr), "=&r" (tem) \ + : "r" (oparg), "i" (-EFAULT), "1" (0)) + +-static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) ++static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, ++ u32 __user *uaddr) + { +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- int oparg = (encoded_op << 8) >> 20; +- int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, ret, tem; + +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; +- +- if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) +- return -EFAULT; +- + pagefault_disable(); + + switch (op) { +@@ -80,30 +71,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) + + pagefault_enable(); + +- if (!ret) { +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: +- ret = (oldval == cmparg); +- break; +- case FUTEX_OP_CMP_NE: +- ret = (oldval != cmparg); +- break; +- case FUTEX_OP_CMP_LT: +- ret = (oldval < cmparg); +- break; +- case FUTEX_OP_CMP_GE: +- ret = (oldval >= cmparg); +- break; +- case FUTEX_OP_CMP_LE: +- ret = (oldval <= cmparg); +- break; +- case FUTEX_OP_CMP_GT: +- ret = (oldval > cmparg); +- break; +- default: +- ret = -ENOSYS; +- } +- } ++ if (!ret) ++ *oval = oldval; ++ + return ret; + } + +diff --git a/arch/xtensa/include/asm/futex.h b/arch/xtensa/include/asm/futex.h +index 72bfc1cbc2b5..5bfbc1c401d4 100644 +--- a/arch/xtensa/include/asm/futex.h ++++ b/arch/xtensa/include/asm/futex.h +@@ -44,18 +44,10 @@ + : "r" (uaddr), "I" (-EFAULT), "r" (oparg) \ + : "memory") + +-static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) ++static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, ++ u32 __user *uaddr) + { +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- int oparg = (encoded_op << 8) >> 20; +- int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, ret; +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; +- +- if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) +- return -EFAULT; + + #if !XCHAL_HAVE_S32C1I + return -ENOSYS; +@@ -89,19 +81,10 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) + + pagefault_enable(); + +- if (ret) +- return ret; ++ if (!ret) ++ *oval = oldval; + +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: return (oldval == cmparg); +- case FUTEX_OP_CMP_NE: return (oldval != cmparg); +- case FUTEX_OP_CMP_LT: return (oldval < cmparg); +- case FUTEX_OP_CMP_GE: return (oldval >= cmparg); +- case FUTEX_OP_CMP_LE: return (oldval <= cmparg); +- case FUTEX_OP_CMP_GT: return (oldval > cmparg); +- } +- +- return -ENOSYS; ++ return ret; + } + + static inline int +diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c +index 551f0f8dead3..91d8a48e53c3 100644 +--- a/drivers/net/bonding/bond_alb.c ++++ b/drivers/net/bonding/bond_alb.c +@@ -450,7 +450,7 @@ static void rlb_update_client(struct rlb_client_info *client_info) + { + int i; + +- if (!client_info->slave) ++ if (!client_info->slave || !is_valid_ether_addr(client_info->mac_dst)) + return; + + for (i = 0; i < RLB_ARP_BURST_SIZE; i++) { +@@ -944,6 +944,10 @@ static void alb_send_lp_vid(struct slave *slave, u8 mac_addr[], + skb->priority = TC_PRIO_CONTROL; + skb->dev = slave->dev; + ++ netdev_dbg(slave->bond->dev, ++ "Send learning packet: dev %s mac %pM vlan %d\n", ++ slave->dev->name, mac_addr, vid); ++ + if (vid) + __vlan_hwaccel_put_tag(skb, vlan_proto, vid); + +@@ -966,14 +970,13 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[], + */ + rcu_read_lock(); + netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) { +- if (is_vlan_dev(upper) && vlan_get_encap_level(upper) == 0) { +- if (strict_match && +- ether_addr_equal_64bits(mac_addr, +- upper->dev_addr)) { ++ if (is_vlan_dev(upper) && ++ bond->nest_level == vlan_get_encap_level(upper) - 1) { ++ if (upper->addr_assign_type == NET_ADDR_STOLEN) { + alb_send_lp_vid(slave, mac_addr, + vlan_dev_vlan_proto(upper), + vlan_dev_vlan_id(upper)); +- } else if (!strict_match) { ++ } else { + alb_send_lp_vid(slave, upper->dev_addr, + vlan_dev_vlan_proto(upper), + vlan_dev_vlan_id(upper)); +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 13a015b8052b..1a139d0f2232 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1732,6 +1732,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) + if (bond_mode_uses_xmit_hash(bond)) + bond_update_slave_arr(bond, NULL); + ++ bond->nest_level = dev_get_nest_level(bond_dev); ++ + netdev_info(bond_dev, "Enslaving %s as %s interface with %s link\n", + slave_dev->name, + bond_is_active_slave(new_slave) ? "an active" : "a backup", +diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c +index 795a133fb074..4ffbe850d746 100644 +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -8720,14 +8720,15 @@ static void tg3_free_consistent(struct tg3 *tp) + tg3_mem_rx_release(tp); + tg3_mem_tx_release(tp); + +- /* Protect tg3_get_stats64() from reading freed tp->hw_stats. */ +- tg3_full_lock(tp, 0); ++ /* tp->hw_stats can be referenced safely: ++ * 1. under rtnl_lock ++ * 2. or under tp->lock if TG3_FLAG_INIT_COMPLETE is set. ++ */ + if (tp->hw_stats) { + dma_free_coherent(&tp->pdev->dev, sizeof(struct tg3_hw_stats), + tp->hw_stats, tp->stats_mapping); + tp->hw_stats = NULL; + } +- tg3_full_unlock(tp); + } + + /* +@@ -14161,7 +14162,7 @@ static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev, + struct tg3 *tp = netdev_priv(dev); + + spin_lock_bh(&tp->lock); +- if (!tp->hw_stats) { ++ if (!tp->hw_stats || !tg3_flag(tp, INIT_COMPLETE)) { + *stats = tp->net_stats_prev; + spin_unlock_bh(&tp->lock); + return stats; +diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +index 24977cc881d2..9a4c4f8281bd 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +@@ -970,6 +970,22 @@ static int mlx4_en_set_coalesce(struct net_device *dev, + if (!coal->tx_max_coalesced_frames_irq) + return -EINVAL; + ++ if (coal->tx_coalesce_usecs > MLX4_EN_MAX_COAL_TIME || ++ coal->rx_coalesce_usecs > MLX4_EN_MAX_COAL_TIME || ++ coal->rx_coalesce_usecs_low > MLX4_EN_MAX_COAL_TIME || ++ coal->rx_coalesce_usecs_high > MLX4_EN_MAX_COAL_TIME) { ++ netdev_info(dev, "%s: maximum coalesce time supported is %d usecs\n", ++ __func__, MLX4_EN_MAX_COAL_TIME); ++ return -ERANGE; ++ } ++ ++ if (coal->tx_max_coalesced_frames > MLX4_EN_MAX_COAL_PKTS || ++ coal->rx_max_coalesced_frames > MLX4_EN_MAX_COAL_PKTS) { ++ netdev_info(dev, "%s: maximum coalesced frames supported is %d\n", ++ __func__, MLX4_EN_MAX_COAL_PKTS); ++ return -ERANGE; ++ } ++ + priv->rx_frames = (coal->rx_max_coalesced_frames == + MLX4_EN_AUTO_CONF) ? + MLX4_EN_RX_COAL_TARGET : +diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +index 18f221d8a04d..247d340be743 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h ++++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +@@ -141,6 +141,9 @@ enum { + #define MLX4_EN_TX_COAL_PKTS 16 + #define MLX4_EN_TX_COAL_TIME 0x10 + ++#define MLX4_EN_MAX_COAL_PKTS U16_MAX ++#define MLX4_EN_MAX_COAL_TIME U16_MAX ++ + #define MLX4_EN_RX_RATE_LOW 400000 + #define MLX4_EN_RX_COAL_TIME_LOW 0 + #define MLX4_EN_RX_RATE_HIGH 450000 +@@ -543,8 +546,8 @@ struct mlx4_en_priv { + u16 rx_usecs_low; + u32 pkt_rate_high; + u16 rx_usecs_high; +- u16 sample_interval; +- u16 adaptive_rx_coal; ++ u32 sample_interval; ++ u32 adaptive_rx_coal; + u32 msg_enable; + u32 loopback_ok; + u32 validate_loopback; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +index a8966e6dbe1b..5d6eab19a9d8 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +@@ -1924,26 +1924,35 @@ int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw, + memset(vf_stats, 0, sizeof(*vf_stats)); + vf_stats->rx_packets = + MLX5_GET_CTR(out, received_eth_unicast.packets) + ++ MLX5_GET_CTR(out, received_ib_unicast.packets) + + MLX5_GET_CTR(out, received_eth_multicast.packets) + ++ MLX5_GET_CTR(out, received_ib_multicast.packets) + + MLX5_GET_CTR(out, received_eth_broadcast.packets); + + vf_stats->rx_bytes = + MLX5_GET_CTR(out, received_eth_unicast.octets) + ++ MLX5_GET_CTR(out, received_ib_unicast.octets) + + MLX5_GET_CTR(out, received_eth_multicast.octets) + ++ MLX5_GET_CTR(out, received_ib_multicast.octets) + + MLX5_GET_CTR(out, received_eth_broadcast.octets); + + vf_stats->tx_packets = + MLX5_GET_CTR(out, transmitted_eth_unicast.packets) + ++ MLX5_GET_CTR(out, transmitted_ib_unicast.packets) + + MLX5_GET_CTR(out, transmitted_eth_multicast.packets) + ++ MLX5_GET_CTR(out, transmitted_ib_multicast.packets) + + MLX5_GET_CTR(out, transmitted_eth_broadcast.packets); + + vf_stats->tx_bytes = + MLX5_GET_CTR(out, transmitted_eth_unicast.octets) + ++ MLX5_GET_CTR(out, transmitted_ib_unicast.octets) + + MLX5_GET_CTR(out, transmitted_eth_multicast.octets) + ++ MLX5_GET_CTR(out, transmitted_ib_multicast.octets) + + MLX5_GET_CTR(out, transmitted_eth_broadcast.octets); + + vf_stats->multicast = +- MLX5_GET_CTR(out, received_eth_multicast.packets); ++ MLX5_GET_CTR(out, received_eth_multicast.packets) + ++ MLX5_GET_CTR(out, received_ib_multicast.packets); + + vf_stats->broadcast = + MLX5_GET_CTR(out, received_eth_broadcast.packets); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +index 331a6ca4856d..5f3402ba9916 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +@@ -153,6 +153,7 @@ static void del_rule(struct fs_node *node); + static void del_flow_table(struct fs_node *node); + static void del_flow_group(struct fs_node *node); + static void del_fte(struct fs_node *node); ++static void cleanup_root_ns(struct mlx5_flow_root_namespace *root_ns); + + static void tree_init_node(struct fs_node *node, + unsigned int refcount, +@@ -1690,24 +1691,28 @@ static int create_anchor_flow_table(struct mlx5_flow_steering *steering) + + static int init_root_ns(struct mlx5_flow_steering *steering) + { ++ int err; + + steering->root_ns = create_root_ns(steering, FS_FT_NIC_RX); + if (!steering->root_ns) +- goto cleanup; ++ return -ENOMEM; + +- if (init_root_tree(steering, &root_fs, &steering->root_ns->ns.node)) +- goto cleanup; ++ err = init_root_tree(steering, &root_fs, &steering->root_ns->ns.node); ++ if (err) ++ goto out_err; + + set_prio_attrs(steering->root_ns); + +- if (create_anchor_flow_table(steering)) +- goto cleanup; ++ err = create_anchor_flow_table(steering); ++ if (err) ++ goto out_err; + + return 0; + +-cleanup: +- mlx5_cleanup_fs(steering->dev); +- return -ENOMEM; ++out_err: ++ cleanup_root_ns(steering->root_ns); ++ steering->root_ns = NULL; ++ return err; + } + + static void clean_tree(struct fs_node *node) +diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +index 4ca82bd8c4f0..eee6e59e6cf3 100644 +--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c ++++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +@@ -854,6 +854,8 @@ static int nfp_net_tx(struct sk_buff *skb, struct net_device *netdev) + + netdev_tx_sent_queue(nd_q, txbuf->real_len); + ++ skb_tx_timestamp(skb); ++ + tx_ring->wr_p += nr_frags + 1; + if (nfp_net_tx_ring_should_stop(tx_ring)) + nfp_net_tx_ring_stop(nd_q, tx_ring); +@@ -866,8 +868,6 @@ static int nfp_net_tx(struct sk_buff *skb, struct net_device *netdev) + tx_ring->wr_ptr_add = 0; + } + +- skb_tx_timestamp(skb); +- + return NETDEV_TX_OK; + + err_unmap: +diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c +index da4c2d8a4173..1420dfb56bac 100644 +--- a/drivers/net/ethernet/realtek/8139too.c ++++ b/drivers/net/ethernet/realtek/8139too.c +@@ -2233,7 +2233,7 @@ static void rtl8139_poll_controller(struct net_device *dev) + struct rtl8139_private *tp = netdev_priv(dev); + const int irq = tp->pci_dev->irq; + +- disable_irq(irq); ++ disable_irq_nosync(irq); + rtl8139_interrupt(irq, dev); + enable_irq(irq); + } +diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c +index dbb63640bc6e..59b932db0d42 100644 +--- a/drivers/net/ethernet/realtek/r8169.c ++++ b/drivers/net/ethernet/realtek/r8169.c +@@ -4861,6 +4861,9 @@ static void rtl_pll_power_down(struct rtl8169_private *tp) + static void rtl_pll_power_up(struct rtl8169_private *tp) + { + rtl_generic_op(tp, tp->pll_power_ops.up); ++ ++ /* give MAC/PHY some time to resume */ ++ msleep(20); + } + + static void rtl_init_pll_power_ops(struct rtl8169_private *tp) +diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c +index a2371aa14a49..e45e2f14fb94 100644 +--- a/drivers/net/ethernet/sun/niu.c ++++ b/drivers/net/ethernet/sun/niu.c +@@ -3442,7 +3442,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, + + len = (val & RCR_ENTRY_L2_LEN) >> + RCR_ENTRY_L2_LEN_SHIFT; +- len -= ETH_FCS_LEN; ++ append_size = len + ETH_HLEN + ETH_FCS_LEN; + + addr = (val & RCR_ENTRY_PKT_BUF_ADDR) << + RCR_ENTRY_PKT_BUF_ADDR_SHIFT; +@@ -3452,7 +3452,6 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, + RCR_ENTRY_PKTBUFSZ_SHIFT]; + + off = addr & ~PAGE_MASK; +- append_size = rcr_size; + if (num_rcr == 1) { + int ptype; + +@@ -3465,7 +3464,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, + else + skb_checksum_none_assert(skb); + } else if (!(val & RCR_ENTRY_MULTI)) +- append_size = len - skb->len; ++ append_size = append_size - skb->len; + + niu_rx_skb_append(skb, page, off, append_size, rcr_size); + if ((page->index + rp->rbr_block_size) - rcr_size == addr) { +diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c +index de336897a28a..d7cb205fe7e2 100644 +--- a/drivers/net/ethernet/ti/cpsw.c ++++ b/drivers/net/ethernet/ti/cpsw.c +@@ -1141,6 +1141,8 @@ static inline void cpsw_add_dual_emac_def_ale_entries( + cpsw_ale_add_ucast(cpsw->ale, priv->mac_addr, + HOST_PORT_NUM, ALE_VLAN | + ALE_SECURE, slave->port_vlan); ++ cpsw_ale_control_set(cpsw->ale, slave_port, ++ ALE_PORT_DROP_UNKNOWN_VLAN, 1); + } + + static void soft_reset_slave(struct cpsw_slave *slave) +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index 1029bd234c22..3e893fe890a0 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -1039,6 +1039,18 @@ static int qmi_wwan_probe(struct usb_interface *intf, + id->driver_info = (unsigned long)&qmi_wwan_info; + } + ++ /* There are devices where the same interface number can be ++ * configured as different functions. We should only bind to ++ * vendor specific functions when matching on interface number ++ */ ++ if (id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER && ++ desc->bInterfaceClass != USB_CLASS_VENDOR_SPEC) { ++ dev_dbg(&intf->dev, ++ "Rejecting interface number match for class %02x\n", ++ desc->bInterfaceClass); ++ return -ENODEV; ++ } ++ + /* Quectel EC20 quirk where we've QMI on interface 4 instead of 0 */ + if (quectel_ec20_detected(intf) && desc->bInterfaceNumber == 0) { + dev_dbg(&intf->dev, "Quectel EC20 quirk, skipping interface 0\n"); +diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c +index cdd2f942317c..b9c7a904c1ea 100644 +--- a/drivers/tty/serial/sccnxp.c ++++ b/drivers/tty/serial/sccnxp.c +@@ -889,7 +889,16 @@ static int sccnxp_probe(struct platform_device *pdev) + goto err_out; + uartclk = 0; + } else { +- clk_prepare_enable(clk); ++ ret = clk_prepare_enable(clk); ++ if (ret) ++ goto err_out; ++ ++ ret = devm_add_action_or_reset(&pdev->dev, ++ (void(*)(void *))clk_disable_unprepare, ++ clk); ++ if (ret) ++ goto err_out; ++ + uartclk = clk_get_rate(clk); + } + +@@ -988,7 +997,7 @@ static int sccnxp_probe(struct platform_device *pdev) + uart_unregister_driver(&s->uart); + err_out: + if (!IS_ERR(s->regulator)) +- return regulator_disable(s->regulator); ++ regulator_disable(s->regulator); + + return ret; + } +diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c +index 85135df0eb34..c19123dcd1a4 100644 +--- a/fs/lockd/svc.c ++++ b/fs/lockd/svc.c +@@ -274,6 +274,8 @@ static void lockd_down_net(struct svc_serv *serv, struct net *net) + if (ln->nlmsvc_users) { + if (--ln->nlmsvc_users == 0) { + nlm_shutdown_hosts_net(net); ++ cancel_delayed_work_sync(&ln->grace_period_end); ++ locks_end_grace(&ln->lockd_manager); + svc_shutdown_net(serv, net); + dprintk("lockd_down_net: per-net data destroyed; net=%p\n", net); + } +diff --git a/fs/proc/base.c b/fs/proc/base.c +index e67fec3c9856..3fec83ba75fa 100644 +--- a/fs/proc/base.c ++++ b/fs/proc/base.c +@@ -252,7 +252,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf, + * Inherently racy -- command line shares address space + * with code and data. + */ +- rv = access_remote_vm(mm, arg_end - 1, &c, 1, 0); ++ rv = access_remote_vm(mm, arg_end - 1, &c, 1, FOLL_ANON); + if (rv <= 0) + goto out_free_page; + +@@ -270,7 +270,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf, + int nr_read; + + _count = min3(count, len, PAGE_SIZE); +- nr_read = access_remote_vm(mm, p, page, _count, 0); ++ nr_read = access_remote_vm(mm, p, page, _count, FOLL_ANON); + if (nr_read < 0) + rv = nr_read; + if (nr_read <= 0) +@@ -305,7 +305,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf, + bool final; + + _count = min3(count, len, PAGE_SIZE); +- nr_read = access_remote_vm(mm, p, page, _count, 0); ++ nr_read = access_remote_vm(mm, p, page, _count, FOLL_ANON); + if (nr_read < 0) + rv = nr_read; + if (nr_read <= 0) +@@ -354,7 +354,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf, + bool final; + + _count = min3(count, len, PAGE_SIZE); +- nr_read = access_remote_vm(mm, p, page, _count, 0); ++ nr_read = access_remote_vm(mm, p, page, _count, FOLL_ANON); + if (nr_read < 0) + rv = nr_read; + if (nr_read <= 0) +@@ -970,7 +970,7 @@ static ssize_t environ_read(struct file *file, char __user *buf, + max_len = min_t(size_t, PAGE_SIZE, count); + this_len = min(max_len, this_len); + +- retval = access_remote_vm(mm, (env_start + src), page, this_len, 0); ++ retval = access_remote_vm(mm, (env_start + src), page, this_len, FOLL_ANON); + + if (retval <= 0) { + ret = retval; +diff --git a/include/asm-generic/futex.h b/include/asm-generic/futex.h +index bf2d34c9d804..f0d8b1c51343 100644 +--- a/include/asm-generic/futex.h ++++ b/include/asm-generic/futex.h +@@ -13,7 +13,7 @@ + */ + + /** +- * futex_atomic_op_inuser() - Atomic arithmetic operation with constant ++ * arch_futex_atomic_op_inuser() - Atomic arithmetic operation with constant + * argument and comparison of the previous + * futex value with another constant. + * +@@ -25,18 +25,11 @@ + * <0 - On error + */ + static inline int +-futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) ++arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, u32 __user *uaddr) + { +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- int oparg = (encoded_op << 8) >> 20; +- int cmparg = (encoded_op << 20) >> 20; + int oldval, ret; + u32 tmp; + +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; +- + preempt_disable(); + pagefault_disable(); + +@@ -74,17 +67,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) + pagefault_enable(); + preempt_enable(); + +- if (ret == 0) { +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; +- case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; +- case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; +- case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; +- case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; +- case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; +- default: ret = -ENOSYS; +- } +- } ++ if (ret == 0) ++ *oval = oldval; ++ + return ret; + } + +@@ -126,18 +111,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + + #else + static inline int +-futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) ++arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, u32 __user *uaddr) + { +- int op = (encoded_op >> 28) & 7; +- int cmp = (encoded_op >> 24) & 15; +- int oparg = (encoded_op << 8) >> 20; +- int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, ret; +- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; +- +- if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) +- return -EFAULT; + + pagefault_disable(); + +@@ -153,17 +129,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) + + pagefault_enable(); + +- if (!ret) { +- switch (cmp) { +- case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; +- case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; +- case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; +- case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; +- case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; +- case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; +- default: ret = -ENOSYS; +- } +- } ++ if (!ret) ++ *oval = oldval; ++ + return ret; + } + +diff --git a/include/linux/mm.h b/include/linux/mm.h +index 4a07ff4f38e1..493d07931ea5 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -2246,6 +2246,7 @@ static inline struct page *follow_page(struct vm_area_struct *vma, + #define FOLL_MLOCK 0x1000 /* lock present pages */ + #define FOLL_REMOTE 0x2000 /* we are working on non-current tsk/mm */ + #define FOLL_COW 0x4000 /* internal GUP flag */ ++#define FOLL_ANON 0x8000 /* don't do file mappings */ + + typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr, + void *data); +diff --git a/include/net/bonding.h b/include/net/bonding.h +index f32f7ef8a23a..7734cc9c7d29 100644 +--- a/include/net/bonding.h ++++ b/include/net/bonding.h +@@ -197,6 +197,7 @@ struct bonding { + struct slave __rcu *primary_slave; + struct bond_up_slave __rcu *slave_arr; /* Array of usable slaves */ + bool force_primary; ++ u32 nest_level; + s32 slave_cnt; /* never change this value outside the attach/detach wrappers */ + int (*recv_probe)(const struct sk_buff *, struct bonding *, + struct slave *); +diff --git a/kernel/exit.c b/kernel/exit.c +index 3076f3089919..6dd7ff4b337a 100644 +--- a/kernel/exit.c ++++ b/kernel/exit.c +@@ -1662,6 +1662,10 @@ SYSCALL_DEFINE4(wait4, pid_t, upid, int __user *, stat_addr, + __WNOTHREAD|__WCLONE|__WALL)) + return -EINVAL; + ++ /* -INT_MIN is not defined */ ++ if (upid == INT_MIN) ++ return -ESRCH; ++ + if (upid == -1) + type = PIDTYPE_MAX; + else if (upid < 0) { +diff --git a/kernel/futex.c b/kernel/futex.c +index bb2265ae5cbc..c3ea6f2a6997 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -1458,6 +1458,45 @@ futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset) + return ret; + } + ++static int futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *uaddr) ++{ ++ unsigned int op = (encoded_op & 0x70000000) >> 28; ++ unsigned int cmp = (encoded_op & 0x0f000000) >> 24; ++ int oparg = sign_extend32((encoded_op & 0x00fff000) >> 12, 11); ++ int cmparg = sign_extend32(encoded_op & 0x00000fff, 11); ++ int oldval, ret; ++ ++ if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) { ++ if (oparg < 0 || oparg > 31) ++ return -EINVAL; ++ oparg = 1 << oparg; ++ } ++ ++ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) ++ return -EFAULT; ++ ++ ret = arch_futex_atomic_op_inuser(op, oparg, &oldval, uaddr); ++ if (ret) ++ return ret; ++ ++ switch (cmp) { ++ case FUTEX_OP_CMP_EQ: ++ return oldval == cmparg; ++ case FUTEX_OP_CMP_NE: ++ return oldval != cmparg; ++ case FUTEX_OP_CMP_LT: ++ return oldval < cmparg; ++ case FUTEX_OP_CMP_GE: ++ return oldval >= cmparg; ++ case FUTEX_OP_CMP_LE: ++ return oldval <= cmparg; ++ case FUTEX_OP_CMP_GT: ++ return oldval > cmparg; ++ default: ++ return -ENOSYS; ++ } ++} ++ + /* + * Wake up all waiters hashed on the physical page that is mapped + * to this virtual address: +diff --git a/mm/gup.c b/mm/gup.c +index 6c3b4e822946..be4ccddac26f 100644 +--- a/mm/gup.c ++++ b/mm/gup.c +@@ -430,6 +430,9 @@ static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags) + if (vm_flags & (VM_IO | VM_PFNMAP)) + return -EFAULT; + ++ if (gup_flags & FOLL_ANON && !vma_is_anonymous(vma)) ++ return -EFAULT; ++ + if (write) { + if (!(vm_flags & VM_WRITE)) { + if (!(gup_flags & FOLL_FORCE)) +diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c +index ed0dd3340084..8e173324693d 100644 +--- a/net/bridge/br_if.c ++++ b/net/bridge/br_if.c +@@ -504,8 +504,8 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) + if (dev->netdev_ops->ndo_start_xmit == br_dev_xmit) + return -ELOOP; + +- /* Device is already being bridged */ +- if (br_port_exists(dev)) ++ /* Device has master upper dev */ ++ if (netdev_master_upper_dev_get(dev)) + return -EBUSY; + + /* No bridging devices that dislike that (e.g. wireless) */ +diff --git a/net/compat.c b/net/compat.c +index a96fd2f3507b..73671e6ec6eb 100644 +--- a/net/compat.c ++++ b/net/compat.c +@@ -372,7 +372,8 @@ static int compat_sock_setsockopt(struct socket *sock, int level, int optname, + optname == SO_ATTACH_REUSEPORT_CBPF) + return do_set_attach_filter(sock, level, optname, + optval, optlen); +- if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) ++ if (!COMPAT_USE_64BIT_TIME && ++ (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)) + return do_set_sock_timeout(sock, level, optname, optval, optlen); + + return sock_setsockopt(sock, level, optname, optval, optlen); +@@ -437,7 +438,8 @@ static int do_get_sock_timeout(struct socket *sock, int level, int optname, + static int compat_sock_getsockopt(struct socket *sock, int level, int optname, + char __user *optval, int __user *optlen) + { +- if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) ++ if (!COMPAT_USE_64BIT_TIME && ++ (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)) + return do_get_sock_timeout(sock, level, optname, optval, optlen); + return sock_getsockopt(sock, level, optname, optval, optlen); + } +diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c +index 7753681195c1..86a2ed0fb219 100644 +--- a/net/dccp/ccids/ccid2.c ++++ b/net/dccp/ccids/ccid2.c +@@ -126,6 +126,16 @@ static void ccid2_change_l_seq_window(struct sock *sk, u64 val) + DCCPF_SEQ_WMAX)); + } + ++static void dccp_tasklet_schedule(struct sock *sk) ++{ ++ struct tasklet_struct *t = &dccp_sk(sk)->dccps_xmitlet; ++ ++ if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) { ++ sock_hold(sk); ++ __tasklet_schedule(t); ++ } ++} ++ + static void ccid2_hc_tx_rto_expire(unsigned long data) + { + struct sock *sk = (struct sock *)data; +@@ -166,7 +176,7 @@ static void ccid2_hc_tx_rto_expire(unsigned long data) + + /* if we were blocked before, we may now send cwnd=1 packet */ + if (sender_was_blocked) +- tasklet_schedule(&dccp_sk(sk)->dccps_xmitlet); ++ dccp_tasklet_schedule(sk); + /* restart backed-off timer */ + sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); + out: +@@ -706,7 +716,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) + done: + /* check if incoming Acks allow pending packets to be sent */ + if (sender_was_blocked && !ccid2_cwnd_network_limited(hc)) +- tasklet_schedule(&dccp_sk(sk)->dccps_xmitlet); ++ dccp_tasklet_schedule(sk); + dccp_ackvec_parsed_cleanup(&hc->tx_av_chunks); + } + +diff --git a/net/dccp/timer.c b/net/dccp/timer.c +index 3a2c34027758..2a952cbd6efa 100644 +--- a/net/dccp/timer.c ++++ b/net/dccp/timer.c +@@ -230,12 +230,12 @@ static void dccp_write_xmitlet(unsigned long data) + else + dccp_write_xmit(sk); + bh_unlock_sock(sk); ++ sock_put(sk); + } + + static void dccp_write_xmit_timer(unsigned long data) + { + dccp_write_xmitlet(data); +- sock_put((struct sock *)data); + } + + void dccp_init_xmit_timers(struct sock *sk) +diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c +index e612991c9185..9adcd4b1b3fd 100644 +--- a/net/ipv4/ping.c ++++ b/net/ipv4/ping.c +@@ -775,8 +775,10 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + ipc.addr = faddr = daddr; + + if (ipc.opt && ipc.opt->opt.srr) { +- if (!daddr) +- return -EINVAL; ++ if (!daddr) { ++ err = -EINVAL; ++ goto out_free; ++ } + faddr = ipc.opt->opt.faddr; + } + tos = get_rttos(&ipc, inet); +@@ -841,6 +843,7 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + + out: + ip_rt_put(rt); ++out_free: + if (free) + kfree(ipc.opt); + if (!err) { +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 6f501c9deaae..84ffebf0192d 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -1118,7 +1118,7 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) + lock_sock(sk); + + flags = msg->msg_flags; +- if (flags & MSG_FASTOPEN) { ++ if ((flags & MSG_FASTOPEN) && !tp->repair) { + err = tcp_sendmsg_fastopen(sk, msg, &copied_syn, size); + if (err == -EINPROGRESS && copied_syn > 0) + goto out; +diff --git a/net/ipv4/tcp_bbr.c b/net/ipv4/tcp_bbr.c +index 8ec60532be2b..9169859506b7 100644 +--- a/net/ipv4/tcp_bbr.c ++++ b/net/ipv4/tcp_bbr.c +@@ -773,7 +773,9 @@ static void bbr_update_min_rtt(struct sock *sk, const struct rate_sample *rs) + } + } + } +- bbr->idle_restart = 0; ++ /* Restart after idle ends only once we process a new S/ACK for data */ ++ if (rs->delivered > 0) ++ bbr->idle_restart = 0; + } + + static void bbr_update_model(struct sock *sk, const struct rate_sample *rs) +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 4cd943096afa..aa2a20e918fd 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -982,8 +982,10 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + sock_tx_timestamp(sk, ipc.sockc.tsflags, &ipc.tx_flags); + + if (ipc.opt && ipc.opt->opt.srr) { +- if (!daddr) +- return -EINVAL; ++ if (!daddr) { ++ err = -EINVAL; ++ goto out_free; ++ } + faddr = ipc.opt->opt.faddr; + connected = 0; + } +@@ -1090,6 +1092,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + + out: + ip_rt_put(rt); ++out_free: + if (free) + kfree(ipc.opt); + if (!err) +diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c +index ce1238492c0f..ee03bc866d1b 100644 +--- a/net/l2tp/l2tp_netlink.c ++++ b/net/l2tp/l2tp_netlink.c +@@ -750,8 +750,6 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int fl + + if ((session->ifname[0] && + nla_put_string(skb, L2TP_ATTR_IFNAME, session->ifname)) || +- (session->offset && +- nla_put_u16(skb, L2TP_ATTR_OFFSET, session->offset)) || + (session->cookie_len && + nla_put(skb, L2TP_ATTR_COOKIE, session->cookie_len, + &session->cookie[0])) || +diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c +index d6bc5f2a1175..85aae8c84aeb 100644 +--- a/net/llc/af_llc.c ++++ b/net/llc/af_llc.c +@@ -926,6 +926,9 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + if (size > llc->dev->mtu) + size = llc->dev->mtu; + copied = size - hdrlen; ++ rc = -EINVAL; ++ if (copied < 0) ++ goto release; + release_sock(sk); + skb = sock_alloc_send_skb(sk, size, noblock, &rc); + lock_sock(sk); +diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c +index 1668916bdbde..326945d9be5f 100644 +--- a/net/openvswitch/flow_netlink.c ++++ b/net/openvswitch/flow_netlink.c +@@ -1296,13 +1296,10 @@ static void nlattr_set(struct nlattr *attr, u8 val, + + /* The nlattr stream should already have been validated */ + nla_for_each_nested(nla, attr, rem) { +- if (tbl[nla_type(nla)].len == OVS_ATTR_NESTED) { +- if (tbl[nla_type(nla)].next) +- tbl = tbl[nla_type(nla)].next; +- nlattr_set(nla, val, tbl); +- } else { ++ if (tbl[nla_type(nla)].len == OVS_ATTR_NESTED) ++ nlattr_set(nla, val, tbl[nla_type(nla)].next ? : tbl); ++ else + memset(nla_data(nla), val, nla_len(nla)); +- } + + if (nla_type(nla) == OVS_KEY_ATTR_CT_STATE) + *(u32 *)nla_data(nla) &= CT_SUPPORTED_MASK; +diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c +index 18e752439f6f..b57b4de73038 100644 +--- a/net/sched/sch_fq.c ++++ b/net/sched/sch_fq.c +@@ -128,6 +128,28 @@ static bool fq_flow_is_detached(const struct fq_flow *f) + return f->next == &detached; + } + ++static bool fq_flow_is_throttled(const struct fq_flow *f) ++{ ++ return f->next == &throttled; ++} ++ ++static void fq_flow_add_tail(struct fq_flow_head *head, struct fq_flow *flow) ++{ ++ if (head->first) ++ head->last->next = flow; ++ else ++ head->first = flow; ++ head->last = flow; ++ flow->next = NULL; ++} ++ ++static void fq_flow_unset_throttled(struct fq_sched_data *q, struct fq_flow *f) ++{ ++ rb_erase(&f->rate_node, &q->delayed); ++ q->throttled_flows--; ++ fq_flow_add_tail(&q->old_flows, f); ++} ++ + static void fq_flow_set_throttled(struct fq_sched_data *q, struct fq_flow *f) + { + struct rb_node **p = &q->delayed.rb_node, *parent = NULL; +@@ -155,15 +177,6 @@ static void fq_flow_set_throttled(struct fq_sched_data *q, struct fq_flow *f) + + static struct kmem_cache *fq_flow_cachep __read_mostly; + +-static void fq_flow_add_tail(struct fq_flow_head *head, struct fq_flow *flow) +-{ +- if (head->first) +- head->last->next = flow; +- else +- head->first = flow; +- head->last = flow; +- flow->next = NULL; +-} + + /* limit number of collected flows per round */ + #define FQ_GC_MAX 8 +@@ -267,6 +280,8 @@ static struct fq_flow *fq_classify(struct sk_buff *skb, struct fq_sched_data *q) + f->socket_hash != sk->sk_hash)) { + f->credit = q->initial_quantum; + f->socket_hash = sk->sk_hash; ++ if (fq_flow_is_throttled(f)) ++ fq_flow_unset_throttled(q, f); + f->time_next_packet = 0ULL; + } + return f; +@@ -430,9 +445,7 @@ static void fq_check_throttled(struct fq_sched_data *q, u64 now) + q->time_next_delayed_flow = f->time_next_packet; + break; + } +- rb_erase(p, &q->delayed); +- q->throttled_flows--; +- fq_flow_add_tail(&q->old_flows, f); ++ fq_flow_unset_throttled(q, f); + } + } + +diff --git a/net/sctp/associola.c b/net/sctp/associola.c +index f10d3397f917..738c55e994c4 100644 +--- a/net/sctp/associola.c ++++ b/net/sctp/associola.c +@@ -1006,9 +1006,10 @@ static void sctp_assoc_bh_rcv(struct work_struct *work) + struct sctp_endpoint *ep; + struct sctp_chunk *chunk; + struct sctp_inq *inqueue; +- int state; + sctp_subtype_t subtype; ++ int first_time = 1; /* is this the first time through the loop */ + int error = 0; ++ int state; + + /* The association should be held so we should be safe. */ + ep = asoc->ep; +@@ -1019,6 +1020,30 @@ static void sctp_assoc_bh_rcv(struct work_struct *work) + state = asoc->state; + subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type); + ++ /* If the first chunk in the packet is AUTH, do special ++ * processing specified in Section 6.3 of SCTP-AUTH spec ++ */ ++ if (first_time && subtype.chunk == SCTP_CID_AUTH) { ++ struct sctp_chunkhdr *next_hdr; ++ ++ next_hdr = sctp_inq_peek(inqueue); ++ if (!next_hdr) ++ goto normal; ++ ++ /* If the next chunk is COOKIE-ECHO, skip the AUTH ++ * chunk while saving a pointer to it so we can do ++ * Authentication later (during cookie-echo ++ * processing). ++ */ ++ if (next_hdr->type == SCTP_CID_COOKIE_ECHO) { ++ chunk->auth_chunk = skb_clone(chunk->skb, ++ GFP_ATOMIC); ++ chunk->auth = 1; ++ continue; ++ } ++ } ++ ++normal: + /* SCTP-AUTH, Section 6.3: + * The receiver has a list of chunk types which it expects + * to be received only after an AUTH-chunk. This list has +@@ -1057,6 +1082,9 @@ static void sctp_assoc_bh_rcv(struct work_struct *work) + /* If there is an error on chunk, discard this packet. */ + if (error && chunk) + chunk->pdiscard = 1; ++ ++ if (first_time) ++ first_time = 0; + } + sctp_association_put(asoc); + } +diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c +index f731de3e8428..e06083c53f57 100644 +--- a/net/sctp/inqueue.c ++++ b/net/sctp/inqueue.c +@@ -217,7 +217,7 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue) + skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t)); + chunk->subh.v = NULL; /* Subheader is no longer valid. */ + +- if (chunk->chunk_end + sizeof(sctp_chunkhdr_t) < ++ if (chunk->chunk_end + sizeof(sctp_chunkhdr_t) <= + skb_tail_pointer(chunk->skb)) { + /* This is not a singleton */ + chunk->singleton = 0; +diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c +index e031797ad311..f4d5efb1d231 100644 +--- a/net/sctp/ipv6.c ++++ b/net/sctp/ipv6.c +@@ -864,6 +864,9 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1, + if (sctp_is_any(sk, addr1) || sctp_is_any(sk, addr2)) + return 1; + ++ if (addr1->sa.sa_family == AF_INET && addr2->sa.sa_family == AF_INET) ++ return addr1->v4.sin_addr.s_addr == addr2->v4.sin_addr.s_addr; ++ + return __sctp_v6_cmp_addr(addr1, addr2); + } + +diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c +index 8ec20a64a3f8..bfd068679710 100644 +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -144,10 +144,8 @@ static sctp_disposition_t sctp_sf_violation_chunk( + void *arg, + sctp_cmd_seq_t *commands); + +-static sctp_ierror_t sctp_sf_authenticate(struct net *net, +- const struct sctp_endpoint *ep, ++static sctp_ierror_t sctp_sf_authenticate( + const struct sctp_association *asoc, +- const sctp_subtype_t type, + struct sctp_chunk *chunk); + + static sctp_disposition_t __sctp_sf_do_9_1_abort(struct net *net, +@@ -615,6 +613,38 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(struct net *net, + return SCTP_DISPOSITION_CONSUME; + } + ++static bool sctp_auth_chunk_verify(struct net *net, struct sctp_chunk *chunk, ++ const struct sctp_association *asoc) ++{ ++ struct sctp_chunk auth; ++ ++ if (!chunk->auth_chunk) ++ return true; ++ ++ /* SCTP-AUTH: auth_chunk pointer is only set when the cookie-echo ++ * is supposed to be authenticated and we have to do delayed ++ * authentication. We've just recreated the association using ++ * the information in the cookie and now it's much easier to ++ * do the authentication. ++ */ ++ ++ /* Make sure that we and the peer are AUTH capable */ ++ if (!net->sctp.auth_enable || !asoc->peer.auth_capable) ++ return false; ++ ++ /* set-up our fake chunk so that we can process it */ ++ auth.skb = chunk->auth_chunk; ++ auth.asoc = chunk->asoc; ++ auth.sctp_hdr = chunk->sctp_hdr; ++ auth.chunk_hdr = (struct sctp_chunkhdr *) ++ skb_push(chunk->auth_chunk, ++ sizeof(struct sctp_chunkhdr)); ++ skb_pull(chunk->auth_chunk, sizeof(struct sctp_chunkhdr)); ++ auth.transport = chunk->transport; ++ ++ return sctp_sf_authenticate(asoc, &auth) == SCTP_IERROR_NO_ERROR; ++} ++ + /* + * Respond to a normal COOKIE ECHO chunk. + * We are the side that is being asked for an association. +@@ -751,36 +781,9 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net, + if (error) + goto nomem_init; + +- /* SCTP-AUTH: auth_chunk pointer is only set when the cookie-echo +- * is supposed to be authenticated and we have to do delayed +- * authentication. We've just recreated the association using +- * the information in the cookie and now it's much easier to +- * do the authentication. +- */ +- if (chunk->auth_chunk) { +- struct sctp_chunk auth; +- sctp_ierror_t ret; +- +- /* Make sure that we and the peer are AUTH capable */ +- if (!net->sctp.auth_enable || !new_asoc->peer.auth_capable) { +- sctp_association_free(new_asoc); +- return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); +- } +- +- /* set-up our fake chunk so that we can process it */ +- auth.skb = chunk->auth_chunk; +- auth.asoc = chunk->asoc; +- auth.sctp_hdr = chunk->sctp_hdr; +- auth.chunk_hdr = (sctp_chunkhdr_t *)skb_push(chunk->auth_chunk, +- sizeof(sctp_chunkhdr_t)); +- skb_pull(chunk->auth_chunk, sizeof(sctp_chunkhdr_t)); +- auth.transport = chunk->transport; +- +- ret = sctp_sf_authenticate(net, ep, new_asoc, type, &auth); +- if (ret != SCTP_IERROR_NO_ERROR) { +- sctp_association_free(new_asoc); +- return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); +- } ++ if (!sctp_auth_chunk_verify(net, chunk, new_asoc)) { ++ sctp_association_free(new_asoc); ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); + } + + repl = sctp_make_cookie_ack(new_asoc, chunk); +@@ -1717,13 +1720,15 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(struct net *net, + GFP_ATOMIC)) + goto nomem; + ++ if (!sctp_auth_chunk_verify(net, chunk, new_asoc)) ++ return SCTP_DISPOSITION_DISCARD; ++ + /* Make sure no new addresses are being added during the + * restart. Though this is a pretty complicated attack + * since you'd have to get inside the cookie. + */ +- if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk, commands)) { ++ if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk, commands)) + return SCTP_DISPOSITION_CONSUME; +- } + + /* If the endpoint is in the SHUTDOWN-ACK-SENT state and recognizes + * the peer has restarted (Action A), it MUST NOT setup a new +@@ -1828,6 +1833,9 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(struct net *net, + GFP_ATOMIC)) + goto nomem; + ++ if (!sctp_auth_chunk_verify(net, chunk, new_asoc)) ++ return SCTP_DISPOSITION_DISCARD; ++ + /* Update the content of current association. */ + sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc)); + sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, +@@ -1920,6 +1928,9 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(struct net *net, + * a COOKIE ACK. + */ + ++ if (!sctp_auth_chunk_verify(net, chunk, asoc)) ++ return SCTP_DISPOSITION_DISCARD; ++ + /* Don't accidentally move back into established state. */ + if (asoc->state < SCTP_STATE_ESTABLISHED) { + sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, +@@ -1959,7 +1970,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(struct net *net, + } + } + +- repl = sctp_make_cookie_ack(new_asoc, chunk); ++ repl = sctp_make_cookie_ack(asoc, chunk); + if (!repl) + goto nomem; + +@@ -3981,10 +3992,8 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_fast( + * + * The return value is the disposition of the chunk. + */ +-static sctp_ierror_t sctp_sf_authenticate(struct net *net, +- const struct sctp_endpoint *ep, ++static sctp_ierror_t sctp_sf_authenticate( + const struct sctp_association *asoc, +- const sctp_subtype_t type, + struct sctp_chunk *chunk) + { + struct sctp_authhdr *auth_hdr; +@@ -4083,7 +4092,7 @@ sctp_disposition_t sctp_sf_eat_auth(struct net *net, + commands); + + auth_hdr = (struct sctp_authhdr *)chunk->skb->data; +- error = sctp_sf_authenticate(net, ep, asoc, type, chunk); ++ error = sctp_sf_authenticate(asoc, chunk); + switch (error) { + case SCTP_IERROR_AUTH_BAD_HMAC: + /* Generate the ERROR chunk and discard the rest +diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c +index bea00058ce35..6825e05a68b2 100644 +--- a/net/sctp/ulpevent.c ++++ b/net/sctp/ulpevent.c +@@ -723,7 +723,6 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc, + return event; + + fail_mark: +- sctp_chunk_put(chunk); + kfree_skb(skb); + fail: + return NULL; +diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c +index 6f5635770d6a..71a94e549301 100644 +--- a/net/xfrm/xfrm_state.c ++++ b/net/xfrm/xfrm_state.c +@@ -1197,6 +1197,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig) + + if (orig->aead) { + x->aead = xfrm_algo_aead_clone(orig->aead); ++ x->geniv = orig->geniv; + if (!x->aead) + goto error; + }