diff --git a/Makefile b/Makefile
index 788d90a0051b..7e4c46b375b3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 4
-SUBLEVEL = 88
+SUBLEVEL = 89
 EXTRAVERSION =
 NAME = Blurry Fish Butt
 
diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S
index 2efb0625331d..db1eee5fe502 100644
--- a/arch/arc/kernel/entry.S
+++ b/arch/arc/kernel/entry.S
@@ -104,6 +104,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 daf2bf52b984..97e9582dcf99 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -885,9 +885,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/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/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 91e5c1758b5c..64e016abb2a5 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -236,6 +236,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,
@@ -264,9 +286,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;
@@ -310,31 +333,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;
                }
        }
@@ -346,29 +369,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 */
 }
 
@@ -378,24 +404,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 */
@@ -688,9 +717,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__
@@ -740,7 +774,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;
@@ -923,7 +957,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 */
@@ -953,15 +987,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);
@@ -1031,15 +1062,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/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index bcd3d6199464..bb16a58cf7e4 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -204,6 +204,7 @@ void set_personality_ia32(bool);
 
 #define ELF_CORE_COPY_REGS(pr_reg, regs)                       \
 do {                                                           \
+       unsigned long base;                                     \
        unsigned v;                                             \
        (pr_reg)[0] = (regs)->r15;                              \
        (pr_reg)[1] = (regs)->r14;                              \
@@ -226,8 +227,8 @@ do {                                                        
        \
        (pr_reg)[18] = (regs)->flags;                           \
        (pr_reg)[19] = (regs)->sp;                              \
        (pr_reg)[20] = (regs)->ss;                              \
-       (pr_reg)[21] = current->thread.fs;                      \
-       (pr_reg)[22] = current->thread.gs;                      \
+       rdmsrl(MSR_FS_BASE, base); (pr_reg)[21] = base;         \
+       rdmsrl(MSR_KERNEL_GS_BASE, base); (pr_reg)[22] = base;  \
        asm("movl %%ds,%0" : "=r" (v)); (pr_reg)[23] = v;       \
        asm("movl %%es,%0" : "=r" (v)); (pr_reg)[24] = v;       \
        asm("movl %%fs,%0" : "=r" (v)); (pr_reg)[25] = v;       \
diff --git a/block/blk-core.c b/block/blk-core.c
index ef083e7a37c5..119658534dfd 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 b3b0004ea8ac..d12782dc9683 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 586f9168ffa4..47d1e834f3f4 100644
--- a/drivers/block/skd_main.c
+++ b/drivers/block/skd_main.c
@@ -2214,6 +2214,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);
 
 }
@@ -2260,6 +2263,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);
 }
 
@@ -4679,15 +4685,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/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 2410df1c2a05..6c4c7caea693 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_FLUSH; 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 7b5880b8874c..c5ceea9222ff 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1023,7 +1023,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);
@@ -1056,6 +1056,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);
 
@@ -1227,6 +1229,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);
 
@@ -1959,6 +1962,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 db3ae4c2b223..6c18e3ec3e48 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 b9346cd9cda1..bbb1dc9e1639 100644
--- a/drivers/md/bcache/writeback.c
+++ b/drivers/md/bcache/writeback.c
@@ -21,7 +21,8 @@
 static void __update_writeback_rate(struct cached_dev *dc)
 {
        struct cache_set *c = dc->disk.c;
-       uint64_t cache_sectors = c->nbuckets * c->sb.bucket_size;
+       uint64_t cache_sectors = c->nbuckets * c->sb.bucket_size -
+                               bcache_flash_devs_sectors_dirty(c);
        uint64_t cache_dirty_target =
                div_u64(cache_sectors * dc->writeback_percent, 100);
 
@@ -190,7 +191,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)
@@ -210,7 +211,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)
@@ -488,17 +489,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)
@@ -522,6 +523,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 073a042aed24..daec4fd782ea 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 4f22e919787a..7a50728b9389 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1960,6 +1960,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/md/raid5.c b/drivers/md/raid5.c
index 8f60520c8392..5eac08ffc697 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -5822,6 +5822,8 @@ static void raid5_do_work(struct work_struct *work)
 
        spin_unlock_irq(&conf->device_lock);
 
