commit:     e3e2cb00d3cd51ee0e0f642dd67f6fe06bb79801
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Sep 27 16:38:38 2017 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Sep 27 16:38:38 2017 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=e3e2cb00

Linux patch 4.9.52

 0000_README             |    4 +
 1051_linux-4.9.52.patch | 3985 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 3989 insertions(+)

diff --git a/0000_README b/0000_README
index 54efac8..2ae097d 100644
--- a/0000_README
+++ b/0000_README
@@ -247,6 +247,10 @@ Patch:  1050_linux-4.9.51.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.9.51
 
+Patch:  1051_linux-4.9.52.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.9.52
+
 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/1051_linux-4.9.52.patch b/1051_linux-4.9.52.patch
new file mode 100644
index 0000000..6e49cca
--- /dev/null
+++ b/1051_linux-4.9.52.patch
@@ -0,0 +1,3985 @@
+diff --git a/Makefile b/Makefile
+index b48aebbe187f..c53de1e38c6a 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 9
+-SUBLEVEL = 51
++SUBLEVEL = 52
+ EXTRAVERSION =
+ NAME = Roaring Lionus
+ 
+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 bdb295e09160..a4dc881da277 100644
+--- a/arch/arc/mm/tlb.c
++++ b/arch/arc/mm/tlb.c
+@@ -896,9 +896,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 4a2d03c72959..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 is 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,78 +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));
+ 
+-      /* And now the addition */
+-      assert(zm & DP_HIDDEN_BIT);
++      assert(hrm & (1 << 62));
+ 
+-      /*
+-       * Provide guard,round and stick bit space.
+-       */
+-      zm <<= 3;
++      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);
++      }
++
++      /* 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,
+@@ -278,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 a8cd8b4f235e..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 is 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,108 +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 */
++      /* Multiple 24 bit xm and ym to give 48 bit results */
++      rm64 = (uint64_t)xm * ym;
+ 
+-      t = lxm * hym; /* 16 * 16 => 32 */
+-      at = lrm + (t << 16);
+-      hrm += at < lrm;
+-      lrm = at;
+-      hrm = hrm + (t >> 16);
++      /* Shunt to top of word */
++      rm64 = rm64 << 16;
+ 
+-      t = hxm * lym; /* 16 * 16 => 32 */
+-      at = lrm + (t << 16);
+-      hrm += at < lrm;
+-      lrm = at;
+-      hrm = hrm + (t >> 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));
+ 
+-      /* 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);
+ }
+ 
+@@ -272,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 b2da7c8baed7..292458b694fb 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 = &regs->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 = &regs->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 *) &current->thread.TS_FPR(reg);
+       char *ptr1 = (char *) &current->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 *)&regs->gpr[reg];
+       char *ptr1 = (char *)&regs->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/s390/include/asm/mmu.h b/arch/s390/include/asm/mmu.h
+index bea785d7f853..af85d6b12028 100644
+--- a/arch/s390/include/asm/mmu.h
++++ b/arch/s390/include/asm/mmu.h
+@@ -5,6 +5,7 @@
+ #include <linux/errno.h>
+ 
+ typedef struct {
++      spinlock_t lock;
+       cpumask_t cpu_attach_mask;
+       atomic_t flush_count;
+       unsigned int flush_mm;
+@@ -25,6 +26,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 515fea5a3fc4..f65a708ac395 100644
+--- a/arch/s390/include/asm/mmu_context.h
++++ b/arch/s390/include/asm/mmu_context.h
+@@ -15,6 +15,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);
+@@ -93,7 +94,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);
+@@ -111,9 +111,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);
+@@ -126,6 +125,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 d1f2801ce836..95379fc83805 100644
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -233,7 +233,7 @@ EXPORT_SYMBOL(blk_start_queue_async);
+  **/
+ void blk_start_queue(struct request_queue *q)
+ {
+-      WARN_ON(!irqs_disabled());
++      WARN_ON(!in_interrupt() && !irqs_disabled());
+ 
+       queue_flag_clear(QUEUE_FLAG_STOPPED, q);
+       __blk_run_queue(q);
+diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
+index 45af0fe00f33..aaf2f810d170 100644
+--- a/crypto/algif_skcipher.c
++++ b/crypto/algif_skcipher.c
+@@ -143,8 +143,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/drivers/block/skd_main.c b/drivers/block/skd_main.c
+index 3822eae102db..6f78cea75103 100644
+--- a/drivers/block/skd_main.c
++++ b/drivers/block/skd_main.c
+@@ -2163,6 +2163,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);
+ 
+ }
+@@ -2209,6 +2212,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);
+ }
+ 
+@@ -4622,15 +4628,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/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 <gary.h...@amd.com>
+  * Author: Tom Lendacky <thomas.lenda...@amd.com>
+  *
+  * 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 2c0ce5f605b3..17b19a68e269 100644
+--- a/drivers/crypto/ccp/ccp-dev-v5.c
++++ b/drivers/crypto/ccp/ccp-dev-v5.c
+@@ -131,6 +131,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_SHA_TYPE(p)         ((p)->sha.type)
+ #define       CCP_RSA_SIZE(p)         ((p)->rsa.size)
+@@ -318,6 +319,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 8ac7ae17e1f4..e23c36c7691c 100644
+--- a/drivers/crypto/ccp/ccp-dev.h
++++ b/drivers/crypto/ccp/ccp-dev.h
+@@ -187,6 +187,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_SHA_SB_COUNT              1
+@@ -472,6 +473,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 50fae4442801..64deb006c3be 100644
+--- a/drivers/crypto/ccp/ccp-ops.c
++++ b/drivers/crypto/ccp/ccp-ops.c
+@@ -779,6 +779,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) {
+@@ -802,7 +804,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)))
+@@ -824,23 +828,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 7309c0824887..a2449d77af07 100644
+--- a/drivers/devfreq/devfreq.c
++++ b/drivers/devfreq/devfreq.c
+@@ -574,7 +574,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, sizeof(unsigned 
int) *
+@@ -618,6 +618,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/sun4i/sun4i_drv.c 
b/drivers/gpu/drm/sun4i/sun4i_drv.c
+index c3b21865443e..1feec34ca9dd 100644
+--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
++++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
+@@ -47,6 +47,13 @@ static void sun4i_drv_disable_vblank(struct drm_device 
*drm, unsigned int pipe)
+       sun4i_tcon_enable_vblank(tcon, false);
+ }
+ 
++static void sun4i_drv_lastclose(struct drm_device *dev)
++{
++      struct sun4i_drv *drv = dev->dev_private;
++
++      drm_fbdev_cma_restore_mode(drv->fbdev);
++}
++
+ static const struct file_operations sun4i_drv_fops = {
+       .owner          = THIS_MODULE,
+       .open           = drm_open,
+@@ -65,6 +72,7 @@ static struct drm_driver sun4i_drv_driver = {
+       .driver_features        = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | 
DRIVER_ATOMIC,
+ 
+       /* Generic Operations */
++      .lastclose              = sun4i_drv_lastclose,
+       .fops                   = &sun4i_drv_fops,
+       .name                   = "sun4i-drm",
+       .desc                   = "Allwinner sun4i Display Engine",
+diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
+index 63e82f8e8308..fb4ce0394ac7 100644
+--- a/drivers/infiniband/core/addr.c
++++ b/drivers/infiniband/core/addr.c
+@@ -446,15 +446,10 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
+ 
+       ret = ipv6_stub->ipv6_dst_lookup(addr->net, NULL, &dst, &fl6);
+       if (ret < 0)
+-              goto put;
++              return ret;
+ 
+       rt = (struct rt6_info *)dst;
+-      if (ipv6_addr_any(&fl6.saddr)) {
+-              ret = ipv6_dev_get_saddr(addr->net, ip6_dst_idev(dst)->dev,
+-                                       &fl6.daddr, 0, &fl6.saddr);
+-              if (ret)
+-                      goto put;
+-
++      if (ipv6_addr_any(&src_in->sin6_addr)) {
+               src_in->sin6_family = AF_INET6;
+               src_in->sin6_addr = fl6.saddr;
+       }
+@@ -471,9 +466,6 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
+ 
+       *pdst = dst;
+       return 0;
+-put:
+-      dst_release(dst);
+-      return ret;
+ }
+ #else
+ static int addr6_resolve(struct sockaddr_in6 *src_in,
+diff --git a/drivers/infiniband/hw/hfi1/rc.c b/drivers/infiniband/hw/hfi1/rc.c
+index 4bd5b5caa243..613074e963bb 100644
+--- a/drivers/infiniband/hw/hfi1/rc.c
++++ b/drivers/infiniband/hw/hfi1/rc.c
+@@ -551,7 +551,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) &&
+@@ -559,6 +559,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/qib/qib_rc.c 
b/drivers/infiniband/hw/qib/qib_rc.c
+index f3fe787c9426..c1523f9a3c12 100644
+--- a/drivers/infiniband/hw/qib/qib_rc.c
++++ b/drivers/infiniband/hw/qib/qib_rc.c
+@@ -357,7 +357,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) &&
+@@ -365,7 +365,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/serio/i8042-x86ia64io.h 
b/drivers/input/serio/i8042-x86ia64io.h
+index 5be14ad29d46..dbf09836ff30 100644
+--- a/drivers/input/serio/i8042-x86ia64io.h
++++ b/drivers/input/serio/i8042-x86ia64io.h
+@@ -904,6 +904,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/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
+index c3ea03c9a1a8..02619cabda8b 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 a37c1776f2e3..e0f1c6d534fe 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.
+diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
+index 66669c8f4161..f4557f558b24 100644
+--- a/drivers/md/bcache/super.c
++++ b/drivers/md/bcache/super.c
+@@ -1025,7 +1025,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);
+@@ -1058,6 +1058,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);
+ 
+@@ -1229,6 +1231,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);
+ 
+@@ -1967,6 +1970,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 b3ff57d61dde..4fbb5532f24c 100644
+--- a/drivers/md/bcache/sysfs.c
++++ b/drivers/md/bcache/sysfs.c
+@@ -191,7 +191,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;
+ 
+@@ -226,7 +226,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 dde6172f3f10..eb70f6894f05 100644
+--- a/drivers/md/bcache/util.c
++++ b/drivers/md/bcache/util.c
+@@ -73,24 +73,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 e51644e503a5..4ce2b19fe120 100644
+--- a/drivers/md/bcache/writeback.c
++++ b/drivers/md/bcache/writeback.c
+@@ -20,7 +20,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 301eaf565167..cdf8d253209e 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)
+ {
+@@ -85,7 +104,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 2d826927a3bf..fb02c3979bf4 100644
+--- a/drivers/md/bitmap.c
++++ b/drivers/md/bitmap.c
+@@ -1992,6 +1992,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.
+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 bacecbd68a6d..dc51dd86377d 100644
+--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
++++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+@@ -773,7 +773,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/pci/hotplug/pciehp_hpc.c 
b/drivers/pci/hotplug/pciehp_hpc.c
+index b57fc6d6e28a..d08dfc8b9ba9 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 c9a146948192..a5b7bd3c9bac 100644
+--- a/drivers/pinctrl/pinctrl-amd.c
++++ b/drivers/pinctrl/pinctrl-amd.c
+@@ -32,6 +32,7 @@
+ #include <linux/pinctrl/pinconf.h>
+ #include <linux/pinctrl/pinconf-generic.h>
+ 
++#include "core.h"
+ #include "pinctrl-utils.h"
+ #include "pinctrl-amd.h"
+ 
+@@ -712,6 +713,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),
+@@ -751,6 +815,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;
+@@ -839,6 +911,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 7bfea47dbb47..e8bbb20779d0 100644
+--- a/drivers/pinctrl/pinctrl-amd.h
++++ b/drivers/pinctrl/pinctrl-amd.h
+@@ -95,6 +95,7 @@ struct amd_gpio {
+       struct gpio_chip        gc;
+       struct resource         *res;
+       struct platform_device  *pdev;
++      u32                     *saved_regs;
+ };
+ 
+ /*  KERNCZ configuration*/
+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 07ffdbb5107f..9bd9b9a29dfc 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/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
+index d8b1fbd4c8aa..35cbd36f8d3b 100644
+--- a/drivers/scsi/megaraid/megaraid_sas_base.c
++++ b/drivers/scsi/megaraid/megaraid_sas_base.c
+@@ -1901,9 +1901,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 {
+@@ -5290,7 +5293,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))
+@@ -5459,6 +5463,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/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
+index 8c4641b518b5..9a34afcb1c4c 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_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
+index 3dfb54abc874..f8ae70476b3a 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/sg.c b/drivers/scsi/sg.c
+index 9236a13d5d2a..02dfbc1373e3 100644
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -122,7 +122,7 @@ struct sg_device;          /* forward declarations */
+ struct sg_fd;
+ 
+ typedef struct sg_request {   /* SG_MAX_QUEUE requests outstanding per file */
+-      struct sg_request *nextrp;      /* NULL -> tail request (slist) */
++      struct list_head entry; /* list entry */
+       struct sg_fd *parentfp; /* NULL -> not in use */
+       Sg_scatter_hold data;   /* hold buffer, perhaps scatter list */
+       sg_io_hdr_t header;     /* scsi command+info, see <scsi/sg.h> */
+@@ -146,8 +146,7 @@ typedef struct sg_fd {             /* holds the state of a 
file descriptor */
+       int timeout;            /* defaults to SG_DEFAULT_TIMEOUT      */
+       int timeout_user;       /* defaults to SG_DEFAULT_TIMEOUT_USER */
+       Sg_scatter_hold reserve;        /* buffer held for this file descriptor 
*/
+-      unsigned save_scat_len; /* original length of trunc. scat. element */
+-      Sg_request *headrp;     /* head of request slist, NULL->empty */
++      struct list_head rq_list; /* head of request list */
+       struct fasync_struct *async_qp; /* used by asynchronous notification */
+       Sg_request req_arr[SG_MAX_QUEUE];       /* used as singly-linked list */
+       char low_dma;           /* as in parent but possibly overridden to 1 */
+@@ -829,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)
+ {
+@@ -941,7 +973,7 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned 
long arg)
+               if (!access_ok(VERIFY_WRITE, ip, sizeof (int)))
+                       return -EFAULT;
+               read_lock_irqsave(&sfp->rq_list_lock, iflags);
+-              for (srp = sfp->headrp; srp; srp = srp->nextrp) {
++              list_for_each_entry(srp, &sfp->rq_list, entry) {
+                       if ((1 == srp->done) && (!srp->sg_io_owned)) {
+                               read_unlock_irqrestore(&sfp->rq_list_lock,
+                                                      iflags);
+@@ -954,7 +986,8 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned 
long arg)
+               return 0;
+       case SG_GET_NUM_WAITING:
+               read_lock_irqsave(&sfp->rq_list_lock, iflags);
+-              for (val = 0, srp = sfp->headrp; srp; srp = srp->nextrp) {
++              val = 0;
++              list_for_each_entry(srp, &sfp->rq_list, entry) {
+                       if ((1 == srp->done) && (!srp->sg_io_owned))
+                               ++val;
+               }
+@@ -1022,42 +1055,15 @@ 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);
+-                      for (srp = sfp->headrp, val = 0; val < SG_MAX_QUEUE;
+-                           ++val, srp = srp ? srp->nextrp : srp) {
+-                              memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
+-                              if (srp) {
+-                                      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;
+-                              }
+-                      }
++                      sg_fill_request_table(sfp, rinfo);
+                       read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+-                      result = __copy_to_user(p, rinfo, 
++                      result = __copy_to_user(p, rinfo,
+                                               SZ_SG_REQ_INFO * SG_MAX_QUEUE);
+                       result = result ? -EFAULT : 0;
+                       kfree(rinfo);
+@@ -1163,7 +1169,7 @@ sg_poll(struct file *filp, poll_table * wait)
+               return POLLERR;
+       poll_wait(filp, &sfp->read_wait, wait);
+       read_lock_irqsave(&sfp->rq_list_lock, iflags);
+-      for (srp = sfp->headrp; srp; srp = srp->nextrp) {
++      list_for_each_entry(srp, &sfp->rq_list, entry) {
+               /* if any read waiting, flag it */
+               if ((0 == res) && (1 == srp->done) && (!srp->sg_io_owned))
+                       res = POLLIN | POLLRDNORM;
+@@ -2049,7 +2055,6 @@ sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp)
+       req_schp->pages = NULL;
+       req_schp->page_order = 0;
+       req_schp->sglist_len = 0;
+-      sfp->save_scat_len = 0;
+       srp->res_used = 0;
+       /* Called without mutex lock to avoid deadlock */
+       sfp->res_in_use = 0;
+@@ -2062,7 +2067,7 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id)
+       unsigned long iflags;
+ 
+       write_lock_irqsave(&sfp->rq_list_lock, iflags);
+-      for (resp = sfp->headrp; resp; resp = resp->nextrp) {
++      list_for_each_entry(resp, &sfp->rq_list, entry) {
+               /* look for requests that are ready + not SG_IO owned */
+               if ((1 == resp->done) && (!resp->sg_io_owned) &&
+                   ((-1 == pack_id) || (resp->header.pack_id == pack_id))) {
+@@ -2080,70 +2085,45 @@ sg_add_request(Sg_fd * sfp)
+ {
+       int k;
+       unsigned long iflags;
+-      Sg_request *resp;
+       Sg_request *rp = sfp->req_arr;
+ 
+       write_lock_irqsave(&sfp->rq_list_lock, iflags);
+-      resp = sfp->headrp;
+-      if (!resp) {
+-              memset(rp, 0, sizeof (Sg_request));
+-              rp->parentfp = sfp;
+-              resp = rp;
+-              sfp->headrp = resp;
+-      } else {
+-              if (0 == sfp->cmd_q)
+-                      resp = NULL;    /* command queuing disallowed */
+-              else {
+-                      for (k = 0; k < SG_MAX_QUEUE; ++k, ++rp) {
+-                              if (!rp->parentfp)
+-                                      break;
+-                      }
+-                      if (k < SG_MAX_QUEUE) {
+-                              memset(rp, 0, sizeof (Sg_request));
+-                              rp->parentfp = sfp;
+-                              while (resp->nextrp)
+-                                      resp = resp->nextrp;
+-                              resp->nextrp = rp;
+-                              resp = rp;
+-                      } else
+-                              resp = NULL;
++      if (!list_empty(&sfp->rq_list)) {
++              if (!sfp->cmd_q)
++                      goto out_unlock;
++
++              for (k = 0; k < SG_MAX_QUEUE; ++k, ++rp) {
++                      if (!rp->parentfp)
++                              break;
+               }
++              if (k >= SG_MAX_QUEUE)
++                      goto out_unlock;
+       }
+-      if (resp) {
+-              resp->nextrp = NULL;
+-              resp->header.duration = jiffies_to_msecs(jiffies);
+-      }
++      memset(rp, 0, sizeof (Sg_request));
++      rp->parentfp = sfp;
++      rp->header.duration = jiffies_to_msecs(jiffies);
++      list_add_tail(&rp->entry, &sfp->rq_list);
+       write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+-      return resp;
++      return rp;
++out_unlock:
++      write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
++      return NULL;
+ }
+ 
+ /* Return of 1 for found; 0 for not found */
+ static int
+ sg_remove_request(Sg_fd * sfp, Sg_request * srp)
+ {
+-      Sg_request *prev_rp;
+-      Sg_request *rp;
+       unsigned long iflags;
+       int res = 0;
+ 
+-      if ((!sfp) || (!srp) || (!sfp->headrp))
++      if (!sfp || !srp || list_empty(&sfp->rq_list))
+               return res;
+       write_lock_irqsave(&sfp->rq_list_lock, iflags);
+-      prev_rp = sfp->headrp;
+-      if (srp == prev_rp) {
+-              sfp->headrp = prev_rp->nextrp;
+-              prev_rp->parentfp = NULL;
++      if (!list_empty(&srp->entry)) {
++              list_del(&srp->entry);
++              srp->parentfp = NULL;
+               res = 1;
+-      } else {
+-              while ((rp = prev_rp->nextrp)) {
+-                      if (srp == rp) {
+-                              prev_rp->nextrp = rp->nextrp;
+-                              rp->parentfp = NULL;
+-                              res = 1;
+-                              break;
+-                      }
+-                      prev_rp = rp;
+-              }
+       }
+       write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+       return res;
+@@ -2162,7 +2142,7 @@ sg_add_sfp(Sg_device * sdp)
+ 
+       init_waitqueue_head(&sfp->read_wait);
+       rwlock_init(&sfp->rq_list_lock);
+-
++      INIT_LIST_HEAD(&sfp->rq_list);
+       kref_init(&sfp->f_ref);
+       mutex_init(&sfp->f_mutex);
+       sfp->timeout = SG_DEFAULT_TIMEOUT;
+@@ -2203,10 +2183,13 @@ sg_remove_sfp_usercontext(struct work_struct *work)
+ {
+       struct sg_fd *sfp = container_of(work, struct sg_fd, ew.work);
+       struct sg_device *sdp = sfp->parentdp;
++      Sg_request *srp;
+ 
+       /* Cleanup any responses which were never read(). */
+-      while (sfp->headrp)
+-              sg_finish_rem_req(sfp->headrp);
++      while (!list_empty(&sfp->rq_list)) {
++              srp = list_first_entry(&sfp->rq_list, Sg_request, entry);
++              sg_finish_rem_req(srp);
++      }
+ 
+       if (sfp->reserve.bufflen > 0) {
+               SCSI_LOG_TIMEOUT(6, sg_printk(KERN_INFO, sdp,
+@@ -2609,7 +2592,7 @@ static int sg_proc_seq_show_devstrs(struct seq_file *s, 
void *v)
+ /* must be called while holding sg_index_lock */
+ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp)
+ {
+-      int k, m, new_interface, blen, usg;
++      int k, new_interface, blen, usg;
+       Sg_request *srp;
+       Sg_fd *fp;
+       const sg_io_hdr_t *hp;
+@@ -2629,13 +2612,11 @@ static void sg_proc_debug_helper(struct seq_file *s, 
Sg_device * sdp)
+               seq_printf(s, "   cmd_q=%d f_packid=%d k_orphan=%d closed=0\n",
+                          (int) fp->cmd_q, (int) fp->force_packid,
+                          (int) fp->keep_orphan);
+-              for (m = 0, srp = fp->headrp;
+-                              srp != NULL;
+-                              ++m, srp = srp->nextrp) {
++              list_for_each_entry(srp, &fp->rq_list, entry) {
+                       hp = &srp->header;
+                       new_interface = (hp->interface_id == '\0') ? 0 : 1;
+                       if (srp->res_used) {
+-                              if (new_interface && 
++                              if (new_interface &&
+                                   (SG_FLAG_MMAP_IO & hp->flags))
+                                       cp = "     mmap>> ";
+                               else
+@@ -2666,7 +2647,7 @@ static void sg_proc_debug_helper(struct seq_file *s, 
Sg_device * sdp)
+                       seq_printf(s, "ms sgat=%d op=0x%02x\n", usg,
+                                  (int) srp->data.cmd_opcode);
+               }
+-              if (0 == m)
++              if (list_empty(&fp->rq_list))
+                       seq_puts(s, "     No requests active\n");
+               read_unlock(&fp->rq_list_lock);
+       }
+diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
+index c5ab1b0037fc..2bf96d33428a 100644
+--- a/drivers/scsi/storvsc_drv.c
++++ b/drivers/scsi/storvsc_drv.c
+@@ -1559,6 +1559,8 @@ static int storvsc_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *scmnd)
+       ret = storvsc_do_io(dev, cmd_request);
+ 
+       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 aa80dc94ddc2..c220c2c0893f 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/super.c b/fs/ext4/super.c
+index 5fa9ba1de429..f72535e1898f 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -2334,6 +2334,7 @@ static void ext4_orphan_cleanup(struct super_block *sb,
+       unsigned int s_flags = sb->s_flags;
+       int nr_orphans = 0, nr_truncates = 0;
+ #ifdef CONFIG_QUOTA
++      int quota_update = 0;
+       int i;
+ #endif
+       if (!es->s_last_orphan) {
+@@ -2372,14 +2373,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
+@@ -2438,10 +2457,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 */
+@@ -5365,6 +5386,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/nfs/callback.c b/fs/nfs/callback.c
+index 0a2115084c3f..582bfee40345 100644
+--- a/fs/nfs/callback.c
++++ b/fs/nfs/callback.c
+@@ -75,7 +75,10 @@ nfs4_callback_svc(void *vrqstp)
+ 
+       set_freezable();
+ 
+-      while (!kthread_should_stop()) {
++      while (!kthread_freezable_should_stop(NULL)) {
++
++              if (signal_pending(current))
++                      flush_signals(current);
+               /*
+                * Listen for a request on the socket
+                */
+@@ -84,6 +87,8 @@ nfs4_callback_svc(void *vrqstp)
+                       continue;
+               svc_process(rqstp);
+       }
++      svc_exit_thread(rqstp);
++      module_put_and_exit(0);
+       return 0;
+ }
+ 
+@@ -102,9 +107,10 @@ nfs41_callback_svc(void *vrqstp)
+ 
+       set_freezable();
+ 
+-      while (!kthread_should_stop()) {
+-              if (try_to_freeze())
+-                      continue;
++      while (!kthread_freezable_should_stop(NULL)) {
++
++              if (signal_pending(current))
++                      flush_signals(current);
+ 
+               prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE);
+               spin_lock_bh(&serv->sv_cb_lock);
+@@ -120,11 +126,13 @@ nfs41_callback_svc(void *vrqstp)
+                               error);
+               } else {
+                       spin_unlock_bh(&serv->sv_cb_lock);
+-                      schedule();
++                      if (!kthread_should_stop())
++                              schedule();
+                       finish_wait(&serv->sv_cb_waitq, &wq);
+               }
+-              flush_signals(current);
+       }
++      svc_exit_thread(rqstp);
++      module_put_and_exit(0);
+       return 0;
+ }
+ 
+@@ -220,14 +228,14 @@ static int nfs_callback_up_net(int minorversion, struct 
svc_serv *serv,
+ static struct svc_serv_ops nfs40_cb_sv_ops = {
+       .svo_function           = nfs4_callback_svc,
+       .svo_enqueue_xprt       = svc_xprt_do_enqueue,
+-      .svo_setup              = svc_set_num_threads,
++      .svo_setup              = svc_set_num_threads_sync,
+       .svo_module             = THIS_MODULE,
+ };
+ #if defined(CONFIG_NFS_V4_1)
+ static struct svc_serv_ops nfs41_cb_sv_ops = {
+       .svo_function           = nfs41_callback_svc,
+       .svo_enqueue_xprt       = svc_xprt_do_enqueue,
+-      .svo_setup              = svc_set_num_threads,
++      .svo_setup              = svc_set_num_threads_sync,
+       .svo_module             = THIS_MODULE,
+ };
+ 
+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 edc5d04b9632..1cfe5ef3060b 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 <thomas.lenda...@amd.com>
+  * Author: Gary R Hook <gary.h...@amd.com>
+@@ -222,6 +222,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/sunrpc/svc.h b/include/linux/sunrpc/svc.h
+index 7321ae933867..102c84dcc11a 100644
+--- a/include/linux/sunrpc/svc.h
++++ b/include/linux/sunrpc/svc.h
+@@ -470,6 +470,7 @@ void                  svc_pool_map_put(void);
+ struct svc_serv *  svc_create_pooled(struct svc_program *, unsigned int,
+                       struct svc_serv_ops *);
+ int              svc_set_num_threads(struct svc_serv *, struct svc_pool *, 
int);
++int              svc_set_num_threads_sync(struct svc_serv *, struct svc_pool 
*, int);
+ int              svc_pool_stats_open(struct svc_serv *serv, struct file 
*file);
+ void             svc_destroy(struct svc_serv *);
+ void             svc_shutdown_net(struct svc_serv *, struct net *);
+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/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 6e432ed7d0fe..53ed8ae5de1c 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -2747,13 +2747,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;
+       }
+ 
+@@ -2808,6 +2809,7 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int 
command)
+       if (ops->flags & (FTRACE_OPS_FL_DYNAMIC | FTRACE_OPS_FL_PER_CPU)) {
+               schedule_on_each_cpu(ftrace_sync);
+ 
++ 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 7379f735a9f4..f95bf81529f5 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -2369,11 +2369,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);
+ }
+ 
+@@ -5658,7 +5664,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_selftest.c b/kernel/trace/trace_selftest.c
+index b0f86ea77881..ca70d11b8aa7 100644
+--- a/kernel/trace/trace_selftest.c
++++ b/kernel/trace/trace_selftest.c
+@@ -272,7 +272,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/mm/page_alloc.c b/mm/page_alloc.c
+index 2abf8d5f0ad4..7064aae8ded7 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -2100,13 +2100,25 @@ static void unreserve_highatomic_pageblock(const 
struct alloc_context *ac)
+                               continue;
+ 
+                       /*
+-                       * It should never happen but changes to locking could
+-                       * inadvertently allow a per-cpu drain to add pages
+-                       * to MIGRATE_HIGHATOMIC while unreserving so be safe
+-                       * and watch for underflows.
++                       * In page freeing path, migratetype change is racy so
++                       * we can counter several free pages in a pageblock
++                       * in this loop althoug we changed the pageblock type
++                       * from highatomic to ac->migratetype. So we should
++                       * adjust the count once.
+                        */
+-                      zone->nr_reserved_highatomic -= min(pageblock_nr_pages,
+-                              zone->nr_reserved_highatomic);
++                      if (get_pageblock_migratetype(page) ==
++                                                      MIGRATE_HIGHATOMIC) {
++                              /*
++                               * It should never happen but changes to
++                               * locking could inadvertently allow a per-cpu
++                               * drain to add pages to MIGRATE_HIGHATOMIC
++                               * while unreserving so be safe and watch for
++                               * underflows.
++                               */
++                              zone->nr_reserved_highatomic -= min(
++                                              pageblock_nr_pages,
++                                              zone->nr_reserved_highatomic);
++                      }
+ 
+                       /*
+                        * Convert to ac->migratetype and avoid the normal
+diff --git a/net/netfilter/nf_conntrack_core.c 
b/net/netfilter/nf_conntrack_core.c
+index 6bd150882ba4..ed9ce7c63252 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -95,19 +95,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);
+ 
+@@ -148,28 +155,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/net/sunrpc/svc.c b/net/sunrpc/svc.c
+index 75f290bddca1..272c34551979 100644
+--- a/net/sunrpc/svc.c
++++ b/net/sunrpc/svc.c
+@@ -702,59 +702,32 @@ choose_victim(struct svc_serv *serv, struct svc_pool 
*pool, unsigned int *state)
+       return task;
+ }
+ 
+-/*
+- * Create or destroy enough new threads to make the number
+- * of threads the given number.  If `pool' is non-NULL, applies
+- * only to threads in that pool, otherwise round-robins between
+- * all pools.  Caller must ensure that mutual exclusion between this and
+- * server startup or shutdown.
+- *
+- * Destroying threads relies on the service threads filling in
+- * rqstp->rq_task, which only the nfs ones do.  Assumes the serv
+- * has been created using svc_create_pooled().
+- *
+- * Based on code that used to be in nfsd_svc() but tweaked
+- * to be pool-aware.
+- */
+-int
+-svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
++/* create new threads */
++static int
++svc_start_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
+ {
+       struct svc_rqst *rqstp;
+       struct task_struct *task;
+       struct svc_pool *chosen_pool;
+-      int error = 0;
+       unsigned int state = serv->sv_nrthreads-1;
+       int node;
+ 
+-      if (pool == NULL) {
+-              /* The -1 assumes caller has done a svc_get() */
+-              nrservs -= (serv->sv_nrthreads-1);
+-      } else {
+-              spin_lock_bh(&pool->sp_lock);
+-              nrservs -= pool->sp_nrthreads;
+-              spin_unlock_bh(&pool->sp_lock);
+-      }
+-
+-      /* create new threads */
+-      while (nrservs > 0) {
++      do {
+               nrservs--;
+               chosen_pool = choose_pool(serv, pool, &state);
+ 
+               node = svc_pool_map_get_node(chosen_pool->sp_id);
+               rqstp = svc_prepare_thread(serv, chosen_pool, node);
+-              if (IS_ERR(rqstp)) {
+-                      error = PTR_ERR(rqstp);
+-                      break;
+-              }
++              if (IS_ERR(rqstp))
++                      return PTR_ERR(rqstp);
+ 
+               __module_get(serv->sv_ops->svo_module);
+               task = kthread_create_on_node(serv->sv_ops->svo_function, rqstp,
+                                             node, "%s", serv->sv_name);
+               if (IS_ERR(task)) {
+-                      error = PTR_ERR(task);
+                       module_put(serv->sv_ops->svo_module);
+                       svc_exit_thread(rqstp);
+-                      break;
++                      return PTR_ERR(task);
+               }
+ 
+               rqstp->rq_task = task;
+@@ -763,18 +736,103 @@ svc_set_num_threads(struct svc_serv *serv, struct 
svc_pool *pool, int nrservs)
+ 
+               svc_sock_update_bufs(serv);
+               wake_up_process(task);
+-      }
++      } while (nrservs > 0);
++
++      return 0;
++}
++
++
++/* destroy old threads */
++static int
++svc_signal_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
++{
++      struct task_struct *task;
++      unsigned int state = serv->sv_nrthreads-1;
++
+       /* destroy old threads */
+-      while (nrservs < 0 &&
+-             (task = choose_victim(serv, pool, &state)) != NULL) {
++      do {
++              task = choose_victim(serv, pool, &state);
++              if (task == NULL)
++                      break;
+               send_sig(SIGINT, task, 1);
+               nrservs++;
++      } while (nrservs < 0);
++
++      return 0;
++}
++
++/*
++ * Create or destroy enough new threads to make the number
++ * of threads the given number.  If `pool' is non-NULL, applies
++ * only to threads in that pool, otherwise round-robins between
++ * all pools.  Caller must ensure that mutual exclusion between this and
++ * server startup or shutdown.
++ *
++ * Destroying threads relies on the service threads filling in
++ * rqstp->rq_task, which only the nfs ones do.  Assumes the serv
++ * has been created using svc_create_pooled().
++ *
++ * Based on code that used to be in nfsd_svc() but tweaked
++ * to be pool-aware.
++ */
++int
++svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
++{
++      if (pool == NULL) {
++              /* The -1 assumes caller has done a svc_get() */
++              nrservs -= (serv->sv_nrthreads-1);
++      } else {
++              spin_lock_bh(&pool->sp_lock);
++              nrservs -= pool->sp_nrthreads;
++              spin_unlock_bh(&pool->sp_lock);
+       }
+ 
+-      return error;
++      if (nrservs > 0)
++              return svc_start_kthreads(serv, pool, nrservs);
++      if (nrservs < 0)
++              return svc_signal_kthreads(serv, pool, nrservs);
++      return 0;
+ }
+ EXPORT_SYMBOL_GPL(svc_set_num_threads);
+ 
++/* destroy old threads */
++static int
++svc_stop_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
++{
++      struct task_struct *task;
++      unsigned int state = serv->sv_nrthreads-1;
++
++      /* destroy old threads */
++      do {
++              task = choose_victim(serv, pool, &state);
++              if (task == NULL)
++                      break;
++              kthread_stop(task);
++              nrservs++;
++      } while (nrservs < 0);
++      return 0;
++}
++
++int
++svc_set_num_threads_sync(struct svc_serv *serv, struct svc_pool *pool, int 
nrservs)
++{
++      if (pool == NULL) {
++              /* The -1 assumes caller has done a svc_get() */
++              nrservs -= (serv->sv_nrthreads-1);
++      } else {
++              spin_lock_bh(&pool->sp_lock);
++              nrservs -= pool->sp_nrthreads;
++              spin_unlock_bh(&pool->sp_lock);
++      }
++
++      if (nrservs > 0)
++              return svc_start_kthreads(serv, pool, nrservs);
++      if (nrservs < 0)
++              return svc_stop_kthreads(serv, pool, nrservs);
++      return 0;
++}
++EXPORT_SYMBOL_GPL(svc_set_num_threads_sync);
++
+ /*
+  * Called from a server thread as it's exiting. Caller must hold the "service
+  * mutex" for the service.

Reply via email to