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 9D4841396D0 for ; Wed, 27 Sep 2017 16:44:50 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id DBAB92BC057; Wed, 27 Sep 2017 16:44:49 +0000 (UTC) Received: from smtp.gentoo.org (mail.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 9B1932BC057 for ; Wed, 27 Sep 2017 16:44:49 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (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 70E433416BA for ; Wed, 27 Sep 2017 16:44:48 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id AA8EE9083 for ; Wed, 27 Sep 2017 16:44: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: <1506530676.6480b3fa1da27836df3f2d330135e093e74e79a0.mpagano@gentoo> Subject: [gentoo-commits] proj/linux-patches:4.13 commit in: / X-VCS-Repository: proj/linux-patches X-VCS-Files: 0000_README 1003_linux-4.13.4.patch X-VCS-Directories: / X-VCS-Committer: mpagano X-VCS-Committer-Name: Mike Pagano X-VCS-Revision: 6480b3fa1da27836df3f2d330135e093e74e79a0 X-VCS-Branch: 4.13 Date: Wed, 27 Sep 2017 16:44: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: 4af1d99f-dfc6-477c-ba00-d2104776dc7b X-Archives-Hash: 787ee48e99093f44e6ebc052d78f1d6f commit: 6480b3fa1da27836df3f2d330135e093e74e79a0 Author: Mike Pagano gentoo org> AuthorDate: Wed Sep 27 16:44:36 2017 +0000 Commit: Mike Pagano gentoo org> CommitDate: Wed Sep 27 16:44:36 2017 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=6480b3fa Linux patch 4.13.4 0000_README | 4 + 1003_linux-4.13.4.patch | 5143 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 5147 insertions(+) diff --git a/0000_README b/0000_README index 70f03ff..aee01b0 100644 --- a/0000_README +++ b/0000_README @@ -55,6 +55,10 @@ Patch: 1002_linux-4.13.3.patch From: http://www.kernel.org Desc: Linux 4.13.3 +Patch: 1003_linux-4.13.4.patch +From: http://www.kernel.org +Desc: Linux 4.13.4 + 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/1003_linux-4.13.4.patch b/1003_linux-4.13.4.patch new file mode 100644 index 0000000..b118fe3 --- /dev/null +++ b/1003_linux-4.13.4.patch @@ -0,0 +1,5143 @@ +diff --git a/Documentation/dev-tools/gdb-kernel-debugging.rst b/Documentation/dev-tools/gdb-kernel-debugging.rst +index 5e93c9bc6619..19df79286f00 100644 +--- a/Documentation/dev-tools/gdb-kernel-debugging.rst ++++ b/Documentation/dev-tools/gdb-kernel-debugging.rst +@@ -31,11 +31,13 @@ Setup + CONFIG_DEBUG_INFO_REDUCED off. If your architecture supports + CONFIG_FRAME_POINTER, keep it enabled. + +-- Install that kernel on the guest. ++- Install that kernel on the guest, turn off KASLR if necessary by adding ++ "nokaslr" to the kernel command line. + Alternatively, QEMU allows to boot the kernel directly using -kernel, + -append, -initrd command line switches. This is generally only useful if + you do not depend on modules. See QEMU documentation for more details on +- this mode. ++ this mode. In this case, you should build the kernel with ++ CONFIG_RANDOMIZE_BASE disabled if the architecture supports KASLR. + + - Enable the gdb stub of QEMU/KVM, either + +diff --git a/Makefile b/Makefile +index 0f31ef4aea7b..159901979dec 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 13 +-SUBLEVEL = 3 ++SUBLEVEL = 4 + EXTRAVERSION = + NAME = Fearless Coyote + +diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S +index 1eea99beecc3..85d9ea4a0acc 100644 +--- a/arch/arc/kernel/entry.S ++++ b/arch/arc/kernel/entry.S +@@ -92,6 +92,12 @@ ENTRY(EV_MachineCheck) + lr r0, [efa] + mov r1, sp + ++ ; hardware auto-disables MMU, re-enable it to allow kernel vaddr ++ ; access for say stack unwinding of modules for crash dumps ++ lr r3, [ARC_REG_PID] ++ or r3, r3, MMU_ENABLE ++ sr r3, [ARC_REG_PID] ++ + lsr r3, r2, 8 + bmsk r3, r3, 7 + brne r3, ECR_C_MCHK_DUP_TLB, 1f +diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c +index b181f3ee38aa..ac81502055f8 100644 +--- a/arch/arc/mm/tlb.c ++++ b/arch/arc/mm/tlb.c +@@ -908,9 +908,6 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address, + + local_irq_save(flags); + +- /* re-enable the MMU */ +- write_aux_reg(ARC_REG_PID, MMU_ENABLE | read_aux_reg(ARC_REG_PID)); +- + /* loop thru all sets of TLB */ + for (set = 0; set < mmu->sets; set++) { + +diff --git a/arch/mips/math-emu/dp_fmax.c b/arch/mips/math-emu/dp_fmax.c +index fd71b8daaaf2..5bec64f2884e 100644 +--- a/arch/mips/math-emu/dp_fmax.c ++++ b/arch/mips/math-emu/dp_fmax.c +@@ -47,14 +47,26 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y) + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + return ieee754dp_nanxcpt(x); + +- /* numbers are preferred to NaNs */ ++ /* ++ * Quiet NaN handling ++ */ ++ ++ /* ++ * The case of both inputs quiet NaNs ++ */ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ return x; ++ ++ /* ++ * The cases of exactly one input quiet NaN (numbers ++ * are here preferred as returned values to NaNs) ++ */ + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + return x; + +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): +@@ -80,9 +92,7 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y) + return ys ? x : y; + + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): +- if (xs == ys) +- return x; +- return ieee754dp_zero(1); ++ return ieee754dp_zero(xs & ys); + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): + DPDNORMX; +@@ -106,16 +116,32 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y) + else if (xs < ys) + return x; + +- /* Compare exponent */ +- if (xe > ye) +- return x; +- else if (xe < ye) +- return y; ++ /* Signs of inputs are equal, let's compare exponents */ ++ if (xs == 0) { ++ /* Inputs are both positive */ ++ if (xe > ye) ++ return x; ++ else if (xe < ye) ++ return y; ++ } else { ++ /* Inputs are both negative */ ++ if (xe > ye) ++ return y; ++ else if (xe < ye) ++ return x; ++ } + +- /* Compare mantissa */ ++ /* Signs and exponents of inputs are equal, let's compare mantissas */ ++ if (xs == 0) { ++ /* Inputs are both positive, with equal signs and exponents */ ++ if (xm <= ym) ++ return y; ++ return x; ++ } ++ /* Inputs are both negative, with equal signs and exponents */ + if (xm <= ym) +- return y; +- return x; ++ return x; ++ return y; + } + + union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) +@@ -147,14 +173,26 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + return ieee754dp_nanxcpt(x); + +- /* numbers are preferred to NaNs */ ++ /* ++ * Quiet NaN handling ++ */ ++ ++ /* ++ * The case of both inputs quiet NaNs ++ */ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ return x; ++ ++ /* ++ * The cases of exactly one input quiet NaN (numbers ++ * are here preferred as returned values to NaNs) ++ */ + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + return x; + +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): +@@ -164,6 +202,9 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) + /* + * Infinity and zero handling + */ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): ++ return ieee754dp_inf(xs & ys); ++ + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): +@@ -171,7 +212,6 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): + return x; + +- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): +@@ -180,9 +220,7 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) + return y; + + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): +- if (xs == ys) +- return x; +- return ieee754dp_zero(1); ++ return ieee754dp_zero(xs & ys); + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): + DPDNORMX; +@@ -207,7 +245,11 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) + return y; + + /* Compare mantissa */ +- if (xm <= ym) ++ if (xm < ym) + return y; +- return x; ++ else if (xm > ym) ++ return x; ++ else if (xs == 0) ++ return x; ++ return y; + } +diff --git a/arch/mips/math-emu/dp_fmin.c b/arch/mips/math-emu/dp_fmin.c +index c1072b0dfb95..a287b23818d8 100644 +--- a/arch/mips/math-emu/dp_fmin.c ++++ b/arch/mips/math-emu/dp_fmin.c +@@ -47,14 +47,26 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y) + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + return ieee754dp_nanxcpt(x); + +- /* numbers are preferred to NaNs */ ++ /* ++ * Quiet NaN handling ++ */ ++ ++ /* ++ * The case of both inputs quiet NaNs ++ */ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ return x; ++ ++ /* ++ * The cases of exactly one input quiet NaN (numbers ++ * are here preferred as returned values to NaNs) ++ */ + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + return x; + +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): +@@ -80,9 +92,7 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y) + return ys ? y : x; + + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): +- if (xs == ys) +- return x; +- return ieee754dp_zero(1); ++ return ieee754dp_zero(xs | ys); + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): + DPDNORMX; +@@ -106,16 +116,32 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y) + else if (xs < ys) + return y; + +- /* Compare exponent */ +- if (xe > ye) +- return y; +- else if (xe < ye) +- return x; ++ /* Signs of inputs are the same, let's compare exponents */ ++ if (xs == 0) { ++ /* Inputs are both positive */ ++ if (xe > ye) ++ return y; ++ else if (xe < ye) ++ return x; ++ } else { ++ /* Inputs are both negative */ ++ if (xe > ye) ++ return x; ++ else if (xe < ye) ++ return y; ++ } + +- /* Compare mantissa */ ++ /* Signs and exponents of inputs are equal, let's compare mantissas */ ++ if (xs == 0) { ++ /* Inputs are both positive, with equal signs and exponents */ ++ if (xm <= ym) ++ return x; ++ return y; ++ } ++ /* Inputs are both negative, with equal signs and exponents */ + if (xm <= ym) +- return x; +- return y; ++ return y; ++ return x; + } + + union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) +@@ -147,14 +173,26 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + return ieee754dp_nanxcpt(x); + +- /* numbers are preferred to NaNs */ ++ /* ++ * Quiet NaN handling ++ */ ++ ++ /* ++ * The case of both inputs quiet NaNs ++ */ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ return x; ++ ++ /* ++ * The cases of exactly one input quiet NaN (numbers ++ * are here preferred as returned values to NaNs) ++ */ + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + return x; + +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): +@@ -164,25 +202,25 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) + /* + * Infinity and zero handling + */ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): ++ return ieee754dp_inf(xs | ys); ++ + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): +- return x; ++ return y; + +- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): +- return y; ++ return x; + + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): +- if (xs == ys) +- return x; +- return ieee754dp_zero(1); ++ return ieee754dp_zero(xs | ys); + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): + DPDNORMX; +@@ -207,7 +245,11 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) + return x; + + /* Compare mantissa */ +- if (xm <= ym) ++ if (xm < ym) ++ return x; ++ else if (xm > ym) ++ return y; ++ else if (xs == 1) + return x; + return y; + } +diff --git a/arch/mips/math-emu/dp_maddf.c b/arch/mips/math-emu/dp_maddf.c +index caa62f20a888..e0d9be5fbf4c 100644 +--- a/arch/mips/math-emu/dp_maddf.c ++++ b/arch/mips/math-emu/dp_maddf.c +@@ -14,22 +14,45 @@ + + #include "ieee754dp.h" + +-enum maddf_flags { +- maddf_negate_product = 1 << 0, +-}; ++ ++/* 128 bits shift right logical with rounding. */ ++void srl128(u64 *hptr, u64 *lptr, int count) ++{ ++ u64 low; ++ ++ if (count >= 128) { ++ *lptr = *hptr != 0 || *lptr != 0; ++ *hptr = 0; ++ } else if (count >= 64) { ++ if (count == 64) { ++ *lptr = *hptr | (*lptr != 0); ++ } else { ++ low = *lptr; ++ *lptr = *hptr >> (count - 64); ++ *lptr |= (*hptr << (128 - count)) != 0 || low != 0; ++ } ++ *hptr = 0; ++ } else { ++ low = *lptr; ++ *lptr = low >> count | *hptr << (64 - count); ++ *lptr |= (low << (64 - count)) != 0; ++ *hptr = *hptr >> count; ++ } ++} + + static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, + union ieee754dp y, enum maddf_flags flags) + { + int re; + int rs; +- u64 rm; + unsigned lxm; + unsigned hxm; + unsigned lym; + unsigned hym; + u64 lrm; + u64 hrm; ++ u64 lzm; ++ u64 hzm; + u64 t; + u64 at; + int s; +@@ -48,52 +71,34 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, + + ieee754_clearcx(); + +- switch (zc) { +- case IEEE754_CLASS_SNAN: +- ieee754_setcx(IEEE754_INVALID_OPERATION); ++ /* ++ * Handle the cases when at least one of x, y or z is a NaN. ++ * Order of precedence is sNaN, qNaN and z, x, y. ++ */ ++ if (zc == IEEE754_CLASS_SNAN) + return ieee754dp_nanxcpt(z); +- case IEEE754_CLASS_DNORM: +- DPDNORMZ; +- /* QNAN and ZERO cases are handled separately below */ +- } +- +- switch (CLPAIR(xc, yc)) { +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): +- case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): +- case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): +- case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): +- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): +- return ieee754dp_nanxcpt(y); +- +- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): +- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): +- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): +- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): +- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): +- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): ++ if (xc == IEEE754_CLASS_SNAN) + return ieee754dp_nanxcpt(x); +- +- case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): +- case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): +- case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): +- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): ++ if (yc == IEEE754_CLASS_SNAN) ++ return ieee754dp_nanxcpt(y); ++ if (zc == IEEE754_CLASS_QNAN) ++ return z; ++ if (xc == IEEE754_CLASS_QNAN) ++ return x; ++ if (yc == IEEE754_CLASS_QNAN) + return y; + +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): +- return x; ++ if (zc == IEEE754_CLASS_DNORM) ++ DPDNORMZ; ++ /* ZERO z cases are handled separately below */ + ++ switch (CLPAIR(xc, yc)) { + + /* + * Infinity handling + */ + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): +- if (zc == IEEE754_CLASS_QNAN) +- return z; + ieee754_setcx(IEEE754_INVALID_OPERATION); + return ieee754dp_indef(); + +@@ -102,9 +107,27 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): +- if (zc == IEEE754_CLASS_QNAN) +- return z; +- return ieee754dp_inf(xs ^ ys); ++ if ((zc == IEEE754_CLASS_INF) && ++ ((!(flags & MADDF_NEGATE_PRODUCT) && (zs != (xs ^ ys))) || ++ ((flags & MADDF_NEGATE_PRODUCT) && (zs == (xs ^ ys))))) { ++ /* ++ * Cases of addition of infinities with opposite signs ++ * or subtraction of infinities with same signs. ++ */ ++ ieee754_setcx(IEEE754_INVALID_OPERATION); ++ return ieee754dp_indef(); ++ } ++ /* ++ * z is here either not an infinity, or an infinity having the ++ * same sign as product (x*y) (in case of MADDF.D instruction) ++ * or product -(x*y) (in MSUBF.D case). The result must be an ++ * infinity, and its sign is determined only by the value of ++ * (flags & MADDF_NEGATE_PRODUCT) and the signs of x and y. ++ */ ++ if (flags & MADDF_NEGATE_PRODUCT) ++ return ieee754dp_inf(1 ^ (xs ^ ys)); ++ else ++ return ieee754dp_inf(xs ^ ys); + + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): +@@ -113,32 +136,42 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): + if (zc == IEEE754_CLASS_INF) + return ieee754dp_inf(zs); +- /* Multiplication is 0 so just return z */ ++ if (zc == IEEE754_CLASS_ZERO) { ++ /* Handle cases +0 + (-0) and similar ones. */ ++ if ((!(flags & MADDF_NEGATE_PRODUCT) ++ && (zs == (xs ^ ys))) || ++ ((flags & MADDF_NEGATE_PRODUCT) ++ && (zs != (xs ^ ys)))) ++ /* ++ * Cases of addition of zeros of equal signs ++ * or subtraction of zeroes of opposite signs. ++ * The sign of the resulting zero is in any ++ * such case determined only by the sign of z. ++ */ ++ return z; ++ ++ return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD); ++ } ++ /* x*y is here 0, and z is not 0, so just return z */ + return z; + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): + DPDNORMX; + + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): +- if (zc == IEEE754_CLASS_QNAN) +- return z; +- else if (zc == IEEE754_CLASS_INF) ++ if (zc == IEEE754_CLASS_INF) + return ieee754dp_inf(zs); + DPDNORMY; + break; + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): +- if (zc == IEEE754_CLASS_QNAN) +- return z; +- else if (zc == IEEE754_CLASS_INF) ++ if (zc == IEEE754_CLASS_INF) + return ieee754dp_inf(zs); + DPDNORMX; + break; + + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): +- if (zc == IEEE754_CLASS_QNAN) +- return z; +- else if (zc == IEEE754_CLASS_INF) ++ if (zc == IEEE754_CLASS_INF) + return ieee754dp_inf(zs); + /* fall through to real computations */ + } +@@ -157,7 +190,7 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, + + re = xe + ye; + rs = xs ^ ys; +- if (flags & maddf_negate_product) ++ if (flags & MADDF_NEGATE_PRODUCT) + rs ^= 1; + + /* shunt to top of word */ +@@ -165,7 +198,7 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, + ym <<= 64 - (DP_FBITS + 1); + + /* +- * Multiply 64 bits xm, ym to give high 64 bits rm with stickness. ++ * Multiply 64 bits xm and ym to give 128 bits result in hrm:lrm. + */ + + /* 32 * 32 => 64 */ +@@ -195,81 +228,110 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, + + hrm = hrm + (t >> 32); + +- rm = hrm | (lrm != 0); +- +- /* +- * Sticky shift down to normal rounding precision. +- */ +- if ((s64) rm < 0) { +- rm = (rm >> (64 - (DP_FBITS + 1 + 3))) | +- ((rm << (DP_FBITS + 1 + 3)) != 0); ++ /* Put explicit bit at bit 126 if necessary */ ++ if ((int64_t)hrm < 0) { ++ lrm = (hrm << 63) | (lrm >> 1); ++ hrm = hrm >> 1; + re++; +- } else { +- rm = (rm >> (64 - (DP_FBITS + 1 + 3 + 1))) | +- ((rm << (DP_FBITS + 1 + 3 + 1)) != 0); + } +- assert(rm & (DP_HIDDEN_BIT << 3)); + +- if (zc == IEEE754_CLASS_ZERO) +- return ieee754dp_format(rs, re, rm); ++ assert(hrm & (1 << 62)); + +- /* And now the addition */ +- assert(zm & DP_HIDDEN_BIT); ++ if (zc == IEEE754_CLASS_ZERO) { ++ /* ++ * Move explicit bit from bit 126 to bit 55 since the ++ * ieee754dp_format code expects the mantissa to be ++ * 56 bits wide (53 + 3 rounding bits). ++ */ ++ srl128(&hrm, &lrm, (126 - 55)); ++ return ieee754dp_format(rs, re, lrm); ++ } + +- /* +- * Provide guard,round and stick bit space. +- */ +- zm <<= 3; ++ /* Move explicit bit from bit 52 to bit 126 */ ++ lzm = 0; ++ hzm = zm << 10; ++ assert(hzm & (1 << 62)); + ++ /* Make the exponents the same */ + if (ze > re) { + /* + * Have to shift y fraction right to align. + */ + s = ze - re; +- rm = XDPSRS(rm, s); ++ srl128(&hrm, &lrm, s); + re += s; + } else if (re > ze) { + /* + * Have to shift x fraction right to align. + */ + s = re - ze; +- zm = XDPSRS(zm, s); ++ srl128(&hzm, &lzm, s); + ze += s; + } + assert(ze == re); + assert(ze <= DP_EMAX); + ++ /* Do the addition */ + if (zs == rs) { + /* +- * Generate 28 bit result of adding two 27 bit numbers +- * leaving result in xm, xs and xe. ++ * Generate 128 bit result by adding two 127 bit numbers ++ * leaving result in hzm:lzm, zs and ze. + */ +- zm = zm + rm; +- +- if (zm >> (DP_FBITS + 1 + 3)) { /* carry out */ +- zm = XDPSRS1(zm); ++ hzm = hzm + hrm + (lzm > (lzm + lrm)); ++ lzm = lzm + lrm; ++ if ((int64_t)hzm < 0) { /* carry out */ ++ srl128(&hzm, &lzm, 1); + ze++; + } + } else { +- if (zm >= rm) { +- zm = zm - rm; ++ if (hzm > hrm || (hzm == hrm && lzm >= lrm)) { ++ hzm = hzm - hrm - (lzm < lrm); ++ lzm = lzm - lrm; + } else { +- zm = rm - zm; ++ hzm = hrm - hzm - (lrm < lzm); ++ lzm = lrm - lzm; + zs = rs; + } +- if (zm == 0) ++ if (lzm == 0 && hzm == 0) + return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD); + + /* +- * Normalize to rounding precision. ++ * Put explicit bit at bit 126 if necessary. + */ +- while ((zm >> (DP_FBITS + 3)) == 0) { +- zm <<= 1; +- ze--; ++ if (hzm == 0) { ++ /* left shift by 63 or 64 bits */ ++ if ((int64_t)lzm < 0) { ++ /* MSB of lzm is the explicit bit */ ++ hzm = lzm >> 1; ++ lzm = lzm << 63; ++ ze -= 63; ++ } else { ++ hzm = lzm; ++ lzm = 0; ++ ze -= 64; ++ } ++ } ++ ++ t = 0; ++ while ((hzm >> (62 - t)) == 0) ++ t++; ++ ++ assert(t <= 62); ++ if (t) { ++ hzm = hzm << t | lzm >> (64 - t); ++ lzm = lzm << t; ++ ze -= t; + } + } + +- return ieee754dp_format(zs, ze, zm); ++ /* ++ * Move explicit bit from bit 126 to bit 55 since the ++ * ieee754dp_format code expects the mantissa to be ++ * 56 bits wide (53 + 3 rounding bits). ++ */ ++ srl128(&hzm, &lzm, (126 - 55)); ++ ++ return ieee754dp_format(zs, ze, lzm); + } + + union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, +@@ -281,5 +343,5 @@ union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, + union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x, + union ieee754dp y) + { +- return _dp_maddf(z, x, y, maddf_negate_product); ++ return _dp_maddf(z, x, y, MADDF_NEGATE_PRODUCT); + } +diff --git a/arch/mips/math-emu/ieee754int.h b/arch/mips/math-emu/ieee754int.h +index 8bc2f6963324..dd2071f430e0 100644 +--- a/arch/mips/math-emu/ieee754int.h ++++ b/arch/mips/math-emu/ieee754int.h +@@ -26,6 +26,10 @@ + + #define CLPAIR(x, y) ((x)*6+(y)) + ++enum maddf_flags { ++ MADDF_NEGATE_PRODUCT = 1 << 0, ++}; ++ + static inline void ieee754_clearcx(void) + { + ieee754_csr.cx = 0; +diff --git a/arch/mips/math-emu/ieee754sp.h b/arch/mips/math-emu/ieee754sp.h +index 8476067075fe..0f63e4202cff 100644 +--- a/arch/mips/math-emu/ieee754sp.h ++++ b/arch/mips/math-emu/ieee754sp.h +@@ -45,6 +45,10 @@ static inline int ieee754sp_finite(union ieee754sp x) + return SPBEXP(x) != SP_EMAX + 1 + SP_EBIAS; + } + ++/* 64 bit right shift with rounding */ ++#define XSPSRS64(v, rs) \ ++ (((rs) >= 64) ? ((v) != 0) : ((v) >> (rs)) | ((v) << (64-(rs)) != 0)) ++ + /* 3bit extended single precision sticky right shift */ + #define XSPSRS(v, rs) \ + ((rs > (SP_FBITS+3))?1:((v) >> (rs)) | ((v) << (32-(rs)) != 0)) +diff --git a/arch/mips/math-emu/sp_fmax.c b/arch/mips/math-emu/sp_fmax.c +index 4d000844e48e..74a5a00d2f22 100644 +--- a/arch/mips/math-emu/sp_fmax.c ++++ b/arch/mips/math-emu/sp_fmax.c +@@ -47,14 +47,26 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y) + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + return ieee754sp_nanxcpt(x); + +- /* numbers are preferred to NaNs */ ++ /* ++ * Quiet NaN handling ++ */ ++ ++ /* ++ * The case of both inputs quiet NaNs ++ */ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ return x; ++ ++ /* ++ * The cases of exactly one input quiet NaN (numbers ++ * are here preferred as returned values to NaNs) ++ */ + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + return x; + +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): +@@ -80,9 +92,7 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y) + return ys ? x : y; + + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): +- if (xs == ys) +- return x; +- return ieee754sp_zero(1); ++ return ieee754sp_zero(xs & ys); + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): + SPDNORMX; +@@ -106,16 +116,32 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y) + else if (xs < ys) + return x; + +- /* Compare exponent */ +- if (xe > ye) +- return x; +- else if (xe < ye) +- return y; ++ /* Signs of inputs are equal, let's compare exponents */ ++ if (xs == 0) { ++ /* Inputs are both positive */ ++ if (xe > ye) ++ return x; ++ else if (xe < ye) ++ return y; ++ } else { ++ /* Inputs are both negative */ ++ if (xe > ye) ++ return y; ++ else if (xe < ye) ++ return x; ++ } + +- /* Compare mantissa */ ++ /* Signs and exponents of inputs are equal, let's compare mantissas */ ++ if (xs == 0) { ++ /* Inputs are both positive, with equal signs and exponents */ ++ if (xm <= ym) ++ return y; ++ return x; ++ } ++ /* Inputs are both negative, with equal signs and exponents */ + if (xm <= ym) +- return y; +- return x; ++ return x; ++ return y; + } + + union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) +@@ -147,14 +173,26 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + return ieee754sp_nanxcpt(x); + +- /* numbers are preferred to NaNs */ ++ /* ++ * Quiet NaN handling ++ */ ++ ++ /* ++ * The case of both inputs quiet NaNs ++ */ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ return x; ++ ++ /* ++ * The cases of exactly one input quiet NaN (numbers ++ * are here preferred as returned values to NaNs) ++ */ + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + return x; + +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): +@@ -164,6 +202,9 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) + /* + * Infinity and zero handling + */ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): ++ return ieee754sp_inf(xs & ys); ++ + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): +@@ -171,7 +212,6 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): + return x; + +- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): +@@ -180,9 +220,7 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) + return y; + + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): +- if (xs == ys) +- return x; +- return ieee754sp_zero(1); ++ return ieee754sp_zero(xs & ys); + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): + SPDNORMX; +@@ -207,7 +245,11 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) + return y; + + /* Compare mantissa */ +- if (xm <= ym) ++ if (xm < ym) + return y; +- return x; ++ else if (xm > ym) ++ return x; ++ else if (xs == 0) ++ return x; ++ return y; + } +diff --git a/arch/mips/math-emu/sp_fmin.c b/arch/mips/math-emu/sp_fmin.c +index 4eb1bb9e9dec..c51385f46b09 100644 +--- a/arch/mips/math-emu/sp_fmin.c ++++ b/arch/mips/math-emu/sp_fmin.c +@@ -47,14 +47,26 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y) + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + return ieee754sp_nanxcpt(x); + +- /* numbers are preferred to NaNs */ ++ /* ++ * Quiet NaN handling ++ */ ++ ++ /* ++ * The case of both inputs quiet NaNs ++ */ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ return x; ++ ++ /* ++ * The cases of exactly one input quiet NaN (numbers ++ * are here preferred as returned values to NaNs) ++ */ + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + return x; + +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): +@@ -80,9 +92,7 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y) + return ys ? y : x; + + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): +- if (xs == ys) +- return x; +- return ieee754sp_zero(1); ++ return ieee754sp_zero(xs | ys); + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): + SPDNORMX; +@@ -106,16 +116,32 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y) + else if (xs < ys) + return y; + +- /* Compare exponent */ +- if (xe > ye) +- return y; +- else if (xe < ye) +- return x; ++ /* Signs of inputs are the same, let's compare exponents */ ++ if (xs == 0) { ++ /* Inputs are both positive */ ++ if (xe > ye) ++ return y; ++ else if (xe < ye) ++ return x; ++ } else { ++ /* Inputs are both negative */ ++ if (xe > ye) ++ return x; ++ else if (xe < ye) ++ return y; ++ } + +- /* Compare mantissa */ ++ /* Signs and exponents of inputs are equal, let's compare mantissas */ ++ if (xs == 0) { ++ /* Inputs are both positive, with equal signs and exponents */ ++ if (xm <= ym) ++ return x; ++ return y; ++ } ++ /* Inputs are both negative, with equal signs and exponents */ + if (xm <= ym) +- return x; +- return y; ++ return y; ++ return x; + } + + union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) +@@ -147,14 +173,26 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + return ieee754sp_nanxcpt(x); + +- /* numbers are preferred to NaNs */ ++ /* ++ * Quiet NaN handling ++ */ ++ ++ /* ++ * The case of both inputs quiet NaNs ++ */ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ return x; ++ ++ /* ++ * The cases of exactly one input quiet NaN (numbers ++ * are here preferred as returned values to NaNs) ++ */ + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + return x; + +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): +@@ -164,25 +202,25 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) + /* + * Infinity and zero handling + */ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): ++ return ieee754sp_inf(xs | ys); ++ + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): +- return x; ++ return y; + +- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): +- return y; ++ return x; + + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): +- if (xs == ys) +- return x; +- return ieee754sp_zero(1); ++ return ieee754sp_zero(xs | ys); + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): + SPDNORMX; +@@ -207,7 +245,11 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) + return x; + + /* Compare mantissa */ +- if (xm <= ym) ++ if (xm < ym) ++ return x; ++ else if (xm > ym) ++ return y; ++ else if (xs == 1) + return x; + return y; + } +diff --git a/arch/mips/math-emu/sp_maddf.c b/arch/mips/math-emu/sp_maddf.c +index c91d5e5d9b5f..7195fe785d81 100644 +--- a/arch/mips/math-emu/sp_maddf.c ++++ b/arch/mips/math-emu/sp_maddf.c +@@ -14,9 +14,6 @@ + + #include "ieee754sp.h" + +-enum maddf_flags { +- maddf_negate_product = 1 << 0, +-}; + + static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, + union ieee754sp y, enum maddf_flags flags) +@@ -24,14 +21,8 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, + int re; + int rs; + unsigned rm; +- unsigned short lxm; +- unsigned short hxm; +- unsigned short lym; +- unsigned short hym; +- unsigned lrm; +- unsigned hrm; +- unsigned t; +- unsigned at; ++ uint64_t rm64; ++ uint64_t zm64; + int s; + + COMPXSP; +@@ -48,51 +39,35 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, + + ieee754_clearcx(); + +- switch (zc) { +- case IEEE754_CLASS_SNAN: +- ieee754_setcx(IEEE754_INVALID_OPERATION); ++ /* ++ * Handle the cases when at least one of x, y or z is a NaN. ++ * Order of precedence is sNaN, qNaN and z, x, y. ++ */ ++ if (zc == IEEE754_CLASS_SNAN) + return ieee754sp_nanxcpt(z); +- case IEEE754_CLASS_DNORM: +- SPDNORMZ; +- /* QNAN and ZERO cases are handled separately below */ +- } +- +- switch (CLPAIR(xc, yc)) { +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): +- case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): +- case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): +- case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): +- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): ++ if (xc == IEEE754_CLASS_SNAN) ++ return ieee754sp_nanxcpt(x); ++ if (yc == IEEE754_CLASS_SNAN) + return ieee754sp_nanxcpt(y); ++ if (zc == IEEE754_CLASS_QNAN) ++ return z; ++ if (xc == IEEE754_CLASS_QNAN) ++ return x; ++ if (yc == IEEE754_CLASS_QNAN) ++ return y; + +- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): +- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): +- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): +- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): +- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): +- case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): +- return ieee754sp_nanxcpt(x); ++ if (zc == IEEE754_CLASS_DNORM) ++ SPDNORMZ; ++ /* ZERO z cases are handled separately below */ + +- case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): +- case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): +- case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): +- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): +- return y; ++ switch (CLPAIR(xc, yc)) { + +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): +- return x; + + /* + * Infinity handling + */ + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): +- if (zc == IEEE754_CLASS_QNAN) +- return z; + ieee754_setcx(IEEE754_INVALID_OPERATION); + return ieee754sp_indef(); + +@@ -101,9 +76,27 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): +- if (zc == IEEE754_CLASS_QNAN) +- return z; +- return ieee754sp_inf(xs ^ ys); ++ if ((zc == IEEE754_CLASS_INF) && ++ ((!(flags & MADDF_NEGATE_PRODUCT) && (zs != (xs ^ ys))) || ++ ((flags & MADDF_NEGATE_PRODUCT) && (zs == (xs ^ ys))))) { ++ /* ++ * Cases of addition of infinities with opposite signs ++ * or subtraction of infinities with same signs. ++ */ ++ ieee754_setcx(IEEE754_INVALID_OPERATION); ++ return ieee754sp_indef(); ++ } ++ /* ++ * z is here either not an infinity, or an infinity having the ++ * same sign as product (x*y) (in case of MADDF.D instruction) ++ * or product -(x*y) (in MSUBF.D case). The result must be an ++ * infinity, and its sign is determined only by the value of ++ * (flags & MADDF_NEGATE_PRODUCT) and the signs of x and y. ++ */ ++ if (flags & MADDF_NEGATE_PRODUCT) ++ return ieee754sp_inf(1 ^ (xs ^ ys)); ++ else ++ return ieee754sp_inf(xs ^ ys); + + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): +@@ -112,32 +105,42 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): + if (zc == IEEE754_CLASS_INF) + return ieee754sp_inf(zs); +- /* Multiplication is 0 so just return z */ ++ if (zc == IEEE754_CLASS_ZERO) { ++ /* Handle cases +0 + (-0) and similar ones. */ ++ if ((!(flags & MADDF_NEGATE_PRODUCT) ++ && (zs == (xs ^ ys))) || ++ ((flags & MADDF_NEGATE_PRODUCT) ++ && (zs != (xs ^ ys)))) ++ /* ++ * Cases of addition of zeros of equal signs ++ * or subtraction of zeroes of opposite signs. ++ * The sign of the resulting zero is in any ++ * such case determined only by the sign of z. ++ */ ++ return z; ++ ++ return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD); ++ } ++ /* x*y is here 0, and z is not 0, so just return z */ + return z; + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): + SPDNORMX; + + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): +- if (zc == IEEE754_CLASS_QNAN) +- return z; +- else if (zc == IEEE754_CLASS_INF) ++ if (zc == IEEE754_CLASS_INF) + return ieee754sp_inf(zs); + SPDNORMY; + break; + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): +- if (zc == IEEE754_CLASS_QNAN) +- return z; +- else if (zc == IEEE754_CLASS_INF) ++ if (zc == IEEE754_CLASS_INF) + return ieee754sp_inf(zs); + SPDNORMX; + break; + + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): +- if (zc == IEEE754_CLASS_QNAN) +- return z; +- else if (zc == IEEE754_CLASS_INF) ++ if (zc == IEEE754_CLASS_INF) + return ieee754sp_inf(zs); + /* fall through to real computations */ + } +@@ -158,111 +161,93 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, + + re = xe + ye; + rs = xs ^ ys; +- if (flags & maddf_negate_product) ++ if (flags & MADDF_NEGATE_PRODUCT) + rs ^= 1; + +- /* shunt to top of word */ +- xm <<= 32 - (SP_FBITS + 1); +- ym <<= 32 - (SP_FBITS + 1); +- +- /* +- * Multiply 32 bits xm, ym to give high 32 bits rm with stickness. +- */ +- lxm = xm & 0xffff; +- hxm = xm >> 16; +- lym = ym & 0xffff; +- hym = ym >> 16; +- +- lrm = lxm * lym; /* 16 * 16 => 32 */ +- hrm = hxm * hym; /* 16 * 16 => 32 */ +- +- t = lxm * hym; /* 16 * 16 => 32 */ +- at = lrm + (t << 16); +- hrm += at < lrm; +- lrm = at; +- hrm = hrm + (t >> 16); ++ /* Multiple 24 bit xm and ym to give 48 bit results */ ++ rm64 = (uint64_t)xm * ym; + +- t = hxm * lym; /* 16 * 16 => 32 */ +- at = lrm + (t << 16); +- hrm += at < lrm; +- lrm = at; +- hrm = hrm + (t >> 16); ++ /* Shunt to top of word */ ++ rm64 = rm64 << 16; + +- rm = hrm | (lrm != 0); +- +- /* +- * Sticky shift down to normal rounding precision. +- */ +- if ((int) rm < 0) { +- rm = (rm >> (32 - (SP_FBITS + 1 + 3))) | +- ((rm << (SP_FBITS + 1 + 3)) != 0); ++ /* Put explicit bit at bit 62 if necessary */ ++ if ((int64_t) rm64 < 0) { ++ rm64 = rm64 >> 1; + re++; +- } else { +- rm = (rm >> (32 - (SP_FBITS + 1 + 3 + 1))) | +- ((rm << (SP_FBITS + 1 + 3 + 1)) != 0); + } +- assert(rm & (SP_HIDDEN_BIT << 3)); +- +- if (zc == IEEE754_CLASS_ZERO) +- return ieee754sp_format(rs, re, rm); + +- /* And now the addition */ ++ assert(rm64 & (1 << 62)); + +- assert(zm & SP_HIDDEN_BIT); ++ if (zc == IEEE754_CLASS_ZERO) { ++ /* ++ * Move explicit bit from bit 62 to bit 26 since the ++ * ieee754sp_format code expects the mantissa to be ++ * 27 bits wide (24 + 3 rounding bits). ++ */ ++ rm = XSPSRS64(rm64, (62 - 26)); ++ return ieee754sp_format(rs, re, rm); ++ } + +- /* +- * Provide guard,round and stick bit space. +- */ +- zm <<= 3; ++ /* Move explicit bit from bit 23 to bit 62 */ ++ zm64 = (uint64_t)zm << (62 - 23); ++ assert(zm64 & (1 << 62)); + ++ /* Make the exponents the same */ + if (ze > re) { + /* + * Have to shift r fraction right to align. + */ + s = ze - re; +- rm = XSPSRS(rm, s); ++ rm64 = XSPSRS64(rm64, s); + re += s; + } else if (re > ze) { + /* + * Have to shift z fraction right to align. + */ + s = re - ze; +- zm = XSPSRS(zm, s); ++ zm64 = XSPSRS64(zm64, s); + ze += s; + } + assert(ze == re); + assert(ze <= SP_EMAX); + ++ /* Do the addition */ + if (zs == rs) { + /* +- * Generate 28 bit result of adding two 27 bit numbers +- * leaving result in zm, zs and ze. ++ * Generate 64 bit result by adding two 63 bit numbers ++ * leaving result in zm64, zs and ze. + */ +- zm = zm + rm; +- +- if (zm >> (SP_FBITS + 1 + 3)) { /* carry out */ +- zm = XSPSRS1(zm); ++ zm64 = zm64 + rm64; ++ if ((int64_t)zm64 < 0) { /* carry out */ ++ zm64 = XSPSRS1(zm64); + ze++; + } + } else { +- if (zm >= rm) { +- zm = zm - rm; ++ if (zm64 >= rm64) { ++ zm64 = zm64 - rm64; + } else { +- zm = rm - zm; ++ zm64 = rm64 - zm64; + zs = rs; + } +- if (zm == 0) ++ if (zm64 == 0) + return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD); + + /* +- * Normalize in extended single precision ++ * Put explicit bit at bit 62 if necessary. + */ +- while ((zm >> (SP_MBITS + 3)) == 0) { +- zm <<= 1; ++ while ((zm64 >> 62) == 0) { ++ zm64 <<= 1; + ze--; + } +- + } ++ ++ /* ++ * Move explicit bit from bit 62 to bit 26 since the ++ * ieee754sp_format code expects the mantissa to be ++ * 27 bits wide (24 + 3 rounding bits). ++ */ ++ zm = XSPSRS64(zm64, (62 - 26)); ++ + return ieee754sp_format(zs, ze, zm); + } + +@@ -275,5 +260,5 @@ union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x, + union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x, + union ieee754sp y) + { +- return _sp_maddf(z, x, y, maddf_negate_product); ++ return _sp_maddf(z, x, y, MADDF_NEGATE_PRODUCT); + } +diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c +index ec7a8b099dd9..fd3c1fcc73eb 100644 +--- a/arch/powerpc/kernel/align.c ++++ b/arch/powerpc/kernel/align.c +@@ -235,6 +235,28 @@ static int emulate_dcbz(struct pt_regs *regs, unsigned char __user *addr) + + #define SWIZ_PTR(p) ((unsigned char __user *)((p) ^ swiz)) + ++#define __get_user_or_set_dar(_regs, _dest, _addr) \ ++ ({ \ ++ int rc = 0; \ ++ typeof(_addr) __addr = (_addr); \ ++ if (__get_user_inatomic(_dest, __addr)) { \ ++ _regs->dar = (unsigned long)__addr; \ ++ rc = -EFAULT; \ ++ } \ ++ rc; \ ++ }) ++ ++#define __put_user_or_set_dar(_regs, _src, _addr) \ ++ ({ \ ++ int rc = 0; \ ++ typeof(_addr) __addr = (_addr); \ ++ if (__put_user_inatomic(_src, __addr)) { \ ++ _regs->dar = (unsigned long)__addr; \ ++ rc = -EFAULT; \ ++ } \ ++ rc; \ ++ }) ++ + static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, + unsigned int reg, unsigned int nb, + unsigned int flags, unsigned int instr, +@@ -263,9 +285,10 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, + } else { + unsigned long pc = regs->nip ^ (swiz & 4); + +- if (__get_user_inatomic(instr, +- (unsigned int __user *)pc)) ++ if (__get_user_or_set_dar(regs, instr, ++ (unsigned int __user *)pc)) + return -EFAULT; ++ + if (swiz == 0 && (flags & SW)) + instr = cpu_to_le32(instr); + nb = (instr >> 11) & 0x1f; +@@ -309,31 +332,31 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, + ((nb0 + 3) / 4) * sizeof(unsigned long)); + + for (i = 0; i < nb; ++i, ++p) +- if (__get_user_inatomic(REG_BYTE(rptr, i ^ bswiz), +- SWIZ_PTR(p))) ++ if (__get_user_or_set_dar(regs, REG_BYTE(rptr, i ^ bswiz), ++ SWIZ_PTR(p))) + return -EFAULT; + if (nb0 > 0) { + rptr = ®s->gpr[0]; + addr += nb; + for (i = 0; i < nb0; ++i, ++p) +- if (__get_user_inatomic(REG_BYTE(rptr, +- i ^ bswiz), +- SWIZ_PTR(p))) ++ if (__get_user_or_set_dar(regs, ++ REG_BYTE(rptr, i ^ bswiz), ++ SWIZ_PTR(p))) + return -EFAULT; + } + + } else { + for (i = 0; i < nb; ++i, ++p) +- if (__put_user_inatomic(REG_BYTE(rptr, i ^ bswiz), +- SWIZ_PTR(p))) ++ if (__put_user_or_set_dar(regs, REG_BYTE(rptr, i ^ bswiz), ++ SWIZ_PTR(p))) + return -EFAULT; + if (nb0 > 0) { + rptr = ®s->gpr[0]; + addr += nb; + for (i = 0; i < nb0; ++i, ++p) +- if (__put_user_inatomic(REG_BYTE(rptr, +- i ^ bswiz), +- SWIZ_PTR(p))) ++ if (__put_user_or_set_dar(regs, ++ REG_BYTE(rptr, i ^ bswiz), ++ SWIZ_PTR(p))) + return -EFAULT; + } + } +@@ -345,29 +368,32 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, + * Only POWER6 has these instructions, and it does true little-endian, + * so we don't need the address swizzling. + */ +-static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg, +- unsigned int flags) ++static int emulate_fp_pair(struct pt_regs *regs, unsigned char __user *addr, ++ unsigned int reg, unsigned int flags) + { + char *ptr0 = (char *) ¤t->thread.TS_FPR(reg); + char *ptr1 = (char *) ¤t->thread.TS_FPR(reg+1); +- int i, ret, sw = 0; ++ int i, sw = 0; + + if (reg & 1) + return 0; /* invalid form: FRS/FRT must be even */ + if (flags & SW) + sw = 7; +- ret = 0; ++ + for (i = 0; i < 8; ++i) { + if (!(flags & ST)) { +- ret |= __get_user(ptr0[i^sw], addr + i); +- ret |= __get_user(ptr1[i^sw], addr + i + 8); ++ if (__get_user_or_set_dar(regs, ptr0[i^sw], addr + i)) ++ return -EFAULT; ++ if (__get_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8)) ++ return -EFAULT; + } else { +- ret |= __put_user(ptr0[i^sw], addr + i); +- ret |= __put_user(ptr1[i^sw], addr + i + 8); ++ if (__put_user_or_set_dar(regs, ptr0[i^sw], addr + i)) ++ return -EFAULT; ++ if (__put_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8)) ++ return -EFAULT; + } + } +- if (ret) +- return -EFAULT; ++ + return 1; /* exception handled and fixed up */ + } + +@@ -377,24 +403,27 @@ static int emulate_lq_stq(struct pt_regs *regs, unsigned char __user *addr, + { + char *ptr0 = (char *)®s->gpr[reg]; + char *ptr1 = (char *)®s->gpr[reg+1]; +- int i, ret, sw = 0; ++ int i, sw = 0; + + if (reg & 1) + return 0; /* invalid form: GPR must be even */ + if (flags & SW) + sw = 7; +- ret = 0; ++ + for (i = 0; i < 8; ++i) { + if (!(flags & ST)) { +- ret |= __get_user(ptr0[i^sw], addr + i); +- ret |= __get_user(ptr1[i^sw], addr + i + 8); ++ if (__get_user_or_set_dar(regs, ptr0[i^sw], addr + i)) ++ return -EFAULT; ++ if (__get_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8)) ++ return -EFAULT; + } else { +- ret |= __put_user(ptr0[i^sw], addr + i); +- ret |= __put_user(ptr1[i^sw], addr + i + 8); ++ if (__put_user_or_set_dar(regs, ptr0[i^sw], addr + i)) ++ return -EFAULT; ++ if (__put_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8)) ++ return -EFAULT; + } + } +- if (ret) +- return -EFAULT; ++ + return 1; /* exception handled and fixed up */ + } + #endif /* CONFIG_PPC64 */ +@@ -687,9 +716,14 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg, + for (j = 0; j < length; j += elsize) { + for (i = 0; i < elsize; ++i) { + if (flags & ST) +- ret |= __put_user(ptr[i^sw], addr + i); ++ ret = __put_user_or_set_dar(regs, ptr[i^sw], ++ addr + i); + else +- ret |= __get_user(ptr[i^sw], addr + i); ++ ret = __get_user_or_set_dar(regs, ptr[i^sw], ++ addr + i); ++ ++ if (ret) ++ return ret; + } + ptr += elsize; + #ifdef __LITTLE_ENDIAN__ +@@ -739,7 +773,7 @@ int fix_alignment(struct pt_regs *regs) + unsigned int dsisr; + unsigned char __user *addr; + unsigned long p, swiz; +- int ret, i; ++ int i; + union data { + u64 ll; + double dd; +@@ -936,7 +970,7 @@ int fix_alignment(struct pt_regs *regs) + if (flags & F) { + /* Special case for 16-byte FP loads and stores */ + PPC_WARN_ALIGNMENT(fp_pair, regs); +- return emulate_fp_pair(addr, reg, flags); ++ return emulate_fp_pair(regs, addr, reg, flags); + } else { + #ifdef CONFIG_PPC64 + /* Special case for 16-byte loads and stores */ +@@ -966,15 +1000,12 @@ int fix_alignment(struct pt_regs *regs) + } + + data.ll = 0; +- ret = 0; + p = (unsigned long)addr; + + for (i = 0; i < nb; i++) +- ret |= __get_user_inatomic(data.v[start + i], +- SWIZ_PTR(p++)); +- +- if (unlikely(ret)) +- return -EFAULT; ++ if (__get_user_or_set_dar(regs, data.v[start + i], ++ SWIZ_PTR(p++))) ++ return -EFAULT; + + } else if (flags & F) { + data.ll = current->thread.TS_FPR(reg); +@@ -1046,15 +1077,13 @@ int fix_alignment(struct pt_regs *regs) + break; + } + +- ret = 0; + p = (unsigned long)addr; + + for (i = 0; i < nb; i++) +- ret |= __put_user_inatomic(data.v[start + i], +- SWIZ_PTR(p++)); ++ if (__put_user_or_set_dar(regs, data.v[start + i], ++ SWIZ_PTR(p++))) ++ return -EFAULT; + +- if (unlikely(ret)) +- return -EFAULT; + } else if (flags & F) + current->thread.TS_FPR(reg) = data.ll; + else +diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c +index 4c7b8591f737..2cb6cbea4b3b 100644 +--- a/arch/powerpc/platforms/powernv/npu-dma.c ++++ b/arch/powerpc/platforms/powernv/npu-dma.c +@@ -545,6 +545,12 @@ static void mmio_invalidate(struct npu_context *npu_context, int va, + struct mmio_atsd_reg mmio_atsd_reg[NV_MAX_NPUS]; + unsigned long pid = npu_context->mm->context.id; + ++ /* ++ * Unfortunately the nest mmu does not support flushing specific ++ * addresses so we have to flush the whole mm. ++ */ ++ flush_tlb_mm(npu_context->mm); ++ + /* + * Loop over all the NPUs this process is active on and launch + * an invalidate. +@@ -576,12 +582,6 @@ static void mmio_invalidate(struct npu_context *npu_context, int va, + } + } + +- /* +- * Unfortunately the nest mmu does not support flushing specific +- * addresses so we have to flush the whole mm. +- */ +- flush_tlb_mm(npu_context->mm); +- + mmio_invalidate_wait(mmio_atsd_reg, flush); + if (flush) + /* Wait for the flush to complete */ +diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c +index ca9b2f4aaa22..bf2f43f7ac6a 100644 +--- a/arch/powerpc/platforms/pseries/hotplug-memory.c ++++ b/arch/powerpc/platforms/pseries/hotplug-memory.c +@@ -817,6 +817,9 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add, struct property *prop) + return -EINVAL; + + for (i = 0; i < num_lmbs && lmbs_to_add != lmbs_added; i++) { ++ if (lmbs[i].flags & DRCONF_MEM_ASSIGNED) ++ continue; ++ + rc = dlpar_acquire_drc(lmbs[i].drc_index); + if (rc) + continue; +@@ -859,6 +862,7 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add, struct property *prop) + lmbs[i].base_addr, lmbs[i].drc_index); + lmbs[i].reserved = 0; + } ++ rc = 0; + } + + return rc; +diff --git a/arch/s390/include/asm/mmu.h b/arch/s390/include/asm/mmu.h +index bd6f30304518..3525fe6e7e4c 100644 +--- a/arch/s390/include/asm/mmu.h ++++ b/arch/s390/include/asm/mmu.h +@@ -5,6 +5,7 @@ + #include + + typedef struct { ++ spinlock_t lock; + cpumask_t cpu_attach_mask; + atomic_t flush_count; + unsigned int flush_mm; +@@ -27,6 +28,7 @@ typedef struct { + } mm_context_t; + + #define INIT_MM_CONTEXT(name) \ ++ .context.lock = __SPIN_LOCK_UNLOCKED(name.context.lock), \ + .context.pgtable_lock = \ + __SPIN_LOCK_UNLOCKED(name.context.pgtable_lock), \ + .context.pgtable_list = LIST_HEAD_INIT(name.context.pgtable_list), \ +diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h +index 24bc41622a98..ebfb2f248ae9 100644 +--- a/arch/s390/include/asm/mmu_context.h ++++ b/arch/s390/include/asm/mmu_context.h +@@ -16,6 +16,7 @@ + static inline int init_new_context(struct task_struct *tsk, + struct mm_struct *mm) + { ++ spin_lock_init(&mm->context.lock); + spin_lock_init(&mm->context.pgtable_lock); + INIT_LIST_HEAD(&mm->context.pgtable_list); + spin_lock_init(&mm->context.gmap_lock); +@@ -102,7 +103,6 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, + if (prev == next) + return; + cpumask_set_cpu(cpu, &next->context.cpu_attach_mask); +- cpumask_set_cpu(cpu, mm_cpumask(next)); + /* Clear old ASCE by loading the kernel ASCE. */ + __ctl_load(S390_lowcore.kernel_asce, 1, 1); + __ctl_load(S390_lowcore.kernel_asce, 7, 7); +@@ -120,9 +120,8 @@ static inline void finish_arch_post_lock_switch(void) + preempt_disable(); + while (atomic_read(&mm->context.flush_count)) + cpu_relax(); +- +- if (mm->context.flush_mm) +- __tlb_flush_mm(mm); ++ cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm)); ++ __tlb_flush_mm_lazy(mm); + preempt_enable(); + } + set_fs(current->thread.mm_segment); +@@ -135,6 +134,7 @@ static inline void activate_mm(struct mm_struct *prev, + struct mm_struct *next) + { + switch_mm(prev, next, current); ++ cpumask_set_cpu(smp_processor_id(), mm_cpumask(next)); + set_user_asce(next); + } + +diff --git a/arch/s390/include/asm/tlbflush.h b/arch/s390/include/asm/tlbflush.h +index 39846100682a..eed927aeb08f 100644 +--- a/arch/s390/include/asm/tlbflush.h ++++ b/arch/s390/include/asm/tlbflush.h +@@ -43,23 +43,6 @@ static inline void __tlb_flush_global(void) + * Flush TLB entries for a specific mm on all CPUs (in case gmap is used + * this implicates multiple ASCEs!). + */ +-static inline void __tlb_flush_full(struct mm_struct *mm) +-{ +- preempt_disable(); +- atomic_inc(&mm->context.flush_count); +- if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) { +- /* Local TLB flush */ +- __tlb_flush_local(); +- } else { +- /* Global TLB flush */ +- __tlb_flush_global(); +- /* Reset TLB flush mask */ +- cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask); +- } +- atomic_dec(&mm->context.flush_count); +- preempt_enable(); +-} +- + static inline void __tlb_flush_mm(struct mm_struct *mm) + { + unsigned long gmap_asce; +@@ -71,16 +54,18 @@ static inline void __tlb_flush_mm(struct mm_struct *mm) + */ + preempt_disable(); + atomic_inc(&mm->context.flush_count); ++ /* Reset TLB flush mask */ ++ cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask); ++ barrier(); + gmap_asce = READ_ONCE(mm->context.gmap_asce); + if (MACHINE_HAS_IDTE && gmap_asce != -1UL) { + if (gmap_asce) + __tlb_flush_idte(gmap_asce); + __tlb_flush_idte(mm->context.asce); + } else { +- __tlb_flush_full(mm); ++ /* Global TLB flush */ ++ __tlb_flush_global(); + } +- /* Reset TLB flush mask */ +- cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask); + atomic_dec(&mm->context.flush_count); + preempt_enable(); + } +@@ -94,7 +79,6 @@ static inline void __tlb_flush_kernel(void) + } + #else + #define __tlb_flush_global() __tlb_flush_local() +-#define __tlb_flush_full(mm) __tlb_flush_local() + + /* + * Flush TLB entries for a specific ASCE on all CPUs. +@@ -112,10 +96,12 @@ static inline void __tlb_flush_kernel(void) + + static inline void __tlb_flush_mm_lazy(struct mm_struct * mm) + { ++ spin_lock(&mm->context.lock); + if (mm->context.flush_mm) { +- __tlb_flush_mm(mm); + mm->context.flush_mm = 0; ++ __tlb_flush_mm(mm); + } ++ spin_unlock(&mm->context.lock); + } + + /* +diff --git a/block/blk-core.c b/block/blk-core.c +index dbecbf4a64e0..658f67309602 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -280,7 +280,7 @@ EXPORT_SYMBOL(blk_start_queue_async); + void blk_start_queue(struct request_queue *q) + { + lockdep_assert_held(q->queue_lock); +- WARN_ON(!irqs_disabled()); ++ WARN_ON(!in_interrupt() && !irqs_disabled()); + WARN_ON_ONCE(q->mq_ops); + + queue_flag_clear(QUEUE_FLAG_STOPPED, q); +@@ -2330,7 +2330,12 @@ blk_status_t blk_insert_cloned_request(struct request_queue *q, struct request * + if (q->mq_ops) { + if (blk_queue_io_stat(q)) + blk_account_io_start(rq, true); +- blk_mq_sched_insert_request(rq, false, true, false, false); ++ /* ++ * Since we have a scheduler attached on the top device, ++ * bypass a potential scheduler on the bottom device for ++ * insert. ++ */ ++ blk_mq_request_bypass_insert(rq); + return BLK_STS_OK; + } + +diff --git a/block/blk-mq.c b/block/blk-mq.c +index 4603b115e234..e0523eb8eee1 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -1357,6 +1357,22 @@ void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, + blk_mq_hctx_mark_pending(hctx, ctx); + } + ++/* ++ * Should only be used carefully, when the caller knows we want to ++ * bypass a potential IO scheduler on the target device. ++ */ ++void blk_mq_request_bypass_insert(struct request *rq) ++{ ++ struct blk_mq_ctx *ctx = rq->mq_ctx; ++ struct blk_mq_hw_ctx *hctx = blk_mq_map_queue(rq->q, ctx->cpu); ++ ++ spin_lock(&hctx->lock); ++ list_add_tail(&rq->queuelist, &hctx->dispatch); ++ spin_unlock(&hctx->lock); ++ ++ blk_mq_run_hw_queue(hctx, false); ++} ++ + void blk_mq_insert_requests(struct blk_mq_hw_ctx *hctx, struct blk_mq_ctx *ctx, + struct list_head *list) + +diff --git a/block/blk-mq.h b/block/blk-mq.h +index 60b01c0309bc..f64747914560 100644 +--- a/block/blk-mq.h ++++ b/block/blk-mq.h +@@ -54,6 +54,7 @@ int blk_mq_alloc_rqs(struct blk_mq_tag_set *set, struct blk_mq_tags *tags, + */ + void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, + bool at_head); ++void blk_mq_request_bypass_insert(struct request *rq); + void blk_mq_insert_requests(struct blk_mq_hw_ctx *hctx, struct blk_mq_ctx *ctx, + struct list_head *list); + +diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c +index 903605dbc1a5..76b875c69a95 100644 +--- a/crypto/algif_skcipher.c ++++ b/crypto/algif_skcipher.c +@@ -144,8 +144,10 @@ static int skcipher_alloc_sgl(struct sock *sk) + sg_init_table(sgl->sg, MAX_SGL_ENTS + 1); + sgl->cur = 0; + +- if (sg) ++ if (sg) { + sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg); ++ sg_unmark_end(sg + (MAX_SGL_ENTS - 1)); ++ } + + list_add_tail(&sgl->list, &ctx->tsgl); + } +diff --git a/crypto/scompress.c b/crypto/scompress.c +index ae1d3cf209e4..0b40d991d65f 100644 +--- a/crypto/scompress.c ++++ b/crypto/scompress.c +@@ -211,9 +211,7 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir) + scratch_dst, &req->dlen, *ctx); + if (!ret) { + if (!req->dst) { +- req->dst = crypto_scomp_sg_alloc(req->dlen, +- req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? +- GFP_KERNEL : GFP_ATOMIC); ++ req->dst = crypto_scomp_sg_alloc(req->dlen, GFP_ATOMIC); + if (!req->dst) + goto out; + } +diff --git a/drivers/block/skd_main.c b/drivers/block/skd_main.c +index d0368682bd43..153f20ce318b 100644 +--- a/drivers/block/skd_main.c ++++ b/drivers/block/skd_main.c +@@ -2160,6 +2160,9 @@ static void skd_send_fitmsg(struct skd_device *skdev, + */ + qcmd |= FIT_QCMD_MSGSIZE_64; + ++ /* Make sure skd_msg_buf is written before the doorbell is triggered. */ ++ smp_wmb(); ++ + SKD_WRITEQ(skdev, qcmd, FIT_Q_COMMAND); + } + +@@ -2202,6 +2205,9 @@ static void skd_send_special_fitmsg(struct skd_device *skdev, + qcmd = skspcl->mb_dma_address; + qcmd |= FIT_QCMD_QID_NORMAL + FIT_QCMD_MSGSIZE_128; + ++ /* Make sure skd_msg_buf is written before the doorbell is triggered. */ ++ smp_wmb(); ++ + SKD_WRITEQ(skdev, qcmd, FIT_Q_COMMAND); + } + +@@ -4539,15 +4545,16 @@ static void skd_free_disk(struct skd_device *skdev) + { + struct gendisk *disk = skdev->disk; + +- if (disk != NULL) { +- struct request_queue *q = disk->queue; ++ if (disk && (disk->flags & GENHD_FL_UP)) ++ del_gendisk(disk); + +- if (disk->flags & GENHD_FL_UP) +- del_gendisk(disk); +- if (q) +- blk_cleanup_queue(q); +- put_disk(disk); ++ if (skdev->queue) { ++ blk_cleanup_queue(skdev->queue); ++ skdev->queue = NULL; ++ disk->queue = NULL; + } ++ ++ put_disk(disk); + skdev->disk = NULL; + } + +diff --git a/drivers/crypto/caam/caamalg_qi.c b/drivers/crypto/caam/caamalg_qi.c +index 3425f2d9a2a1..fe0185ceac16 100644 +--- a/drivers/crypto/caam/caamalg_qi.c ++++ b/drivers/crypto/caam/caamalg_qi.c +@@ -776,9 +776,9 @@ static void ablkcipher_done(struct caam_drv_req *drv_req, u32 status) + struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); + struct caam_ctx *caam_ctx = crypto_ablkcipher_ctx(ablkcipher); + struct device *qidev = caam_ctx->qidev; +-#ifdef DEBUG + int ivsize = crypto_ablkcipher_ivsize(ablkcipher); + ++#ifdef DEBUG + dev_err(qidev, "%s %d: status 0x%x\n", __func__, __LINE__, status); + #endif + +@@ -799,6 +799,13 @@ static void ablkcipher_done(struct caam_drv_req *drv_req, u32 status) + ablkcipher_unmap(qidev, edesc, req); + qi_cache_free(edesc); + ++ /* ++ * The crypto API expects us to set the IV (req->info) to the last ++ * ciphertext block. This is used e.g. by the CTS mode. ++ */ ++ scatterwalk_map_and_copy(req->info, req->dst, req->nbytes - ivsize, ++ ivsize, 0); ++ + ablkcipher_request_complete(req, status); + } + +@@ -1968,7 +1975,7 @@ static struct caam_aead_alg driver_aeads[] = { + .cra_name = "echainiv(authenc(hmac(sha256)," + "cbc(des)))", + .cra_driver_name = "echainiv-authenc-" +- "hmac-sha256-cbc-desi-" ++ "hmac-sha256-cbc-des-" + "caam-qi", + .cra_blocksize = DES_BLOCK_SIZE, + }, +diff --git a/drivers/crypto/ccp/ccp-crypto-aes-xts.c b/drivers/crypto/ccp/ccp-crypto-aes-xts.c +index 58a4244b4752..3f26a415ef44 100644 +--- a/drivers/crypto/ccp/ccp-crypto-aes-xts.c ++++ b/drivers/crypto/ccp/ccp-crypto-aes-xts.c +@@ -1,8 +1,9 @@ + /* + * AMD Cryptographic Coprocessor (CCP) AES XTS crypto API support + * +- * Copyright (C) 2013 Advanced Micro Devices, Inc. ++ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc. + * ++ * Author: Gary R Hook + * Author: Tom Lendacky + * + * This program is free software; you can redistribute it and/or modify +@@ -164,6 +165,7 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request *req, + memset(&rctx->cmd, 0, sizeof(rctx->cmd)); + INIT_LIST_HEAD(&rctx->cmd.entry); + rctx->cmd.engine = CCP_ENGINE_XTS_AES_128; ++ rctx->cmd.u.xts.type = CCP_AES_TYPE_128; + rctx->cmd.u.xts.action = (encrypt) ? CCP_AES_ACTION_ENCRYPT + : CCP_AES_ACTION_DECRYPT; + rctx->cmd.u.xts.unit_size = unit_size; +diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c +index b10d2d2075cb..9bc134a4ebf0 100644 +--- a/drivers/crypto/ccp/ccp-dev-v5.c ++++ b/drivers/crypto/ccp/ccp-dev-v5.c +@@ -145,6 +145,7 @@ union ccp_function { + #define CCP_AES_MODE(p) ((p)->aes.mode) + #define CCP_AES_TYPE(p) ((p)->aes.type) + #define CCP_XTS_SIZE(p) ((p)->aes_xts.size) ++#define CCP_XTS_TYPE(p) ((p)->aes_xts.type) + #define CCP_XTS_ENCRYPT(p) ((p)->aes_xts.encrypt) + #define CCP_DES3_SIZE(p) ((p)->des3.size) + #define CCP_DES3_ENCRYPT(p) ((p)->des3.encrypt) +@@ -344,6 +345,7 @@ static int ccp5_perform_xts_aes(struct ccp_op *op) + CCP5_CMD_PROT(&desc) = 0; + + function.raw = 0; ++ CCP_XTS_TYPE(&function) = op->u.xts.type; + CCP_XTS_ENCRYPT(&function) = op->u.xts.action; + CCP_XTS_SIZE(&function) = op->u.xts.unit_size; + CCP5_CMD_FUNCTION(&desc) = function.raw; +diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h +index a70154ac7405..7b8370e9c42e 100644 +--- a/drivers/crypto/ccp/ccp-dev.h ++++ b/drivers/crypto/ccp/ccp-dev.h +@@ -192,6 +192,7 @@ + #define CCP_AES_CTX_SB_COUNT 1 + + #define CCP_XTS_AES_KEY_SB_COUNT 1 ++#define CCP5_XTS_AES_KEY_SB_COUNT 2 + #define CCP_XTS_AES_CTX_SB_COUNT 1 + + #define CCP_DES3_KEY_SB_COUNT 1 +@@ -497,6 +498,7 @@ struct ccp_aes_op { + }; + + struct ccp_xts_aes_op { ++ enum ccp_aes_type type; + enum ccp_aes_action action; + enum ccp_xts_aes_unit_size unit_size; + }; +diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c +index c0dfdacbdff5..f3542aede519 100644 +--- a/drivers/crypto/ccp/ccp-ops.c ++++ b/drivers/crypto/ccp/ccp-ops.c +@@ -1038,6 +1038,8 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue *cmd_q, + struct ccp_op op; + unsigned int unit_size, dm_offset; + bool in_place = false; ++ unsigned int sb_count; ++ enum ccp_aes_type aestype; + int ret; + + switch (xts->unit_size) { +@@ -1061,7 +1063,9 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue *cmd_q, + return -EINVAL; + } + +- if (xts->key_len != AES_KEYSIZE_128) ++ if (xts->key_len == AES_KEYSIZE_128) ++ aestype = CCP_AES_TYPE_128; ++ else + return -EINVAL; + + if (!xts->final && (xts->src_len & (AES_BLOCK_SIZE - 1))) +@@ -1083,23 +1087,44 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue *cmd_q, + op.sb_key = cmd_q->sb_key; + op.sb_ctx = cmd_q->sb_ctx; + op.init = 1; ++ op.u.xts.type = aestype; + op.u.xts.action = xts->action; + op.u.xts.unit_size = xts->unit_size; + +- /* All supported key sizes fit in a single (32-byte) SB entry +- * and must be in little endian format. Use the 256-bit byte +- * swap passthru option to convert from big endian to little +- * endian. ++ /* A version 3 device only supports 128-bit keys, which fits into a ++ * single SB entry. A version 5 device uses a 512-bit vector, so two ++ * SB entries. + */ ++ if (cmd_q->ccp->vdata->version == CCP_VERSION(3, 0)) ++ sb_count = CCP_XTS_AES_KEY_SB_COUNT; ++ else ++ sb_count = CCP5_XTS_AES_KEY_SB_COUNT; + ret = ccp_init_dm_workarea(&key, cmd_q, +- CCP_XTS_AES_KEY_SB_COUNT * CCP_SB_BYTES, ++ sb_count * CCP_SB_BYTES, + DMA_TO_DEVICE); + if (ret) + return ret; + +- dm_offset = CCP_SB_BYTES - AES_KEYSIZE_128; +- ccp_set_dm_area(&key, dm_offset, xts->key, 0, xts->key_len); +- ccp_set_dm_area(&key, 0, xts->key, dm_offset, xts->key_len); ++ if (cmd_q->ccp->vdata->version == CCP_VERSION(3, 0)) { ++ /* All supported key sizes must be in little endian format. ++ * Use the 256-bit byte swap passthru option to convert from ++ * big endian to little endian. ++ */ ++ dm_offset = CCP_SB_BYTES - AES_KEYSIZE_128; ++ ccp_set_dm_area(&key, dm_offset, xts->key, 0, xts->key_len); ++ ccp_set_dm_area(&key, 0, xts->key, xts->key_len, xts->key_len); ++ } else { ++ /* Version 5 CCPs use a 512-bit space for the key: each portion ++ * occupies 256 bits, or one entire slot, and is zero-padded. ++ */ ++ unsigned int pad; ++ ++ dm_offset = CCP_SB_BYTES; ++ pad = dm_offset - xts->key_len; ++ ccp_set_dm_area(&key, pad, xts->key, 0, xts->key_len); ++ ccp_set_dm_area(&key, dm_offset + pad, xts->key, xts->key_len, ++ xts->key_len); ++ } + ret = ccp_copy_to_sb(cmd_q, &key, op.jobid, op.sb_key, + CCP_PASSTHRU_BYTESWAP_256BIT); + if (ret) { +diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c +index dea04871b50d..a1c4ee818614 100644 +--- a/drivers/devfreq/devfreq.c ++++ b/drivers/devfreq/devfreq.c +@@ -564,7 +564,7 @@ struct devfreq *devfreq_add_device(struct device *dev, + err = device_register(&devfreq->dev); + if (err) { + mutex_unlock(&devfreq->lock); +- goto err_out; ++ goto err_dev; + } + + devfreq->trans_table = devm_kzalloc(&devfreq->dev, +@@ -610,6 +610,9 @@ struct devfreq *devfreq_add_device(struct device *dev, + mutex_unlock(&devfreq_list_lock); + + device_unregister(&devfreq->dev); ++err_dev: ++ if (devfreq) ++ kfree(devfreq); + err_out: + return ERR_PTR(err); + } +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +index 4083be61b328..6417febe18b9 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +@@ -95,9 +95,8 @@ int psp_wait_for(struct psp_context *psp, uint32_t reg_index, + int i; + struct amdgpu_device *adev = psp->adev; + +- val = RREG32(reg_index); +- + for (i = 0; i < adev->usec_timeout; i++) { ++ val = RREG32(reg_index); + if (check_changed) { + if (val != reg_val) + return 0; +diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c +index c98d77d0c8f8..6f80ad8f588b 100644 +--- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c ++++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c +@@ -237,11 +237,9 @@ int psp_v3_1_bootloader_load_sos(struct psp_context *psp) + + /* there might be handshake issue with hardware which needs delay */ + mdelay(20); +-#if 0 + ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_81), + RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81), + 0, true); +-#endif + + return ret; + } +diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c +index 4a11d4da4c92..ff30b34c8984 100644 +--- a/drivers/infiniband/hw/hfi1/init.c ++++ b/drivers/infiniband/hw/hfi1/init.c +@@ -483,7 +483,6 @@ void hfi1_init_pportdata(struct pci_dev *pdev, struct hfi1_pportdata *ppd, + + ppd->pkeys[default_pkey_idx] = DEFAULT_P_KEY; + ppd->part_enforce |= HFI1_PART_ENFORCE_IN; +- ppd->part_enforce |= HFI1_PART_ENFORCE_OUT; + + if (loopback) { + hfi1_early_err(&pdev->dev, +diff --git a/drivers/infiniband/hw/hfi1/rc.c b/drivers/infiniband/hw/hfi1/rc.c +index 1080778a1f7c..0c73fb0c2c1b 100644 +--- a/drivers/infiniband/hw/hfi1/rc.c ++++ b/drivers/infiniband/hw/hfi1/rc.c +@@ -425,7 +425,7 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) + case IB_WR_RDMA_WRITE: + if (newreq && !(qp->s_flags & RVT_S_UNLIMITED_CREDIT)) + qp->s_lsn++; +- /* FALLTHROUGH */ ++ goto no_flow_control; + case IB_WR_RDMA_WRITE_WITH_IMM: + /* If no credit, return. */ + if (!(qp->s_flags & RVT_S_UNLIMITED_CREDIT) && +@@ -433,6 +433,7 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) + qp->s_flags |= RVT_S_WAIT_SSN_CREDIT; + goto bail; + } ++no_flow_control: + put_ib_reth_vaddr( + wqe->rdma_wr.remote_addr, + &ohdr->u.rc.reth); +diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c +index 2c40a2e989d2..a0eb2f96179a 100644 +--- a/drivers/infiniband/hw/mlx5/mr.c ++++ b/drivers/infiniband/hw/mlx5/mr.c +@@ -48,6 +48,7 @@ enum { + #define MLX5_UMR_ALIGN 2048 + + static int clean_mr(struct mlx5_ib_mr *mr); ++static int max_umr_order(struct mlx5_ib_dev *dev); + static int use_umr(struct mlx5_ib_dev *dev, int order); + static int unreg_umr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr); + +@@ -491,16 +492,18 @@ static struct mlx5_ib_mr *alloc_cached_mr(struct mlx5_ib_dev *dev, int order) + struct mlx5_mr_cache *cache = &dev->cache; + struct mlx5_ib_mr *mr = NULL; + struct mlx5_cache_ent *ent; ++ int last_umr_cache_entry; + int c; + int i; + + c = order2idx(dev, order); +- if (c < 0 || c > MAX_UMR_CACHE_ENTRY) { ++ last_umr_cache_entry = order2idx(dev, max_umr_order(dev)); ++ if (c < 0 || c > last_umr_cache_entry) { + mlx5_ib_warn(dev, "order %d, cache index %d\n", order, c); + return NULL; + } + +- for (i = c; i < MAX_UMR_CACHE_ENTRY; i++) { ++ for (i = c; i <= last_umr_cache_entry; i++) { + ent = &cache->ent[i]; + + mlx5_ib_dbg(dev, "order %d, cache index %d\n", ent->order, i); +@@ -816,11 +819,16 @@ static int get_octo_len(u64 addr, u64 len, int page_size) + return (npages + 1) / 2; + } + +-static int use_umr(struct mlx5_ib_dev *dev, int order) ++static int max_umr_order(struct mlx5_ib_dev *dev) + { + if (MLX5_CAP_GEN(dev->mdev, umr_extended_translation_offset)) +- return order <= MAX_UMR_CACHE_ENTRY + 2; +- return order <= MLX5_MAX_UMR_SHIFT; ++ return MAX_UMR_CACHE_ENTRY + 2; ++ return MLX5_MAX_UMR_SHIFT; ++} ++ ++static int use_umr(struct mlx5_ib_dev *dev, int order) ++{ ++ return order <= max_umr_order(dev); + } + + static int mr_umem_get(struct ib_pd *pd, u64 start, u64 length, +diff --git a/drivers/infiniband/hw/qib/qib_rc.c b/drivers/infiniband/hw/qib/qib_rc.c +index 4ddbcac5eabe..e9a91736b12d 100644 +--- a/drivers/infiniband/hw/qib/qib_rc.c ++++ b/drivers/infiniband/hw/qib/qib_rc.c +@@ -348,7 +348,7 @@ int qib_make_rc_req(struct rvt_qp *qp, unsigned long *flags) + case IB_WR_RDMA_WRITE: + if (newreq && !(qp->s_flags & RVT_S_UNLIMITED_CREDIT)) + qp->s_lsn++; +- /* FALLTHROUGH */ ++ goto no_flow_control; + case IB_WR_RDMA_WRITE_WITH_IMM: + /* If no credit, return. */ + if (!(qp->s_flags & RVT_S_UNLIMITED_CREDIT) && +@@ -356,7 +356,7 @@ int qib_make_rc_req(struct rvt_qp *qp, unsigned long *flags) + qp->s_flags |= RVT_S_WAIT_SSN_CREDIT; + goto bail; + } +- ++no_flow_control: + ohdr->u.rc.reth.vaddr = + cpu_to_be64(wqe->rdma_wr.remote_addr); + ohdr->u.rc.reth.rkey = +diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c +index ca0e19ae7a90..f6d0c8f51613 100644 +--- a/drivers/input/joystick/xpad.c ++++ b/drivers/input/joystick/xpad.c +@@ -1764,10 +1764,12 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id + struct usb_endpoint_descriptor *ep = + &intf->cur_altsetting->endpoint[i].desc; + +- if (usb_endpoint_dir_in(ep)) +- ep_irq_in = ep; +- else +- ep_irq_out = ep; ++ if (usb_endpoint_xfer_int(ep)) { ++ if (usb_endpoint_dir_in(ep)) ++ ep_irq_in = ep; ++ else ++ ep_irq_out = ep; ++ } + } + + if (!ep_irq_in || !ep_irq_out) { +diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h +index f932a83b4990..9125ad017eda 100644 +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ b/drivers/input/serio/i8042-x86ia64io.h +@@ -839,6 +839,13 @@ static const struct dmi_system_id __initconst i8042_dmi_kbdreset_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "P34"), + }, + }, ++ { ++ /* Gigabyte P57 - Elantech touchpad */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "P57"), ++ }, ++ }, + { + /* Schenker XMG C504 - Elantech touchpad */ + .matches = { +diff --git a/drivers/mailbox/bcm-flexrm-mailbox.c b/drivers/mailbox/bcm-flexrm-mailbox.c +index da67882caa7b..0e298ed42ae0 100644 +--- a/drivers/mailbox/bcm-flexrm-mailbox.c ++++ b/drivers/mailbox/bcm-flexrm-mailbox.c +@@ -95,7 +95,7 @@ + + /* Register RING_CMPL_START_ADDR fields */ + #define CMPL_START_ADDR_VALUE(pa) \ +- ((u32)((((u64)(pa)) >> RING_CMPL_ALIGN_ORDER) & 0x03ffffff)) ++ ((u32)((((u64)(pa)) >> RING_CMPL_ALIGN_ORDER) & 0x07ffffff)) + + /* Register RING_CONTROL fields */ + #define CONTROL_MASK_DISABLE_CONTROL 12 +diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h +index dee542fff68e..2ed9bd231d84 100644 +--- a/drivers/md/bcache/bcache.h ++++ b/drivers/md/bcache/bcache.h +@@ -333,6 +333,7 @@ struct cached_dev { + /* Limit number of writeback bios in flight */ + struct semaphore in_flight; + struct task_struct *writeback_thread; ++ struct workqueue_struct *writeback_write_wq; + + struct keybuf writeback_keys; + +diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c +index 019b3df9f1c6..4b413db99276 100644 +--- a/drivers/md/bcache/request.c ++++ b/drivers/md/bcache/request.c +@@ -196,12 +196,12 @@ static void bch_data_insert_start(struct closure *cl) + struct data_insert_op *op = container_of(cl, struct data_insert_op, cl); + struct bio *bio = op->bio, *n; + +- if (atomic_sub_return(bio_sectors(bio), &op->c->sectors_to_gc) < 0) +- wake_up_gc(op->c); +- + if (op->bypass) + return bch_data_invalidate(cl); + ++ if (atomic_sub_return(bio_sectors(bio), &op->c->sectors_to_gc) < 0) ++ wake_up_gc(op->c); ++ + /* + * Journal writes are marked REQ_PREFLUSH; if the original write was a + * flush, it'll wait on the journal write. +@@ -400,12 +400,6 @@ static bool check_should_bypass(struct cached_dev *dc, struct bio *bio) + if (!congested && !dc->sequential_cutoff) + goto rescale; + +- if (!congested && +- mode == CACHE_MODE_WRITEBACK && +- op_is_write(bio->bi_opf) && +- op_is_sync(bio->bi_opf)) +- goto rescale; +- + spin_lock(&dc->io_lock); + + hlist_for_each_entry(i, iohash(dc, bio->bi_iter.bi_sector), hash) +diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c +index 8352fad765f6..046fc5bddf54 100644 +--- a/drivers/md/bcache/super.c ++++ b/drivers/md/bcache/super.c +@@ -1026,7 +1026,7 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c) + } + + if (BDEV_STATE(&dc->sb) == BDEV_STATE_DIRTY) { +- bch_sectors_dirty_init(dc); ++ bch_sectors_dirty_init(&dc->disk); + atomic_set(&dc->has_dirty, 1); + atomic_inc(&dc->count); + bch_writeback_queue(dc); +@@ -1059,6 +1059,8 @@ static void cached_dev_free(struct closure *cl) + cancel_delayed_work_sync(&dc->writeback_rate_update); + if (!IS_ERR_OR_NULL(dc->writeback_thread)) + kthread_stop(dc->writeback_thread); ++ if (dc->writeback_write_wq) ++ destroy_workqueue(dc->writeback_write_wq); + + mutex_lock(&bch_register_lock); + +@@ -1228,6 +1230,7 @@ static int flash_dev_run(struct cache_set *c, struct uuid_entry *u) + goto err; + + bcache_device_attach(d, c, u - c->uuids); ++ bch_sectors_dirty_init(d); + bch_flash_dev_request_init(d); + add_disk(d->disk); + +@@ -1964,6 +1967,8 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, + else + err = "device busy"; + mutex_unlock(&bch_register_lock); ++ if (!IS_ERR(bdev)) ++ bdput(bdev); + if (attr == &ksysfs_register_quiet) + goto out; + } +diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c +index f90f13616980..ab2f8ce1e3bc 100644 +--- a/drivers/md/bcache/sysfs.c ++++ b/drivers/md/bcache/sysfs.c +@@ -192,7 +192,7 @@ STORE(__cached_dev) + { + struct cached_dev *dc = container_of(kobj, struct cached_dev, + disk.kobj); +- unsigned v = size; ++ ssize_t v = size; + struct cache_set *c; + struct kobj_uevent_env *env; + +@@ -227,7 +227,7 @@ STORE(__cached_dev) + bch_cached_dev_run(dc); + + if (attr == &sysfs_cache_mode) { +- ssize_t v = bch_read_string_list(buf, bch_cache_modes + 1); ++ v = bch_read_string_list(buf, bch_cache_modes + 1); + + if (v < 0) + return v; +diff --git a/drivers/md/bcache/util.c b/drivers/md/bcache/util.c +index 8c3a938f4bf0..176d3c2ef5f5 100644 +--- a/drivers/md/bcache/util.c ++++ b/drivers/md/bcache/util.c +@@ -74,24 +74,44 @@ STRTO_H(strtouint, unsigned int) + STRTO_H(strtoll, long long) + STRTO_H(strtoull, unsigned long long) + ++/** ++ * bch_hprint() - formats @v to human readable string for sysfs. ++ * ++ * @v - signed 64 bit integer ++ * @buf - the (at least 8 byte) buffer to format the result into. ++ * ++ * Returns the number of bytes used by format. ++ */ + ssize_t bch_hprint(char *buf, int64_t v) + { + static const char units[] = "?kMGTPEZY"; +- char dec[4] = ""; +- int u, t = 0; +- +- for (u = 0; v >= 1024 || v <= -1024; u++) { +- t = v & ~(~0 << 10); +- v >>= 10; +- } +- +- if (!u) +- return sprintf(buf, "%llu", v); +- +- if (v < 100 && v > -100) +- snprintf(dec, sizeof(dec), ".%i", t / 100); +- +- return sprintf(buf, "%lli%s%c", v, dec, units[u]); ++ int u = 0, t; ++ ++ uint64_t q; ++ ++ if (v < 0) ++ q = -v; ++ else ++ q = v; ++ ++ /* For as long as the number is more than 3 digits, but at least ++ * once, shift right / divide by 1024. Keep the remainder for ++ * a digit after the decimal point. ++ */ ++ do { ++ u++; ++ ++ t = q & ~(~0 << 10); ++ q >>= 10; ++ } while (q >= 1000); ++ ++ if (v < 0) ++ /* '-', up to 3 digits, '.', 1 digit, 1 character, null; ++ * yields 8 bytes. ++ */ ++ return sprintf(buf, "-%llu.%i%c", q, t * 10 / 1024, units[u]); ++ else ++ return sprintf(buf, "%llu.%i%c", q, t * 10 / 1024, units[u]); + } + + ssize_t bch_snprint_string_list(char *buf, size_t size, const char * const list[], +diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c +index 42c66e76f05e..a635d6ac7fde 100644 +--- a/drivers/md/bcache/writeback.c ++++ b/drivers/md/bcache/writeback.c +@@ -21,7 +21,8 @@ + static void __update_writeback_rate(struct cached_dev *dc) + { + struct cache_set *c = dc->disk.c; +- uint64_t cache_sectors = c->nbuckets * c->sb.bucket_size; ++ uint64_t cache_sectors = c->nbuckets * c->sb.bucket_size - ++ bcache_flash_devs_sectors_dirty(c); + uint64_t cache_dirty_target = + div_u64(cache_sectors * dc->writeback_percent, 100); + +@@ -186,7 +187,7 @@ static void write_dirty(struct closure *cl) + + closure_bio_submit(&io->bio, cl); + +- continue_at(cl, write_dirty_finish, system_wq); ++ continue_at(cl, write_dirty_finish, io->dc->writeback_write_wq); + } + + static void read_dirty_endio(struct bio *bio) +@@ -206,7 +207,7 @@ static void read_dirty_submit(struct closure *cl) + + closure_bio_submit(&io->bio, cl); + +- continue_at(cl, write_dirty, system_wq); ++ continue_at(cl, write_dirty, io->dc->writeback_write_wq); + } + + static void read_dirty(struct cached_dev *dc) +@@ -482,17 +483,17 @@ static int sectors_dirty_init_fn(struct btree_op *_op, struct btree *b, + return MAP_CONTINUE; + } + +-void bch_sectors_dirty_init(struct cached_dev *dc) ++void bch_sectors_dirty_init(struct bcache_device *d) + { + struct sectors_dirty_init op; + + bch_btree_op_init(&op.op, -1); +- op.inode = dc->disk.id; ++ op.inode = d->id; + +- bch_btree_map_keys(&op.op, dc->disk.c, &KEY(op.inode, 0, 0), ++ bch_btree_map_keys(&op.op, d->c, &KEY(op.inode, 0, 0), + sectors_dirty_init_fn, 0); + +- dc->disk.sectors_dirty_last = bcache_dev_sectors_dirty(&dc->disk); ++ d->sectors_dirty_last = bcache_dev_sectors_dirty(d); + } + + void bch_cached_dev_writeback_init(struct cached_dev *dc) +@@ -516,6 +517,11 @@ void bch_cached_dev_writeback_init(struct cached_dev *dc) + + int bch_cached_dev_writeback_start(struct cached_dev *dc) + { ++ dc->writeback_write_wq = alloc_workqueue("bcache_writeback_wq", ++ WQ_MEM_RECLAIM, 0); ++ if (!dc->writeback_write_wq) ++ return -ENOMEM; ++ + dc->writeback_thread = kthread_create(bch_writeback_thread, dc, + "bcache_writeback"); + if (IS_ERR(dc->writeback_thread)) +diff --git a/drivers/md/bcache/writeback.h b/drivers/md/bcache/writeback.h +index 629bd1a502fd..e35421d20d2e 100644 +--- a/drivers/md/bcache/writeback.h ++++ b/drivers/md/bcache/writeback.h +@@ -14,6 +14,25 @@ static inline uint64_t bcache_dev_sectors_dirty(struct bcache_device *d) + return ret; + } + ++static inline uint64_t bcache_flash_devs_sectors_dirty(struct cache_set *c) ++{ ++ uint64_t i, ret = 0; ++ ++ mutex_lock(&bch_register_lock); ++ ++ for (i = 0; i < c->nr_uuids; i++) { ++ struct bcache_device *d = c->devices[i]; ++ ++ if (!d || !UUID_FLASH_ONLY(&c->uuids[i])) ++ continue; ++ ret += bcache_dev_sectors_dirty(d); ++ } ++ ++ mutex_unlock(&bch_register_lock); ++ ++ return ret; ++} ++ + static inline unsigned offset_to_stripe(struct bcache_device *d, + uint64_t offset) + { +@@ -84,7 +103,7 @@ static inline void bch_writeback_add(struct cached_dev *dc) + + void bcache_dev_sectors_dirty_add(struct cache_set *, unsigned, uint64_t, int); + +-void bch_sectors_dirty_init(struct cached_dev *dc); ++void bch_sectors_dirty_init(struct bcache_device *); + void bch_cached_dev_writeback_init(struct cached_dev *); + int bch_cached_dev_writeback_start(struct cached_dev *); + +diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c +index 40f3cd7eab0f..d2121637b4ab 100644 +--- a/drivers/md/bitmap.c ++++ b/drivers/md/bitmap.c +@@ -625,7 +625,7 @@ static int bitmap_read_sb(struct bitmap *bitmap) + err = read_sb_page(bitmap->mddev, + offset, + sb_page, +- 0, sizeof(bitmap_super_t)); ++ 0, PAGE_SIZE); + } + if (err) + return err; +@@ -2058,6 +2058,11 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks, + long pages; + struct bitmap_page *new_bp; + ++ if (bitmap->storage.file && !init) { ++ pr_info("md: cannot resize file-based bitmap\n"); ++ return -EINVAL; ++ } ++ + if (chunksize == 0) { + /* If there is enough space, leave the chunk size unchanged, + * else increase by factor of two until there is enough space. +@@ -2118,7 +2123,7 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks, + if (store.sb_page && bitmap->storage.sb_page) + memcpy(page_address(store.sb_page), + page_address(bitmap->storage.sb_page), +- sizeof(bitmap_super_t)); ++ PAGE_SIZE); + bitmap_file_unmap(&bitmap->storage); + bitmap->storage = store; + +diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c +index 78de7ddf5081..3df28f2f9b38 100644 +--- a/drivers/media/i2c/adv7180.c ++++ b/drivers/media/i2c/adv7180.c +@@ -1402,6 +1402,8 @@ static int adv7180_remove(struct i2c_client *client) + + static const struct i2c_device_id adv7180_id[] = { + { "adv7180", (kernel_ulong_t)&adv7180_info }, ++ { "adv7180cp", (kernel_ulong_t)&adv7180_info }, ++ { "adv7180st", (kernel_ulong_t)&adv7180_info }, + { "adv7182", (kernel_ulong_t)&adv7182_info }, + { "adv7280", (kernel_ulong_t)&adv7280_info }, + { "adv7280-m", (kernel_ulong_t)&adv7280_m_info }, +diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c +index 5f4434c0a8f1..2d6187904552 100644 +--- a/drivers/media/platform/qcom/venus/helpers.c ++++ b/drivers/media/platform/qcom/venus/helpers.c +@@ -243,7 +243,7 @@ static void return_buf_error(struct venus_inst *inst, + if (vbuf->vb2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + v4l2_m2m_src_buf_remove_by_buf(m2m_ctx, vbuf); + else +- v4l2_m2m_src_buf_remove_by_buf(m2m_ctx, vbuf); ++ v4l2_m2m_dst_buf_remove_by_buf(m2m_ctx, vbuf); + + v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); + } +diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c +index db1e7b70c998..9080e39ea391 100644 +--- a/drivers/media/rc/lirc_dev.c ++++ b/drivers/media/rc/lirc_dev.c +@@ -59,6 +59,8 @@ static void lirc_release(struct device *ld) + { + struct irctl *ir = container_of(ld, struct irctl, dev); + ++ put_device(ir->dev.parent); ++ + if (ir->buf_internal) { + lirc_buffer_free(ir->buf); + kfree(ir->buf); +@@ -218,6 +220,8 @@ int lirc_register_driver(struct lirc_driver *d) + + mutex_unlock(&lirc_dev_lock); + ++ get_device(ir->dev.parent); ++ + dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n", + ir->d.name, ir->d.minor); + +diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c +index c2ee6e39fd0c..20397aba6849 100644 +--- a/drivers/media/usb/uvc/uvc_ctrl.c ++++ b/drivers/media/usb/uvc/uvc_ctrl.c +@@ -2002,6 +2002,13 @@ int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, + goto done; + } + ++ /* Validate the user-provided bit-size and offset */ ++ if (mapping->size > 32 || ++ mapping->offset + mapping->size > ctrl->info.size * 8) { ++ ret = -EINVAL; ++ goto done; ++ } ++ + list_for_each_entry(map, &ctrl->info.mappings, list) { + if (mapping->id == map->id) { + uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', " +diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +index 6f52970f8b54..0c14e995667c 100644 +--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c ++++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +@@ -796,7 +796,8 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u + copy_to_user(&up->u, &kp->u, sizeof(kp->u)) || + put_user(kp->pending, &up->pending) || + put_user(kp->sequence, &up->sequence) || +- compat_put_timespec(&kp->timestamp, &up->timestamp) || ++ put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) || ++ put_user(kp->timestamp.tv_nsec, &up->timestamp.tv_nsec) || + put_user(kp->id, &up->id) || + copy_to_user(up->reserved, kp->reserved, 8 * sizeof(__u32))) + return -EFAULT; +diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c +index 1a138c83f877..a0c44d16bf30 100644 +--- a/drivers/misc/cxl/api.c ++++ b/drivers/misc/cxl/api.c +@@ -336,6 +336,10 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed, + mmput(ctx->mm); + } + ++ /* ++ * Increment driver use count. Enables global TLBIs for hash ++ * and callbacks to handle the segment table ++ */ + cxl_ctx_get(); + + if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) { +diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c +index 0761271d68c5..4bfad9f6dc9f 100644 +--- a/drivers/misc/cxl/file.c ++++ b/drivers/misc/cxl/file.c +@@ -95,7 +95,6 @@ static int __afu_open(struct inode *inode, struct file *file, bool master) + + pr_devel("afu_open pe: %i\n", ctx->pe); + file->private_data = ctx; +- cxl_ctx_get(); + + /* indicate success */ + rc = 0; +@@ -225,6 +224,12 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, + if (ctx->mm) + mmput(ctx->mm); + ++ /* ++ * Increment driver use count. Enables global TLBIs for hash ++ * and callbacks to handle the segment table ++ */ ++ cxl_ctx_get(); ++ + trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr); + + if ((rc = cxl_ops->attach_process(ctx, false, work.work_element_descriptor, +@@ -233,6 +238,7 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, + cxl_adapter_context_put(ctx->afu->adapter); + put_pid(ctx->pid); + ctx->pid = NULL; ++ cxl_ctx_put(); + cxl_context_mm_count_put(ctx); + goto out; + } +diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c +index 517a315e259b..35bd50bcbbd5 100644 +--- a/drivers/net/wireless/ath/wcn36xx/main.c ++++ b/drivers/net/wireless/ath/wcn36xx/main.c +@@ -372,6 +372,8 @@ static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed) + + wcn36xx_dbg(WCN36XX_DBG_MAC, "mac config changed 0x%08x\n", changed); + ++ mutex_lock(&wcn->conf_mutex); ++ + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + int ch = WCN36XX_HW_CHANNEL(wcn); + wcn36xx_dbg(WCN36XX_DBG_MAC, "wcn36xx_config channel switch=%d\n", +@@ -382,6 +384,8 @@ static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed) + } + } + ++ mutex_unlock(&wcn->conf_mutex); ++ + return 0; + } + +@@ -396,6 +400,8 @@ static void wcn36xx_configure_filter(struct ieee80211_hw *hw, + + wcn36xx_dbg(WCN36XX_DBG_MAC, "mac configure filter\n"); + ++ mutex_lock(&wcn->conf_mutex); ++ + *total &= FIF_ALLMULTI; + + fp = (void *)(unsigned long)multicast; +@@ -408,6 +414,8 @@ static void wcn36xx_configure_filter(struct ieee80211_hw *hw, + else if (NL80211_IFTYPE_STATION == vif->type && tmp->sta_assoc) + wcn36xx_smd_set_mc_list(wcn, vif, fp); + } ++ ++ mutex_unlock(&wcn->conf_mutex); + kfree(fp); + } + +@@ -471,6 +479,8 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + key_conf->key, + key_conf->keylen); + ++ mutex_lock(&wcn->conf_mutex); ++ + switch (key_conf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + vif_priv->encrypt_type = WCN36XX_HAL_ED_WEP40; +@@ -565,6 +575,8 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + } + + out: ++ mutex_unlock(&wcn->conf_mutex); ++ + return ret; + } + +@@ -725,6 +737,8 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, + wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss info changed vif %p changed 0x%08x\n", + vif, changed); + ++ mutex_lock(&wcn->conf_mutex); ++ + if (changed & BSS_CHANGED_BEACON_INFO) { + wcn36xx_dbg(WCN36XX_DBG_MAC, + "mac bss changed dtim period %d\n", +@@ -787,7 +801,13 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, + bss_conf->aid); + + vif_priv->sta_assoc = true; +- rcu_read_lock(); ++ ++ /* ++ * Holding conf_mutex ensures mutal exclusion with ++ * wcn36xx_sta_remove() and as such ensures that sta ++ * won't be freed while we're operating on it. As such ++ * we do not need to hold the rcu_read_lock(). ++ */ + sta = ieee80211_find_sta(vif, bss_conf->bssid); + if (!sta) { + wcn36xx_err("sta %pM is not found\n", +@@ -811,7 +831,6 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, + * place where AID is available. + */ + wcn36xx_smd_config_sta(wcn, vif, sta); +- rcu_read_unlock(); + } else { + wcn36xx_dbg(WCN36XX_DBG_MAC, + "disassociated bss %pM vif %pM AID=%d\n", +@@ -873,6 +892,9 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, + } + } + out: ++ ++ mutex_unlock(&wcn->conf_mutex); ++ + return; + } + +@@ -882,7 +904,10 @@ static int wcn36xx_set_rts_threshold(struct ieee80211_hw *hw, u32 value) + struct wcn36xx *wcn = hw->priv; + wcn36xx_dbg(WCN36XX_DBG_MAC, "mac set RTS threshold %d\n", value); + ++ mutex_lock(&wcn->conf_mutex); + wcn36xx_smd_update_cfg(wcn, WCN36XX_HAL_CFG_RTS_THRESHOLD, value); ++ mutex_unlock(&wcn->conf_mutex); ++ + return 0; + } + +@@ -893,8 +918,12 @@ static void wcn36xx_remove_interface(struct ieee80211_hw *hw, + struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); + wcn36xx_dbg(WCN36XX_DBG_MAC, "mac remove interface vif %p\n", vif); + ++ mutex_lock(&wcn->conf_mutex); ++ + list_del(&vif_priv->list); + wcn36xx_smd_delete_sta_self(wcn, vif->addr); ++ ++ mutex_unlock(&wcn->conf_mutex); + } + + static int wcn36xx_add_interface(struct ieee80211_hw *hw, +@@ -915,9 +944,13 @@ static int wcn36xx_add_interface(struct ieee80211_hw *hw, + return -EOPNOTSUPP; + } + ++ mutex_lock(&wcn->conf_mutex); ++ + list_add(&vif_priv->list, &wcn->vif_list); + wcn36xx_smd_add_sta_self(wcn, vif); + ++ mutex_unlock(&wcn->conf_mutex); ++ + return 0; + } + +@@ -930,6 +963,8 @@ static int wcn36xx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta add vif %p sta %pM\n", + vif, sta->addr); + ++ mutex_lock(&wcn->conf_mutex); ++ + spin_lock_init(&sta_priv->ampdu_lock); + sta_priv->vif = vif_priv; + /* +@@ -941,6 +976,9 @@ static int wcn36xx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + sta_priv->aid = sta->aid; + wcn36xx_smd_config_sta(wcn, vif, sta); + } ++ ++ mutex_unlock(&wcn->conf_mutex); ++ + return 0; + } + +@@ -954,8 +992,13 @@ static int wcn36xx_sta_remove(struct ieee80211_hw *hw, + wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta remove vif %p sta %pM index %d\n", + vif, sta->addr, sta_priv->sta_index); + ++ mutex_lock(&wcn->conf_mutex); ++ + wcn36xx_smd_delete_sta(wcn, sta_priv->sta_index); + sta_priv->vif = NULL; ++ ++ mutex_unlock(&wcn->conf_mutex); ++ + return 0; + } + +@@ -999,6 +1042,8 @@ static int wcn36xx_ampdu_action(struct ieee80211_hw *hw, + wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu action action %d tid %d\n", + action, tid); + ++ mutex_lock(&wcn->conf_mutex); ++ + switch (action) { + case IEEE80211_AMPDU_RX_START: + sta_priv->tid = tid; +@@ -1038,6 +1083,8 @@ static int wcn36xx_ampdu_action(struct ieee80211_hw *hw, + wcn36xx_err("Unknown AMPDU action\n"); + } + ++ mutex_unlock(&wcn->conf_mutex); ++ + return 0; + } + +@@ -1216,6 +1263,7 @@ static int wcn36xx_probe(struct platform_device *pdev) + wcn = hw->priv; + wcn->hw = hw; + wcn->dev = &pdev->dev; ++ mutex_init(&wcn->conf_mutex); + mutex_init(&wcn->hal_mutex); + mutex_init(&wcn->scan_lock); + +diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h +index b52b4da9a967..6aefba4c0cda 100644 +--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h ++++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h +@@ -202,6 +202,9 @@ struct wcn36xx { + struct qcom_smem_state *tx_rings_empty_state; + unsigned tx_rings_empty_state_bit; + ++ /* prevents concurrent FW reconfiguration */ ++ struct mutex conf_mutex; ++ + /* + * smd_buf must be protected with smd_mutex to garantee + * that all messages are sent one after another +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +index 3ee6767392b6..d25bad052d78 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +@@ -79,6 +79,7 @@ + /* NVM offsets (in words) definitions */ + enum wkp_nvm_offsets { + /* NVM HW-Section offset (in words) definitions */ ++ SUBSYSTEM_ID = 0x0A, + HW_ADDR = 0x15, + + /* NVM SW-Section offset (in words) definitions */ +@@ -254,13 +255,12 @@ static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz, + static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, + struct iwl_nvm_data *data, + const __le16 * const nvm_ch_flags, +- bool lar_supported) ++ bool lar_supported, bool no_wide_in_5ghz) + { + int ch_idx; + int n_channels = 0; + struct ieee80211_channel *channel; + u16 ch_flags; +- bool is_5ghz; + int num_of_ch, num_2ghz_channels; + const u8 *nvm_chan; + +@@ -275,12 +275,20 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, + } + + for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) { ++ bool is_5ghz = (ch_idx >= num_2ghz_channels); ++ + ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx); + +- if (ch_idx >= num_2ghz_channels && +- !data->sku_cap_band_52GHz_enable) ++ if (is_5ghz && !data->sku_cap_band_52GHz_enable) + continue; + ++ /* workaround to disable wide channels in 5GHz */ ++ if (no_wide_in_5ghz && is_5ghz) { ++ ch_flags &= ~(NVM_CHANNEL_40MHZ | ++ NVM_CHANNEL_80MHZ | ++ NVM_CHANNEL_160MHZ); ++ } ++ + if (ch_flags & NVM_CHANNEL_160MHZ) + data->vht160_supported = true; + +@@ -303,8 +311,8 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, + n_channels++; + + channel->hw_value = nvm_chan[ch_idx]; +- channel->band = (ch_idx < num_2ghz_channels) ? +- NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; ++ channel->band = is_5ghz ? ++ NL80211_BAND_5GHZ : NL80211_BAND_2GHZ; + channel->center_freq = + ieee80211_channel_to_frequency( + channel->hw_value, channel->band); +@@ -316,7 +324,6 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, + * is not used in mvm, and is used for backwards compatibility + */ + channel->max_power = IWL_DEFAULT_MAX_TX_POWER; +- is_5ghz = channel->band == NL80211_BAND_5GHZ; + + /* don't put limitations in case we're using LAR */ + if (!lar_supported) +@@ -432,14 +439,15 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg, + + void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, + struct iwl_nvm_data *data, const __le16 *nvm_ch_flags, +- u8 tx_chains, u8 rx_chains, bool lar_supported) ++ u8 tx_chains, u8 rx_chains, bool lar_supported, ++ bool no_wide_in_5ghz) + { + int n_channels; + int n_used = 0; + struct ieee80211_supported_band *sband; + + n_channels = iwl_init_channel_map(dev, cfg, data, nvm_ch_flags, +- lar_supported); ++ lar_supported, no_wide_in_5ghz); + sband = &data->bands[NL80211_BAND_2GHZ]; + sband->band = NL80211_BAND_2GHZ; + sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS]; +@@ -645,6 +653,39 @@ static int iwl_set_hw_address(struct iwl_trans *trans, + return 0; + } + ++static bool ++iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg, ++ const __le16 *nvm_hw) ++{ ++ /* ++ * Workaround a bug in Indonesia SKUs where the regulatory in ++ * some 7000-family OTPs erroneously allow wide channels in ++ * 5GHz. To check for Indonesia, we take the SKU value from ++ * bits 1-4 in the subsystem ID and check if it is either 5 or ++ * 9. In those cases, we need to force-disable wide channels ++ * in 5GHz otherwise the FW will throw a sysassert when we try ++ * to use them. ++ */ ++ if (cfg->device_family == IWL_DEVICE_FAMILY_7000) { ++ /* ++ * Unlike the other sections in the NVM, the hw ++ * section uses big-endian. ++ */ ++ u16 subsystem_id = be16_to_cpup((const __be16 *)nvm_hw ++ + SUBSYSTEM_ID); ++ u8 sku = (subsystem_id & 0x1e) >> 1; ++ ++ if (sku == 5 || sku == 9) { ++ IWL_DEBUG_EEPROM(dev, ++ "disabling wide channels in 5GHz (0x%0x %d)\n", ++ subsystem_id, sku); ++ return true; ++ } ++ } ++ ++ return false; ++} ++ + struct iwl_nvm_data * + iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, + const __le16 *nvm_hw, const __le16 *nvm_sw, +@@ -655,6 +696,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, + struct device *dev = trans->dev; + struct iwl_nvm_data *data; + bool lar_enabled; ++ bool no_wide_in_5ghz = iwl_nvm_no_wide_in_5ghz(dev, cfg, nvm_hw); + u32 sku, radio_cfg; + u16 lar_config; + const __le16 *ch_section; +@@ -725,7 +767,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, + } + + iwl_init_sbands(dev, cfg, data, ch_section, tx_chains, rx_chains, +- lar_fw_supported && lar_enabled); ++ lar_fw_supported && lar_enabled, no_wide_in_5ghz); + data->calib_version = 255; + + return data; +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h +index 3fd6506a02ab..50d9b3eaa4f8 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h +@@ -93,7 +93,8 @@ void iwl_set_hw_address_from_csr(struct iwl_trans *trans, + */ + void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, + struct iwl_nvm_data *data, const __le16 *nvm_ch_flags, +- u8 tx_chains, u8 rx_chains, bool lar_supported); ++ u8 tx_chains, u8 rx_chains, bool lar_supported, ++ bool no_wide_in_5ghz); + + /** + * iwl_parse_mcc_info - parse MCC (mobile country code) info coming from FW +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +index dac7e542a190..4de565cec747 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +@@ -628,7 +628,8 @@ int iwl_mvm_nvm_get_from_fw(struct iwl_mvm *mvm) + rsp->regulatory.channel_profile, + mvm->nvm_data->valid_tx_ant & mvm->fw->valid_tx_ant, + mvm->nvm_data->valid_rx_ant & mvm->fw->valid_rx_ant, +- rsp->regulatory.lar_enabled && lar_fw_supported); ++ rsp->regulatory.lar_enabled && lar_fw_supported, ++ false); + + iwl_free_resp(&hcmd); + return 0; +diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c +index 026830a138ae..e5d5ce9e3010 100644 +--- a/drivers/pci/hotplug/pciehp_hpc.c ++++ b/drivers/pci/hotplug/pciehp_hpc.c +@@ -586,6 +586,14 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id) + events = status & (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | + PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_CC | + PCI_EXP_SLTSTA_DLLSC); ++ ++ /* ++ * If we've already reported a power fault, don't report it again ++ * until we've done something to handle it. ++ */ ++ if (ctrl->power_fault_detected) ++ events &= ~PCI_EXP_SLTSTA_PFD; ++ + if (!events) + return IRQ_NONE; + +diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c +index de0ea474fb73..e5824c7b7b6b 100644 +--- a/drivers/pci/hotplug/shpchp_hpc.c ++++ b/drivers/pci/hotplug/shpchp_hpc.c +@@ -1062,6 +1062,8 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) + if (rc) { + ctrl_info(ctrl, "Can't get msi for the hotplug controller\n"); + ctrl_info(ctrl, "Use INTx for the hotplug controller\n"); ++ } else { ++ pci_set_master(pdev); + } + + rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED, +diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c +index e6779d4352a2..7c30fd986560 100644 +--- a/drivers/pinctrl/pinctrl-amd.c ++++ b/drivers/pinctrl/pinctrl-amd.c +@@ -36,6 +36,7 @@ + #include + #include + ++#include "core.h" + #include "pinctrl-utils.h" + #include "pinctrl-amd.h" + +@@ -725,6 +726,69 @@ static const struct pinconf_ops amd_pinconf_ops = { + .pin_config_group_set = amd_pinconf_group_set, + }; + ++#ifdef CONFIG_PM_SLEEP ++static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin) ++{ ++ const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin); ++ ++ if (!pd) ++ return false; ++ ++ /* ++ * Only restore the pin if it is actually in use by the kernel (or ++ * by userspace). ++ */ ++ if (pd->mux_owner || pd->gpio_owner || ++ gpiochip_line_is_irq(&gpio_dev->gc, pin)) ++ return true; ++ ++ return false; ++} ++ ++int amd_gpio_suspend(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct amd_gpio *gpio_dev = platform_get_drvdata(pdev); ++ struct pinctrl_desc *desc = gpio_dev->pctrl->desc; ++ int i; ++ ++ for (i = 0; i < desc->npins; i++) { ++ int pin = desc->pins[i].number; ++ ++ if (!amd_gpio_should_save(gpio_dev, pin)) ++ continue; ++ ++ gpio_dev->saved_regs[i] = readl(gpio_dev->base + pin*4); ++ } ++ ++ return 0; ++} ++ ++int amd_gpio_resume(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct amd_gpio *gpio_dev = platform_get_drvdata(pdev); ++ struct pinctrl_desc *desc = gpio_dev->pctrl->desc; ++ int i; ++ ++ for (i = 0; i < desc->npins; i++) { ++ int pin = desc->pins[i].number; ++ ++ if (!amd_gpio_should_save(gpio_dev, pin)) ++ continue; ++ ++ writel(gpio_dev->saved_regs[i], gpio_dev->base + pin*4); ++ } ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops amd_gpio_pm_ops = { ++ SET_LATE_SYSTEM_SLEEP_PM_OPS(amd_gpio_suspend, ++ amd_gpio_resume) ++}; ++#endif ++ + static struct pinctrl_desc amd_pinctrl_desc = { + .pins = kerncz_pins, + .npins = ARRAY_SIZE(kerncz_pins), +@@ -764,6 +828,14 @@ static int amd_gpio_probe(struct platform_device *pdev) + return -EINVAL; + } + ++#ifdef CONFIG_PM_SLEEP ++ gpio_dev->saved_regs = devm_kcalloc(&pdev->dev, amd_pinctrl_desc.npins, ++ sizeof(*gpio_dev->saved_regs), ++ GFP_KERNEL); ++ if (!gpio_dev->saved_regs) ++ return -ENOMEM; ++#endif ++ + gpio_dev->pdev = pdev; + gpio_dev->gc.direction_input = amd_gpio_direction_input; + gpio_dev->gc.direction_output = amd_gpio_direction_output; +@@ -853,6 +925,9 @@ static struct platform_driver amd_gpio_driver = { + .driver = { + .name = "amd_gpio", + .acpi_match_table = ACPI_PTR(amd_gpio_acpi_match), ++#ifdef CONFIG_PM_SLEEP ++ .pm = &amd_gpio_pm_ops, ++#endif + }, + .probe = amd_gpio_probe, + .remove = amd_gpio_remove, +diff --git a/drivers/pinctrl/pinctrl-amd.h b/drivers/pinctrl/pinctrl-amd.h +index 5b1cb965c767..8fa453a59da5 100644 +--- a/drivers/pinctrl/pinctrl-amd.h ++++ b/drivers/pinctrl/pinctrl-amd.h +@@ -97,6 +97,7 @@ struct amd_gpio { + unsigned int hwbank_num; + struct resource *res; + struct platform_device *pdev; ++ u32 *saved_regs; + }; + + /* KERNCZ configuration*/ +diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c +index 731530a9ce38..9ab8faf528a6 100644 +--- a/drivers/pinctrl/samsung/pinctrl-exynos.c ++++ b/drivers/pinctrl/samsung/pinctrl-exynos.c +@@ -174,10 +174,10 @@ static int exynos_irq_request_resources(struct irq_data *irqd) + + spin_lock_irqsave(&bank->slock, flags); + +- con = readl(bank->eint_base + reg_con); ++ con = readl(bank->pctl_base + reg_con); + con &= ~(mask << shift); + con |= EXYNOS_EINT_FUNC << shift; +- writel(con, bank->eint_base + reg_con); ++ writel(con, bank->pctl_base + reg_con); + + spin_unlock_irqrestore(&bank->slock, flags); + +@@ -202,10 +202,10 @@ static void exynos_irq_release_resources(struct irq_data *irqd) + + spin_lock_irqsave(&bank->slock, flags); + +- con = readl(bank->eint_base + reg_con); ++ con = readl(bank->pctl_base + reg_con); + con &= ~(mask << shift); + con |= FUNC_INPUT << shift; +- writel(con, bank->eint_base + reg_con); ++ writel(con, bank->pctl_base + reg_con); + + spin_unlock_irqrestore(&bank->slock, flags); + +diff --git a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c +index 49774851e84a..edf27264b603 100644 +--- a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c ++++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c +@@ -151,7 +151,7 @@ static void s3c24xx_eint_set_function(struct samsung_pinctrl_drv_data *d, + u32 val; + + /* Make sure that pin is configured as interrupt */ +- reg = bank->pctl_base + bank->pctl_offset; ++ reg = d->virt_base + bank->pctl_offset; + shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC]; + mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; + +@@ -184,7 +184,7 @@ static int s3c24xx_eint_type(struct irq_data *data, unsigned int type) + s3c24xx_eint_set_handler(data, type); + + /* Set up interrupt trigger */ +- reg = bank->eint_base + EINT_REG(index); ++ reg = d->virt_base + EINT_REG(index); + shift = EINT_OFFS(index); + + val = readl(reg); +@@ -259,29 +259,32 @@ static void s3c2410_demux_eint0_3(struct irq_desc *desc) + static void s3c2412_eint0_3_ack(struct irq_data *data) + { + struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); ++ struct samsung_pinctrl_drv_data *d = bank->drvdata; + + unsigned long bitval = 1UL << data->hwirq; +- writel(bitval, bank->eint_base + EINTPEND_REG); ++ writel(bitval, d->virt_base + EINTPEND_REG); + } + + static void s3c2412_eint0_3_mask(struct irq_data *data) + { + struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); ++ struct samsung_pinctrl_drv_data *d = bank->drvdata; + unsigned long mask; + +- mask = readl(bank->eint_base + EINTMASK_REG); ++ mask = readl(d->virt_base + EINTMASK_REG); + mask |= (1UL << data->hwirq); +- writel(mask, bank->eint_base + EINTMASK_REG); ++ writel(mask, d->virt_base + EINTMASK_REG); + } + + static void s3c2412_eint0_3_unmask(struct irq_data *data) + { + struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); ++ struct samsung_pinctrl_drv_data *d = bank->drvdata; + unsigned long mask; + +- mask = readl(bank->eint_base + EINTMASK_REG); ++ mask = readl(d->virt_base + EINTMASK_REG); + mask &= ~(1UL << data->hwirq); +- writel(mask, bank->eint_base + EINTMASK_REG); ++ writel(mask, d->virt_base + EINTMASK_REG); + } + + static struct irq_chip s3c2412_eint0_3_chip = { +@@ -316,31 +319,34 @@ static void s3c2412_demux_eint0_3(struct irq_desc *desc) + static void s3c24xx_eint_ack(struct irq_data *data) + { + struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); ++ struct samsung_pinctrl_drv_data *d = bank->drvdata; + unsigned char index = bank->eint_offset + data->hwirq; + +- writel(1UL << index, bank->eint_base + EINTPEND_REG); ++ writel(1UL << index, d->virt_base + EINTPEND_REG); + } + + static void s3c24xx_eint_mask(struct irq_data *data) + { + struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); ++ struct samsung_pinctrl_drv_data *d = bank->drvdata; + unsigned char index = bank->eint_offset + data->hwirq; + unsigned long mask; + +- mask = readl(bank->eint_base + EINTMASK_REG); ++ mask = readl(d->virt_base + EINTMASK_REG); + mask |= (1UL << index); +- writel(mask, bank->eint_base + EINTMASK_REG); ++ writel(mask, d->virt_base + EINTMASK_REG); + } + + static void s3c24xx_eint_unmask(struct irq_data *data) + { + struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); ++ struct samsung_pinctrl_drv_data *d = bank->drvdata; + unsigned char index = bank->eint_offset + data->hwirq; + unsigned long mask; + +- mask = readl(bank->eint_base + EINTMASK_REG); ++ mask = readl(d->virt_base + EINTMASK_REG); + mask &= ~(1UL << index); +- writel(mask, bank->eint_base + EINTMASK_REG); ++ writel(mask, d->virt_base + EINTMASK_REG); + } + + static struct irq_chip s3c24xx_eint_chip = { +@@ -356,14 +362,13 @@ static inline void s3c24xx_demux_eint(struct irq_desc *desc, + { + struct s3c24xx_eint_data *data = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); +- struct irq_data *irqd = irq_desc_get_irq_data(desc); +- struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); ++ struct samsung_pinctrl_drv_data *d = data->drvdata; + unsigned int pend, mask; + + chained_irq_enter(chip, desc); + +- pend = readl(bank->eint_base + EINTPEND_REG); +- mask = readl(bank->eint_base + EINTMASK_REG); ++ pend = readl(d->virt_base + EINTPEND_REG); ++ mask = readl(d->virt_base + EINTMASK_REG); + + pend &= ~mask; + pend &= range; +diff --git a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c +index 4a88d7446e87..e63663b32907 100644 +--- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c ++++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c +@@ -280,7 +280,7 @@ static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d, + u32 val; + + /* Make sure that pin is configured as interrupt */ +- reg = bank->pctl_base + bank->pctl_offset; ++ reg = d->virt_base + bank->pctl_offset; + shift = pin; + if (bank_type->fld_width[PINCFG_TYPE_FUNC] * shift >= 32) { + /* 4-bit bank type with 2 con regs */ +@@ -308,8 +308,9 @@ static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d, + static inline void s3c64xx_gpio_irq_set_mask(struct irq_data *irqd, bool mask) + { + struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); ++ struct samsung_pinctrl_drv_data *d = bank->drvdata; + unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq; +- void __iomem *reg = bank->eint_base + EINTMASK_REG(bank->eint_offset); ++ void __iomem *reg = d->virt_base + EINTMASK_REG(bank->eint_offset); + u32 val; + + val = readl(reg); +@@ -333,8 +334,9 @@ static void s3c64xx_gpio_irq_mask(struct irq_data *irqd) + static void s3c64xx_gpio_irq_ack(struct irq_data *irqd) + { + struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); ++ struct samsung_pinctrl_drv_data *d = bank->drvdata; + unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq; +- void __iomem *reg = bank->eint_base + EINTPEND_REG(bank->eint_offset); ++ void __iomem *reg = d->virt_base + EINTPEND_REG(bank->eint_offset); + + writel(1 << index, reg); + } +@@ -357,7 +359,7 @@ static int s3c64xx_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) + s3c64xx_irq_set_handler(irqd, type); + + /* Set up interrupt trigger */ +- reg = bank->eint_base + EINTCON_REG(bank->eint_offset); ++ reg = d->virt_base + EINTCON_REG(bank->eint_offset); + shift = EINT_OFFS(bank->eint_offset) + irqd->hwirq; + shift = 4 * (shift / 4); /* 4 EINTs per trigger selector */ + +@@ -409,8 +411,7 @@ static void s3c64xx_eint_gpio_irq(struct irq_desc *desc) + { + struct irq_chip *chip = irq_desc_get_chip(desc); + struct s3c64xx_eint_gpio_data *data = irq_desc_get_handler_data(desc); +- struct irq_data *irqd = irq_desc_get_irq_data(desc); +- struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); ++ struct samsung_pinctrl_drv_data *drvdata = data->drvdata; + + chained_irq_enter(chip, desc); + +@@ -420,7 +421,7 @@ static void s3c64xx_eint_gpio_irq(struct irq_desc *desc) + unsigned int pin; + unsigned int virq; + +- svc = readl(bank->eint_base + SERVICE_REG); ++ svc = readl(drvdata->virt_base + SERVICE_REG); + group = SVC_GROUP(svc); + pin = svc & SVC_NUM_MASK; + +@@ -515,15 +516,15 @@ static inline void s3c64xx_eint0_irq_set_mask(struct irq_data *irqd, bool mask) + { + struct s3c64xx_eint0_domain_data *ddata = + irq_data_get_irq_chip_data(irqd); +- struct samsung_pin_bank *bank = ddata->bank; ++ struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata; + u32 val; + +- val = readl(bank->eint_base + EINT0MASK_REG); ++ val = readl(d->virt_base + EINT0MASK_REG); + if (mask) + val |= 1 << ddata->eints[irqd->hwirq]; + else + val &= ~(1 << ddata->eints[irqd->hwirq]); +- writel(val, bank->eint_base + EINT0MASK_REG); ++ writel(val, d->virt_base + EINT0MASK_REG); + } + + static void s3c64xx_eint0_irq_unmask(struct irq_data *irqd) +@@ -540,10 +541,10 @@ static void s3c64xx_eint0_irq_ack(struct irq_data *irqd) + { + struct s3c64xx_eint0_domain_data *ddata = + irq_data_get_irq_chip_data(irqd); +- struct samsung_pin_bank *bank = ddata->bank; ++ struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata; + + writel(1 << ddata->eints[irqd->hwirq], +- bank->eint_base + EINT0PEND_REG); ++ d->virt_base + EINT0PEND_REG); + } + + static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type) +@@ -551,7 +552,7 @@ static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type) + struct s3c64xx_eint0_domain_data *ddata = + irq_data_get_irq_chip_data(irqd); + struct samsung_pin_bank *bank = ddata->bank; +- struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata; ++ struct samsung_pinctrl_drv_data *d = bank->drvdata; + void __iomem *reg; + int trigger; + u8 shift; +@@ -566,7 +567,7 @@ static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type) + s3c64xx_irq_set_handler(irqd, type); + + /* Set up interrupt trigger */ +- reg = bank->eint_base + EINT0CON0_REG; ++ reg = d->virt_base + EINT0CON0_REG; + shift = ddata->eints[irqd->hwirq]; + if (shift >= EINT_MAX_PER_REG) { + reg += 4; +@@ -598,19 +599,14 @@ static struct irq_chip s3c64xx_eint0_irq_chip = { + static inline void s3c64xx_irq_demux_eint(struct irq_desc *desc, u32 range) + { + struct irq_chip *chip = irq_desc_get_chip(desc); +- struct irq_data *irqd = irq_desc_get_irq_data(desc); +- struct s3c64xx_eint0_domain_data *ddata = +- irq_data_get_irq_chip_data(irqd); +- struct samsung_pin_bank *bank = ddata->bank; +- + struct s3c64xx_eint0_data *data = irq_desc_get_handler_data(desc); +- ++ struct samsung_pinctrl_drv_data *drvdata = data->drvdata; + unsigned int pend, mask; + + chained_irq_enter(chip, desc); + +- pend = readl(bank->eint_base + EINT0PEND_REG); +- mask = readl(bank->eint_base + EINT0MASK_REG); ++ pend = readl(drvdata->virt_base + EINT0PEND_REG); ++ mask = readl(drvdata->virt_base + EINT0MASK_REG); + + pend = pend & range & ~mask; + pend &= range; +diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c +index f542642eed8d..61bbd54e35ba 100644 +--- a/drivers/pinctrl/samsung/pinctrl-samsung.c ++++ b/drivers/pinctrl/samsung/pinctrl-samsung.c +@@ -1013,6 +1013,12 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d, + bank->eint_base = virt_base[0]; + bank->pctl_base = virt_base[bdata->pctl_res_idx]; + } ++ /* ++ * Legacy platforms should provide only one resource with IO memory. ++ * Store it as virt_base because legacy driver needs to access it ++ * through samsung_pinctrl_drv_data. ++ */ ++ d->virt_base = virt_base[0]; + + for_each_child_of_node(node, np) { + if (!of_find_property(np, "gpio-controller", NULL)) +diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h +index 515a61035e54..61c4cab0ad24 100644 +--- a/drivers/pinctrl/samsung/pinctrl-samsung.h ++++ b/drivers/pinctrl/samsung/pinctrl-samsung.h +@@ -247,6 +247,10 @@ struct samsung_pin_ctrl { + /** + * struct samsung_pinctrl_drv_data: wrapper for holding driver data together. + * @node: global list node ++ * @virt_base: register base address of the controller; this will be equal ++ * to each bank samsung_pin_bank->pctl_base and used on legacy ++ * platforms (like S3C24XX or S3C64XX) which has to access the base ++ * through samsung_pinctrl_drv_data, not samsung_pin_bank). + * @dev: device instance representing the controller. + * @irq: interrpt number used by the controller to notify gpio interrupts. + * @ctrl: pin controller instance managed by the driver. +@@ -262,6 +266,7 @@ struct samsung_pin_ctrl { + */ + struct samsung_pinctrl_drv_data { + struct list_head node; ++ void __iomem *virt_base; + struct device *dev; + int irq; + +diff --git a/drivers/regulator/cpcap-regulator.c b/drivers/regulator/cpcap-regulator.c +index cc98aceed1c1..ce1cab320f6f 100644 +--- a/drivers/regulator/cpcap-regulator.c ++++ b/drivers/regulator/cpcap-regulator.c +@@ -77,6 +77,8 @@ + #define CPCAP_BIT_VAUDIO_MODE0 BIT(1) + #define CPCAP_BIT_V_AUDIO_EN BIT(0) + ++#define CPCAP_BIT_AUDIO_NORMAL_MODE 0x00 ++ + /* + * Off mode configuration bit. Used currently only by SW5 on omap4. There's + * the following comment in Motorola Linux kernel tree for it: +@@ -217,7 +219,7 @@ static unsigned int cpcap_regulator_get_mode(struct regulator_dev *rdev) + + regmap_read(rdev->regmap, rdev->desc->enable_reg, &value); + +- if (!(value & CPCAP_BIT_AUDIO_LOW_PWR)) ++ if (value & CPCAP_BIT_AUDIO_LOW_PWR) + return REGULATOR_MODE_STANDBY; + + return REGULATOR_MODE_NORMAL; +@@ -230,10 +232,10 @@ static int cpcap_regulator_set_mode(struct regulator_dev *rdev, + + switch (mode) { + case REGULATOR_MODE_NORMAL: +- value = CPCAP_BIT_AUDIO_LOW_PWR; ++ value = CPCAP_BIT_AUDIO_NORMAL_MODE; + break; + case REGULATOR_MODE_STANDBY: +- value = 0; ++ value = CPCAP_BIT_AUDIO_LOW_PWR; + break; + default: + return -EINVAL; +diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c +index d5bf36ec8a75..34367d172961 100644 +--- a/drivers/s390/scsi/zfcp_dbf.c ++++ b/drivers/s390/scsi/zfcp_dbf.c +@@ -3,7 +3,7 @@ + * + * Debug traces for zfcp. + * +- * Copyright IBM Corp. 2002, 2016 ++ * Copyright IBM Corp. 2002, 2017 + */ + + #define KMSG_COMPONENT "zfcp" +@@ -447,6 +447,7 @@ static u16 zfcp_dbf_san_res_cap_len_if_gpn_ft(char *tag, + struct fc_ct_hdr *reqh = sg_virt(ct_els->req); + struct fc_ns_gid_ft *reqn = (struct fc_ns_gid_ft *)(reqh + 1); + struct scatterlist *resp_entry = ct_els->resp; ++ struct fc_ct_hdr *resph; + struct fc_gpn_ft_resp *acc; + int max_entries, x, last = 0; + +@@ -473,6 +474,13 @@ static u16 zfcp_dbf_san_res_cap_len_if_gpn_ft(char *tag, + return len; /* not GPN_FT response so do not cap */ + + acc = sg_virt(resp_entry); ++ ++ /* cap all but accept CT responses to at least the CT header */ ++ resph = (struct fc_ct_hdr *)acc; ++ if ((ct_els->status) || ++ (resph->ct_cmd != cpu_to_be16(FC_FS_ACC))) ++ return max(FC_CT_HDR_LEN, ZFCP_DBF_SAN_MAX_PAYLOAD); ++ + max_entries = (reqh->ct_mr_size * 4 / sizeof(struct fc_gpn_ft_resp)) + + 1 /* zfcp_fc_scan_ports: bytes correct, entries off-by-one + * to account for header as 1st pseudo "entry" */; +@@ -555,8 +563,8 @@ void zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *sc, + rec->scsi_retries = sc->retries; + rec->scsi_allowed = sc->allowed; + rec->scsi_id = sc->device->id; +- /* struct zfcp_dbf_scsi needs to be updated to handle 64bit LUNs */ + rec->scsi_lun = (u32)sc->device->lun; ++ rec->scsi_lun_64_hi = (u32)(sc->device->lun >> 32); + rec->host_scribble = (unsigned long)sc->host_scribble; + + memcpy(rec->scsi_opcode, sc->cmnd, +@@ -564,19 +572,32 @@ void zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *sc, + + if (fsf) { + rec->fsf_req_id = fsf->req_id; ++ rec->pl_len = FCP_RESP_WITH_EXT; + fcp_rsp = (struct fcp_resp_with_ext *) + &(fsf->qtcb->bottom.io.fcp_rsp); ++ /* mandatory parts of FCP_RSP IU in this SCSI record */ + memcpy(&rec->fcp_rsp, fcp_rsp, FCP_RESP_WITH_EXT); + if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL) { + fcp_rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1]; + rec->fcp_rsp_info = fcp_rsp_info->rsp_code; ++ rec->pl_len += be32_to_cpu(fcp_rsp->ext.fr_rsp_len); + } + if (fcp_rsp->resp.fr_flags & FCP_SNS_LEN_VAL) { +- rec->pl_len = min((u16)SCSI_SENSE_BUFFERSIZE, +- (u16)ZFCP_DBF_PAY_MAX_REC); +- zfcp_dbf_pl_write(dbf, sc->sense_buffer, rec->pl_len, +- "fcp_sns", fsf->req_id); ++ rec->pl_len += be32_to_cpu(fcp_rsp->ext.fr_sns_len); + } ++ /* complete FCP_RSP IU in associated PAYload record ++ * but only if there are optional parts ++ */ ++ if (fcp_rsp->resp.fr_flags != 0) ++ zfcp_dbf_pl_write( ++ dbf, fcp_rsp, ++ /* at least one full PAY record ++ * but not beyond hardware response field ++ */ ++ min_t(u16, max_t(u16, rec->pl_len, ++ ZFCP_DBF_PAY_MAX_REC), ++ FSF_FCP_RSP_SIZE), ++ "fcp_riu", fsf->req_id); + } + + debug_event(dbf->scsi, level, rec, sizeof(*rec)); +diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h +index db186d44cfaf..b60667c145fd 100644 +--- a/drivers/s390/scsi/zfcp_dbf.h ++++ b/drivers/s390/scsi/zfcp_dbf.h +@@ -2,7 +2,7 @@ + * zfcp device driver + * debug feature declarations + * +- * Copyright IBM Corp. 2008, 2016 ++ * Copyright IBM Corp. 2008, 2017 + */ + + #ifndef ZFCP_DBF_H +@@ -204,7 +204,7 @@ enum zfcp_dbf_scsi_id { + * @id: unique number of recovery record type + * @tag: identifier string specifying the location of initiation + * @scsi_id: scsi device id +- * @scsi_lun: scsi device logical unit number ++ * @scsi_lun: scsi device logical unit number, low part of 64 bit, old 32 bit + * @scsi_result: scsi result + * @scsi_retries: current retry number of scsi request + * @scsi_allowed: allowed retries +@@ -214,6 +214,7 @@ enum zfcp_dbf_scsi_id { + * @host_scribble: LLD specific data attached to SCSI request + * @pl_len: length of paload stored as zfcp_dbf_pay + * @fsf_rsp: response for fsf request ++ * @scsi_lun_64_hi: scsi device logical unit number, high part of 64 bit + */ + struct zfcp_dbf_scsi { + u8 id; +@@ -230,6 +231,7 @@ struct zfcp_dbf_scsi { + u64 host_scribble; + u16 pl_len; + struct fcp_resp_with_ext fcp_rsp; ++ u32 scsi_lun_64_hi; + } __packed; + + /** +@@ -323,7 +325,11 @@ void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req) + { + struct fsf_qtcb *qtcb = req->qtcb; + +- if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) && ++ if (unlikely(req->status & (ZFCP_STATUS_FSFREQ_DISMISSED | ++ ZFCP_STATUS_FSFREQ_ERROR))) { ++ zfcp_dbf_hba_fsf_resp("fs_rerr", 3, req); ++ ++ } else if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) && + (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) { + zfcp_dbf_hba_fsf_resp("fs_perr", 1, req); + +@@ -401,7 +407,8 @@ void zfcp_dbf_scsi_abort(char *tag, struct scsi_cmnd *scmd, + * @flag: indicates type of reset (Target Reset, Logical Unit Reset) + */ + static inline +-void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag) ++void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag, ++ struct zfcp_fsf_req *fsf_req) + { + char tmp_tag[ZFCP_DBF_TAG_LEN]; + +@@ -411,7 +418,7 @@ void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag) + memcpy(tmp_tag, "lr_", 3); + + memcpy(&tmp_tag[3], tag, 4); +- _zfcp_dbf_scsi(tmp_tag, 1, scmnd, NULL); ++ _zfcp_dbf_scsi(tmp_tag, 1, scmnd, fsf_req); + } + + /** +diff --git a/drivers/s390/scsi/zfcp_fc.h b/drivers/s390/scsi/zfcp_fc.h +index df2b541c8287..a2275825186f 100644 +--- a/drivers/s390/scsi/zfcp_fc.h ++++ b/drivers/s390/scsi/zfcp_fc.h +@@ -4,7 +4,7 @@ + * Fibre Channel related definitions and inline functions for the zfcp + * device driver + * +- * Copyright IBM Corp. 2009 ++ * Copyright IBM Corp. 2009, 2017 + */ + + #ifndef ZFCP_FC_H +@@ -279,6 +279,10 @@ void zfcp_fc_eval_fcp_rsp(struct fcp_resp_with_ext *fcp_rsp, + !(rsp_flags & FCP_SNS_LEN_VAL) && + fcp_rsp->resp.fr_status == SAM_STAT_GOOD) + set_host_byte(scsi, DID_ERROR); ++ } else if (unlikely(rsp_flags & FCP_RESID_OVER)) { ++ /* FCP_DL was not sufficient for SCSI data length */ ++ if (fcp_rsp->resp.fr_status == SAM_STAT_GOOD) ++ set_host_byte(scsi, DID_ERROR); + } + } + +diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c +index 27ff38f839fc..1964391db904 100644 +--- a/drivers/s390/scsi/zfcp_fsf.c ++++ b/drivers/s390/scsi/zfcp_fsf.c +@@ -928,8 +928,8 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req) + + switch (header->fsf_status) { + case FSF_GOOD: +- zfcp_dbf_san_res("fsscth2", req); + ct->status = 0; ++ zfcp_dbf_san_res("fsscth2", req); + break; + case FSF_SERVICE_CLASS_NOT_SUPPORTED: + zfcp_fsf_class_not_supp(req); +@@ -1109,8 +1109,8 @@ static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req) + + switch (header->fsf_status) { + case FSF_GOOD: +- zfcp_dbf_san_res("fsselh1", req); + send_els->status = 0; ++ zfcp_dbf_san_res("fsselh1", req); + break; + case FSF_SERVICE_CLASS_NOT_SUPPORTED: + zfcp_fsf_class_not_supp(req); +@@ -2258,7 +2258,8 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd) + fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd; + zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd, 0); + +- if (scsi_prot_sg_count(scsi_cmnd)) { ++ if ((scsi_get_prot_op(scsi_cmnd) != SCSI_PROT_NORMAL) && ++ scsi_prot_sg_count(scsi_cmnd)) { + zfcp_qdio_set_data_div(qdio, &req->qdio_req, + scsi_prot_sg_count(scsi_cmnd)); + retval = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, +diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c +index 0678cf714c0e..a1eeeaaa0fca 100644 +--- a/drivers/s390/scsi/zfcp_scsi.c ++++ b/drivers/s390/scsi/zfcp_scsi.c +@@ -3,7 +3,7 @@ + * + * Interface to Linux SCSI midlayer. + * +- * Copyright IBM Corp. 2002, 2016 ++ * Copyright IBM Corp. 2002, 2017 + */ + + #define KMSG_COMPONENT "zfcp" +@@ -273,25 +273,29 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) + + zfcp_erp_wait(adapter); + ret = fc_block_scsi_eh(scpnt); +- if (ret) ++ if (ret) { ++ zfcp_dbf_scsi_devreset("fiof", scpnt, tm_flags, NULL); + return ret; ++ } + + if (!(atomic_read(&adapter->status) & + ZFCP_STATUS_COMMON_RUNNING)) { +- zfcp_dbf_scsi_devreset("nres", scpnt, tm_flags); ++ zfcp_dbf_scsi_devreset("nres", scpnt, tm_flags, NULL); + return SUCCESS; + } + } +- if (!fsf_req) ++ if (!fsf_req) { ++ zfcp_dbf_scsi_devreset("reqf", scpnt, tm_flags, NULL); + return FAILED; ++ } + + wait_for_completion(&fsf_req->completion); + + if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) { +- zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags); ++ zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags, fsf_req); + retval = FAILED; + } else { +- zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags); ++ zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags, fsf_req); + zfcp_scsi_forget_cmnds(zfcp_sdev, tm_flags); + } + +diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c +index a1a2c71e1626..b051d97af468 100644 +--- a/drivers/scsi/aacraid/aachba.c ++++ b/drivers/scsi/aacraid/aachba.c +@@ -594,6 +594,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd) + + aac_fib_init(cmd_fibcontext); + dinfo = (struct aac_get_name *) fib_data(cmd_fibcontext); ++ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; + + dinfo->command = cpu_to_le32(VM_ContainerConfig); + dinfo->type = cpu_to_le32(CT_READ_NAME); +@@ -611,10 +612,8 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd) + /* + * Check that the command queued to the controller + */ +- if (status == -EINPROGRESS) { +- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; ++ if (status == -EINPROGRESS) + return 0; +- } + + printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status); + aac_fib_complete(cmd_fibcontext); +@@ -725,6 +724,7 @@ static void _aac_probe_container1(void * context, struct fib * fibptr) + + dinfo->count = cpu_to_le32(scmd_id(scsicmd)); + dinfo->type = cpu_to_le32(FT_FILESYS); ++ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; + + status = aac_fib_send(ContainerCommand, + fibptr, +@@ -736,9 +736,7 @@ static void _aac_probe_container1(void * context, struct fib * fibptr) + /* + * Check that the command queued to the controller + */ +- if (status == -EINPROGRESS) +- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; +- else if (status < 0) { ++ if (status < 0 && status != -EINPROGRESS) { + /* Inherit results from VM_NameServe, if any */ + dresp->status = cpu_to_le32(ST_OK); + _aac_probe_container2(context, fibptr); +@@ -766,6 +764,7 @@ static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(stru + dinfo->count = cpu_to_le32(scmd_id(scsicmd)); + dinfo->type = cpu_to_le32(FT_FILESYS); + scsicmd->SCp.ptr = (char *)callback; ++ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; + + status = aac_fib_send(ContainerCommand, + fibptr, +@@ -777,10 +776,9 @@ static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(stru + /* + * Check that the command queued to the controller + */ +- if (status == -EINPROGRESS) { +- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; ++ if (status == -EINPROGRESS) + return 0; +- } ++ + if (status < 0) { + scsicmd->SCp.ptr = NULL; + aac_fib_complete(fibptr); +@@ -1126,6 +1124,7 @@ static int aac_get_container_serial(struct scsi_cmnd * scsicmd) + dinfo->command = cpu_to_le32(VM_ContainerConfig); + dinfo->type = cpu_to_le32(CT_CID_TO_32BITS_UID); + dinfo->cid = cpu_to_le32(scmd_id(scsicmd)); ++ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; + + status = aac_fib_send(ContainerCommand, + cmd_fibcontext, +@@ -1138,10 +1137,8 @@ static int aac_get_container_serial(struct scsi_cmnd * scsicmd) + /* + * Check that the command queued to the controller + */ +- if (status == -EINPROGRESS) { +- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; ++ if (status == -EINPROGRESS) + return 0; +- } + + printk(KERN_WARNING "aac_get_container_serial: aac_fib_send failed with status: %d.\n", status); + aac_fib_complete(cmd_fibcontext); +@@ -2335,16 +2332,14 @@ static int aac_read(struct scsi_cmnd * scsicmd) + * Alocate and initialize a Fib + */ + cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd); +- ++ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; + status = aac_adapter_read(cmd_fibcontext, scsicmd, lba, count); + + /* + * Check that the command queued to the controller + */ +- if (status == -EINPROGRESS) { +- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; ++ if (status == -EINPROGRESS) + return 0; +- } + + printk(KERN_WARNING "aac_read: aac_fib_send failed with status: %d.\n", status); + /* +@@ -2429,16 +2424,14 @@ static int aac_write(struct scsi_cmnd * scsicmd) + * Allocate and initialize a Fib then setup a BlockWrite command + */ + cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd); +- ++ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; + status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua); + + /* + * Check that the command queued to the controller + */ +- if (status == -EINPROGRESS) { +- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; ++ if (status == -EINPROGRESS) + return 0; +- } + + printk(KERN_WARNING "aac_write: aac_fib_send failed with status: %d\n", status); + /* +@@ -2588,6 +2581,7 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd) + synchronizecmd->cid = cpu_to_le32(scmd_id(scsicmd)); + synchronizecmd->count = + cpu_to_le32(sizeof(((struct aac_synchronize_reply *)NULL)->data)); ++ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; + + /* + * Now send the Fib to the adapter +@@ -2603,10 +2597,8 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd) + /* + * Check that the command queued to the controller + */ +- if (status == -EINPROGRESS) { +- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; ++ if (status == -EINPROGRESS) + return 0; +- } + + printk(KERN_WARNING + "aac_synchronize: aac_fib_send failed with status: %d.\n", status); +@@ -2666,6 +2658,7 @@ static int aac_start_stop(struct scsi_cmnd *scsicmd) + pmcmd->cid = cpu_to_le32(sdev_id(sdev)); + pmcmd->parm = (scsicmd->cmnd[1] & 1) ? + cpu_to_le32(CT_PM_UNIT_IMMEDIATE) : 0; ++ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; + + /* + * Now send the Fib to the adapter +@@ -2681,10 +2674,8 @@ static int aac_start_stop(struct scsi_cmnd *scsicmd) + /* + * Check that the command queued to the controller + */ +- if (status == -EINPROGRESS) { +- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; ++ if (status == -EINPROGRESS) + return 0; +- } + + aac_fib_complete(cmd_fibcontext); + aac_fib_free(cmd_fibcontext); +@@ -3692,16 +3683,14 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) + * Allocate and initialize a Fib then setup a BlockWrite command + */ + cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd); +- ++ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; + status = aac_adapter_scsi(cmd_fibcontext, scsicmd); + + /* + * Check that the command queued to the controller + */ +- if (status == -EINPROGRESS) { +- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; ++ if (status == -EINPROGRESS) + return 0; +- } + + printk(KERN_WARNING "aac_srb: aac_fib_send failed with status: %d\n", status); + aac_fib_complete(cmd_fibcontext); +@@ -3739,15 +3728,14 @@ static int aac_send_hba_fib(struct scsi_cmnd *scsicmd) + if (!cmd_fibcontext) + return -1; + ++ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; + status = aac_adapter_hba(cmd_fibcontext, scsicmd); + + /* + * Check that the command queued to the controller + */ +- if (status == -EINPROGRESS) { +- scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; ++ if (status == -EINPROGRESS) + return 0; +- } + + pr_warn("aac_hba_cmd_req: aac_fib_send failed with status: %d\n", + status); +diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c +index 71c4746341ea..3ee4ea79f81a 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_base.c ++++ b/drivers/scsi/megaraid/megaraid_sas_base.c +@@ -1995,9 +1995,12 @@ static void megasas_complete_outstanding_ioctls(struct megasas_instance *instanc + if (cmd_fusion->sync_cmd_idx != (u32)ULONG_MAX) { + cmd_mfi = instance->cmd_list[cmd_fusion->sync_cmd_idx]; + if (cmd_mfi->sync_cmd && +- cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT) ++ (cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT)) { ++ cmd_mfi->frame->hdr.cmd_status = ++ MFI_STAT_WRONG_STATE; + megasas_complete_cmd(instance, + cmd_mfi, DID_OK); ++ } + } + } + } else { +@@ -5478,7 +5481,8 @@ static int megasas_init_fw(struct megasas_instance *instance) + instance->throttlequeuedepth = + MEGASAS_THROTTLE_QUEUE_DEPTH; + +- if (resetwaittime > MEGASAS_RESET_WAIT_TIME) ++ if ((resetwaittime < 1) || ++ (resetwaittime > MEGASAS_RESET_WAIT_TIME)) + resetwaittime = MEGASAS_RESET_WAIT_TIME; + + if ((scmd_timeout < 10) || (scmd_timeout > MEGASAS_DEFAULT_CMD_TIMEOUT)) +@@ -5649,6 +5653,14 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num, + prev_aen.word = + le32_to_cpu(instance->aen_cmd->frame->dcmd.mbox.w[1]); + ++ if ((curr_aen.members.class < MFI_EVT_CLASS_DEBUG) || ++ (curr_aen.members.class > MFI_EVT_CLASS_DEAD)) { ++ dev_info(&instance->pdev->dev, ++ "%s %d out of range class %d send by application\n", ++ __func__, __LINE__, curr_aen.members.class); ++ return 0; ++ } ++ + /* + * A class whose enum value is smaller is inclusive of all + * higher values. If a PROGRESS (= -1) was previously +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c +index 985510628f56..8152962f152d 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c +@@ -3287,7 +3287,7 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance, + mpi25_ieee_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT | + MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR; + +- mpi25_ieee_chain->Length = cpu_to_le32(instance->max_chain_frame_sz); ++ mpi25_ieee_chain->Length = cpu_to_le32(instance->mfi_frame_size); + } + + /** +diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c +index 2c3783684815..85e7bae4a7ef 100644 +--- a/drivers/scsi/qedi/qedi_main.c ++++ b/drivers/scsi/qedi/qedi_main.c +@@ -1575,7 +1575,7 @@ struct qedi_cmd *qedi_get_cmd_from_tid(struct qedi_ctx *qedi, u32 tid) + { + struct qedi_cmd *cmd = NULL; + +- if (tid > MAX_ISCSI_TASK_ENTRIES) ++ if (tid >= MAX_ISCSI_TASK_ENTRIES) + return NULL; + + cmd = qedi->itt_map[tid].p_cmd; +diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c +index 08a1feb3a195..8c6ff1682fb1 100644 +--- a/drivers/scsi/qla2xxx/qla_attr.c ++++ b/drivers/scsi/qla2xxx/qla_attr.c +@@ -318,6 +318,8 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, + return -EINVAL; + if (start > ha->optrom_size) + return -EINVAL; ++ if (size > ha->optrom_size - start) ++ size = ha->optrom_size - start; + + mutex_lock(&ha->optrom_mutex); + switch (val) { +@@ -343,8 +345,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, + } + + ha->optrom_region_start = start; +- ha->optrom_region_size = start + size > ha->optrom_size ? +- ha->optrom_size - start : size; ++ ha->optrom_region_size = start + size; + + ha->optrom_state = QLA_SREADING; + ha->optrom_buffer = vmalloc(ha->optrom_region_size); +@@ -417,8 +418,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, + } + + ha->optrom_region_start = start; +- ha->optrom_region_size = start + size > ha->optrom_size ? +- ha->optrom_size - start : size; ++ ha->optrom_region_size = start + size; + + ha->optrom_state = QLA_SWRITING; + ha->optrom_buffer = vmalloc(ha->optrom_region_size); +diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c +index b323a7c71eda..0ec250993e93 100644 +--- a/drivers/scsi/qla2xxx/qla_gs.c ++++ b/drivers/scsi/qla2xxx/qla_gs.c +@@ -3080,7 +3080,7 @@ int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport) + GPSC_RSP_SIZE); + + /* GPSC req */ +- memcpy(ct_req->req.gpsc.port_name, fcport->port_name, ++ memcpy(ct_req->req.gpsc.port_name, fcport->fabric_port_name, + WWN_SIZE); + + sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns; +diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c +index 072ad1aa5505..8f83571afc7b 100644 +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -7804,6 +7804,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, + ha->queue_pair_map[qpair_id] = qpair; + qpair->id = qpair_id; + qpair->vp_idx = vp_idx; ++ qpair->fw_started = ha->flags.fw_started; + INIT_LIST_HEAD(&qpair->hints_list); + qpair->chip_reset = ha->base_qpair->chip_reset; + qpair->enable_class_2 = ha->base_qpair->enable_class_2; +diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c +index 7b3b702ef622..ec2c398f5663 100644 +--- a/drivers/scsi/qla2xxx/qla_isr.c ++++ b/drivers/scsi/qla2xxx/qla_isr.c +@@ -3429,7 +3429,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) + } + + /* Enable MSI-X vector for response queue update for queue 0 */ +- if (IS_QLA25XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) { ++ if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { + if (ha->msixbase && ha->mqiobase && + (ha->max_rsp_queues > 1 || ha->max_req_queues > 1 || + ql2xmqsupport)) +diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c +index 7c6d1a404011..1f1a81c6eaa9 100644 +--- a/drivers/scsi/qla2xxx/qla_mbx.c ++++ b/drivers/scsi/qla2xxx/qla_mbx.c +@@ -54,6 +54,7 @@ static struct rom_cmd { + { MBC_GET_MEM_OFFLOAD_CNTRL_STAT }, + { MBC_GET_RETRY_COUNT }, + { MBC_TRACE_CONTROL }, ++ { MBC_INITIALIZE_MULTIQ }, + }; + + static int is_rom_cmd(uint16_t cmd) +@@ -3689,7 +3690,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, + if (qla_ini_mode_enabled(vha) && + ha->flags.fawwpn_enabled && + (rptid_entry->u.f1.flags & +- VP_FLAGS_NAME_VALID)) { ++ BIT_6)) { + memcpy(vha->port_name, + rptid_entry->u.f1.port_name, + WWN_SIZE); +diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c +index f0605cd196fb..3089094b48fa 100644 +--- a/drivers/scsi/qla2xxx/qla_mid.c ++++ b/drivers/scsi/qla2xxx/qla_mid.c +@@ -74,7 +74,7 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha) + * ensures no active vp_list traversal while the vport is removed + * from the queue) + */ +- wait_event_timeout(vha->vref_waitq, atomic_read(&vha->vref_count), ++ wait_event_timeout(vha->vref_waitq, !atomic_read(&vha->vref_count), + 10*HZ); + + spin_lock_irqsave(&ha->vport_slock, flags); +diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c +index e101cd3043b9..4e2a64773060 100644 +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -6796,7 +6796,7 @@ qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha) + if (!QLA_TGT_MODE_ENABLED()) + return; + +- if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) { ++ if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { + ISP_ATIO_Q_IN(base_vha) = &ha->mqiobase->isp25mq.atio_q_in; + ISP_ATIO_Q_OUT(base_vha) = &ha->mqiobase->isp25mq.atio_q_out; + } else { +diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c +index aad6ebb51735..1a9de8419997 100644 +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -828,6 +828,39 @@ static int max_sectors_bytes(struct request_queue *q) + return max_sectors << 9; + } + ++static void ++sg_fill_request_table(Sg_fd *sfp, sg_req_info_t *rinfo) ++{ ++ Sg_request *srp; ++ int val; ++ unsigned int ms; ++ ++ val = 0; ++ list_for_each_entry(srp, &sfp->rq_list, entry) { ++ if (val > SG_MAX_QUEUE) ++ break; ++ rinfo[val].req_state = srp->done + 1; ++ rinfo[val].problem = ++ srp->header.masked_status & ++ srp->header.host_status & ++ srp->header.driver_status; ++ if (srp->done) ++ rinfo[val].duration = ++ srp->header.duration; ++ else { ++ ms = jiffies_to_msecs(jiffies); ++ rinfo[val].duration = ++ (ms > srp->header.duration) ? ++ (ms - srp->header.duration) : 0; ++ } ++ rinfo[val].orphan = srp->orphan; ++ rinfo[val].sg_io_owned = srp->sg_io_owned; ++ rinfo[val].pack_id = srp->header.pack_id; ++ rinfo[val].usr_ptr = srp->header.usr_ptr; ++ val++; ++ } ++} ++ + static long + sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) + { +@@ -1012,38 +1045,13 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) + return -EFAULT; + else { + sg_req_info_t *rinfo; +- unsigned int ms; + +- rinfo = kmalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE, +- GFP_KERNEL); ++ rinfo = kzalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE, ++ GFP_KERNEL); + if (!rinfo) + return -ENOMEM; + read_lock_irqsave(&sfp->rq_list_lock, iflags); +- val = 0; +- list_for_each_entry(srp, &sfp->rq_list, entry) { +- if (val >= SG_MAX_QUEUE) +- break; +- memset(&rinfo[val], 0, SZ_SG_REQ_INFO); +- rinfo[val].req_state = srp->done + 1; +- rinfo[val].problem = +- srp->header.masked_status & +- srp->header.host_status & +- srp->header.driver_status; +- if (srp->done) +- rinfo[val].duration = +- srp->header.duration; +- else { +- ms = jiffies_to_msecs(jiffies); +- rinfo[val].duration = +- (ms > srp->header.duration) ? +- (ms - srp->header.duration) : 0; +- } +- rinfo[val].orphan = srp->orphan; +- rinfo[val].sg_io_owned = srp->sg_io_owned; +- rinfo[val].pack_id = srp->header.pack_id; +- rinfo[val].usr_ptr = srp->header.usr_ptr; +- val++; +- } ++ sg_fill_request_table(sfp, rinfo); + read_unlock_irqrestore(&sfp->rq_list_lock, iflags); + result = __copy_to_user(p, rinfo, + SZ_SG_REQ_INFO * SG_MAX_QUEUE); +diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c +index 3cc8d67783a1..5e7200f05873 100644 +--- a/drivers/scsi/storvsc_drv.c ++++ b/drivers/scsi/storvsc_drv.c +@@ -1640,6 +1640,8 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) + put_cpu(); + + if (ret == -EAGAIN) { ++ if (payload_sz > sizeof(cmd_request->mpb)) ++ kfree(payload); + /* no more space */ + return SCSI_MLQUEUE_DEVICE_BUSY; + } +diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c +index 4e7a4e9dcf4d..f8eba1c5412f 100644 +--- a/drivers/tty/tty_buffer.c ++++ b/drivers/tty/tty_buffer.c +@@ -361,6 +361,32 @@ int tty_insert_flip_string_flags(struct tty_port *port, + } + EXPORT_SYMBOL(tty_insert_flip_string_flags); + ++/** ++ * __tty_insert_flip_char - Add one character to the tty buffer ++ * @port: tty port ++ * @ch: character ++ * @flag: flag byte ++ * ++ * Queue a single byte to the tty buffering, with an optional flag. ++ * This is the slow path of tty_insert_flip_char. ++ */ ++int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag) ++{ ++ struct tty_buffer *tb; ++ int flags = (flag == TTY_NORMAL) ? TTYB_NORMAL : 0; ++ ++ if (!__tty_buffer_request_room(port, 1, flags)) ++ return 0; ++ ++ tb = port->buf.tail; ++ if (~tb->flags & TTYB_NORMAL) ++ *flag_buf_ptr(tb, tb->used) = flag; ++ *char_buf_ptr(tb, tb->used++) = ch; ++ ++ return 1; ++} ++EXPORT_SYMBOL(__tty_insert_flip_char); ++ + /** + * tty_schedule_flip - push characters to ldisc + * @port: tty port to push from +diff --git a/fs/ext4/file.c b/fs/ext4/file.c +index 0d7cf0cc9b87..86ea1d92839a 100644 +--- a/fs/ext4/file.c ++++ b/fs/ext4/file.c +@@ -595,7 +595,7 @@ static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize) + inode_lock(inode); + + isize = i_size_read(inode); +- if (offset >= isize) { ++ if (offset < 0 || offset >= isize) { + inode_unlock(inode); + return -ENXIO; + } +@@ -658,7 +658,7 @@ static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize) + inode_lock(inode); + + isize = i_size_read(inode); +- if (offset >= isize) { ++ if (offset < 0 || offset >= isize) { + inode_unlock(inode); + return -ENXIO; + } +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index d61a70e2193a..c9e7be58756b 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2404,6 +2404,7 @@ static void ext4_orphan_cleanup(struct super_block *sb, + unsigned int s_flags = sb->s_flags; + int ret, nr_orphans = 0, nr_truncates = 0; + #ifdef CONFIG_QUOTA ++ int quota_update = 0; + int i; + #endif + if (!es->s_last_orphan) { +@@ -2442,14 +2443,32 @@ static void ext4_orphan_cleanup(struct super_block *sb, + #ifdef CONFIG_QUOTA + /* Needed for iput() to work correctly and not trash data */ + sb->s_flags |= MS_ACTIVE; +- /* Turn on quotas so that they are updated correctly */ ++ ++ /* ++ * Turn on quotas which were not enabled for read-only mounts if ++ * filesystem has quota feature, so that they are updated correctly. ++ */ ++ if (ext4_has_feature_quota(sb) && (s_flags & MS_RDONLY)) { ++ int ret = ext4_enable_quotas(sb); ++ ++ if (!ret) ++ quota_update = 1; ++ else ++ ext4_msg(sb, KERN_ERR, ++ "Cannot turn on quotas: error %d", ret); ++ } ++ ++ /* Turn on journaled quotas used for old sytle */ + for (i = 0; i < EXT4_MAXQUOTAS; i++) { + if (EXT4_SB(sb)->s_qf_names[i]) { + int ret = ext4_quota_on_mount(sb, i); +- if (ret < 0) ++ ++ if (!ret) ++ quota_update = 1; ++ else + ext4_msg(sb, KERN_ERR, + "Cannot turn on journaled " +- "quota: error %d", ret); ++ "quota: type %d: error %d", i, ret); + } + } + #endif +@@ -2510,10 +2529,12 @@ static void ext4_orphan_cleanup(struct super_block *sb, + ext4_msg(sb, KERN_INFO, "%d truncate%s cleaned up", + PLURAL(nr_truncates)); + #ifdef CONFIG_QUOTA +- /* Turn quotas off */ +- for (i = 0; i < EXT4_MAXQUOTAS; i++) { +- if (sb_dqopt(sb)->files[i]) +- dquot_quota_off(sb, i); ++ /* Turn off quotas if they were enabled for orphan cleanup */ ++ if (quota_update) { ++ for (i = 0; i < EXT4_MAXQUOTAS; i++) { ++ if (sb_dqopt(sb)->files[i]) ++ dquot_quota_off(sb, i); ++ } + } + #endif + sb->s_flags = s_flags; /* Restore MS_RDONLY status */ +@@ -5512,6 +5533,9 @@ static int ext4_enable_quotas(struct super_block *sb) + DQUOT_USAGE_ENABLED | + (quota_mopt[type] ? DQUOT_LIMITS_ENABLED : 0)); + if (err) { ++ for (type--; type >= 0; type--) ++ dquot_quota_off(sb, type); ++ + ext4_warning(sb, + "Failed to enable quota tracking " + "(type=%d, err=%d). Please run " +diff --git a/fs/orangefs/acl.c b/fs/orangefs/acl.c +index 7a3754488312..9409aac232f7 100644 +--- a/fs/orangefs/acl.c ++++ b/fs/orangefs/acl.c +@@ -61,9 +61,9 @@ struct posix_acl *orangefs_get_acl(struct inode *inode, int type) + return acl; + } + +-int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type) ++static int __orangefs_set_acl(struct inode *inode, struct posix_acl *acl, ++ int type) + { +- struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); + int error = 0; + void *value = NULL; + size_t size = 0; +@@ -72,22 +72,6 @@ int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type) + switch (type) { + case ACL_TYPE_ACCESS: + name = XATTR_NAME_POSIX_ACL_ACCESS; +- if (acl) { +- umode_t mode; +- +- error = posix_acl_update_mode(inode, &mode, &acl); +- if (error) { +- gossip_err("%s: posix_acl_update_mode err: %d\n", +- __func__, +- error); +- return error; +- } +- +- if (inode->i_mode != mode) +- SetModeFlag(orangefs_inode); +- inode->i_mode = mode; +- mark_inode_dirty_sync(inode); +- } + break; + case ACL_TYPE_DEFAULT: + name = XATTR_NAME_POSIX_ACL_DEFAULT; +@@ -132,6 +116,29 @@ int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type) + return error; + } + ++int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type) ++{ ++ int error; ++ ++ if (type == ACL_TYPE_ACCESS && acl) { ++ umode_t mode; ++ ++ error = posix_acl_update_mode(inode, &mode, &acl); ++ if (error) { ++ gossip_err("%s: posix_acl_update_mode err: %d\n", ++ __func__, ++ error); ++ return error; ++ } ++ ++ if (inode->i_mode != mode) ++ SetModeFlag(ORANGEFS_I(inode)); ++ inode->i_mode = mode; ++ mark_inode_dirty_sync(inode); ++ } ++ return __orangefs_set_acl(inode, acl, type); ++} ++ + int orangefs_init_acl(struct inode *inode, struct inode *dir) + { + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); +@@ -146,13 +153,14 @@ int orangefs_init_acl(struct inode *inode, struct inode *dir) + return error; + + if (default_acl) { +- error = orangefs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); ++ error = __orangefs_set_acl(inode, default_acl, ++ ACL_TYPE_DEFAULT); + posix_acl_release(default_acl); + } + + if (acl) { + if (!error) +- error = orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS); ++ error = __orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS); + posix_acl_release(acl); + } + +diff --git a/include/linux/ccp.h b/include/linux/ccp.h +index 3285c944194a..ab693c3afd0d 100644 +--- a/include/linux/ccp.h ++++ b/include/linux/ccp.h +@@ -1,7 +1,7 @@ + /* + * AMD Cryptographic Coprocessor (CCP) driver + * +- * Copyright (C) 2013,2016 Advanced Micro Devices, Inc. ++ * Copyright (C) 2013,2017 Advanced Micro Devices, Inc. + * + * Author: Tom Lendacky + * Author: Gary R Hook +@@ -231,6 +231,7 @@ enum ccp_xts_aes_unit_size { + * AES operation the new IV overwrites the old IV. + */ + struct ccp_xts_aes_engine { ++ enum ccp_aes_type type; + enum ccp_aes_action action; + enum ccp_xts_aes_unit_size unit_size; + +diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h +index 898cfe2eeb42..bc46e729fdde 100644 +--- a/include/linux/cpuset.h ++++ b/include/linux/cpuset.h +@@ -57,7 +57,9 @@ static inline void cpuset_dec(void) + + extern int cpuset_init(void); + extern void cpuset_init_smp(void); ++extern void cpuset_force_rebuild(void); + extern void cpuset_update_active_cpus(void); ++extern void cpuset_wait_for_hotplug(void); + extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask); + extern void cpuset_cpus_allowed_fallback(struct task_struct *p); + extern nodemask_t cpuset_mems_allowed(struct task_struct *p); +@@ -170,11 +172,15 @@ static inline bool cpusets_enabled(void) { return false; } + static inline int cpuset_init(void) { return 0; } + static inline void cpuset_init_smp(void) {} + ++static inline void cpuset_force_rebuild(void) { } ++ + static inline void cpuset_update_active_cpus(void) + { + partition_sched_domains(1, NULL, NULL); + } + ++static inline void cpuset_wait_for_hotplug(void) { } ++ + static inline void cpuset_cpus_allowed(struct task_struct *p, + struct cpumask *mask) + { +diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h +index 6383115e9d2c..2e028854bac7 100644 +--- a/include/linux/ftrace.h ++++ b/include/linux/ftrace.h +@@ -307,7 +307,7 @@ DECLARE_PER_CPU(int, disable_stack_tracer); + static inline void stack_tracer_disable(void) + { + /* Preemption or interupts must be disabled */ +- if (IS_ENABLED(CONFIG_PREEMPT_DEBUG)) ++ if (IS_ENABLED(CONFIG_DEBUG_PREEMPT)) + WARN_ON_ONCE(!preempt_count() || !irqs_disabled()); + this_cpu_inc(disable_stack_tracer); + } +@@ -320,7 +320,7 @@ static inline void stack_tracer_disable(void) + */ + static inline void stack_tracer_enable(void) + { +- if (IS_ENABLED(CONFIG_PREEMPT_DEBUG)) ++ if (IS_ENABLED(CONFIG_DEBUG_PREEMPT)) + WARN_ON_ONCE(!preempt_count() || !irqs_disabled()); + this_cpu_dec(disable_stack_tracer); + } +diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h +index c28dd523f96e..d43837f2ce3a 100644 +--- a/include/linux/tty_flip.h ++++ b/include/linux/tty_flip.h +@@ -12,6 +12,7 @@ extern int tty_prepare_flip_string(struct tty_port *port, + unsigned char **chars, size_t size); + extern void tty_flip_buffer_push(struct tty_port *port); + void tty_schedule_flip(struct tty_port *port); ++int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag); + + static inline int tty_insert_flip_char(struct tty_port *port, + unsigned char ch, char flag) +@@ -26,7 +27,7 @@ static inline int tty_insert_flip_char(struct tty_port *port, + *char_buf_ptr(tb, tb->used++) = ch; + return 1; + } +- return tty_insert_flip_string_flags(port, &ch, &flag, 1); ++ return __tty_insert_flip_char(port, ch, flag); + } + + static inline int tty_insert_flip_string(struct tty_port *port, +diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h +index acdd6f915a8d..20ef8e6ec2db 100644 +--- a/include/linux/uaccess.h ++++ b/include/linux/uaccess.h +@@ -156,7 +156,7 @@ copy_to_user(void __user *to, const void *from, unsigned long n) + } + #ifdef CONFIG_COMPAT + static __always_inline unsigned long __must_check +-copy_in_user(void __user *to, const void *from, unsigned long n) ++copy_in_user(void __user *to, const void __user *from, unsigned long n) + { + might_fault(); + if (access_ok(VERIFY_WRITE, to, n) && access_ok(VERIFY_READ, from, n)) +diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c +index 87a1213dd326..e8cb34193433 100644 +--- a/kernel/cgroup/cpuset.c ++++ b/kernel/cgroup/cpuset.c +@@ -2260,6 +2260,13 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs) + mutex_unlock(&cpuset_mutex); + } + ++static bool force_rebuild; ++ ++void cpuset_force_rebuild(void) ++{ ++ force_rebuild = true; ++} ++ + /** + * cpuset_hotplug_workfn - handle CPU/memory hotunplug for a cpuset + * +@@ -2334,8 +2341,10 @@ static void cpuset_hotplug_workfn(struct work_struct *work) + } + + /* rebuild sched domains if cpus_allowed has changed */ +- if (cpus_updated) ++ if (cpus_updated || force_rebuild) { ++ force_rebuild = false; + rebuild_sched_domains(); ++ } + } + + void cpuset_update_active_cpus(void) +@@ -2354,6 +2363,11 @@ void cpuset_update_active_cpus(void) + schedule_work(&cpuset_hotplug_work); + } + ++void cpuset_wait_for_hotplug(void) ++{ ++ flush_work(&cpuset_hotplug_work); ++} ++ + /* + * Keep top_cpuset.mems_allowed tracking node_states[N_MEMORY]. + * Call this routine anytime after node_states[N_MEMORY] changes. +diff --git a/kernel/cpu.c b/kernel/cpu.c +index eee033134262..a88c29ab09be 100644 +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -1252,7 +1252,17 @@ static int cpuhp_store_callbacks(enum cpuhp_state state, const char *name, + struct cpuhp_step *sp; + int ret = 0; + +- if (state == CPUHP_AP_ONLINE_DYN || state == CPUHP_BP_PREPARE_DYN) { ++ /* ++ * If name is NULL, then the state gets removed. ++ * ++ * CPUHP_AP_ONLINE_DYN and CPUHP_BP_PREPARE_DYN are handed out on ++ * the first allocation from these dynamic ranges, so the removal ++ * would trigger a new allocation and clear the wrong (already ++ * empty) state, leaving the callbacks of the to be cleared state ++ * dangling, which causes wreckage on the next hotplug operation. ++ */ ++ if (name && (state == CPUHP_AP_ONLINE_DYN || ++ state == CPUHP_BP_PREPARE_DYN)) { + ret = cpuhp_reserve_state(state); + if (ret < 0) + return ret; +diff --git a/kernel/power/process.c b/kernel/power/process.c +index 78672d324a6e..50f25cb370c6 100644 +--- a/kernel/power/process.c ++++ b/kernel/power/process.c +@@ -20,8 +20,9 @@ + #include + #include + #include ++#include + +-/* ++/* + * Timeout for stopping processes + */ + unsigned int __read_mostly freeze_timeout_msecs = 20 * MSEC_PER_SEC; +@@ -202,6 +203,8 @@ void thaw_processes(void) + __usermodehelper_set_disable_depth(UMH_FREEZING); + thaw_workqueues(); + ++ cpuset_wait_for_hotplug(); ++ + read_lock(&tasklist_lock); + for_each_process_thread(g, p) { + /* No other threads should have PF_SUSPEND_TASK set */ +diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c +index d0ca524bf042..258a9abee0b0 100644 +--- a/kernel/rcu/srcutree.c ++++ b/kernel/rcu/srcutree.c +@@ -896,6 +896,15 @@ static void __synchronize_srcu(struct srcu_struct *sp, bool do_norm) + __call_srcu(sp, &rcu.head, wakeme_after_rcu, do_norm); + wait_for_completion(&rcu.completion); + destroy_rcu_head_on_stack(&rcu.head); ++ ++ /* ++ * Make sure that later code is ordered after the SRCU grace ++ * period. This pairs with the raw_spin_lock_irq_rcu_node() ++ * in srcu_invoke_callbacks(). Unlike Tree RCU, this is needed ++ * because the current CPU might have been totally uninvolved with ++ * (and thus unordered against) that grace period. ++ */ ++ smp_mb(); + } + + /** +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index 0869b20fba81..99326c370c9c 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -5538,16 +5538,15 @@ static void cpuset_cpu_active(void) + * operation in the resume sequence, just build a single sched + * domain, ignoring cpusets. + */ +- num_cpus_frozen--; +- if (likely(num_cpus_frozen)) { +- partition_sched_domains(1, NULL, NULL); ++ partition_sched_domains(1, NULL, NULL); ++ if (--num_cpus_frozen) + return; +- } + /* + * This is the last CPU online operation. So fall through and + * restore the original sched domains by considering the + * cpuset configurations. + */ ++ cpuset_force_rebuild(); + } + cpuset_update_active_cpus(); + } +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index 96cea88fa00f..725819569fa7 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -2828,13 +2828,14 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command) + + if (!command || !ftrace_enabled) { + /* +- * If these are per_cpu ops, they still need their +- * per_cpu field freed. Since, function tracing is ++ * If these are dynamic or per_cpu ops, they still ++ * need their data freed. Since, function tracing is + * not currently active, we can just free them + * without synchronizing all CPUs. + */ +- if (ops->flags & FTRACE_OPS_FL_PER_CPU) +- per_cpu_ops_free(ops); ++ if (ops->flags & (FTRACE_OPS_FL_DYNAMIC | FTRACE_OPS_FL_PER_CPU)) ++ goto free_ops; ++ + return 0; + } + +@@ -2900,6 +2901,7 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command) + if (IS_ENABLED(CONFIG_PREEMPT)) + synchronize_rcu_tasks(); + ++ free_ops: + arch_ftrace_trampoline_free(ops); + + if (ops->flags & FTRACE_OPS_FL_PER_CPU) +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 44004d8aa3b3..5efb4b63174e 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -2799,11 +2799,17 @@ static char *get_trace_buf(void) + if (!buffer || buffer->nesting >= 4) + return NULL; + +- return &buffer->buffer[buffer->nesting++][0]; ++ buffer->nesting++; ++ ++ /* Interrupts must see nesting incremented before we use the buffer */ ++ barrier(); ++ return &buffer->buffer[buffer->nesting][0]; + } + + static void put_trace_buf(void) + { ++ /* Don't let the decrement of nesting leak before this */ ++ barrier(); + this_cpu_dec(trace_percpu_buffer->nesting); + } + +@@ -6220,7 +6226,7 @@ static int tracing_set_clock(struct trace_array *tr, const char *clockstr) + tracing_reset_online_cpus(&tr->trace_buffer); + + #ifdef CONFIG_TRACER_MAX_TRACE +- if (tr->flags & TRACE_ARRAY_FL_GLOBAL && tr->max_buffer.buffer) ++ if (tr->max_buffer.buffer) + ring_buffer_set_clock(tr->max_buffer.buffer, trace_clocks[i].func); + tracing_reset_online_cpus(&tr->max_buffer); + #endif +diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c +index 36132f9280e6..51a6e09a7410 100644 +--- a/kernel/trace/trace_events.c ++++ b/kernel/trace/trace_events.c +@@ -406,7 +406,7 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file, + + if (file->flags & EVENT_FILE_FL_RECORDED_TGID) { + tracing_stop_tgid_record(); +- clear_bit(EVENT_FILE_FL_RECORDED_CMD_BIT, &file->flags); ++ clear_bit(EVENT_FILE_FL_RECORDED_TGID_BIT, &file->flags); + } + + call->class->reg(call, TRACE_REG_UNREGISTER, file); +diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c +index cb917cebae29..b17ec642793b 100644 +--- a/kernel/trace/trace_selftest.c ++++ b/kernel/trace/trace_selftest.c +@@ -273,7 +273,7 @@ static int trace_selftest_ops(struct trace_array *tr, int cnt) + goto out_free; + if (cnt > 1) { + if (trace_selftest_test_global_cnt == 0) +- goto out; ++ goto out_free; + } + if (trace_selftest_test_dyn_cnt == 0) + goto out_free; +diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c +index 9979f46c81dc..51390febd5e3 100644 +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -96,19 +96,26 @@ static struct conntrack_gc_work conntrack_gc_work; + + void nf_conntrack_lock(spinlock_t *lock) __acquires(lock) + { ++ /* 1) Acquire the lock */ + spin_lock(lock); +- while (unlikely(nf_conntrack_locks_all)) { +- spin_unlock(lock); + +- /* +- * Order the 'nf_conntrack_locks_all' load vs. the +- * spin_unlock_wait() loads below, to ensure +- * that 'nf_conntrack_locks_all_lock' is indeed held: +- */ +- smp_rmb(); /* spin_lock(&nf_conntrack_locks_all_lock) */ +- spin_unlock_wait(&nf_conntrack_locks_all_lock); +- spin_lock(lock); +- } ++ /* 2) read nf_conntrack_locks_all, with ACQUIRE semantics ++ * It pairs with the smp_store_release() in nf_conntrack_all_unlock() ++ */ ++ if (likely(smp_load_acquire(&nf_conntrack_locks_all) == false)) ++ return; ++ ++ /* fast path failed, unlock */ ++ spin_unlock(lock); ++ ++ /* Slow path 1) get global lock */ ++ spin_lock(&nf_conntrack_locks_all_lock); ++ ++ /* Slow path 2) get the lock we want */ ++ spin_lock(lock); ++ ++ /* Slow path 3) release the global lock */ ++ spin_unlock(&nf_conntrack_locks_all_lock); + } + EXPORT_SYMBOL_GPL(nf_conntrack_lock); + +@@ -149,28 +156,27 @@ static void nf_conntrack_all_lock(void) + int i; + + spin_lock(&nf_conntrack_locks_all_lock); +- nf_conntrack_locks_all = true; + +- /* +- * Order the above store of 'nf_conntrack_locks_all' against +- * the spin_unlock_wait() loads below, such that if +- * nf_conntrack_lock() observes 'nf_conntrack_locks_all' +- * we must observe nf_conntrack_locks[] held: +- */ +- smp_mb(); /* spin_lock(&nf_conntrack_locks_all_lock) */ ++ nf_conntrack_locks_all = true; + + for (i = 0; i < CONNTRACK_LOCKS; i++) { +- spin_unlock_wait(&nf_conntrack_locks[i]); ++ spin_lock(&nf_conntrack_locks[i]); ++ ++ /* This spin_unlock provides the "release" to ensure that ++ * nf_conntrack_locks_all==true is visible to everyone that ++ * acquired spin_lock(&nf_conntrack_locks[]). ++ */ ++ spin_unlock(&nf_conntrack_locks[i]); + } + } + + static void nf_conntrack_all_unlock(void) + { +- /* +- * All prior stores must be complete before we clear ++ /* All prior stores must be complete before we clear + * 'nf_conntrack_locks_all'. Otherwise nf_conntrack_lock() + * might observe the false value but not the entire +- * critical section: ++ * critical section. ++ * It pairs with the smp_load_acquire() in nf_conntrack_lock() + */ + smp_store_release(&nf_conntrack_locks_all, false); + spin_unlock(&nf_conntrack_locks_all_lock); +diff --git a/sound/core/seq_device.c b/sound/core/seq_device.c +index c4acf17e9f5e..e40a2cba5002 100644 +--- a/sound/core/seq_device.c ++++ b/sound/core/seq_device.c +@@ -148,8 +148,10 @@ void snd_seq_device_load_drivers(void) + flush_work(&autoload_work); + } + EXPORT_SYMBOL(snd_seq_device_load_drivers); ++#define cancel_autoload_drivers() cancel_work_sync(&autoload_work) + #else + #define queue_autoload_drivers() /* NOP */ ++#define cancel_autoload_drivers() /* NOP */ + #endif + + /* +@@ -159,6 +161,7 @@ static int snd_seq_device_dev_free(struct snd_device *device) + { + struct snd_seq_device *dev = device->device_data; + ++ cancel_autoload_drivers(); + put_device(&dev->dev); + return 0; + }