+       r5l_flush_stripe_to_raid(conf->log);
+
        async_tx_issue_pending_all();
        blk_finish_plug(&plug);
 
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index 3e59b288b8a8..618e4e2b4207 100644
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -2001,6 +2001,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 109f687d1cbd..4379b949bb93 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/net/ethernet/freescale/gianfar.c 
b/drivers/net/ethernet/freescale/gianfar.c
index 4cd2a7d0124f..7923bfdc9b30 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -3676,7 +3676,7 @@ static noinline void gfar_update_link_state(struct 
gfar_private *priv)
                u32 tempval1 = gfar_read(&regs->maccfg1);
                u32 tempval = gfar_read(&regs->maccfg2);
                u32 ecntrl = gfar_read(&regs->ecntrl);
-               u32 tx_flow_oldval = (tempval & MACCFG1_TX_FLOW);
+               u32 tx_flow_oldval = (tempval1 & MACCFG1_TX_FLOW);
 
                if (phydev->duplex != priv->oldduplex) {
                        if (!(phydev->duplex))
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c 
b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
index 829be21f97b2..be258d90de9e 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
@@ -724,7 +724,7 @@ static void ql_build_coredump_seg_header(
        seg_hdr->cookie = MPI_COREDUMP_COOKIE;
        seg_hdr->segNum = seg_number;
        seg_hdr->segSize = seg_size;
-       memcpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1);
+       strncpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1);
 }
 
 /*
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 49d9f0a789fe..7d0690433ee0 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -541,9 +541,6 @@ void phy_stop_machine(struct phy_device *phydev)
        if (phydev->state > PHY_UP && phydev->state != PHY_HALTED)
                phydev->state = PHY_UP;
        mutex_unlock(&phydev->lock);
-
-       /* Now we can run the state machine synchronously */
-       phy_state_machine(&phydev->state_queue.work);
 }
 
 /**
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index 7d223e9080ef..77dddee2753a 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/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 17c440b9d086..6835bae33ec4 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -1824,9 +1824,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 {
@@ -5094,6 +5097,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 1ed85dfc008d..ac12ee844bfc 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -404,6 +404,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) {
@@ -429,8 +431,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);
@@ -503,8 +504,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/sg.c b/drivers/scsi/sg.c
index 71325972e503..39e8b5dc23fa 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -133,7 +133,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> */
@@ -157,8 +157,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 */
@@ -840,6 +839,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)
 {
@@ -951,7 +983,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);
@@ -964,7 +996,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;
                }
@@ -1032,42 +1065,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);
@@ -1173,7 +1179,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;
@@ -2059,7 +2065,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;
@@ -2072,7 +2077,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))) {
@@ -2090,70 +2095,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;
@@ -2172,7 +2152,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;
@@ -2213,10 +2193,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,
@@ -2619,7 +2602,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;
@@ -2639,13 +2622,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
@@ -2676,7 +2657,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 cd5c1c060481..6df2841cb7f9 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1511,6 +1511,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 fb31eecb708d..8f3566cde3eb 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 68345a9e59b8..32941cd6d34b 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2205,6 +2205,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) {
@@ -2243,14 +2244,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
@@ -2309,10 +2328,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 */
@@ -5120,6 +5141,9 @@ static int ext4_enable_quotas(struct super_block *sb)
                        err = ext4_quota_enable(sb, type, QFMT_VFS_V1,
                                                DQUOT_USAGE_ENABLED);
                        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/f2fs/recovery.c b/fs/f2fs/recovery.c
index cbf74f47cce8..e32f349f341b 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -276,7 +276,7 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info 
*sbi,
                return 0;
 
        /* Get the previous summary */
-       for (i = CURSEG_WARM_DATA; i <= CURSEG_COLD_DATA; i++) {
+       for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
                struct curseg_info *curseg = CURSEG_I(sbi, i);
                if (curseg->segno == segno) {
                        sum = curseg->sum_blk->entries[blkoff];
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index c7f1ce41442a..9e5a6842346e 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1145,9 +1145,7 @@ static void put_ol_stateid_locked(struct nfs4_ol_stateid 
*stp,
 
 static bool unhash_lock_stateid(struct nfs4_ol_stateid *stp)
 {
-       struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner);
-
-       lockdep_assert_held(&oo->oo_owner.so_client->cl_lock);
+       lockdep_assert_held(&stp->st_stid.sc_client->cl_lock);
 
        list_del_init(&stp->st_locks);
        nfs4_unhash_stid(&stp->st_stid);
@@ -1156,12 +1154,12 @@ static bool unhash_lock_stateid(struct nfs4_ol_stateid 
*stp)
 
 static void release_lock_stateid(struct nfs4_ol_stateid *stp)
 {
-       struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner);
+       struct nfs4_client *clp = stp->st_stid.sc_client;
        bool unhashed;
 
-       spin_lock(&oo->oo_owner.so_client->cl_lock);
+       spin_lock(&clp->cl_lock);
        unhashed = unhash_lock_stateid(stp);
-       spin_unlock(&oo->oo_owner.so_client->cl_lock);
+       spin_unlock(&clp->cl_lock);
        if (unhashed)
                nfs4_put_stid(&stp->st_stid);
 }
diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h
index c28dd523f96e..d43837f2ce3a 100644
--- a/include/linux/tty_flip.h
+++ b/include/linux/tty_flip.h
@@ -12,6 +12,7 @@ extern int tty_prepare_flip_string(struct tty_port *port,
                unsigned char **chars, size_t size);
 extern void tty_flip_buffer_push(struct tty_port *port);
 void tty_schedule_flip(struct tty_port *port);
+int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag);
 
 static inline int tty_insert_flip_char(struct tty_port *port,
                                        unsigned char ch, char flag)
@@ -26,7 +27,7 @@ static inline int tty_insert_flip_char(struct tty_port *port,
                *char_buf_ptr(tb, tb->used++) = ch;
                return 1;
        }
-       return tty_insert_flip_string_flags(port, &ch, &flag, 1);
+       return __tty_insert_flip_char(port, ch, flag);
 }
 
 static inline int tty_insert_flip_string(struct tty_port *port,
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index ac42bbb37b2d..c26a6e4dc306 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -1,14 +1,9 @@
 #ifndef __NET_FRAG_H__
 #define __NET_FRAG_H__
 
-#include <linux/percpu_counter.h>
-
 struct netns_frags {
-       /* The percpu_counter "mem" need to be cacheline aligned.
-        *  mem.count must not share cacheline with other writers
-        */
-       struct percpu_counter   mem ____cacheline_aligned_in_smp;
-
+       /* Keep atomic mem on separate cachelines in structs that include it */
+       atomic_t                mem ____cacheline_aligned_in_smp;
        /* sysctls */
        int                     timeout;
        int                     high_thresh;
@@ -108,15 +103,10 @@ struct inet_frags {
 int inet_frags_init(struct inet_frags *);
 void inet_frags_fini(struct inet_frags *);
 
-static inline int inet_frags_init_net(struct netns_frags *nf)
-{
-       return percpu_counter_init(&nf->mem, 0, GFP_KERNEL);
-}
-static inline void inet_frags_uninit_net(struct netns_frags *nf)
+static inline void inet_frags_init_net(struct netns_frags *nf)
 {
-       percpu_counter_destroy(&nf->mem);
+       atomic_set(&nf->mem, 0);
 }
-
 void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f);
 
 void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f);
@@ -140,37 +130,24 @@ static inline bool inet_frag_evicting(struct 
inet_frag_queue *q)
 
 /* Memory Tracking Functions. */
 
-/* The default percpu_counter batch size is not big enough to scale to
- * fragmentation mem acct sizes.
- * The mem size of a 64K fragment is approx:
- *  (44 fragments * 2944 truesize) + frag_queue struct(200) = 129736 bytes
- */
-static unsigned int frag_percpu_counter_batch = 130000;
-
 static inline int frag_mem_limit(struct netns_frags *nf)
 {
-       return percpu_counter_read(&nf->mem);
+       return atomic_read(&nf->mem);
 }
 
 static inline void sub_frag_mem_limit(struct netns_frags *nf, int i)
 {
-       __percpu_counter_add(&nf->mem, -i, frag_percpu_counter_batch);
+       atomic_sub(i, &nf->mem);
 }
 
 static inline void add_frag_mem_limit(struct netns_frags *nf, int i)
 {
-       __percpu_counter_add(&nf->mem, i, frag_percpu_counter_batch);
+       atomic_add(i, &nf->mem);
 }
 
-static inline unsigned int sum_frag_mem_limit(struct netns_frags *nf)
+static inline int sum_frag_mem_limit(struct netns_frags *nf)
 {
-       unsigned int res;
-
-       local_bh_disable();
-       res = percpu_counter_sum_positive(&nf->mem);
-       local_bh_enable();
-
-       return res;
+       return atomic_read(&nf->mem);
 }
 
 /* RFC 3168 support :
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index fb961a576abe..fa5e703a14ed 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -68,6 +68,7 @@ struct fib6_node {
        __u16                   fn_flags;
        int                     fn_sernum;
        struct rt6_info         *rr_ptr;
+       struct rcu_head         rcu;
 };
 
 #ifndef CONFIG_IPV6_SUBTREES
@@ -102,7 +103,7 @@ struct rt6_info {
         * the same cache line.
         */
        struct fib6_table               *rt6i_table;
-       struct fib6_node                *rt6i_node;
+       struct fib6_node __rcu          *rt6i_node;
 
        struct in6_addr                 rt6i_gateway;
 
@@ -165,13 +166,40 @@ static inline void rt6_update_expires(struct rt6_info 
*rt0, int timeout)
        rt0->rt6i_flags |= RTF_EXPIRES;
 }
 
+/* Function to safely get fn->sernum for passed in rt
+ * and store result in passed in cookie.
+ * Return true if we can get cookie safely
+ * Return false if not
+ */
+static inline bool rt6_get_cookie_safe(const struct rt6_info *rt,
+                                      u32 *cookie)
+{
+       struct fib6_node *fn;
+       bool status = false;
+
+       rcu_read_lock();
+       fn = rcu_dereference(rt->rt6i_node);
+
+       if (fn) {
+               *cookie = fn->fn_sernum;
+               status = true;
+       }
+
+       rcu_read_unlock();
+       return status;
+}
+
 static inline u32 rt6_get_cookie(const struct rt6_info *rt)
 {
+       u32 cookie = 0;
+
        if (rt->rt6i_flags & RTF_PCPU ||
            (unlikely(rt->dst.flags & DST_NOCACHE) && rt->dst.from))
                rt = (struct rt6_info *)(rt->dst.from);
 
-       return rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
+       rt6_get_cookie_safe(rt, &cookie);
+
+       return cookie;
 }
 
 static inline void ip6_rt_put(struct rt6_info *rt)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index eba904bae48c..38d73a6e2857 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -2667,13 +2667,14 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int 
command)
 
        if (!command || !ftrace_enabled) {
                /*
-                * If these are control ops, they still need their
-                * per_cpu field freed. Since, function tracing is
+                * If these are dynamic or control 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_CONTROL)
-                       control_ops_free(ops);
+               if (ops->flags & (FTRACE_OPS_FL_DYNAMIC | 
FTRACE_OPS_FL_CONTROL))
+                       goto free_ops;
+
                return 0;
        }
 
@@ -2728,6 +2729,7 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int 
command)
        if (ops->flags & (FTRACE_OPS_FL_DYNAMIC | FTRACE_OPS_FL_CONTROL)) {
                schedule_on_each_cpu(ftrace_sync);
 
+ free_ops:
                arch_ftrace_trampoline_free(ops);
 
                if (ops->flags & FTRACE_OPS_FL_CONTROL)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index d59ebd9d21df..4743066010c4 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -5237,7 +5237,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 53286b2f5b1c..6b5421ae86c6 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1748,13 +1748,25 @@ static void unreserve_highatomic_pageblock(const struct 
alloc_context *ac)
                                                struct page, lru);
 
                        /*
-                        * 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/ieee802154/6lowpan/reassembly.c 
b/net/ieee802154/6lowpan/reassembly.c
index 6b437e8760d3..12e8cf4bda9f 100644
--- a/net/ieee802154/6lowpan/reassembly.c
+++ b/net/ieee802154/6lowpan/reassembly.c
@@ -580,19 +580,14 @@ static int __net_init lowpan_frags_init_net(struct net 
*net)
 {
        struct netns_ieee802154_lowpan *ieee802154_lowpan =
                net_ieee802154_lowpan(net);
-       int res;
 
        ieee802154_lowpan->frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
        ieee802154_lowpan->frags.low_thresh = IPV6_FRAG_LOW_THRESH;
        ieee802154_lowpan->frags.timeout = IPV6_FRAG_TIMEOUT;
 
-       res = inet_frags_init_net(&ieee802154_lowpan->frags);
-       if (res)
-               return res;
-       res = lowpan_frags_ns_sysctl_register(net);
-       if (res)
-               inet_frags_uninit_net(&ieee802154_lowpan->frags);
-       return res;
+       inet_frags_init_net(&ieee802154_lowpan->frags);
+
+       return lowpan_frags_ns_sysctl_register(net);
 }
 
 static void __net_exit lowpan_frags_exit_net(struct net *net)
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index fe144dae7372..c5fb2f694ed0 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -234,10 +234,8 @@ evict_again:
        cond_resched();
 
        if (read_seqretry(&f->rnd_seqlock, seq) ||
-           percpu_counter_sum(&nf->mem))
+           sum_frag_mem_limit(nf))
                goto evict_again;
-
-       percpu_counter_destroy(&nf->mem);
 }
 EXPORT_SYMBOL(inet_frags_exit_net);
 
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index b8a0607dab96..e2e162432aa3 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -840,8 +840,6 @@ static void __init ip4_frags_ctl_register(void)
 
 static int __net_init ipv4_frags_init_net(struct net *net)
 {
-       int res;
-
        /* Fragment cache limits.
         *
         * The fragment memory accounting code, (tries to) account for
@@ -865,13 +863,9 @@ static int __net_init ipv4_frags_init_net(struct net *net)
         */
        net->ipv4.frags.timeout = IP_FRAG_TIME;
 
-       res = inet_frags_init_net(&net->ipv4.frags);
-       if (res)
-               return res;
-       res = ip4_frags_ns_ctl_register(net);
-       if (res)
-               inet_frags_uninit_net(&net->ipv4.frags);
-       return res;
+       inet_frags_init_net(&net->ipv4.frags);
+
+       return ip4_frags_ns_ctl_register(net);
 }
 
 static void __net_exit ipv4_frags_exit_net(struct net *net)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 0870a86e9d96..5597120c8ffd 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2260,6 +2260,10 @@ int tcp_disconnect(struct sock *sk, int flags)
        tcp_set_ca_state(sk, TCP_CA_Open);
        tcp_clear_retrans(tp);
        inet_csk_delack_init(sk);
+       /* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0
+        * issue in __tcp_select_window()
+        */
+       icsk->icsk_ack.rcv_mss = TCP_MIN_MSS;
        tcp_init_send_head(sk);
        memset(&tp->rx_opt, 0, sizeof(tp->rx_opt));
        __sk_dst_reset(sk);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 735b22b1b4ea..92174881844d 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -5152,7 +5152,7 @@ static void __ipv6_ifa_notify(int event, struct 
inet6_ifaddr *ifp)
                 * our DAD process, so we don't need
                 * to do it again
                 */
-               if (!(ifp->rt->rt6i_node))
+               if (!rcu_access_pointer(ifp->rt->rt6i_node))
                        ip6_ins_rt(ifp->rt);
                if (ifp->idev->cnf.forwarding)
                        addrconf_join_anycast(ifp);
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index aad8cdf15472..c23e02a7ccb0 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -150,11 +150,23 @@ static struct fib6_node *node_alloc(void)
        return fn;
 }
 
-static void node_free(struct fib6_node *fn)
+static void node_free_immediate(struct fib6_node *fn)
+{
+       kmem_cache_free(fib6_node_kmem, fn);
+}
+
+static void node_free_rcu(struct rcu_head *head)
 {
+       struct fib6_node *fn = container_of(head, struct fib6_node, rcu);
+
        kmem_cache_free(fib6_node_kmem, fn);
 }
 
+static void node_free(struct fib6_node *fn)
+{
+       call_rcu(&fn->rcu, node_free_rcu);
+}
+
 static void rt6_rcu_free(struct rt6_info *rt)
 {
        call_rcu(&rt->dst.rcu_head, dst_rcu_free);
@@ -191,6 +203,12 @@ static void rt6_release(struct rt6_info *rt)
        }
 }
 
+static void fib6_free_table(struct fib6_table *table)
+{
+       inetpeer_invalidate_tree(&table->tb6_peers);
+       kfree(table);
+}
+
 static void fib6_link_table(struct net *net, struct fib6_table *tb)
 {
        unsigned int h;
@@ -588,9 +606,9 @@ insert_above:
 
                if (!in || !ln) {
                        if (in)
-                               node_free(in);
+                               node_free_immediate(in);
                        if (ln)
-                               node_free(ln);
+                               node_free_immediate(ln);
                        return ERR_PTR(-ENOMEM);
                }
 
@@ -857,7 +875,7 @@ add:
 
                rt->dst.rt6_next = iter;
                *ins = rt;
-               rt->rt6i_node = fn;
+               rcu_assign_pointer(rt->rt6i_node, fn);
                atomic_inc(&rt->rt6i_ref);
                inet6_rt_notify(RTM_NEWROUTE, rt, info, 0);
                info->nl_net->ipv6.rt6_stats->fib_rt_entries++;
@@ -882,7 +900,7 @@ add:
                        return err;
 
                *ins = rt;
-               rt->rt6i_node = fn;
+               rcu_assign_pointer(rt->rt6i_node, fn);
                rt->dst.rt6_next = iter->dst.rt6_next;
                atomic_inc(&rt->rt6i_ref);
                inet6_rt_notify(RTM_NEWROUTE, rt, info, NLM_F_REPLACE);
@@ -1015,7 +1033,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt,
                                   root, and then (in failure) stale node
                                   in main tree.
                                 */
-                               node_free(sfn);
+                               node_free_immediate(sfn);
                                err = PTR_ERR(sn);
                                goto failure;
                        }
@@ -1442,8 +1460,9 @@ static void fib6_del_route(struct fib6_node *fn, struct 
rt6_info **rtp,
 
 int fib6_del(struct rt6_info *rt, struct nl_info *info)
 {
+       struct fib6_node *fn = rcu_dereference_protected(rt->rt6i_node,
+                                   lockdep_is_held(&rt->rt6i_table->tb6_lock));
        struct net *net = info->nl_net;
-       struct fib6_node *fn = rt->rt6i_node;
        struct rt6_info **rtp;
 
 #if RT6_DEBUG >= 2
@@ -1632,7 +1651,9 @@ static int fib6_clean_node(struct fib6_walker *w)
                        if (res) {
 #if RT6_DEBUG >= 2
                                pr_debug("%s: del failed: rt=%p@%p err=%d\n",
-                                        __func__, rt, rt->rt6i_node, res);
+                                        __func__, rt,
+                                        rcu_access_pointer(rt->rt6i_node),
+                                        res);
 #endif
                                continue;
                        }
@@ -1870,15 +1891,22 @@ out_timer:
 
 static void fib6_net_exit(struct net *net)
 {
+       unsigned int i;
+
        rt6_ifdown(net, NULL);
        del_timer_sync(&net->ipv6.ip6_fib_timer);
 
-#ifdef CONFIG_IPV6_MULTIPLE_TABLES
-       inetpeer_invalidate_tree(&net->ipv6.fib6_local_tbl->tb6_peers);
-       kfree(net->ipv6.fib6_local_tbl);
-#endif
-       inetpeer_invalidate_tree(&net->ipv6.fib6_main_tbl->tb6_peers);
-       kfree(net->ipv6.fib6_main_tbl);
+       for (i = 0; i < FIB6_TABLE_HASHSZ; i++) {
+               struct hlist_head *head = &net->ipv6.fib_table_hash[i];
+               struct hlist_node *tmp;
+               struct fib6_table *tb;
+
+               hlist_for_each_entry_safe(tb, tmp, head, tb6_hlist) {
+                       hlist_del(&tb->tb6_hlist);
+                       fib6_free_table(tb);
+               }
+       }
+
        kfree(net->ipv6.fib_table_hash);
        kfree(net->ipv6.rt6_stats);
 }
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c 
b/net/ipv6/netfilter/nf_conntrack_reasm.c
index bab4441ed4e4..eb2dc39f7066 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -649,18 +649,12 @@ EXPORT_SYMBOL_GPL(nf_ct_frag6_consume_orig);
 
 static int nf_ct_net_init(struct net *net)
 {
-       int res;
-
        net->nf_frag.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
        net->nf_frag.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
        net->nf_frag.frags.timeout = IPV6_FRAG_TIMEOUT;
-       res = inet_frags_init_net(&net->nf_frag.frags);
-       if (res)
-               return res;
-       res = nf_ct_frag6_sysctl_register(net);
-       if (res)
-               inet_frags_uninit_net(&net->nf_frag.frags);
-       return res;
+       inet_frags_init_net(&net->nf_frag.frags);
+
+       return nf_ct_frag6_sysctl_register(net);
 }
 
 static void nf_ct_net_exit(struct net *net)
diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c
index f9f02581c4ca..f99a04674419 100644
--- a/net/ipv6/output_core.c
+++ b/net/ipv6/output_core.c
@@ -86,7 +86,6 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
 
        while (offset <= packet_len) {
                struct ipv6_opt_hdr *exthdr;
-               unsigned int len;
 
                switch (**nexthdr) {
 
@@ -112,10 +111,9 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
 
                exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
                                                 offset);
-               len = ipv6_optlen(exthdr);
-               if (len + offset >= IPV6_MAXPLEN)
+               offset += ipv6_optlen(exthdr);
+               if (offset > IPV6_MAXPLEN)
                        return -EINVAL;
-               offset += len;
                *nexthdr = &exthdr->nexthdr;
        }
 
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index a234552a7e3d..58f2139ebb5e 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -708,19 +708,13 @@ static void ip6_frags_sysctl_unregister(void)
 
 static int __net_init ipv6_frags_init_net(struct net *net)
 {
-       int res;
-
        net->ipv6.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
        net->ipv6.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
        net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT;
 
-       res = inet_frags_init_net(&net->ipv6.frags);
-       if (res)
-               return res;
-       res = ip6_frags_ns_sysctl_register(net);
-       if (res)
-               inet_frags_uninit_net(&net->ipv6.frags);
-       return res;
+       inet_frags_init_net(&net->ipv6.frags);
+
+       return ip6_frags_ns_sysctl_register(net);
 }
 
 static void __net_exit ipv6_frags_exit_net(struct net *net)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index ef335070e98a..48917437550e 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1248,7 +1248,9 @@ static void rt6_dst_from_metrics_check(struct rt6_info 
*rt)
 
 static struct dst_entry *rt6_check(struct rt6_info *rt, u32 cookie)
 {
-       if (!rt->rt6i_node || (rt->rt6i_node->fn_sernum != cookie))
+       u32 rt_cookie;
+
+       if (!rt6_get_cookie_safe(rt, &rt_cookie) || rt_cookie != cookie)
                return NULL;
 
        if (rt6_check_expired(rt))
@@ -1316,8 +1318,14 @@ static void ip6_link_failure(struct sk_buff *skb)
                if (rt->rt6i_flags & RTF_CACHE) {
                        dst_hold(&rt->dst);
                        ip6_del_rt(rt);
-               } else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT)) {
-                       rt->rt6i_node->fn_sernum = -1;
+               } else {
+                       struct fib6_node *fn;
+
+                       rcu_read_lock();
+                       fn = rcu_dereference(rt->rt6i_node);
+                       if (fn && (rt->rt6i_flags & RTF_DEFAULT))
+                               fn->fn_sernum = -1;
+                       rcu_read_unlock();
                }
        }
 }
@@ -1334,7 +1342,8 @@ static void rt6_do_update_pmtu(struct rt6_info *rt, u32 
mtu)
 static bool rt6_cache_allowed_for_pmtu(const struct rt6_info *rt)
 {
        return !(rt->rt6i_flags & RTF_CACHE) &&
-               (rt->rt6i_flags & RTF_PCPU || rt->rt6i_node);
+               (rt->rt6i_flags & RTF_PCPU ||
+                rcu_access_pointer(rt->rt6i_node));
 }
 
 static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk,

Reply via email to