commit:     645f3565be0d4dce743c0b1a2b71093f0889d815
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Mon Apr 30 10:29:51 2018 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Mon Apr 30 10:29:51 2018 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=645f3565

Linux patch 4.14.38

 0000_README              |    4 +
 1037_linux-4.14.38.patch | 4524 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 4528 insertions(+)

diff --git a/0000_README b/0000_README
index 73aafae..03b1461 100644
--- a/0000_README
+++ b/0000_README
@@ -191,6 +191,10 @@ Patch:  1036_linux-4.14.37.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.14.37
 
+Patch:  1037_linux-4.14.38.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.14.38
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1037_linux-4.14.38.patch b/1037_linux-4.14.38.patch
new file mode 100644
index 0000000..4612b61
--- /dev/null
+++ b/1037_linux-4.14.38.patch
@@ -0,0 +1,4524 @@
+diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
+index fb385af482ff..8cfb44ffe853 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -2541,6 +2541,9 @@
+ 
+       noalign         [KNL,ARM]
+ 
++      noaltinstr      [S390] Disables alternative instructions patching
++                      (CPU alternatives feature).
++
+       noapic          [SMP,APIC] Tells the kernel to not make use of any
+                       IOAPICs that may be present in the system.
+ 
+diff --git a/Makefile b/Makefile
+index ee330f5449e6..27a8d5c37180 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 4
+ PATCHLEVEL = 14
+-SUBLEVEL = 37
++SUBLEVEL = 38
+ EXTRAVERSION =
+ NAME = Petit Gorille
+ 
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
+index 910628d18add..1fc5060d7027 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
+@@ -155,17 +155,6 @@
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+-
+-      vdd_log: vdd-log {
+-              compatible = "pwm-regulator";
+-              pwms = <&pwm2 0 25000 0>;
+-              regulator-name = "vdd_log";
+-              regulator-min-microvolt = <800000>;
+-              regulator-max-microvolt = <1400000>;
+-              regulator-always-on;
+-              regulator-boot-on;
+-              status = "okay";
+-      };
+ };
+ 
+ &cpu_b0 {
+diff --git a/arch/microblaze/Kconfig.platform 
b/arch/microblaze/Kconfig.platform
+index 1b3d8c849101..f7f1739c11b9 100644
+--- a/arch/microblaze/Kconfig.platform
++++ b/arch/microblaze/Kconfig.platform
+@@ -20,6 +20,7 @@ config OPT_LIB_FUNCTION
+ config OPT_LIB_ASM
+       bool "Optimalized lib function ASM"
+       depends on OPT_LIB_FUNCTION && (XILINX_MICROBLAZE0_USE_BARREL = 1)
++      depends on CPU_BIG_ENDIAN
+       default n
+       help
+         Allows turn on optimalized library function (memcpy and memmove).
+diff --git a/arch/microblaze/lib/fastcopy.S b/arch/microblaze/lib/fastcopy.S
+index 62021d7e249e..fdc48bb065d8 100644
+--- a/arch/microblaze/lib/fastcopy.S
++++ b/arch/microblaze/lib/fastcopy.S
+@@ -29,10 +29,6 @@
+  *    between mem locations with size of xfer spec'd in bytes
+  */
+ 
+-#ifdef __MICROBLAZEEL__
+-#error Microblaze LE not support ASM optimized lib func. Disable OPT_LIB_ASM.
+-#endif
+-
+ #include <linux/linkage.h>
+       .text
+       .globl  memcpy
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index ae55e715cc74..49fb6614ea8c 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -121,6 +121,7 @@ config S390
+       select GENERIC_CLOCKEVENTS
+       select GENERIC_CPU_AUTOPROBE
+       select GENERIC_CPU_DEVICES if !SMP
++      select GENERIC_CPU_VULNERABILITIES
+       select GENERIC_FIND_FIRST_BIT
+       select GENERIC_SMP_IDLE_THREAD
+       select GENERIC_TIME_VSYSCALL
+@@ -538,6 +539,51 @@ config ARCH_RANDOM
+ 
+         If unsure, say Y.
+ 
++config KERNEL_NOBP
++      def_bool n
++      prompt "Enable modified branch prediction for the kernel by default"
++      help
++        If this option is selected the kernel will switch to a modified
++        branch prediction mode if the firmware interface is available.
++        The modified branch prediction mode improves the behaviour in
++        regard to speculative execution.
++
++        With the option enabled the kernel parameter "nobp=0" or "nospec"
++        can be used to run the kernel in the normal branch prediction mode.
++
++        With the option disabled the modified branch prediction mode is
++        enabled with the "nobp=1" kernel parameter.
++
++        If unsure, say N.
++
++config EXPOLINE
++      def_bool n
++      prompt "Avoid speculative indirect branches in the kernel"
++      help
++        Compile the kernel with the expoline compiler options to guard
++        against kernel-to-user data leaks by avoiding speculative indirect
++        branches.
++        Requires a compiler with -mindirect-branch=thunk support for full
++        protection. The kernel may run slower.
++
++        If unsure, say N.
++
++choice
++      prompt "Expoline default"
++      depends on EXPOLINE
++      default EXPOLINE_FULL
++
++config EXPOLINE_OFF
++      bool "spectre_v2=off"
++
++config EXPOLINE_AUTO
++      bool "spectre_v2=auto"
++
++config EXPOLINE_FULL
++      bool "spectre_v2=on"
++
++endchoice
++
+ endmenu
+ 
+ menu "Memory setup"
+@@ -812,6 +858,7 @@ config PFAULT
+ config SHARED_KERNEL
+       bool "VM shared kernel support"
+       depends on !JUMP_LABEL
++      depends on !ALTERNATIVES
+       help
+         Select this option, if you want to share the text segment of the
+         Linux kernel between different VM guests. This reduces memory
+diff --git a/arch/s390/Makefile b/arch/s390/Makefile
+index dac821cfcd43..ec3fa105f448 100644
+--- a/arch/s390/Makefile
++++ b/arch/s390/Makefile
+@@ -81,6 +81,16 @@ ifeq ($(call cc-option-yn,-mwarn-dynamicstack),y)
+ cflags-$(CONFIG_WARN_DYNAMIC_STACK) += -mwarn-dynamicstack
+ endif
+ 
++ifdef CONFIG_EXPOLINE
++  ifeq ($(call cc-option-yn,$(CC_FLAGS_MARCH) -mindirect-branch=thunk),y)
++    CC_FLAGS_EXPOLINE := -mindirect-branch=thunk
++    CC_FLAGS_EXPOLINE += -mfunction-return=thunk
++    CC_FLAGS_EXPOLINE += -mindirect-branch-table
++    export CC_FLAGS_EXPOLINE
++    cflags-y += $(CC_FLAGS_EXPOLINE) -DCC_USING_EXPOLINE
++  endif
++endif
++
+ ifdef CONFIG_FUNCTION_TRACER
+ # make use of hotpatch feature if the compiler supports it
+ cc_hotpatch   := -mhotpatch=0,3
+diff --git a/arch/s390/include/asm/alternative.h 
b/arch/s390/include/asm/alternative.h
+new file mode 100644
+index 000000000000..a72002056b54
+--- /dev/null
++++ b/arch/s390/include/asm/alternative.h
+@@ -0,0 +1,149 @@
++#ifndef _ASM_S390_ALTERNATIVE_H
++#define _ASM_S390_ALTERNATIVE_H
++
++#ifndef __ASSEMBLY__
++
++#include <linux/types.h>
++#include <linux/stddef.h>
++#include <linux/stringify.h>
++
++struct alt_instr {
++      s32 instr_offset;       /* original instruction */
++      s32 repl_offset;        /* offset to replacement instruction */
++      u16 facility;           /* facility bit set for replacement */
++      u8  instrlen;           /* length of original instruction */
++      u8  replacementlen;     /* length of new instruction */
++} __packed;
++
++void apply_alternative_instructions(void);
++void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
++
++/*
++ * |661:       |662:    |6620      |663:
++ * +-----------+---------------------+
++ * | oldinstr  | oldinstr_padding    |
++ * |         +----------+----------+
++ * |         |          |          |
++ * |         | >6 bytes |6/4/2 nops|
++ * |         |6 bytes jg----------->
++ * +-----------+---------------------+
++ *             ^^ static padding ^^
++ *
++ * .altinstr_replacement section
++ * +---------------------+-----------+
++ * |6641:                          |6651:
++ * | alternative instr 1           |
++ * +-----------+---------+- - - - - -+
++ * |6642:              |6652:      |
++ * | alternative instr 2 | padding
++ * +---------------------+- - - - - -+
++ *                      ^ runtime ^
++ *
++ * .altinstructions section
++ * +---------------------------------+
++ * | alt_instr entries for each      |
++ * | alternative instr                     |
++ * +---------------------------------+
++ */
++
++#define b_altinstr(num)       "664"#num
++#define e_altinstr(num)       "665"#num
++
++#define e_oldinstr_pad_end    "663"
++#define oldinstr_len          "662b-661b"
++#define oldinstr_total_len    e_oldinstr_pad_end"b-661b"
++#define altinstr_len(num)     e_altinstr(num)"b-"b_altinstr(num)"b"
++#define oldinstr_pad_len(num) \
++      "-(((" altinstr_len(num) ")-(" oldinstr_len ")) > 0) * " \
++      "((" altinstr_len(num) ")-(" oldinstr_len "))"
++
++#define INSTR_LEN_SANITY_CHECK(len)                                   \
++      ".if " len " > 254\n"                                           \
++      "\t.error \"cpu alternatives does not support instructions "    \
++              "blocks > 254 bytes\"\n"                                \
++      ".endif\n"                                                      \
++      ".if (" len ") %% 2\n"                                          \
++      "\t.error \"cpu alternatives instructions length is odd\"\n"    \
++      ".endif\n"
++
++#define OLDINSTR_PADDING(oldinstr, num)                                       
\
++      ".if " oldinstr_pad_len(num) " > 6\n"                           \
++      "\tjg " e_oldinstr_pad_end "f\n"                                \
++      "6620:\n"                                                       \
++      "\t.fill (" oldinstr_pad_len(num) " - (6620b-662b)) / 2, 2, 0x0700\n" \
++      ".else\n"                                                       \
++      "\t.fill " oldinstr_pad_len(num) " / 6, 6, 0xc0040000\n"        \
++      "\t.fill " oldinstr_pad_len(num) " %% 6 / 4, 4, 0x47000000\n"   \
++      "\t.fill " oldinstr_pad_len(num) " %% 6 %% 4 / 2, 2, 0x0700\n"  \
++      ".endif\n"
++
++#define OLDINSTR(oldinstr, num)                                               
\
++      "661:\n\t" oldinstr "\n662:\n"                                  \
++      OLDINSTR_PADDING(oldinstr, num)                                 \
++      e_oldinstr_pad_end ":\n"                                        \
++      INSTR_LEN_SANITY_CHECK(oldinstr_len)
++
++#define OLDINSTR_2(oldinstr, num1, num2)                              \
++      "661:\n\t" oldinstr "\n662:\n"                                  \
++      ".if " altinstr_len(num1) " < " altinstr_len(num2) "\n"         \
++      OLDINSTR_PADDING(oldinstr, num2)                                \
++      ".else\n"                                                       \
++      OLDINSTR_PADDING(oldinstr, num1)                                \
++      ".endif\n"                                                      \
++      e_oldinstr_pad_end ":\n"                                        \
++      INSTR_LEN_SANITY_CHECK(oldinstr_len)
++
++#define ALTINSTR_ENTRY(facility, num)                                 \
++      "\t.long 661b - .\n"                    /* old instruction */   \
++      "\t.long " b_altinstr(num)"b - .\n"     /* alt instruction */   \
++      "\t.word " __stringify(facility) "\n"   /* facility bit    */   \
++      "\t.byte " oldinstr_total_len "\n"      /* source len      */   \
++      "\t.byte " altinstr_len(num) "\n"       /* alt instruction len */
++
++#define ALTINSTR_REPLACEMENT(altinstr, num)   /* replacement */       \
++      b_altinstr(num)":\n\t" altinstr "\n" e_altinstr(num) ":\n"      \
++      INSTR_LEN_SANITY_CHECK(altinstr_len(num))
++
++/* alternative assembly primitive: */
++#define ALTERNATIVE(oldinstr, altinstr, facility) \
++      ".pushsection .altinstr_replacement, \"ax\"\n"                  \
++      ALTINSTR_REPLACEMENT(altinstr, 1)                               \
++      ".popsection\n"                                                 \
++      OLDINSTR(oldinstr, 1)                                           \
++      ".pushsection .altinstructions,\"a\"\n"                         \
++      ALTINSTR_ENTRY(facility, 1)                                     \
++      ".popsection\n"
++
++#define ALTERNATIVE_2(oldinstr, altinstr1, facility1, altinstr2, facility2)\
++      ".pushsection .altinstr_replacement, \"ax\"\n"                  \
++      ALTINSTR_REPLACEMENT(altinstr1, 1)                              \
++      ALTINSTR_REPLACEMENT(altinstr2, 2)                              \
++      ".popsection\n"                                                 \
++      OLDINSTR_2(oldinstr, 1, 2)                                      \
++      ".pushsection .altinstructions,\"a\"\n"                         \
++      ALTINSTR_ENTRY(facility1, 1)                                    \
++      ALTINSTR_ENTRY(facility2, 2)                                    \
++      ".popsection\n"
++
++/*
++ * Alternative instructions for different CPU types or capabilities.
++ *
++ * This allows to use optimized instructions even on generic binary
++ * kernels.
++ *
++ * oldinstr is padded with jump and nops at compile time if altinstr is
++ * longer. altinstr is padded with jump and nops at run-time during patching.
++ *
++ * For non barrier like inlines please define new variants
++ * without volatile and memory clobber.
++ */
++#define alternative(oldinstr, altinstr, facility)                     \
++      asm volatile(ALTERNATIVE(oldinstr, altinstr, facility) : : : "memory")
++
++#define alternative_2(oldinstr, altinstr1, facility1, altinstr2, facility2) \
++      asm volatile(ALTERNATIVE_2(oldinstr, altinstr1, facility1,          \
++                                 altinstr2, facility2) ::: "memory")
++
++#endif /* __ASSEMBLY__ */
++
++#endif /* _ASM_S390_ALTERNATIVE_H */
+diff --git a/arch/s390/include/asm/barrier.h b/arch/s390/include/asm/barrier.h
+index 10432607a573..f9eddbca79d2 100644
+--- a/arch/s390/include/asm/barrier.h
++++ b/arch/s390/include/asm/barrier.h
+@@ -49,6 +49,30 @@ do {                                                        
                \
+ #define __smp_mb__before_atomic()     barrier()
+ #define __smp_mb__after_atomic()      barrier()
+ 
++/**
++ * array_index_mask_nospec - generate a mask for array_idx() that is
++ * ~0UL when the bounds check succeeds and 0 otherwise
++ * @index: array element index
++ * @size: number of elements in array
++ */
++#define array_index_mask_nospec array_index_mask_nospec
++static inline unsigned long array_index_mask_nospec(unsigned long index,
++                                                  unsigned long size)
++{
++      unsigned long mask;
++
++      if (__builtin_constant_p(size) && size > 0) {
++              asm("   clgr    %2,%1\n"
++                  "   slbgr   %0,%0\n"
++                  :"=d" (mask) : "d" (size-1), "d" (index) :"cc");
++              return mask;
++      }
++      asm("   clgr    %1,%2\n"
++          "   slbgr   %0,%0\n"
++          :"=d" (mask) : "d" (size), "d" (index) :"cc");
++      return ~mask;
++}
++
+ #include <asm-generic/barrier.h>
+ 
+ #endif /* __ASM_BARRIER_H */
+diff --git a/arch/s390/include/asm/facility.h 
b/arch/s390/include/asm/facility.h
+index f040644575b7..2d58478c2745 100644
+--- a/arch/s390/include/asm/facility.h
++++ b/arch/s390/include/asm/facility.h
+@@ -15,6 +15,24 @@
+ 
+ #define MAX_FACILITY_BIT (sizeof(((struct lowcore *)0)->stfle_fac_list) * 8)
+ 
++static inline void __set_facility(unsigned long nr, void *facilities)
++{
++      unsigned char *ptr = (unsigned char *) facilities;
++
++      if (nr >= MAX_FACILITY_BIT)
++              return;
++      ptr[nr >> 3] |= 0x80 >> (nr & 7);
++}
++
++static inline void __clear_facility(unsigned long nr, void *facilities)
++{
++      unsigned char *ptr = (unsigned char *) facilities;
++
++      if (nr >= MAX_FACILITY_BIT)
++              return;
++      ptr[nr >> 3] &= ~(0x80 >> (nr & 7));
++}
++
+ static inline int __test_facility(unsigned long nr, void *facilities)
+ {
+       unsigned char *ptr;
+diff --git a/arch/s390/include/asm/kvm_host.h 
b/arch/s390/include/asm/kvm_host.h
+index 51375e766e90..d660e784e445 100644
+--- a/arch/s390/include/asm/kvm_host.h
++++ b/arch/s390/include/asm/kvm_host.h
+@@ -210,7 +210,8 @@ struct kvm_s390_sie_block {
+       __u16   ipa;                    /* 0x0056 */
+       __u32   ipb;                    /* 0x0058 */
+       __u32   scaoh;                  /* 0x005c */
+-      __u8    reserved60;             /* 0x0060 */
++#define FPF_BPBC      0x20
++      __u8    fpf;                    /* 0x0060 */
+ #define ECB_GS                0x40
+ #define ECB_TE                0x10
+ #define ECB_SRSI      0x04
+diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
+index 917f7344cab6..88a212df0dbc 100644
+--- a/arch/s390/include/asm/lowcore.h
++++ b/arch/s390/include/asm/lowcore.h
+@@ -140,7 +140,9 @@ struct lowcore {
+       /* Per cpu primary space access list */
+       __u32   paste[16];                      /* 0x0400 */
+ 
+-      __u8    pad_0x04c0[0x0e00-0x0440];      /* 0x0440 */
++      /* br %r1 trampoline */
++      __u16   br_r1_trampoline;               /* 0x0440 */
++      __u8    pad_0x0442[0x0e00-0x0442];      /* 0x0442 */
+ 
+       /*
+        * 0xe00 contains the address of the IPL Parameter Information
+@@ -155,7 +157,8 @@ struct lowcore {
+       __u8    pad_0x0e20[0x0f00-0x0e20];      /* 0x0e20 */
+ 
+       /* Extended facility list */
+-      __u64   stfle_fac_list[32];             /* 0x0f00 */
++      __u64   stfle_fac_list[16];             /* 0x0f00 */
++      __u64   alt_stfle_fac_list[16];         /* 0x0f80 */
+       __u8    pad_0x1000[0x11b0-0x1000];      /* 0x1000 */
+ 
+       /* Pointer to the machine check extended save area */
+diff --git a/arch/s390/include/asm/nospec-branch.h 
b/arch/s390/include/asm/nospec-branch.h
+new file mode 100644
+index 000000000000..b4bd8c41e9d3
+--- /dev/null
++++ b/arch/s390/include/asm/nospec-branch.h
+@@ -0,0 +1,17 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#ifndef _ASM_S390_EXPOLINE_H
++#define _ASM_S390_EXPOLINE_H
++
++#ifndef __ASSEMBLY__
++
++#include <linux/types.h>
++
++extern int nospec_disable;
++
++void nospec_init_branches(void);
++void nospec_auto_detect(void);
++void nospec_revert(s32 *start, s32 *end);
++
++#endif /* __ASSEMBLY__ */
++
++#endif /* _ASM_S390_EXPOLINE_H */
+diff --git a/arch/s390/include/asm/processor.h 
b/arch/s390/include/asm/processor.h
+index 9cf92abe23c3..0a39cd102c49 100644
+--- a/arch/s390/include/asm/processor.h
++++ b/arch/s390/include/asm/processor.h
+@@ -89,6 +89,7 @@ void cpu_detect_mhz_feature(void);
+ extern const struct seq_operations cpuinfo_op;
+ extern int sysctl_ieee_emulation_warnings;
+ extern void execve_tail(void);
++extern void __bpon(void);
+ 
+ /*
+  * User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit.
+@@ -377,6 +378,9 @@ extern void memcpy_absolute(void *, void *, size_t);
+       memcpy_absolute(&(dest), &__tmp, sizeof(__tmp));        \
+ } while (0)
+ 
++extern int s390_isolate_bp(void);
++extern int s390_isolate_bp_guest(void);
++
+ #endif /* __ASSEMBLY__ */
+ 
+ #endif /* __ASM_S390_PROCESSOR_H */
+diff --git a/arch/s390/include/asm/thread_info.h 
b/arch/s390/include/asm/thread_info.h
+index 0880a37b6d3b..301b4f70bf31 100644
+--- a/arch/s390/include/asm/thread_info.h
++++ b/arch/s390/include/asm/thread_info.h
+@@ -60,6 +60,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct 
task_struct *src);
+ #define TIF_GUARDED_STORAGE   4       /* load guarded storage control block */
+ #define TIF_PATCH_PENDING     5       /* pending live patching update */
+ #define TIF_PGSTE             6       /* New mm's will use 4K page tables */
++#define TIF_ISOLATE_BP                8       /* Run process with isolated BP 
*/
++#define TIF_ISOLATE_BP_GUEST  9       /* Run KVM guests with isolated BP */
+ 
+ #define TIF_31BIT             16      /* 32bit process */
+ #define TIF_MEMDIE            17      /* is terminating due to OOM killer */
+@@ -80,6 +82,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct 
task_struct *src);
+ #define _TIF_UPROBE           _BITUL(TIF_UPROBE)
+ #define _TIF_GUARDED_STORAGE  _BITUL(TIF_GUARDED_STORAGE)
+ #define _TIF_PATCH_PENDING    _BITUL(TIF_PATCH_PENDING)
++#define _TIF_ISOLATE_BP               _BITUL(TIF_ISOLATE_BP)
++#define _TIF_ISOLATE_BP_GUEST _BITUL(TIF_ISOLATE_BP_GUEST)
+ 
+ #define _TIF_31BIT            _BITUL(TIF_31BIT)
+ #define _TIF_SINGLE_STEP      _BITUL(TIF_SINGLE_STEP)
+diff --git a/arch/s390/include/uapi/asm/kvm.h 
b/arch/s390/include/uapi/asm/kvm.h
+index 9ad172dcd912..a3938db010f7 100644
+--- a/arch/s390/include/uapi/asm/kvm.h
++++ b/arch/s390/include/uapi/asm/kvm.h
+@@ -228,6 +228,7 @@ struct kvm_guest_debug_arch {
+ #define KVM_SYNC_RICCB  (1UL << 7)
+ #define KVM_SYNC_FPRS   (1UL << 8)
+ #define KVM_SYNC_GSCB   (1UL << 9)
++#define KVM_SYNC_BPBC   (1UL << 10)
+ /* length and alignment of the sdnx as a power of two */
+ #define SDNXC 8
+ #define SDNXL (1UL << SDNXC)
+@@ -251,7 +252,9 @@ struct kvm_sync_regs {
+       };
+       __u8  reserved[512];    /* for future vector expansion */
+       __u32 fpc;              /* valid on KVM_SYNC_VRS or KVM_SYNC_FPRS */
+-      __u8 padding1[52];      /* riccb needs to be 64byte aligned */
++      __u8 bpbc : 1;          /* bp mode */
++      __u8 reserved2 : 7;
++      __u8 padding1[51];      /* riccb needs to be 64byte aligned */
+       __u8 riccb[64];         /* runtime instrumentation controls block */
+       __u8 padding2[192];     /* sdnx needs to be 256byte aligned */
+       union {
+diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
+index 4ce2d05929a7..a3a4cafb6080 100644
+--- a/arch/s390/kernel/Makefile
++++ b/arch/s390/kernel/Makefile
+@@ -29,6 +29,7 @@ UBSAN_SANITIZE_early.o       := n
+ #
+ ifneq ($(CC_FLAGS_MARCH),-march=z900)
+ CFLAGS_REMOVE_als.o   += $(CC_FLAGS_MARCH)
++CFLAGS_REMOVE_als.o   += $(CC_FLAGS_EXPOLINE)
+ CFLAGS_als.o          += -march=z900
+ AFLAGS_REMOVE_head.o  += $(CC_FLAGS_MARCH)
+ AFLAGS_head.o         += -march=z900
+@@ -57,10 +58,13 @@ obj-y      += processor.o sys_s390.o ptrace.o signal.o 
cpcmd.o ebcdic.o nmi.o
+ obj-y += debug.o irq.o ipl.o dis.o diag.o vdso.o als.o
+ obj-y += sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o
+ obj-y += runtime_instr.o cache.o fpu.o dumpstack.o guarded_storage.o
+-obj-y += entry.o reipl.o relocate_kernel.o kdebugfs.o
++obj-y += entry.o reipl.o relocate_kernel.o kdebugfs.o alternative.o
++obj-y += nospec-branch.o
+ 
+ extra-y                               += head.o head64.o vmlinux.lds
+ 
++CFLAGS_REMOVE_nospec-branch.o += $(CC_FLAGS_EXPOLINE)
++
+ obj-$(CONFIG_MODULES)         += module.o
+ obj-$(CONFIG_SMP)             += smp.o
+ obj-$(CONFIG_SCHED_TOPOLOGY)  += topology.o
+diff --git a/arch/s390/kernel/alternative.c b/arch/s390/kernel/alternative.c
+new file mode 100644
+index 000000000000..b57b293998dc
+--- /dev/null
++++ b/arch/s390/kernel/alternative.c
+@@ -0,0 +1,112 @@
++#include <linux/module.h>
++#include <asm/alternative.h>
++#include <asm/facility.h>
++#include <asm/nospec-branch.h>
++
++#define MAX_PATCH_LEN (255 - 1)
++
++static int __initdata_or_module alt_instr_disabled;
++
++static int __init disable_alternative_instructions(char *str)
++{
++      alt_instr_disabled = 1;
++      return 0;
++}
++
++early_param("noaltinstr", disable_alternative_instructions);
++
++struct brcl_insn {
++      u16 opc;
++      s32 disp;
++} __packed;
++
++static u16 __initdata_or_module nop16 = 0x0700;
++static u32 __initdata_or_module nop32 = 0x47000000;
++static struct brcl_insn __initdata_or_module nop48 = {
++      0xc004, 0
++};
++
++static const void *nops[] __initdata_or_module = {
++      &nop16,
++      &nop32,
++      &nop48
++};
++
++static void __init_or_module add_jump_padding(void *insns, unsigned int len)
++{
++      struct brcl_insn brcl = {
++              0xc0f4,
++              len / 2
++      };
++
++      memcpy(insns, &brcl, sizeof(brcl));
++      insns += sizeof(brcl);
++      len -= sizeof(brcl);
++
++      while (len > 0) {
++              memcpy(insns, &nop16, 2);
++              insns += 2;
++              len -= 2;
++      }
++}
++
++static void __init_or_module add_padding(void *insns, unsigned int len)
++{
++      if (len > 6)
++              add_jump_padding(insns, len);
++      else if (len >= 2)
++              memcpy(insns, nops[len / 2 - 1], len);
++}
++
++static void __init_or_module __apply_alternatives(struct alt_instr *start,
++                                                struct alt_instr *end)
++{
++      struct alt_instr *a;
++      u8 *instr, *replacement;
++      u8 insnbuf[MAX_PATCH_LEN];
++
++      /*
++       * The scan order should be from start to end. A later scanned
++       * alternative code can overwrite previously scanned alternative code.
++       */
++      for (a = start; a < end; a++) {
++              int insnbuf_sz = 0;
++
++              instr = (u8 *)&a->instr_offset + a->instr_offset;
++              replacement = (u8 *)&a->repl_offset + a->repl_offset;
++
++              if (!__test_facility(a->facility,
++                                   S390_lowcore.alt_stfle_fac_list))
++                      continue;
++
++              if (unlikely(a->instrlen % 2 || a->replacementlen % 2)) {
++                      WARN_ONCE(1, "cpu alternatives instructions length is "
++                                   "odd, skipping patching\n");
++                      continue;
++              }
++
++              memcpy(insnbuf, replacement, a->replacementlen);
++              insnbuf_sz = a->replacementlen;
++
++              if (a->instrlen > a->replacementlen) {
++                      add_padding(insnbuf + a->replacementlen,
++                                  a->instrlen - a->replacementlen);
++                      insnbuf_sz += a->instrlen - a->replacementlen;
++              }
++
++              s390_kernel_write(instr, insnbuf, insnbuf_sz);
++      }
++}
++
++void __init_or_module apply_alternatives(struct alt_instr *start,
++                                       struct alt_instr *end)
++{
++      if (!alt_instr_disabled)
++              __apply_alternatives(start, end);
++}
++
++extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
++void __init apply_alternative_instructions(void)
++{
++      apply_alternatives(__alt_instructions, __alt_instructions_end);
++}
+diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
+index f7b280f0ab16..a3219837fa70 100644
+--- a/arch/s390/kernel/early.c
++++ b/arch/s390/kernel/early.c
+@@ -329,6 +329,11 @@ static noinline __init void setup_facility_list(void)
+ {
+       stfle(S390_lowcore.stfle_fac_list,
+             ARRAY_SIZE(S390_lowcore.stfle_fac_list));
++      memcpy(S390_lowcore.alt_stfle_fac_list,
++             S390_lowcore.stfle_fac_list,
++             sizeof(S390_lowcore.alt_stfle_fac_list));
++      if (!IS_ENABLED(CONFIG_KERNEL_NOBP))
++              __clear_facility(82, S390_lowcore.alt_stfle_fac_list);
+ }
+ 
+ static __init void detect_diag9c(void)
+diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
+index 7c6904d616d8..ed9aaa212d4a 100644
+--- a/arch/s390/kernel/entry.S
++++ b/arch/s390/kernel/entry.S
+@@ -106,6 +106,7 @@ _PIF_WORK  = (_PIF_PER_TRAP | _PIF_SYSCALL_RESTART)
+       aghi    %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
+       j       3f
+ 1:    UPDATE_VTIME %r14,%r15,\timer
++      BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
+ 2:    lg      %r15,__LC_ASYNC_STACK   # load async stack
+ 3:    la      %r11,STACK_FRAME_OVERHEAD(%r15)
+       .endm
+@@ -158,6 +159,130 @@ _PIF_WORK        = (_PIF_PER_TRAP | _PIF_SYSCALL_RESTART)
+               tm      off+\addr, \mask
+       .endm
+ 
++      .macro BPOFF
++      .pushsection .altinstr_replacement, "ax"
++660:  .long   0xb2e8c000
++      .popsection
++661:  .long   0x47000000
++      .pushsection .altinstructions, "a"
++      .long 661b - .
++      .long 660b - .
++      .word 82
++      .byte 4
++      .byte 4
++      .popsection
++      .endm
++
++      .macro BPON
++      .pushsection .altinstr_replacement, "ax"
++662:  .long   0xb2e8d000
++      .popsection
++663:  .long   0x47000000
++      .pushsection .altinstructions, "a"
++      .long 663b - .
++      .long 662b - .
++      .word 82
++      .byte 4
++      .byte 4
++      .popsection
++      .endm
++
++      .macro BPENTER tif_ptr,tif_mask
++      .pushsection .altinstr_replacement, "ax"
++662:  .word   0xc004, 0x0000, 0x0000  # 6 byte nop
++      .word   0xc004, 0x0000, 0x0000  # 6 byte nop
++      .popsection
++664:  TSTMSK  \tif_ptr,\tif_mask
++      jz      . + 8
++      .long   0xb2e8d000
++      .pushsection .altinstructions, "a"
++      .long 664b - .
++      .long 662b - .
++      .word 82
++      .byte 12
++      .byte 12
++      .popsection
++      .endm
++
++      .macro BPEXIT tif_ptr,tif_mask
++      TSTMSK  \tif_ptr,\tif_mask
++      .pushsection .altinstr_replacement, "ax"
++662:  jnz     . + 8
++      .long   0xb2e8d000
++      .popsection
++664:  jz      . + 8
++      .long   0xb2e8c000
++      .pushsection .altinstructions, "a"
++      .long 664b - .
++      .long 662b - .
++      .word 82
++      .byte 8
++      .byte 8
++      .popsection
++      .endm
++
++#ifdef CONFIG_EXPOLINE
++
++      .macro GEN_BR_THUNK name,reg,tmp
++      .section .text.\name,"axG",@progbits,\name,comdat
++      .globl \name
++      .hidden \name
++      .type \name,@function
++\name:
++      .cfi_startproc
++#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
++      exrl    0,0f
++#else
++      larl    \tmp,0f
++      ex      0,0(\tmp)
++#endif
++      j       .
++0:    br      \reg
++      .cfi_endproc
++      .endm
++
++      GEN_BR_THUNK __s390x_indirect_jump_r1use_r9,%r9,%r1
++      GEN_BR_THUNK __s390x_indirect_jump_r1use_r14,%r14,%r1
++      GEN_BR_THUNK __s390x_indirect_jump_r11use_r14,%r14,%r11
++
++      .macro BASR_R14_R9
++0:    brasl   %r14,__s390x_indirect_jump_r1use_r9
++      .pushsection .s390_indirect_branches,"a",@progbits
++      .long   0b-.
++      .popsection
++      .endm
++
++      .macro BR_R1USE_R14
++0:    jg      __s390x_indirect_jump_r1use_r14
++      .pushsection .s390_indirect_branches,"a",@progbits
++      .long   0b-.
++      .popsection
++      .endm
++
++      .macro BR_R11USE_R14
++0:    jg      __s390x_indirect_jump_r11use_r14
++      .pushsection .s390_indirect_branches,"a",@progbits
++      .long   0b-.
++      .popsection
++      .endm
++
++#else /* CONFIG_EXPOLINE */
++
++      .macro BASR_R14_R9
++      basr    %r14,%r9
++      .endm
++
++      .macro BR_R1USE_R14
++      br      %r14
++      .endm
++
++      .macro BR_R11USE_R14
++      br      %r14
++      .endm
++
++#endif /* CONFIG_EXPOLINE */
++
++
+       .section .kprobes.text, "ax"
+ .Ldummy:
+       /*
+@@ -170,6 +295,11 @@ _PIF_WORK = (_PIF_PER_TRAP | _PIF_SYSCALL_RESTART)
+        */
+       nop     0
+ 
++ENTRY(__bpon)
++      .globl __bpon
++      BPON
++      BR_R1USE_R14
++
+ /*
+  * Scheduler resume function, called by switch_to
+  *  gpr2 = (task_struct *) prev
+@@ -193,9 +323,9 @@ ENTRY(__switch_to)
+       mvc     __LC_CURRENT_PID(4,%r0),__TASK_pid(%r3) # store pid of next
+       lmg     %r6,%r15,__SF_GPRS(%r15)        # load gprs of next task
+       TSTMSK  __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP
+-      bzr     %r14
++      jz      0f
+       .insn   s,0xb2800000,__LC_LPP           # set program parameter
+-      br      %r14
++0:    BR_R1USE_R14
+ 
+ .L__critical_start:
+ 
+@@ -207,9 +337,11 @@ ENTRY(__switch_to)
+  */
+ ENTRY(sie64a)
+       stmg    %r6,%r14,__SF_GPRS(%r15)        # save kernel registers
++      lg      %r12,__LC_CURRENT
+       stg     %r2,__SF_EMPTY(%r15)            # save control block pointer
+       stg     %r3,__SF_EMPTY+8(%r15)          # save guest register save area
+       xc      __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # reason code = 0
++      mvc     __SF_EMPTY+24(8,%r15),__TI_flags(%r12) # copy thread flags
+       TSTMSK  __LC_CPU_FLAGS,_CIF_FPU         # load guest fp/vx registers ?
+       jno     .Lsie_load_guest_gprs
+       brasl   %r14,load_fpu_regs              # load guest fp/vx regs
+@@ -226,8 +358,12 @@ ENTRY(sie64a)
+       jnz     .Lsie_skip
+       TSTMSK  __LC_CPU_FLAGS,_CIF_FPU
+       jo      .Lsie_skip                      # exit if fp/vx regs changed
++      BPEXIT  __SF_EMPTY+24(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
+ .Lsie_entry:
+       sie     0(%r14)
++.Lsie_exit:
++      BPOFF
++      BPENTER __SF_EMPTY+24(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
+ .Lsie_skip:
+       ni      __SIE_PROG0C+3(%r14),0xfe       # no longer in SIE
+       lctlg   %c1,%c1,__LC_USER_ASCE          # load primary asce
+@@ -248,9 +384,15 @@ ENTRY(sie64a)
+ sie_exit:
+       lg      %r14,__SF_EMPTY+8(%r15)         # load guest register save area
+       stmg    %r0,%r13,0(%r14)                # save guest gprs 0-13
++      xgr     %r0,%r0                         # clear guest registers to
++      xgr     %r1,%r1                         # prevent speculative use
++      xgr     %r2,%r2
++      xgr     %r3,%r3
++      xgr     %r4,%r4
++      xgr     %r5,%r5
+       lmg     %r6,%r14,__SF_GPRS(%r15)        # restore kernel registers
+       lg      %r2,__SF_EMPTY+16(%r15)         # return exit reason code
+-      br      %r14
++      BR_R1USE_R14
+ .Lsie_fault:
+       lghi    %r14,-EFAULT
+       stg     %r14,__SF_EMPTY+16(%r15)        # set exit reason code
+@@ -273,6 +415,7 @@ ENTRY(system_call)
+       stpt    __LC_SYNC_ENTER_TIMER
+ .Lsysc_stmg:
+       stmg    %r8,%r15,__LC_SAVE_AREA_SYNC
++      BPOFF
+       lg      %r12,__LC_CURRENT
+       lghi    %r13,__TASK_thread
+       lghi    %r14,_PIF_SYSCALL
+@@ -281,12 +424,15 @@ ENTRY(system_call)
+       la      %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
+ .Lsysc_vtime:
+       UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER
++      BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
+       stmg    %r0,%r7,__PT_R0(%r11)
+       mvc     __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
+       mvc     __PT_PSW(16,%r11),__LC_SVC_OLD_PSW
+       mvc     __PT_INT_CODE(4,%r11),__LC_SVC_ILC
+       stg     %r14,__PT_FLAGS(%r11)
+ .Lsysc_do_svc:
++      # clear user controlled register to prevent speculative use
++      xgr     %r0,%r0
+       # load address of system call table
+       lg      %r10,__THREAD_sysc_table(%r13,%r12)
+       llgh    %r8,__PT_INT_CODE+2(%r11)
+@@ -305,7 +451,7 @@ ENTRY(system_call)
+       lgf     %r9,0(%r8,%r10)                 # get system call add.
+       TSTMSK  __TI_flags(%r12),_TIF_TRACE
+       jnz     .Lsysc_tracesys
+-      basr    %r14,%r9                        # call sys_xxxx
++      BASR_R14_R9                             # call sys_xxxx
+       stg     %r2,__PT_R2(%r11)               # store return value
+ 
+ .Lsysc_return:
+@@ -317,6 +463,7 @@ ENTRY(system_call)
+       jnz     .Lsysc_work                     # check for work
+       TSTMSK  __LC_CPU_FLAGS,_CIF_WORK
+       jnz     .Lsysc_work
++      BPEXIT  __TI_flags(%r12),_TIF_ISOLATE_BP
+ .Lsysc_restore:
+       lg      %r14,__LC_VDSO_PER_CPU
+       lmg     %r0,%r10,__PT_R0(%r11)
+@@ -481,7 +628,7 @@ ENTRY(system_call)
+       lmg     %r3,%r7,__PT_R3(%r11)
+       stg     %r7,STACK_FRAME_OVERHEAD(%r15)
+       lg      %r2,__PT_ORIG_GPR2(%r11)
+-      basr    %r14,%r9                # call sys_xxx
++      BASR_R14_R9                     # call sys_xxx
+       stg     %r2,__PT_R2(%r11)       # store return value
+ .Lsysc_tracenogo:
+       TSTMSK  __TI_flags(%r12),_TIF_TRACE
+@@ -505,7 +652,7 @@ ENTRY(ret_from_fork)
+       lmg     %r9,%r10,__PT_R9(%r11)  # load gprs
+ ENTRY(kernel_thread_starter)
+       la      %r2,0(%r10)
+-      basr    %r14,%r9
++      BASR_R14_R9
+       j       .Lsysc_tracenogo
+ 
+ /*
+@@ -514,6 +661,7 @@ ENTRY(kernel_thread_starter)
+ 
+ ENTRY(pgm_check_handler)
+       stpt    __LC_SYNC_ENTER_TIMER
++      BPOFF
+       stmg    %r8,%r15,__LC_SAVE_AREA_SYNC
+       lg      %r10,__LC_LAST_BREAK
+       lg      %r12,__LC_CURRENT
+@@ -540,6 +688,7 @@ ENTRY(pgm_check_handler)
+       aghi    %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
+       j       4f
+ 2:    UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
++      BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
+       lg      %r15,__LC_KERNEL_STACK
+       lgr     %r14,%r12
+       aghi    %r14,__TASK_thread      # pointer to thread_struct
+@@ -550,6 +699,15 @@ ENTRY(pgm_check_handler)
+ 3:    stg     %r10,__THREAD_last_break(%r14)
+ 4:    la      %r11,STACK_FRAME_OVERHEAD(%r15)
+       stmg    %r0,%r7,__PT_R0(%r11)
++      # clear user controlled registers to prevent speculative use
++      xgr     %r0,%r0
++      xgr     %r1,%r1
++      xgr     %r2,%r2
++      xgr     %r3,%r3
++      xgr     %r4,%r4
++      xgr     %r5,%r5
++      xgr     %r6,%r6
++      xgr     %r7,%r7
+       mvc     __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
+       stmg    %r8,%r9,__PT_PSW(%r11)
+       mvc     __PT_INT_CODE(4,%r11),__LC_PGM_ILC
+@@ -571,9 +729,9 @@ ENTRY(pgm_check_handler)
+       nill    %r10,0x007f
+       sll     %r10,2
+       je      .Lpgm_return
+-      lgf     %r1,0(%r10,%r1)         # load address of handler routine
++      lgf     %r9,0(%r10,%r1)         # load address of handler routine
+       lgr     %r2,%r11                # pass pointer to pt_regs
+-      basr    %r14,%r1                # branch to interrupt-handler
++      BASR_R14_R9                     # branch to interrupt-handler
+ .Lpgm_return:
+       LOCKDEP_SYS_EXIT
+       tm      __PT_PSW+1(%r11),0x01   # returning to user ?
+@@ -609,12 +767,23 @@ ENTRY(pgm_check_handler)
+ ENTRY(io_int_handler)
+       STCK    __LC_INT_CLOCK
+       stpt    __LC_ASYNC_ENTER_TIMER
++      BPOFF
+       stmg    %r8,%r15,__LC_SAVE_AREA_ASYNC
+       lg      %r12,__LC_CURRENT
+       larl    %r13,cleanup_critical
+       lmg     %r8,%r9,__LC_IO_OLD_PSW
+       SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_ENTER_TIMER
+       stmg    %r0,%r7,__PT_R0(%r11)
++      # clear user controlled registers to prevent speculative use
++      xgr     %r0,%r0
++      xgr     %r1,%r1
++      xgr     %r2,%r2
++      xgr     %r3,%r3
++      xgr     %r4,%r4
++      xgr     %r5,%r5
++      xgr     %r6,%r6
++      xgr     %r7,%r7
++      xgr     %r10,%r10
+       mvc     __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
+       stmg    %r8,%r9,__PT_PSW(%r11)
+       mvc     __PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
+@@ -649,9 +818,13 @@ ENTRY(io_int_handler)
+       lg      %r14,__LC_VDSO_PER_CPU
+       lmg     %r0,%r10,__PT_R0(%r11)
+       mvc     __LC_RETURN_PSW(16),__PT_PSW(%r11)
++      tm      __PT_PSW+1(%r11),0x01   # returning to user ?
++      jno     .Lio_exit_kernel
++      BPEXIT  __TI_flags(%r12),_TIF_ISOLATE_BP
+ .Lio_exit_timer:
+       stpt    __LC_EXIT_TIMER
+       mvc     __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
++.Lio_exit_kernel:
+       lmg     %r11,%r15,__PT_R11(%r11)
+       lpswe   __LC_RETURN_PSW
+ .Lio_done:
+@@ -814,12 +987,23 @@ ENTRY(io_int_handler)
+ ENTRY(ext_int_handler)
+       STCK    __LC_INT_CLOCK
+       stpt    __LC_ASYNC_ENTER_TIMER
++      BPOFF
+       stmg    %r8,%r15,__LC_SAVE_AREA_ASYNC
+       lg      %r12,__LC_CURRENT
+       larl    %r13,cleanup_critical
+       lmg     %r8,%r9,__LC_EXT_OLD_PSW
+       SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_ENTER_TIMER
+       stmg    %r0,%r7,__PT_R0(%r11)
++      # clear user controlled registers to prevent speculative use
++      xgr     %r0,%r0
++      xgr     %r1,%r1
++      xgr     %r2,%r2
++      xgr     %r3,%r3
++      xgr     %r4,%r4
++      xgr     %r5,%r5
++      xgr     %r6,%r6
++      xgr     %r7,%r7
++      xgr     %r10,%r10
+       mvc     __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
+       stmg    %r8,%r9,__PT_PSW(%r11)
+       lghi    %r1,__LC_EXT_PARAMS2
+@@ -852,11 +1036,12 @@ ENTRY(psw_idle)
+ .Lpsw_idle_stcctm:
+ #endif
+       oi      __LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT
++      BPON
+       STCK    __CLOCK_IDLE_ENTER(%r2)
+       stpt    __TIMER_IDLE_ENTER(%r2)
+ .Lpsw_idle_lpsw:
+       lpswe   __SF_EMPTY(%r15)
+-      br      %r14
++      BR_R1USE_R14
+ .Lpsw_idle_end:
+ 
+ /*
+@@ -870,7 +1055,7 @@ ENTRY(save_fpu_regs)
+       lg      %r2,__LC_CURRENT
+       aghi    %r2,__TASK_thread
+       TSTMSK  __LC_CPU_FLAGS,_CIF_FPU
+-      bor     %r14
++      jo      .Lsave_fpu_regs_exit
+       stfpc   __THREAD_FPU_fpc(%r2)
+       lg      %r3,__THREAD_FPU_regs(%r2)
+       TSTMSK  __LC_MACHINE_FLAGS,MACHINE_FLAG_VX
+@@ -897,7 +1082,8 @@ ENTRY(save_fpu_regs)
+       std     15,120(%r3)
+ .Lsave_fpu_regs_done:
+       oi      __LC_CPU_FLAGS+7,_CIF_FPU
+-      br      %r14
++.Lsave_fpu_regs_exit:
++      BR_R1USE_R14
+ .Lsave_fpu_regs_end:
+ EXPORT_SYMBOL(save_fpu_regs)
+ 
+@@ -915,7 +1101,7 @@ load_fpu_regs:
+       lg      %r4,__LC_CURRENT
+       aghi    %r4,__TASK_thread
+       TSTMSK  __LC_CPU_FLAGS,_CIF_FPU
+-      bnor    %r14
++      jno     .Lload_fpu_regs_exit
+       lfpc    __THREAD_FPU_fpc(%r4)
+       TSTMSK  __LC_MACHINE_FLAGS,MACHINE_FLAG_VX
+       lg      %r4,__THREAD_FPU_regs(%r4)      # %r4 <- reg save area
+@@ -942,7 +1128,8 @@ load_fpu_regs:
+       ld      15,120(%r4)
+ .Lload_fpu_regs_done:
+       ni      __LC_CPU_FLAGS+7,255-_CIF_FPU
+-      br      %r14
++.Lload_fpu_regs_exit:
++      BR_R1USE_R14
+ .Lload_fpu_regs_end:
+ 
+ .L__critical_end:
+@@ -952,6 +1139,7 @@ load_fpu_regs:
+  */
+ ENTRY(mcck_int_handler)
+       STCK    __LC_MCCK_CLOCK
++      BPOFF
+       la      %r1,4095                # revalidate r1
+       spt     __LC_CPU_TIMER_SAVE_AREA-4095(%r1)      # revalidate cpu timer
+       lmg     %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
+@@ -982,6 +1170,16 @@ ENTRY(mcck_int_handler)
+ .Lmcck_skip:
+       lghi    %r14,__LC_GPREGS_SAVE_AREA+64
+       stmg    %r0,%r7,__PT_R0(%r11)
++      # clear user controlled registers to prevent speculative use
++      xgr     %r0,%r0
++      xgr     %r1,%r1
++      xgr     %r2,%r2
++      xgr     %r3,%r3
++      xgr     %r4,%r4
++      xgr     %r5,%r5
++      xgr     %r6,%r6
++      xgr     %r7,%r7
++      xgr     %r10,%r10
+       mvc     __PT_R8(64,%r11),0(%r14)
+       stmg    %r8,%r9,__PT_PSW(%r11)
+       xc      __PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
+@@ -1007,6 +1205,7 @@ ENTRY(mcck_int_handler)
+       mvc     __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
+       tm      __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
+       jno     0f
++      BPEXIT  __TI_flags(%r12),_TIF_ISOLATE_BP
+       stpt    __LC_EXIT_TIMER
+       mvc     __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
+ 0:    lmg     %r11,%r15,__PT_R11(%r11)
+@@ -1102,7 +1301,7 @@ cleanup_critical:
+       jl      0f
+       clg     %r9,BASED(.Lcleanup_table+104)  # .Lload_fpu_regs_end
+       jl      .Lcleanup_load_fpu_regs
+-0:    br      %r14
++0:    BR_R11USE_R14
+ 
+       .align  8
+ .Lcleanup_table:
+@@ -1133,11 +1332,12 @@ cleanup_critical:
+       clg     %r9,BASED(.Lsie_crit_mcck_length)
+       jh      1f
+       oi      __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
+-1:    lg      %r9,__SF_EMPTY(%r15)            # get control block pointer
++1:    BPENTER __SF_EMPTY+24(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
++      lg      %r9,__SF_EMPTY(%r15)            # get control block pointer
+       ni      __SIE_PROG0C+3(%r9),0xfe        # no longer in SIE
+       lctlg   %c1,%c1,__LC_USER_ASCE          # load primary asce
+       larl    %r9,sie_exit                    # skip forward to sie_exit
+-      br      %r14
++      BR_R11USE_R14
+ #endif
+ 
+ .Lcleanup_system_call:
+@@ -1175,6 +1375,7 @@ cleanup_critical:
+       stg     %r15,__LC_SYSTEM_TIMER
+ 0:    # update accounting time stamp
+       mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
++      BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
+       # set up saved register r11
+       lg      %r15,__LC_KERNEL_STACK
+       la      %r9,STACK_FRAME_OVERHEAD(%r15)
+@@ -1190,7 +1391,7 @@ cleanup_critical:
+       stg     %r15,56(%r11)           # r15 stack pointer
+       # set new psw address and exit
+       larl    %r9,.Lsysc_do_svc
+-      br      %r14
++      BR_R11USE_R14
+ .Lcleanup_system_call_insn:
+       .quad   system_call
+       .quad   .Lsysc_stmg
+@@ -1202,7 +1403,7 @@ cleanup_critical:
+ 
+ .Lcleanup_sysc_tif:
+       larl    %r9,.Lsysc_tif
+-      br      %r14
++      BR_R11USE_R14
+ 
+ .Lcleanup_sysc_restore:
+       # check if stpt has been executed
+@@ -1219,14 +1420,14 @@ cleanup_critical:
+       mvc     0(64,%r11),__PT_R8(%r9)
+       lmg     %r0,%r7,__PT_R0(%r9)
+ 1:    lmg     %r8,%r9,__LC_RETURN_PSW
+-      br      %r14
++      BR_R11USE_R14
+ .Lcleanup_sysc_restore_insn:
+       .quad   .Lsysc_exit_timer
+       .quad   .Lsysc_done - 4
+ 
+ .Lcleanup_io_tif:
+       larl    %r9,.Lio_tif
+-      br      %r14
++      BR_R11USE_R14
+ 
+ .Lcleanup_io_restore:
+       # check if stpt has been executed
+@@ -1240,7 +1441,7 @@ cleanup_critical:
+       mvc     0(64,%r11),__PT_R8(%r9)
+       lmg     %r0,%r7,__PT_R0(%r9)
+ 1:    lmg     %r8,%r9,__LC_RETURN_PSW
+-      br      %r14
++      BR_R11USE_R14
+ .Lcleanup_io_restore_insn:
+       .quad   .Lio_exit_timer
+       .quad   .Lio_done - 4
+@@ -1293,17 +1494,17 @@ cleanup_critical:
+       # prepare return psw
+       nihh    %r8,0xfcfd              # clear irq & wait state bits
+       lg      %r9,48(%r11)            # return from psw_idle
+-      br      %r14
++      BR_R11USE_R14
+ .Lcleanup_idle_insn:
+       .quad   .Lpsw_idle_lpsw
+ 
+ .Lcleanup_save_fpu_regs:
+       larl    %r9,save_fpu_regs
+-      br      %r14
++      BR_R11USE_R14
+ 
+ .Lcleanup_load_fpu_regs:
+       larl    %r9,load_fpu_regs
+-      br      %r14
++      BR_R11USE_R14
+ 
+ /*
+  * Integer constants
+@@ -1323,7 +1524,6 @@ cleanup_critical:
+ .Lsie_crit_mcck_length:
+       .quad   .Lsie_skip - .Lsie_entry
+ #endif
+-
+       .section .rodata, "a"
+ #define SYSCALL(esame,emu)    .long esame
+       .globl  sys_call_table
+diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
+index d1a0e2c521d7..b565e784bae8 100644
+--- a/arch/s390/kernel/ipl.c
++++ b/arch/s390/kernel/ipl.c
+@@ -564,6 +564,7 @@ static struct kset *ipl_kset;
+ 
+ static void __ipl_run(void *unused)
+ {
++      __bpon();
+       diag308(DIAG308_LOAD_CLEAR, NULL);
+       if (MACHINE_IS_VM)
+               __cpcmd("IPL", NULL, 0, NULL);
+diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
+index 1a27f307a920..b441e069e674 100644
+--- a/arch/s390/kernel/module.c
++++ b/arch/s390/kernel/module.c
+@@ -31,6 +31,9 @@
+ #include <linux/kernel.h>
+ #include <linux/moduleloader.h>
+ #include <linux/bug.h>
++#include <asm/alternative.h>
++#include <asm/nospec-branch.h>
++#include <asm/facility.h>
+ 
+ #if 0
+ #define DEBUGP printk
+@@ -168,7 +171,11 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr 
*sechdrs,
+       me->arch.got_offset = me->core_layout.size;
+       me->core_layout.size += me->arch.got_size;
+       me->arch.plt_offset = me->core_layout.size;
+-      me->core_layout.size += me->arch.plt_size;
++      if (me->arch.plt_size) {
++              if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_disable)
++                      me->arch.plt_size += PLT_ENTRY_SIZE;
++              me->core_layout.size += me->arch.plt_size;
++      }
+       return 0;
+ }
+ 
+@@ -322,9 +329,20 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, 
Elf_Sym *symtab,
+                       unsigned int *ip;
+                       ip = me->core_layout.base + me->arch.plt_offset +
+                               info->plt_offset;
+-                      ip[0] = 0x0d10e310; /* basr 1,0; lg 1,10(1); br 1 */
+-                      ip[1] = 0x100a0004;
+-                      ip[2] = 0x07f10000;
++                      ip[0] = 0x0d10e310;     /* basr 1,0  */
++                      ip[1] = 0x100a0004;     /* lg   1,10(1) */
++                      if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_disable) {
++                              unsigned int *ij;
++                              ij = me->core_layout.base +
++                                      me->arch.plt_offset +
++                                      me->arch.plt_size - PLT_ENTRY_SIZE;
++                              ip[2] = 0xa7f40000 +    /* j __jump_r1 */
++                                      (unsigned int)(u16)
++                                      (((unsigned long) ij - 8 -
++                                        (unsigned long) ip) / 2);
++                      } else {
++                              ip[2] = 0x07f10000;     /* br %r1 */
++                      }
+                       ip[3] = (unsigned int) (val >> 32);
+                       ip[4] = (unsigned int) val;
+                       info->plt_initialized = 1;
+@@ -429,6 +447,45 @@ int module_finalize(const Elf_Ehdr *hdr,
+                   const Elf_Shdr *sechdrs,
+                   struct module *me)
+ {
++      const Elf_Shdr *s;
++      char *secstrings, *secname;
++      void *aseg;
++
++      if (IS_ENABLED(CONFIG_EXPOLINE) &&
++          !nospec_disable && me->arch.plt_size) {
++              unsigned int *ij;
++
++              ij = me->core_layout.base + me->arch.plt_offset +
++                      me->arch.plt_size - PLT_ENTRY_SIZE;
++              if (test_facility(35)) {
++                      ij[0] = 0xc6000000;     /* exrl %r0,.+10        */
++                      ij[1] = 0x0005a7f4;     /* j    .               */
++                      ij[2] = 0x000007f1;     /* br   %r1             */
++              } else {
++                      ij[0] = 0x44000000 | (unsigned int)
++                              offsetof(struct lowcore, br_r1_trampoline);
++                      ij[1] = 0xa7f40000;     /* j    .               */
++              }
++      }
++
++      secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
++      for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
++              aseg = (void *) s->sh_addr;
++              secname = secstrings + s->sh_name;
++
++              if (!strcmp(".altinstructions", secname))
++                      /* patch .altinstructions */
++                      apply_alternatives(aseg, aseg + s->sh_size);
++
++              if (IS_ENABLED(CONFIG_EXPOLINE) &&
++                  (!strncmp(".s390_indirect", secname, 14)))
++                      nospec_revert(aseg, aseg + s->sh_size);
++
++              if (IS_ENABLED(CONFIG_EXPOLINE) &&
++                  (!strncmp(".s390_return", secname, 12)))
++                      nospec_revert(aseg, aseg + s->sh_size);
++      }
++
+       jump_label_apply_nops(me);
+       return 0;
+ }
+diff --git a/arch/s390/kernel/nospec-branch.c 
b/arch/s390/kernel/nospec-branch.c
+new file mode 100644
+index 000000000000..9f3b5b382743
+--- /dev/null
++++ b/arch/s390/kernel/nospec-branch.c
+@@ -0,0 +1,169 @@
++// SPDX-License-Identifier: GPL-2.0
++#include <linux/module.h>
++#include <linux/device.h>
++#include <asm/facility.h>
++#include <asm/nospec-branch.h>
++
++static int __init nobp_setup_early(char *str)
++{
++      bool enabled;
++      int rc;
++
++      rc = kstrtobool(str, &enabled);
++      if (rc)
++              return rc;
++      if (enabled && test_facility(82)) {
++              /*
++               * The user explicitely requested nobp=1, enable it and
++               * disable the expoline support.
++               */
++              __set_facility(82, S390_lowcore.alt_stfle_fac_list);
++              if (IS_ENABLED(CONFIG_EXPOLINE))
++                      nospec_disable = 1;
++      } else {
++              __clear_facility(82, S390_lowcore.alt_stfle_fac_list);
++      }
++      return 0;
++}
++early_param("nobp", nobp_setup_early);
++
++static int __init nospec_setup_early(char *str)
++{
++      __clear_facility(82, S390_lowcore.alt_stfle_fac_list);
++      return 0;
++}
++early_param("nospec", nospec_setup_early);
++
++static int __init nospec_report(void)
++{
++      if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable)
++              pr_info("Spectre V2 mitigation: execute trampolines.\n");
++      if (__test_facility(82, S390_lowcore.alt_stfle_fac_list))
++              pr_info("Spectre V2 mitigation: limited branch prediction.\n");
++      return 0;
++}
++arch_initcall(nospec_report);
++
++#ifdef CONFIG_SYSFS
++ssize_t cpu_show_spectre_v1(struct device *dev,
++                          struct device_attribute *attr, char *buf)
++{
++      return sprintf(buf, "Mitigation: __user pointer sanitization\n");
++}
++
++ssize_t cpu_show_spectre_v2(struct device *dev,
++                          struct device_attribute *attr, char *buf)
++{
++      if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable)
++              return sprintf(buf, "Mitigation: execute trampolines\n");
++      if (__test_facility(82, S390_lowcore.alt_stfle_fac_list))
++              return sprintf(buf, "Mitigation: limited branch prediction.\n");
++      return sprintf(buf, "Vulnerable\n");
++}
++#endif
++
++#ifdef CONFIG_EXPOLINE
++
++int nospec_disable = IS_ENABLED(CONFIG_EXPOLINE_OFF);
++
++static int __init nospectre_v2_setup_early(char *str)
++{
++      nospec_disable = 1;
++      return 0;
++}
++early_param("nospectre_v2", nospectre_v2_setup_early);
++
++void __init nospec_auto_detect(void)
++{
++      if (IS_ENABLED(CC_USING_EXPOLINE)) {
++              /*
++               * The kernel has been compiled with expolines.
++               * Keep expolines enabled and disable nobp.
++               */
++              nospec_disable = 0;
++              __clear_facility(82, S390_lowcore.alt_stfle_fac_list);
++      }
++      /*
++       * If the kernel has not been compiled with expolines the
++       * nobp setting decides what is done, this depends on the
++       * CONFIG_KERNEL_NP option and the nobp/nospec parameters.
++       */
++}
++
++static int __init spectre_v2_setup_early(char *str)
++{
++      if (str && !strncmp(str, "on", 2)) {
++              nospec_disable = 0;
++              __clear_facility(82, S390_lowcore.alt_stfle_fac_list);
++      }
++      if (str && !strncmp(str, "off", 3))
++              nospec_disable = 1;
++      if (str && !strncmp(str, "auto", 4))
++              nospec_auto_detect();
++      return 0;
++}
++early_param("spectre_v2", spectre_v2_setup_early);
++
++static void __init_or_module __nospec_revert(s32 *start, s32 *end)
++{
++      enum { BRCL_EXPOLINE, BRASL_EXPOLINE } type;
++      u8 *instr, *thunk, *br;
++      u8 insnbuf[6];
++      s32 *epo;
++
++      /* Second part of the instruction replace is always a nop */
++      memcpy(insnbuf + 2, (char[]) { 0x47, 0x00, 0x00, 0x00 }, 4);
++      for (epo = start; epo < end; epo++) {
++              instr = (u8 *) epo + *epo;
++              if (instr[0] == 0xc0 && (instr[1] & 0x0f) == 0x04)
++                      type = BRCL_EXPOLINE;   /* brcl instruction */
++              else if (instr[0] == 0xc0 && (instr[1] & 0x0f) == 0x05)
++                      type = BRASL_EXPOLINE;  /* brasl instruction */
++              else
++                      continue;
++              thunk = instr + (*(int *)(instr + 2)) * 2;
++              if (thunk[0] == 0xc6 && thunk[1] == 0x00)
++                      /* exrl %r0,<target-br> */
++                      br = thunk + (*(int *)(thunk + 2)) * 2;
++              else if (thunk[0] == 0xc0 && (thunk[1] & 0x0f) == 0x00 &&
++                       thunk[6] == 0x44 && thunk[7] == 0x00 &&
++                       (thunk[8] & 0x0f) == 0x00 && thunk[9] == 0x00 &&
++                       (thunk[1] & 0xf0) == (thunk[8] & 0xf0))
++                      /* larl %rx,<target br> + ex %r0,0(%rx) */
++                      br = thunk + (*(int *)(thunk + 2)) * 2;
++              else
++                      continue;
++              if (br[0] != 0x07 || (br[1] & 0xf0) != 0xf0)
++                      continue;
++              switch (type) {
++              case BRCL_EXPOLINE:
++                      /* brcl to thunk, replace with br + nop */
++                      insnbuf[0] = br[0];
++                      insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f);
++                      break;
++              case BRASL_EXPOLINE:
++                      /* brasl to thunk, replace with basr + nop */
++                      insnbuf[0] = 0x0d;
++                      insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f);
++                      break;
++              }
++
++              s390_kernel_write(instr, insnbuf, 6);
++      }
++}
++
++void __init_or_module nospec_revert(s32 *start, s32 *end)
++{
++      if (nospec_disable)
++              __nospec_revert(start, end);
++}
++
++extern s32 __nospec_call_start[], __nospec_call_end[];
++extern s32 __nospec_return_start[], __nospec_return_end[];
++void __init nospec_init_branches(void)
++{
++      nospec_revert(__nospec_call_start, __nospec_call_end);
++      nospec_revert(__nospec_return_start, __nospec_return_end);
++}
++
++#endif /* CONFIG_EXPOLINE */
+diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c
+index 5362fd868d0d..6fe2e1875058 100644
+--- a/arch/s390/kernel/processor.c
++++ b/arch/s390/kernel/processor.c
+@@ -197,3 +197,21 @@ const struct seq_operations cpuinfo_op = {
+       .stop   = c_stop,
+       .show   = show_cpuinfo,
+ };
++
++int s390_isolate_bp(void)
++{
++      if (!test_facility(82))
++              return -EOPNOTSUPP;
++      set_thread_flag(TIF_ISOLATE_BP);
++      return 0;
++}
++EXPORT_SYMBOL(s390_isolate_bp);
++
++int s390_isolate_bp_guest(void)
++{
++      if (!test_facility(82))
++              return -EOPNOTSUPP;
++      set_thread_flag(TIF_ISOLATE_BP_GUEST);
++      return 0;
++}
++EXPORT_SYMBOL(s390_isolate_bp_guest);
+diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
+index 164a1e16b53e..98c1f7941142 100644
+--- a/arch/s390/kernel/setup.c
++++ b/arch/s390/kernel/setup.c
+@@ -66,6 +66,8 @@
+ #include <asm/sclp.h>
+ #include <asm/sysinfo.h>
+ #include <asm/numa.h>
++#include <asm/alternative.h>
++#include <asm/nospec-branch.h>
+ #include "entry.h"
+ 
+ /*
+@@ -338,7 +340,9 @@ static void __init setup_lowcore(void)
+       lc->preempt_count = S390_lowcore.preempt_count;
+       lc->stfl_fac_list = S390_lowcore.stfl_fac_list;
+       memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list,
+-             MAX_FACILITY_BIT/8);
++             sizeof(lc->stfle_fac_list));
++      memcpy(lc->alt_stfle_fac_list, S390_lowcore.alt_stfle_fac_list,
++             sizeof(lc->alt_stfle_fac_list));
+       if (MACHINE_HAS_VX || MACHINE_HAS_GS) {
+               unsigned long bits, size;
+ 
+@@ -381,6 +385,7 @@ static void __init setup_lowcore(void)
+ #ifdef CONFIG_SMP
+       lc->spinlock_lockval = arch_spin_lockval(0);
+ #endif
++      lc->br_r1_trampoline = 0x07f1;  /* br %r1 */
+ 
+       set_prefix((u32)(unsigned long) lc);
+       lowcore_ptr[0] = lc;
+@@ -892,6 +897,9 @@ void __init setup_arch(char **cmdline_p)
+       init_mm.end_data = (unsigned long) &_edata;
+       init_mm.brk = (unsigned long) &_end;
+ 
++      if (IS_ENABLED(CONFIG_EXPOLINE_AUTO))
++              nospec_auto_detect();
++
+       parse_early_param();
+ #ifdef CONFIG_CRASH_DUMP
+       /* Deactivate elfcorehdr= kernel parameter */
+@@ -955,6 +963,10 @@ void __init setup_arch(char **cmdline_p)
+       conmode_default();
+       set_preferred_console();
+ 
++      apply_alternative_instructions();
++      if (IS_ENABLED(CONFIG_EXPOLINE))
++              nospec_init_branches();
++
+       /* Setup zfcpdump support */
+       setup_zfcpdump();
+ 
+diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
+index 7ffaf9fd6d19..ae5df4177803 100644
+--- a/arch/s390/kernel/smp.c
++++ b/arch/s390/kernel/smp.c
+@@ -228,6 +228,7 @@ static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu)
+       lc->mcesad = mcesa_origin | mcesa_bits;
+       lc->cpu_nr = cpu;
+       lc->spinlock_lockval = arch_spin_lockval(cpu);
++      lc->br_r1_trampoline = 0x07f1;  /* br %r1 */
+       if (vdso_alloc_per_cpu(lc))
+               goto out;
+       lowcore_ptr[cpu] = lc;
+@@ -282,7 +283,9 @@ static void pcpu_prepare_secondary(struct pcpu *pcpu, int 
cpu)
+       __ctl_store(lc->cregs_save_area, 0, 15);
+       save_access_regs((unsigned int *) lc->access_regs_save_area);
+       memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list,
+-             MAX_FACILITY_BIT/8);
++             sizeof(lc->stfle_fac_list));
++      memcpy(lc->alt_stfle_fac_list, S390_lowcore.alt_stfle_fac_list,
++             sizeof(lc->alt_stfle_fac_list));
+ }
+ 
+ static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk)
+@@ -332,6 +335,7 @@ static void pcpu_delegate(struct pcpu *pcpu, void 
(*func)(void *),
+       mem_assign_absolute(lc->restart_fn, (unsigned long) func);
+       mem_assign_absolute(lc->restart_data, (unsigned long) data);
+       mem_assign_absolute(lc->restart_source, source_cpu);
++      __bpon();
+       asm volatile(
+               "0:     sigp    0,%0,%2 # sigp restart to target cpu\n"
+               "       brc     2,0b    # busy, try again\n"
+@@ -907,6 +911,7 @@ void __cpu_die(unsigned int cpu)
+ void __noreturn cpu_die(void)
+ {
+       idle_task_exit();
++      __bpon();
+       pcpu_sigp_retry(pcpu_devices + smp_processor_id(), SIGP_STOP, 0);
+       for (;;) ;
+ }
+diff --git a/arch/s390/kernel/uprobes.c b/arch/s390/kernel/uprobes.c
+index d9d1f512f019..5007fac01bb5 100644
+--- a/arch/s390/kernel/uprobes.c
++++ b/arch/s390/kernel/uprobes.c
+@@ -150,6 +150,15 @@ unsigned long arch_uretprobe_hijack_return_addr(unsigned 
long trampoline,
+       return orig;
+ }
+ 
++bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx,
++                           struct pt_regs *regs)
++{
++      if (ctx == RP_CHECK_CHAIN_CALL)
++              return user_stack_pointer(regs) <= ret->stack;
++      else
++              return user_stack_pointer(regs) < ret->stack;
++}
++
+ /* Instruction Emulation */
+ 
+ static void adjust_psw_addr(psw_t *psw, unsigned long len)
+diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
+index 96a713a470e7..85dd3c7bdd86 100644
+--- a/arch/s390/kernel/vmlinux.lds.S
++++ b/arch/s390/kernel/vmlinux.lds.S
+@@ -105,6 +105,43 @@ SECTIONS
+               EXIT_DATA
+       }
+ 
++      /*
++       * struct alt_inst entries. From the header (alternative.h):
++       * "Alternative instructions for different CPU types or capabilities"
++       * Think locking instructions on spinlocks.
++       * Note, that it is a part of __init region.
++       */
++      . = ALIGN(8);
++      .altinstructions : {
++              __alt_instructions = .;
++              *(.altinstructions)
++              __alt_instructions_end = .;
++      }
++
++      /*
++       * And here are the replacement instructions. The linker sticks
++       * them as binary blobs. The .altinstructions has enough data to
++       * get the address and the length of them to patch the kernel safely.
++       * Note, that it is a part of __init region.
++       */
++      .altinstr_replacement : {
++              *(.altinstr_replacement)
++      }
++
++      /*
++       * Table with the patch locations to undo expolines
++      */
++      .nospec_call_table : {
++              __nospec_call_start = . ;
++              *(.s390_indirect*)
++              __nospec_call_end = . ;
++      }
++      .nospec_return_table : {
++              __nospec_return_start = . ;
++              *(.s390_return*)
++              __nospec_return_end = . ;
++      }
++
+       /* early.c uses stsi, which requires page aligned data. */
+       . = ALIGN(PAGE_SIZE);
+       INIT_DATA_SECTION(0x100)
+diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
+index 0bce918db11a..4f6adbea592b 100644
+--- a/arch/s390/kvm/kvm-s390.c
++++ b/arch/s390/kvm/kvm-s390.c
+@@ -449,6 +449,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
+       case KVM_CAP_S390_GS:
+               r = test_facility(133);
+               break;
++      case KVM_CAP_S390_BPB:
++              r = test_facility(82);
++              break;
+       default:
+               r = 0;
+       }
+@@ -2231,6 +2234,8 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
+       kvm_s390_set_prefix(vcpu, 0);
+       if (test_kvm_facility(vcpu->kvm, 64))
+               vcpu->run->kvm_valid_regs |= KVM_SYNC_RICCB;
++      if (test_kvm_facility(vcpu->kvm, 82))
++              vcpu->run->kvm_valid_regs |= KVM_SYNC_BPBC;
+       if (test_kvm_facility(vcpu->kvm, 133))
+               vcpu->run->kvm_valid_regs |= KVM_SYNC_GSCB;
+       /* fprs can be synchronized via vrs, even if the guest has no vx. With
+@@ -2372,6 +2377,7 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu 
*vcpu)
+       current->thread.fpu.fpc = 0;
+       vcpu->arch.sie_block->gbea = 1;
+       vcpu->arch.sie_block->pp = 0;
++      vcpu->arch.sie_block->fpf &= ~FPF_BPBC;
+       vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID;
+       kvm_clear_async_pf_completion_queue(vcpu);
+       if (!kvm_s390_user_cpu_state_ctrl(vcpu->kvm))
+@@ -3318,6 +3324,11 @@ static void sync_regs(struct kvm_vcpu *vcpu, struct 
kvm_run *kvm_run)
+               vcpu->arch.sie_block->ecd |= ECD_HOSTREGMGMT;
+               vcpu->arch.gs_enabled = 1;
+       }
++      if ((kvm_run->kvm_dirty_regs & KVM_SYNC_BPBC) &&
++          test_kvm_facility(vcpu->kvm, 82)) {
++              vcpu->arch.sie_block->fpf &= ~FPF_BPBC;
++              vcpu->arch.sie_block->fpf |= kvm_run->s.regs.bpbc ? FPF_BPBC : 
0;
++      }
+       save_access_regs(vcpu->arch.host_acrs);
+       restore_access_regs(vcpu->run->s.regs.acrs);
+       /* save host (userspace) fprs/vrs */
+@@ -3364,6 +3375,7 @@ static void store_regs(struct kvm_vcpu *vcpu, struct 
kvm_run *kvm_run)
+       kvm_run->s.regs.pft = vcpu->arch.pfault_token;
+       kvm_run->s.regs.pfs = vcpu->arch.pfault_select;
+       kvm_run->s.regs.pfc = vcpu->arch.pfault_compare;
++      kvm_run->s.regs.bpbc = (vcpu->arch.sie_block->fpf & FPF_BPBC) == 
FPF_BPBC;
+       save_access_regs(vcpu->run->s.regs.acrs);
+       restore_access_regs(vcpu->arch.host_acrs);
+       /* Save guest register state */
+diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c
+index a74204db759b..eb7b530d1783 100644
+--- a/arch/s390/kvm/vsie.c
++++ b/arch/s390/kvm/vsie.c
+@@ -234,6 +234,12 @@ static void unshadow_scb(struct kvm_vcpu *vcpu, struct 
vsie_page *vsie_page)
+       memcpy(scb_o->gcr, scb_s->gcr, 128);
+       scb_o->pp = scb_s->pp;
+ 
++      /* branch prediction */
++      if (test_kvm_facility(vcpu->kvm, 82)) {
++              scb_o->fpf &= ~FPF_BPBC;
++              scb_o->fpf |= scb_s->fpf & FPF_BPBC;
++      }
++
+       /* interrupt intercept */
+       switch (scb_s->icptcode) {
+       case ICPT_PROGI:
+@@ -280,6 +286,7 @@ static int shadow_scb(struct kvm_vcpu *vcpu, struct 
vsie_page *vsie_page)
+       scb_s->ecb3 = 0;
+       scb_s->ecd = 0;
+       scb_s->fac = 0;
++      scb_s->fpf = 0;
+ 
+       rc = prepare_cpuflags(vcpu, vsie_page);
+       if (rc)
+@@ -339,6 +346,9 @@ static int shadow_scb(struct kvm_vcpu *vcpu, struct 
vsie_page *vsie_page)
+                       prefix_unmapped(vsie_page);
+               scb_s->ecb |= ECB_TE;
+       }
++      /* branch prediction */
++      if (test_kvm_facility(vcpu->kvm, 82))
++              scb_s->fpf |= scb_o->fpf & FPF_BPBC;
+       /* SIMD */
+       if (test_kvm_facility(vcpu->kvm, 129)) {
+               scb_s->eca |= scb_o->eca & ECA_VX;
+@@ -821,6 +831,7 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct 
vsie_page *vsie_page)
+ {
+       struct kvm_s390_sie_block *scb_s = &vsie_page->scb_s;
+       struct kvm_s390_sie_block *scb_o = vsie_page->scb_o;
++      int guest_bp_isolation;
+       int rc;
+ 
+       handle_last_fault(vcpu, vsie_page);
+@@ -831,6 +842,20 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct 
vsie_page *vsie_page)
+               s390_handle_mcck();
+ 
+       srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
++
++      /* save current guest state of bp isolation override */
++      guest_bp_isolation = test_thread_flag(TIF_ISOLATE_BP_GUEST);
++
++      /*
++       * The guest is running with BPBC, so we have to force it on for our
++       * nested guest. This is done by enabling BPBC globally, so the BPBC
++       * control in the SCB (which the nested guest can modify) is simply
++       * ignored.
++       */
++      if (test_kvm_facility(vcpu->kvm, 82) &&
++          vcpu->arch.sie_block->fpf & FPF_BPBC)
++              set_thread_flag(TIF_ISOLATE_BP_GUEST);
++
+       local_irq_disable();
+       guest_enter_irqoff();
+       local_irq_enable();
+@@ -840,6 +865,11 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct 
vsie_page *vsie_page)
+       local_irq_disable();
+       guest_exit_irqoff();
+       local_irq_enable();
++
++      /* restore guest state for bp isolation override */
++      if (!guest_bp_isolation)
++              clear_thread_flag(TIF_ISOLATE_BP_GUEST);
++
+       vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
+ 
+       if (rc == -EINTR) {
+diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
+index f53ccc680238..dbdd460a9958 100644
+--- a/drivers/acpi/acpi_video.c
++++ b/drivers/acpi/acpi_video.c
+@@ -2123,6 +2123,25 @@ static int __init intel_opregion_present(void)
+       return opregion;
+ }
+ 
++static bool dmi_is_desktop(void)
++{
++      const char *chassis_type;
++
++      chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE);
++      if (!chassis_type)
++              return false;
++
++      if (!strcmp(chassis_type, "3") || /*  3: Desktop */
++          !strcmp(chassis_type, "4") || /*  4: Low Profile Desktop */
++          !strcmp(chassis_type, "5") || /*  5: Pizza Box */
++          !strcmp(chassis_type, "6") || /*  6: Mini Tower */
++          !strcmp(chassis_type, "7") || /*  7: Tower */
++          !strcmp(chassis_type, "11"))  /* 11: Main Server Chassis */
++              return true;
++
++      return false;
++}
++
+ int acpi_video_register(void)
+ {
+       int ret = 0;
+@@ -2143,8 +2162,12 @@ int acpi_video_register(void)
+        * win8 ready (where we also prefer the native backlight driver, so
+        * normally the acpi_video code should not register there anyways).
+        */
+-      if (only_lcd == -1)
+-              only_lcd = acpi_osi_is_win8();
++      if (only_lcd == -1) {
++              if (dmi_is_desktop() && acpi_osi_is_win8())
++                      only_lcd = true;
++              else
++                      only_lcd = false;
++      }
+ 
+       dmi_check_system(video_dmi_table);
+ 
+diff --git a/drivers/block/swim.c b/drivers/block/swim.c
+index 84434d3ea19b..e88d50f75a4a 100644
+--- a/drivers/block/swim.c
++++ b/drivers/block/swim.c
+@@ -110,7 +110,7 @@ struct iwm {
+ /* Select values for swim_select and swim_readbit */
+ 
+ #define READ_DATA_0   0x074
+-#define TWOMEG_DRIVE  0x075
++#define ONEMEG_DRIVE  0x075
+ #define SINGLE_SIDED  0x076
+ #define DRIVE_PRESENT 0x077
+ #define DISK_IN               0x170
+@@ -118,9 +118,9 @@ struct iwm {
+ #define TRACK_ZERO    0x172
+ #define TACHO         0x173
+ #define READ_DATA_1   0x174
+-#define MFM_MODE      0x175
++#define GCR_MODE      0x175
+ #define SEEK_COMPLETE 0x176
+-#define ONEMEG_MEDIA  0x177
++#define TWOMEG_MEDIA  0x177
+ 
+ /* Bits in handshake register */
+ 
+@@ -612,7 +612,6 @@ static void setup_medium(struct floppy_state *fs)
+               struct floppy_struct *g;
+               fs->disk_in = 1;
+               fs->write_protected = swim_readbit(base, WRITE_PROT);
+-              fs->type = swim_readbit(base, ONEMEG_MEDIA);
+ 
+               if (swim_track00(base))
+                       printk(KERN_ERR
+@@ -620,6 +619,9 @@ static void setup_medium(struct floppy_state *fs)
+ 
+               swim_track00(base);
+ 
++              fs->type = swim_readbit(base, TWOMEG_MEDIA) ?
++                      HD_MEDIA : DD_MEDIA;
++              fs->head_number = swim_readbit(base, SINGLE_SIDED) ? 1 : 2;
+               get_floppy_geometry(fs, 0, &g);
+               fs->total_secs = g->size;
+               fs->secpercyl = g->head * g->sect;
+@@ -646,7 +648,7 @@ static int floppy_open(struct block_device *bdev, fmode_t 
mode)
+ 
+       swim_write(base, setup, S_IBM_DRIVE  | S_FCLK_DIV2);
+       udelay(10);
+-      swim_drive(base, INTERNAL_DRIVE);
++      swim_drive(base, fs->location);
+       swim_motor(base, ON);
+       swim_action(base, SETMFM);
+       if (fs->ejected)
+@@ -656,6 +658,8 @@ static int floppy_open(struct block_device *bdev, fmode_t 
mode)
+               goto out;
+       }
+ 
++      set_capacity(fs->disk, fs->total_secs);
++
+       if (mode & FMODE_NDELAY)
+               return 0;
+ 
+@@ -727,14 +731,9 @@ static int floppy_ioctl(struct block_device *bdev, 
fmode_t mode,
+               if (copy_to_user((void __user *) param, (void *) &floppy_type,
+                                sizeof(struct floppy_struct)))
+                       return -EFAULT;
+-              break;
+-
+-      default:
+-              printk(KERN_DEBUG "SWIM floppy_ioctl: unknown cmd %d\n",
+-                     cmd);
+-              return -ENOSYS;
++              return 0;
+       }
+-      return 0;
++      return -ENOTTY;
+ }
+ 
+ static int floppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+@@ -795,7 +794,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, 
void *data)
+       struct swim_priv *swd = data;
+       int drive = (*part & 3);
+ 
+-      if (drive > swd->floppy_count)
++      if (drive >= swd->floppy_count)
+               return NULL;
+ 
+       *part = 0;
+@@ -813,10 +812,9 @@ static int swim_add_floppy(struct swim_priv *swd, enum 
drive_location location)
+ 
+       swim_motor(base, OFF);
+ 
+-      if (swim_readbit(base, SINGLE_SIDED))
+-              fs->head_number = 1;
+-      else
+-              fs->head_number = 2;
++      fs->type = HD_MEDIA;
++      fs->head_number = 2;
++
+       fs->ref_count = 0;
+       fs->ejected = 1;
+ 
+@@ -834,10 +832,12 @@ static int swim_floppy_init(struct swim_priv *swd)
+       /* scan floppy drives */
+ 
+       swim_drive(base, INTERNAL_DRIVE);
+-      if (swim_readbit(base, DRIVE_PRESENT))
++      if (swim_readbit(base, DRIVE_PRESENT) &&
++          !swim_readbit(base, ONEMEG_DRIVE))
+               swim_add_floppy(swd, INTERNAL_DRIVE);
+       swim_drive(base, EXTERNAL_DRIVE);
+-      if (swim_readbit(base, DRIVE_PRESENT))
++      if (swim_readbit(base, DRIVE_PRESENT) &&
++          !swim_readbit(base, ONEMEG_DRIVE))
+               swim_add_floppy(swd, EXTERNAL_DRIVE);
+ 
+       /* register floppy drives */
+@@ -861,7 +861,6 @@ static int swim_floppy_init(struct swim_priv *swd)
+                                                             &swd->lock);
+               if (!swd->unit[drive].disk->queue) {
+                       err = -ENOMEM;
+-                      put_disk(swd->unit[drive].disk);
+                       goto exit_put_disks;
+               }
+               blk_queue_bounce_limit(swd->unit[drive].disk->queue,
+@@ -911,7 +910,7 @@ static int swim_probe(struct platform_device *dev)
+               goto out;
+       }
+ 
+-      swim_base = ioremap(res->start, resource_size(res));
++      swim_base = (struct swim __iomem *)res->start;
+       if (!swim_base) {
+               ret = -ENOMEM;
+               goto out_release_io;
+@@ -923,7 +922,7 @@ static int swim_probe(struct platform_device *dev)
+       if (!get_swim_mode(swim_base)) {
+               printk(KERN_INFO "SWIM device not found !\n");
+               ret = -ENODEV;
+-              goto out_iounmap;
++              goto out_release_io;
+       }
+ 
+       /* set platform driver data */
+@@ -931,7 +930,7 @@ static int swim_probe(struct platform_device *dev)
+       swd = kzalloc(sizeof(struct swim_priv), GFP_KERNEL);
+       if (!swd) {
+               ret = -ENOMEM;
+-              goto out_iounmap;
++              goto out_release_io;
+       }
+       platform_set_drvdata(dev, swd);
+ 
+@@ -945,8 +944,6 @@ static int swim_probe(struct platform_device *dev)
+ 
+ out_kfree:
+       kfree(swd);
+-out_iounmap:
+-      iounmap(swim_base);
+ out_release_io:
+       release_mem_region(res->start, resource_size(res));
+ out:
+@@ -974,8 +971,6 @@ static int swim_remove(struct platform_device *dev)
+       for (drive = 0; drive < swd->floppy_count; drive++)
+               floppy_eject(&swd->unit[drive]);
+ 
+-      iounmap(swd->base);
+-
+       res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       if (res)
+               release_mem_region(res->start, resource_size(res));
+diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
+index 9f931f8f6b4c..0d7527c6825a 100644
+--- a/drivers/block/swim3.c
++++ b/drivers/block/swim3.c
+@@ -148,7 +148,7 @@ struct swim3 {
+ #define MOTOR_ON      2
+ #define RELAX         3       /* also eject in progress */
+ #define READ_DATA_0   4
+-#define TWOMEG_DRIVE  5
++#define ONEMEG_DRIVE  5
+ #define SINGLE_SIDED  6       /* drive or diskette is 4MB type? */
+ #define DRIVE_PRESENT 7
+ #define DISK_IN               8
+@@ -156,9 +156,9 @@ struct swim3 {
+ #define TRACK_ZERO    10
+ #define TACHO         11
+ #define READ_DATA_1   12
+-#define MFM_MODE      13
++#define GCR_MODE      13
+ #define SEEK_COMPLETE 14
+-#define ONEMEG_MEDIA  15
++#define TWOMEG_MEDIA  15
+ 
+ /* Definitions of values used in writing and formatting */
+ #define DATA_ESCAPE   0x99
+diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
+index e36d160c458f..5f7d86509f2f 100644
+--- a/drivers/cdrom/cdrom.c
++++ b/drivers/cdrom/cdrom.c
+@@ -2374,7 +2374,7 @@ static int cdrom_ioctl_media_changed(struct 
cdrom_device_info *cdi,
+       if (!CDROM_CAN(CDC_SELECT_DISC) || arg == CDSL_CURRENT)
+               return media_changed(cdi, 1);
+ 
+-      if ((unsigned int)arg >= cdi->capacity)
++      if (arg >= cdi->capacity)
+               return -EINVAL;
+ 
+       info = kmalloc(sizeof(*info), GFP_KERNEL);
+diff --git a/drivers/char/tpm/tpm-interface.c 
b/drivers/char/tpm/tpm-interface.c
+index 1d01a8f77db1..dba5259def60 100644
+--- a/drivers/char/tpm/tpm-interface.c
++++ b/drivers/char/tpm/tpm-interface.c
+@@ -369,20 +369,40 @@ static int tpm_validate_command(struct tpm_chip *chip,
+       return -EINVAL;
+ }
+ 
+-/**
+- * tmp_transmit - Internal kernel interface to transmit TPM commands.
+- *
+- * @chip: TPM chip to use
+- * @buf: TPM command buffer
+- * @bufsiz: length of the TPM command buffer
+- * @flags: tpm transmit flags - bitmap
+- *
+- * Return:
+- *     0 when the operation is successful.
+- *     A negative number for system errors (errno).
+- */
+-ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space,
+-                   u8 *buf, size_t bufsiz, unsigned int flags)
++static int tpm_request_locality(struct tpm_chip *chip)
++{
++      int rc;
++
++      if (!chip->ops->request_locality)
++              return 0;
++
++      rc = chip->ops->request_locality(chip, 0);
++      if (rc < 0)
++              return rc;
++
++      chip->locality = rc;
++
++      return 0;
++}
++
++static void tpm_relinquish_locality(struct tpm_chip *chip)
++{
++      int rc;
++
++      if (!chip->ops->relinquish_locality)
++              return;
++
++      rc = chip->ops->relinquish_locality(chip, chip->locality);
++      if (rc)
++              dev_err(&chip->dev, "%s: : error %d\n", __func__, rc);
++
++      chip->locality = -1;
++}
++
++static ssize_t tpm_try_transmit(struct tpm_chip *chip,
++                              struct tpm_space *space,
++                              u8 *buf, size_t bufsiz,
++                              unsigned int flags)
+ {
+       struct tpm_output_header *header = (void *)buf;
+       int rc;
+@@ -422,8 +442,6 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct 
tpm_space *space,
+       if (!(flags & TPM_TRANSMIT_UNLOCKED))
+               mutex_lock(&chip->tpm_mutex);
+ 
+-      if (chip->dev.parent)
+-              pm_runtime_get_sync(chip->dev.parent);
+ 
+       if (chip->ops->clk_enable != NULL)
+               chip->ops->clk_enable(chip, true);
+@@ -431,14 +449,15 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct 
tpm_space *space,
+       /* Store the decision as chip->locality will be changed. */
+       need_locality = chip->locality == -1;
+ 
+-      if (!(flags & TPM_TRANSMIT_RAW) &&
+-          need_locality && chip->ops->request_locality)  {
+-              rc = chip->ops->request_locality(chip, 0);
++      if (!(flags & TPM_TRANSMIT_RAW) && need_locality) {
++              rc = tpm_request_locality(chip);
+               if (rc < 0)
+                       goto out_no_locality;
+-              chip->locality = rc;
+       }
+ 
++      if (chip->dev.parent)
++              pm_runtime_get_sync(chip->dev.parent);
++
+       rc = tpm2_prepare_space(chip, space, ordinal, buf);
+       if (rc)
+               goto out;
+@@ -499,27 +518,83 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct 
tpm_space *space,
+       rc = tpm2_commit_space(chip, space, ordinal, buf, &len);
+ 
+ out:
+-      if (need_locality && chip->ops->relinquish_locality) {
+-              chip->ops->relinquish_locality(chip, chip->locality);
+-              chip->locality = -1;
+-      }
++      if (chip->dev.parent)
++              pm_runtime_put_sync(chip->dev.parent);
++
++      if (need_locality)
++              tpm_relinquish_locality(chip);
++
+ out_no_locality:
+       if (chip->ops->clk_enable != NULL)
+               chip->ops->clk_enable(chip, false);
+ 
+-      if (chip->dev.parent)
+-              pm_runtime_put_sync(chip->dev.parent);
+-
+       if (!(flags & TPM_TRANSMIT_UNLOCKED))
+               mutex_unlock(&chip->tpm_mutex);
+       return rc ? rc : len;
+ }
+ 
+ /**
+- * tmp_transmit_cmd - send a tpm command to the device
++ * tpm_transmit - Internal kernel interface to transmit TPM commands.
++ *
++ * @chip: TPM chip to use
++ * @space: tpm space
++ * @buf: TPM command buffer
++ * @bufsiz: length of the TPM command buffer
++ * @flags: tpm transmit flags - bitmap
++ *
++ * A wrapper around tpm_try_transmit that handles TPM2_RC_RETRY
++ * returns from the TPM and retransmits the command after a delay up
++ * to a maximum wait of TPM2_DURATION_LONG.
++ *
++ * Note: TPM1 never returns TPM2_RC_RETRY so the retry logic is TPM2
++ * only
++ *
++ * Return:
++ *     the length of the return when the operation is successful.
++ *     A negative number for system errors (errno).
++ */
++ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space,
++                   u8 *buf, size_t bufsiz, unsigned int flags)
++{
++      struct tpm_output_header *header = (struct tpm_output_header *)buf;
++      /* space for header and handles */
++      u8 save[TPM_HEADER_SIZE + 3*sizeof(u32)];
++      unsigned int delay_msec = TPM2_DURATION_SHORT;
++      u32 rc = 0;
++      ssize_t ret;
++      const size_t save_size = min(space ? sizeof(save) : TPM_HEADER_SIZE,
++                                   bufsiz);
++
++      /*
++       * Subtlety here: if we have a space, the handles will be
++       * transformed, so when we restore the header we also have to
++       * restore the handles.
++       */
++      memcpy(save, buf, save_size);
++
++      for (;;) {
++              ret = tpm_try_transmit(chip, space, buf, bufsiz, flags);
++              if (ret < 0)
++                      break;
++              rc = be32_to_cpu(header->return_code);
++              if (rc != TPM2_RC_RETRY)
++                      break;
++              delay_msec *= 2;
++              if (delay_msec > TPM2_DURATION_LONG) {
++                      dev_err(&chip->dev, "TPM is in retry loop\n");
++                      break;
++              }
++              tpm_msleep(delay_msec);
++              memcpy(buf, save, save_size);
++      }
++      return ret;
++}
++/**
++ * tpm_transmit_cmd - send a tpm command to the device
+  *    The function extracts tpm out header return code
+  *
+  * @chip: TPM chip to use
++ * @space: tpm space
+  * @buf: TPM command buffer
+  * @bufsiz: length of the buffer
+  * @min_rsp_body_length: minimum expected length of response body
+diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
+index 0b5b499f726a..b83b30a3eea5 100644
+--- a/drivers/char/tpm/tpm.h
++++ b/drivers/char/tpm/tpm.h
+@@ -106,6 +106,7 @@ enum tpm2_return_codes {
+       TPM2_RC_COMMAND_CODE    = 0x0143,
+       TPM2_RC_TESTING         = 0x090A, /* RC_WARN */
+       TPM2_RC_REFERENCE_H0    = 0x0910,
++      TPM2_RC_RETRY           = 0x0922,
+ };
+ 
+ enum tpm2_algorithms {
+diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
+index 8f0a98dea327..bb756ad7897e 100644
+--- a/drivers/char/tpm/tpm_crb.c
++++ b/drivers/char/tpm/tpm_crb.c
+@@ -117,6 +117,25 @@ struct tpm2_crb_smc {
+       u32 smc_func_id;
+ };
+ 
++static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value,
++                              unsigned long timeout)
++{
++      ktime_t start;
++      ktime_t stop;
++
++      start = ktime_get();
++      stop = ktime_add(start, ms_to_ktime(timeout));
++
++      do {
++              if ((ioread32(reg) & mask) == value)
++                      return true;
++
++              usleep_range(50, 100);
++      } while (ktime_before(ktime_get(), stop));
++
++      return ((ioread32(reg) & mask) == value);
++}
++
+ /**
+  * crb_go_idle - request tpm crb device to go the idle state
+  *
+@@ -132,37 +151,24 @@ struct tpm2_crb_smc {
+  *
+  * Return: 0 always
+  */
+-static int __maybe_unused crb_go_idle(struct device *dev, struct crb_priv 
*priv)
++static int crb_go_idle(struct device *dev, struct crb_priv *priv)
+ {
+       if ((priv->flags & CRB_FL_ACPI_START) ||
+           (priv->flags & CRB_FL_CRB_SMC_START))
+               return 0;
+ 
+       iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req);
+-      /* we don't really care when this settles */
+ 
++      if (!crb_wait_for_reg_32(&priv->regs_t->ctrl_req,
++                               CRB_CTRL_REQ_GO_IDLE/* mask */,
++                               0, /* value */
++                               TPM2_TIMEOUT_C)) {
++              dev_warn(dev, "goIdle timed out\n");
++              return -ETIME;
++      }
+       return 0;
+ }
+ 
+-static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value,
+-                              unsigned long timeout)
+-{
+-      ktime_t start;
+-      ktime_t stop;
+-
+-      start = ktime_get();
+-      stop = ktime_add(start, ms_to_ktime(timeout));
+-
+-      do {
+-              if ((ioread32(reg) & mask) == value)
+-                      return true;
+-
+-              usleep_range(50, 100);
+-      } while (ktime_before(ktime_get(), stop));
+-
+-      return false;
+-}
+-
+ /**
+  * crb_cmd_ready - request tpm crb device to enter ready state
+  *
+@@ -177,8 +183,7 @@ static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 
mask, u32 value,
+  *
+  * Return: 0 on success -ETIME on timeout;
+  */
+-static int __maybe_unused crb_cmd_ready(struct device *dev,
+-                                      struct crb_priv *priv)
++static int crb_cmd_ready(struct device *dev, struct crb_priv *priv)
+ {
+       if ((priv->flags & CRB_FL_ACPI_START) ||
+           (priv->flags & CRB_FL_CRB_SMC_START))
+@@ -196,11 +201,11 @@ static int __maybe_unused crb_cmd_ready(struct device 
*dev,
+       return 0;
+ }
+ 
+-static int crb_request_locality(struct tpm_chip *chip, int loc)
++static int __crb_request_locality(struct device *dev,
++                                struct crb_priv *priv, int loc)
+ {
+-      struct crb_priv *priv = dev_get_drvdata(&chip->dev);
+       u32 value = CRB_LOC_STATE_LOC_ASSIGNED |
+-              CRB_LOC_STATE_TPM_REG_VALID_STS;
++                  CRB_LOC_STATE_TPM_REG_VALID_STS;
+ 
+       if (!priv->regs_h)
+               return 0;
+@@ -208,21 +213,45 @@ static int crb_request_locality(struct tpm_chip *chip, 
int loc)
+       iowrite32(CRB_LOC_CTRL_REQUEST_ACCESS, &priv->regs_h->loc_ctrl);
+       if (!crb_wait_for_reg_32(&priv->regs_h->loc_state, value, value,
+                                TPM2_TIMEOUT_C)) {
+-              dev_warn(&chip->dev, "TPM_LOC_STATE_x.requestAccess timed 
out\n");
++              dev_warn(dev, "TPM_LOC_STATE_x.requestAccess timed out\n");
+               return -ETIME;
+       }
+ 
+       return 0;
+ }
+ 
+-static void crb_relinquish_locality(struct tpm_chip *chip, int loc)
++static int crb_request_locality(struct tpm_chip *chip, int loc)
+ {
+       struct crb_priv *priv = dev_get_drvdata(&chip->dev);
+ 
++      return __crb_request_locality(&chip->dev, priv, loc);
++}
++
++static int __crb_relinquish_locality(struct device *dev,
++                                   struct crb_priv *priv, int loc)
++{
++      u32 mask = CRB_LOC_STATE_LOC_ASSIGNED |
++                 CRB_LOC_STATE_TPM_REG_VALID_STS;
++      u32 value = CRB_LOC_STATE_TPM_REG_VALID_STS;
++
+       if (!priv->regs_h)
+-              return;
++              return 0;
+ 
+       iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl);
++      if (!crb_wait_for_reg_32(&priv->regs_h->loc_state, mask, value,
++                               TPM2_TIMEOUT_C)) {
++              dev_warn(dev, "TPM_LOC_STATE_x.requestAccess timed out\n");
++              return -ETIME;
++      }
++
++      return 0;
++}
++
++static int crb_relinquish_locality(struct tpm_chip *chip, int loc)
++{
++      struct crb_priv *priv = dev_get_drvdata(&chip->dev);
++
++      return __crb_relinquish_locality(&chip->dev, priv, loc);
+ }
+ 
+ static u8 crb_status(struct tpm_chip *chip)
+@@ -466,6 +495,10 @@ static int crb_map_io(struct acpi_device *device, struct 
crb_priv *priv,
+                       dev_warn(dev, FW_BUG "Bad ACPI memory layout");
+       }
+ 
++      ret = __crb_request_locality(dev, priv, 0);
++      if (ret)
++              return ret;
++
+       priv->regs_t = crb_map_res(dev, priv, &io_res, buf->control_address,
+                                  sizeof(struct crb_regs_tail));
+       if (IS_ERR(priv->regs_t))
+@@ -522,6 +555,8 @@ static int crb_map_io(struct acpi_device *device, struct 
crb_priv *priv,
+ 
+       crb_go_idle(dev, priv);
+ 
++      __crb_relinquish_locality(dev, priv, 0);
++
+       return ret;
+ }
+ 
+@@ -589,10 +624,14 @@ static int crb_acpi_add(struct acpi_device *device)
+       chip->acpi_dev_handle = device->handle;
+       chip->flags = TPM_CHIP_FLAG_TPM2;
+ 
+-      rc  = crb_cmd_ready(dev, priv);
++      rc = __crb_request_locality(dev, priv, 0);
+       if (rc)
+               return rc;
+ 
++      rc  = crb_cmd_ready(dev, priv);
++      if (rc)
++              goto out;
++
+       pm_runtime_get_noresume(dev);
+       pm_runtime_set_active(dev);
+       pm_runtime_enable(dev);
+@@ -602,12 +641,15 @@ static int crb_acpi_add(struct acpi_device *device)
+               crb_go_idle(dev, priv);
+               pm_runtime_put_noidle(dev);
+               pm_runtime_disable(dev);
+-              return rc;
++              goto out;
+       }
+ 
+-      pm_runtime_put(dev);
++      pm_runtime_put_sync(dev);
+ 
+-      return 0;
++out:
++      __crb_relinquish_locality(dev, priv, 0);
++
++      return rc;
+ }
+ 
+ static int crb_acpi_remove(struct acpi_device *device)
+diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
+index a21e31c2b952..58123df6b5f6 100644
+--- a/drivers/char/tpm/tpm_tis_core.c
++++ b/drivers/char/tpm/tpm_tis_core.c
+@@ -77,11 +77,13 @@ static bool check_locality(struct tpm_chip *chip, int l)
+       return false;
+ }
+ 
+-static void release_locality(struct tpm_chip *chip, int l)
++static int release_locality(struct tpm_chip *chip, int l)
+ {
+       struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+ 
+       tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
++
++      return 0;
+ }
+ 
+ static int request_locality(struct tpm_chip *chip, int l)
+diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+index bf14214fa464..4db31b89507c 100644
+--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+@@ -1634,6 +1634,8 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
+        * (and possibly on the platform). So far only i.MX6Q (v1.30a) and
+        * i.MX6DL (v1.31a) have been identified as needing the workaround, with
+        * 4 and 1 iterations respectively.
++       * The Amlogic Meson GX SoCs (v2.01a) have been identified as needing
++       * the workaround with a single iteration.
+        */
+ 
+       switch (hdmi->version) {
+@@ -1641,6 +1643,7 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
+               count = 4;
+               break;
+       case 0x131a:
++      case 0x201a:
+               count = 1;
+               break;
+       default:
+diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
+index 345f6035599e..f1d93676b0fc 100644
+--- a/drivers/message/fusion/mptsas.c
++++ b/drivers/message/fusion/mptsas.c
+@@ -1995,6 +1995,7 @@ static struct scsi_host_template mptsas_driver_template 
= {
+       .cmd_per_lun                    = 7,
+       .use_clustering                 = ENABLE_CLUSTERING,
+       .shost_attrs                    = mptscsih_host_attrs,
++      .no_write_same                  = 1,
+ };
+ 
+ static int mptsas_get_linkerrors(struct sas_phy *phy)
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 82f28ffccddf..bf3be2e6d4a8 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -1656,8 +1656,7 @@ int bond_enslave(struct net_device *bond_dev, struct 
net_device *slave_dev)
+       } /* switch(bond_mode) */
+ 
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+-      slave_dev->npinfo = bond->dev->npinfo;
+-      if (slave_dev->npinfo) {
++      if (bond->dev->npinfo) {
+               if (slave_enable_netpoll(new_slave)) {
+                       netdev_info(bond_dev, "master_dev is using netpoll, but 
new slave device does not support netpoll\n");
+                       res = -EBUSY;
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h 
b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
+index 7ea72ef11a55..d272dc6984ac 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
+@@ -1321,6 +1321,10 @@
+ #define MDIO_VEND2_AN_STAT            0x8002
+ #endif
+ 
++#ifndef MDIO_VEND2_PMA_CDR_CONTROL
++#define MDIO_VEND2_PMA_CDR_CONTROL    0x8056
++#endif
++
+ #ifndef MDIO_CTRL1_SPEED1G
+ #define MDIO_CTRL1_SPEED1G            (MDIO_CTRL1_SPEED10G & ~BMCR_SPEED100)
+ #endif
+@@ -1369,6 +1373,10 @@
+ #define XGBE_AN_CL37_TX_CONFIG_MASK   0x08
+ #define XGBE_AN_CL37_MII_CTRL_8BIT    0x0100
+ 
++#define XGBE_PMA_CDR_TRACK_EN_MASK    0x01
++#define XGBE_PMA_CDR_TRACK_EN_OFF     0x00
++#define XGBE_PMA_CDR_TRACK_EN_ON      0x01
++
+ /* Bit setting and getting macros
+  *  The get macro will extract the current bit field value from within
+  *  the variable
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c 
b/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c
+index 7d128be61310..b91143947ed2 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c
+@@ -519,6 +519,22 @@ void xgbe_debugfs_init(struct xgbe_prv_data *pdata)
+                                  "debugfs_create_file failed\n");
+       }
+ 
++      if (pdata->vdata->an_cdr_workaround) {
++              pfile = debugfs_create_bool("an_cdr_workaround", 0600,
++                                          pdata->xgbe_debugfs,
++                                          &pdata->debugfs_an_cdr_workaround);
++              if (!pfile)
++                      netdev_err(pdata->netdev,
++                                 "debugfs_create_bool failed\n");
++
++              pfile = debugfs_create_bool("an_cdr_track_early", 0600,
++                                          pdata->xgbe_debugfs,
++                                          &pdata->debugfs_an_cdr_track_early);
++              if (!pfile)
++                      netdev_err(pdata->netdev,
++                                 "debugfs_create_bool failed\n");
++      }
++
+       kfree(buf);
+ }
+ 
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c 
b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
+index d91fa595be98..e31d9d1fb6a6 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
+@@ -349,6 +349,7 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata)
+       XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1);
+ 
+       /* Call MDIO/PHY initialization routine */
++      pdata->debugfs_an_cdr_workaround = pdata->vdata->an_cdr_workaround;
+       ret = pdata->phy_if.phy_init(pdata);
+       if (ret)
+               return ret;
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c 
b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+index 072b9f664597..1b45cd73a258 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+@@ -432,11 +432,16 @@ static void xgbe_an73_disable(struct xgbe_prv_data 
*pdata)
+       xgbe_an73_set(pdata, false, false);
+       xgbe_an73_disable_interrupts(pdata);
+ 
++      pdata->an_start = 0;
++
+       netif_dbg(pdata, link, pdata->netdev, "CL73 AN disabled\n");
+ }
+ 
+ static void xgbe_an_restart(struct xgbe_prv_data *pdata)
+ {
++      if (pdata->phy_if.phy_impl.an_pre)
++              pdata->phy_if.phy_impl.an_pre(pdata);
++
+       switch (pdata->an_mode) {
+       case XGBE_AN_MODE_CL73:
+       case XGBE_AN_MODE_CL73_REDRV:
+@@ -453,6 +458,9 @@ static void xgbe_an_restart(struct xgbe_prv_data *pdata)
+ 
+ static void xgbe_an_disable(struct xgbe_prv_data *pdata)
+ {
++      if (pdata->phy_if.phy_impl.an_post)
++              pdata->phy_if.phy_impl.an_post(pdata);
++
+       switch (pdata->an_mode) {
+       case XGBE_AN_MODE_CL73:
+       case XGBE_AN_MODE_CL73_REDRV:
+@@ -505,11 +513,11 @@ static enum xgbe_an xgbe_an73_tx_training(struct 
xgbe_prv_data *pdata,
+               XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL,
+                           reg);
+ 
+-              if (pdata->phy_if.phy_impl.kr_training_post)
+-                      pdata->phy_if.phy_impl.kr_training_post(pdata);
+-
+               netif_dbg(pdata, link, pdata->netdev,
+                         "KR training initiated\n");
++
++              if (pdata->phy_if.phy_impl.kr_training_post)
++                      pdata->phy_if.phy_impl.kr_training_post(pdata);
+       }
+ 
+       return XGBE_AN_PAGE_RECEIVED;
+@@ -637,11 +645,11 @@ static enum xgbe_an xgbe_an73_incompat_link(struct 
xgbe_prv_data *pdata)
+                       return XGBE_AN_NO_LINK;
+       }
+ 
+-      xgbe_an73_disable(pdata);
++      xgbe_an_disable(pdata);
+ 
+       xgbe_switch_mode(pdata);
+ 
+-      xgbe_an73_restart(pdata);
++      xgbe_an_restart(pdata);
+ 
+       return XGBE_AN_INCOMPAT_LINK;
+ }
+@@ -820,6 +828,9 @@ static void xgbe_an37_state_machine(struct xgbe_prv_data 
*pdata)
+               pdata->an_result = pdata->an_state;
+               pdata->an_state = XGBE_AN_READY;
+ 
++              if (pdata->phy_if.phy_impl.an_post)
++                      pdata->phy_if.phy_impl.an_post(pdata);
++
+               netif_dbg(pdata, link, pdata->netdev, "CL37 AN result: %s\n",
+                         xgbe_state_as_string(pdata->an_result));
+       }
+@@ -903,6 +914,9 @@ static void xgbe_an73_state_machine(struct xgbe_prv_data 
*pdata)
+               pdata->kx_state = XGBE_RX_BPA;
+               pdata->an_start = 0;
+ 
++              if (pdata->phy_if.phy_impl.an_post)
++                      pdata->phy_if.phy_impl.an_post(pdata);
++
+               netif_dbg(pdata, link, pdata->netdev, "CL73 AN result: %s\n",
+                         xgbe_state_as_string(pdata->an_result));
+       }
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c 
b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
+index eb23f9ba1a9a..82d1f416ee2a 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
+@@ -456,6 +456,7 @@ static const struct xgbe_version_data xgbe_v2a = {
+       .irq_reissue_support            = 1,
+       .tx_desc_prefetch               = 5,
+       .rx_desc_prefetch               = 5,
++      .an_cdr_workaround              = 1,
+ };
+ 
+ static const struct xgbe_version_data xgbe_v2b = {
+@@ -470,6 +471,7 @@ static const struct xgbe_version_data xgbe_v2b = {
+       .irq_reissue_support            = 1,
+       .tx_desc_prefetch               = 5,
+       .rx_desc_prefetch               = 5,
++      .an_cdr_workaround              = 1,
+ };
+ 
+ static const struct pci_device_id xgbe_pci_table[] = {
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c 
b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+index 3304a291aa96..aac884314000 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+@@ -147,6 +147,14 @@
+ /* Rate-change complete wait/retry count */
+ #define XGBE_RATECHANGE_COUNT         500
+ 
++/* CDR delay values for KR support (in usec) */
++#define XGBE_CDR_DELAY_INIT           10000
++#define XGBE_CDR_DELAY_INC            10000
++#define XGBE_CDR_DELAY_MAX            100000
++
++/* RRC frequency during link status check */
++#define XGBE_RRC_FREQUENCY            10
++
+ enum xgbe_port_mode {
+       XGBE_PORT_MODE_RSVD = 0,
+       XGBE_PORT_MODE_BACKPLANE,
+@@ -245,6 +253,10 @@ enum xgbe_sfp_speed {
+ #define XGBE_SFP_BASE_VENDOR_SN                       4
+ #define XGBE_SFP_BASE_VENDOR_SN_LEN           16
+ 
++#define XGBE_SFP_EXTD_OPT1                    1
++#define XGBE_SFP_EXTD_OPT1_RX_LOS             BIT(1)
++#define XGBE_SFP_EXTD_OPT1_TX_FAULT           BIT(3)
++
+ #define XGBE_SFP_EXTD_DIAG                    28
+ #define XGBE_SFP_EXTD_DIAG_ADDR_CHANGE                BIT(2)
+ 
+@@ -324,6 +336,7 @@ struct xgbe_phy_data {
+ 
+       unsigned int sfp_gpio_address;
+       unsigned int sfp_gpio_mask;
++      unsigned int sfp_gpio_inputs;
+       unsigned int sfp_gpio_rx_los;
+       unsigned int sfp_gpio_tx_fault;
+       unsigned int sfp_gpio_mod_absent;
+@@ -355,6 +368,10 @@ struct xgbe_phy_data {
+       unsigned int redrv_addr;
+       unsigned int redrv_lane;
+       unsigned int redrv_model;
++
++      /* KR AN support */
++      unsigned int phy_cdr_notrack;
++      unsigned int phy_cdr_delay;
+ };
+ 
+ /* I2C, MDIO and GPIO lines are muxed, so only one device at a time */
+@@ -974,6 +991,49 @@ static void xgbe_phy_sfp_external_phy(struct 
xgbe_prv_data *pdata)
+       phy_data->sfp_phy_avail = 1;
+ }
+ 
++static bool xgbe_phy_check_sfp_rx_los(struct xgbe_phy_data *phy_data)
++{
++      u8 *sfp_extd = phy_data->sfp_eeprom.extd;
++
++      if (!(sfp_extd[XGBE_SFP_EXTD_OPT1] & XGBE_SFP_EXTD_OPT1_RX_LOS))
++              return false;
++
++      if (phy_data->sfp_gpio_mask & XGBE_GPIO_NO_RX_LOS)
++              return false;
++
++      if (phy_data->sfp_gpio_inputs & (1 << phy_data->sfp_gpio_rx_los))
++              return true;
++
++      return false;
++}
++
++static bool xgbe_phy_check_sfp_tx_fault(struct xgbe_phy_data *phy_data)
++{
++      u8 *sfp_extd = phy_data->sfp_eeprom.extd;
++
++      if (!(sfp_extd[XGBE_SFP_EXTD_OPT1] & XGBE_SFP_EXTD_OPT1_TX_FAULT))
++              return false;
++
++      if (phy_data->sfp_gpio_mask & XGBE_GPIO_NO_TX_FAULT)
++              return false;
++
++      if (phy_data->sfp_gpio_inputs & (1 << phy_data->sfp_gpio_tx_fault))
++              return true;
++
++      return false;
++}
++
++static bool xgbe_phy_check_sfp_mod_absent(struct xgbe_phy_data *phy_data)
++{
++      if (phy_data->sfp_gpio_mask & XGBE_GPIO_NO_MOD_ABSENT)
++              return false;
++
++      if (phy_data->sfp_gpio_inputs & (1 << phy_data->sfp_gpio_mod_absent))
++              return true;
++
++      return false;
++}
++
+ static bool xgbe_phy_belfuse_parse_quirks(struct xgbe_prv_data *pdata)
+ {
+       struct xgbe_phy_data *phy_data = pdata->phy_data;
+@@ -1019,6 +1079,10 @@ static void xgbe_phy_sfp_parse_eeprom(struct 
xgbe_prv_data *pdata)
+       if (sfp_base[XGBE_SFP_BASE_EXT_ID] != XGBE_SFP_EXT_ID_SFP)
+               return;
+ 
++      /* Update transceiver signals (eeprom extd/options) */
++      phy_data->sfp_tx_fault = xgbe_phy_check_sfp_tx_fault(phy_data);
++      phy_data->sfp_rx_los = xgbe_phy_check_sfp_rx_los(phy_data);
++
+       if (xgbe_phy_sfp_parse_quirks(pdata))
+               return;
+ 
+@@ -1184,7 +1248,6 @@ static int xgbe_phy_sfp_read_eeprom(struct xgbe_prv_data 
*pdata)
+ static void xgbe_phy_sfp_signals(struct xgbe_prv_data *pdata)
+ {
+       struct xgbe_phy_data *phy_data = pdata->phy_data;
+-      unsigned int gpio_input;
+       u8 gpio_reg, gpio_ports[2];
+       int ret;
+ 
+@@ -1199,23 +1262,9 @@ static void xgbe_phy_sfp_signals(struct xgbe_prv_data 
*pdata)
+               return;
+       }
+ 
+-      gpio_input = (gpio_ports[1] << 8) | gpio_ports[0];
+-
+-      if (phy_data->sfp_gpio_mask & XGBE_GPIO_NO_MOD_ABSENT) {
+-              /* No GPIO, just assume the module is present for now */
+-              phy_data->sfp_mod_absent = 0;
+-      } else {
+-              if (!(gpio_input & (1 << phy_data->sfp_gpio_mod_absent)))
+-                      phy_data->sfp_mod_absent = 0;
+-      }
+-
+-      if (!(phy_data->sfp_gpio_mask & XGBE_GPIO_NO_RX_LOS) &&
+-          (gpio_input & (1 << phy_data->sfp_gpio_rx_los)))
+-              phy_data->sfp_rx_los = 1;
++      phy_data->sfp_gpio_inputs = (gpio_ports[1] << 8) | gpio_ports[0];
+ 
+-      if (!(phy_data->sfp_gpio_mask & XGBE_GPIO_NO_TX_FAULT) &&
+-          (gpio_input & (1 << phy_data->sfp_gpio_tx_fault)))
+-              phy_data->sfp_tx_fault = 1;
++      phy_data->sfp_mod_absent = xgbe_phy_check_sfp_mod_absent(phy_data);
+ }
+ 
+ static void xgbe_phy_sfp_mod_absent(struct xgbe_prv_data *pdata)
+@@ -2361,7 +2410,7 @@ static int xgbe_phy_link_status(struct xgbe_prv_data 
*pdata, int *an_restart)
+               return 1;
+ 
+       /* No link, attempt a receiver reset cycle */
+-      if (phy_data->rrc_count++) {
++      if (phy_data->rrc_count++ > XGBE_RRC_FREQUENCY) {
+               phy_data->rrc_count = 0;
+               xgbe_phy_rrc(pdata);
+       }
+@@ -2669,6 +2718,103 @@ static bool xgbe_phy_port_enabled(struct xgbe_prv_data 
*pdata)
+       return true;
+ }
+ 
++static void xgbe_phy_cdr_track(struct xgbe_prv_data *pdata)
++{
++      struct xgbe_phy_data *phy_data = pdata->phy_data;
++
++      if (!pdata->debugfs_an_cdr_workaround)
++              return;
++
++      if (!phy_data->phy_cdr_notrack)
++              return;
++
++      usleep_range(phy_data->phy_cdr_delay,
++                   phy_data->phy_cdr_delay + 500);
++
++      XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_VEND2_PMA_CDR_CONTROL,
++                       XGBE_PMA_CDR_TRACK_EN_MASK,
++                       XGBE_PMA_CDR_TRACK_EN_ON);
++
++      phy_data->phy_cdr_notrack = 0;
++}
++
++static void xgbe_phy_cdr_notrack(struct xgbe_prv_data *pdata)
++{
++      struct xgbe_phy_data *phy_data = pdata->phy_data;
++
++      if (!pdata->debugfs_an_cdr_workaround)
++              return;
++
++      if (phy_data->phy_cdr_notrack)
++              return;
++
++      XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_VEND2_PMA_CDR_CONTROL,
++                       XGBE_PMA_CDR_TRACK_EN_MASK,
++                       XGBE_PMA_CDR_TRACK_EN_OFF);
++
++      xgbe_phy_rrc(pdata);
++
++      phy_data->phy_cdr_notrack = 1;
++}
++
++static void xgbe_phy_kr_training_post(struct xgbe_prv_data *pdata)
++{
++      if (!pdata->debugfs_an_cdr_track_early)
++              xgbe_phy_cdr_track(pdata);
++}
++
++static void xgbe_phy_kr_training_pre(struct xgbe_prv_data *pdata)
++{
++      if (pdata->debugfs_an_cdr_track_early)
++              xgbe_phy_cdr_track(pdata);
++}
++
++static void xgbe_phy_an_post(struct xgbe_prv_data *pdata)
++{
++      struct xgbe_phy_data *phy_data = pdata->phy_data;
++
++      switch (pdata->an_mode) {
++      case XGBE_AN_MODE_CL73:
++      case XGBE_AN_MODE_CL73_REDRV:
++              if (phy_data->cur_mode != XGBE_MODE_KR)
++                      break;
++
++              xgbe_phy_cdr_track(pdata);
++
++              switch (pdata->an_result) {
++              case XGBE_AN_READY:
++              case XGBE_AN_COMPLETE:
++                      break;
++              default:
++                      if (phy_data->phy_cdr_delay < XGBE_CDR_DELAY_MAX)
++                              phy_data->phy_cdr_delay += XGBE_CDR_DELAY_INC;
++                      else
++                              phy_data->phy_cdr_delay = XGBE_CDR_DELAY_INIT;
++                      break;
++              }
++              break;
++      default:
++              break;
++      }
++}
++
++static void xgbe_phy_an_pre(struct xgbe_prv_data *pdata)
++{
++      struct xgbe_phy_data *phy_data = pdata->phy_data;
++
++      switch (pdata->an_mode) {
++      case XGBE_AN_MODE_CL73:
++      case XGBE_AN_MODE_CL73_REDRV:
++              if (phy_data->cur_mode != XGBE_MODE_KR)
++                      break;
++
++              xgbe_phy_cdr_notrack(pdata);
++              break;
++      default:
++              break;
++      }
++}
++
+ static void xgbe_phy_stop(struct xgbe_prv_data *pdata)
+ {
+       struct xgbe_phy_data *phy_data = pdata->phy_data;
+@@ -2680,6 +2826,9 @@ static void xgbe_phy_stop(struct xgbe_prv_data *pdata)
+       xgbe_phy_sfp_reset(phy_data);
+       xgbe_phy_sfp_mod_absent(pdata);
+ 
++      /* Reset CDR support */
++      xgbe_phy_cdr_track(pdata);
++
+       /* Power off the PHY */
+       xgbe_phy_power_off(pdata);
+ 
+@@ -2712,6 +2861,9 @@ static int xgbe_phy_start(struct xgbe_prv_data *pdata)
+       /* Start in highest supported mode */
+       xgbe_phy_set_mode(pdata, phy_data->start_mode);
+ 
++      /* Reset CDR support */
++      xgbe_phy_cdr_track(pdata);
++
+       /* After starting the I2C controller, we can check for an SFP */
+       switch (phy_data->port_mode) {
+       case XGBE_PORT_MODE_SFP:
+@@ -3019,6 +3171,8 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
+               }
+       }
+ 
++      phy_data->phy_cdr_delay = XGBE_CDR_DELAY_INIT;
++
+       /* Register for driving external PHYs */
+       mii = devm_mdiobus_alloc(pdata->dev);
+       if (!mii) {
+@@ -3071,4 +3225,10 @@ void xgbe_init_function_ptrs_phy_v2(struct xgbe_phy_if 
*phy_if)
+       phy_impl->an_advertising        = xgbe_phy_an_advertising;
+ 
+       phy_impl->an_outcome            = xgbe_phy_an_outcome;
++
++      phy_impl->an_pre                = xgbe_phy_an_pre;
++      phy_impl->an_post               = xgbe_phy_an_post;
++
++      phy_impl->kr_training_pre       = xgbe_phy_kr_training_pre;
++      phy_impl->kr_training_post      = xgbe_phy_kr_training_post;
+ }
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h 
b/drivers/net/ethernet/amd/xgbe/xgbe.h
+index ad102c8bac7b..95d4b56448c6 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
++++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
+@@ -833,6 +833,7 @@ struct xgbe_hw_if {
+ /* This structure represents implementation specific routines for an
+  * implementation of a PHY. All routines are required unless noted below.
+  *   Optional routines:
++ *     an_pre, an_post
+  *     kr_training_pre, kr_training_post
+  */
+ struct xgbe_phy_impl_if {
+@@ -875,6 +876,10 @@ struct xgbe_phy_impl_if {
+       /* Process results of auto-negotiation */
+       enum xgbe_mode (*an_outcome)(struct xgbe_prv_data *);
+ 
++      /* Pre/Post auto-negotiation support */
++      void (*an_pre)(struct xgbe_prv_data *);
++      void (*an_post)(struct xgbe_prv_data *);
++
+       /* Pre/Post KR training enablement support */
+       void (*kr_training_pre)(struct xgbe_prv_data *);
+       void (*kr_training_post)(struct xgbe_prv_data *);
+@@ -989,6 +994,7 @@ struct xgbe_version_data {
+       unsigned int irq_reissue_support;
+       unsigned int tx_desc_prefetch;
+       unsigned int rx_desc_prefetch;
++      unsigned int an_cdr_workaround;
+ };
+ 
+ struct xgbe_vxlan_data {
+@@ -1257,6 +1263,9 @@ struct xgbe_prv_data {
+       unsigned int debugfs_xprop_reg;
+ 
+       unsigned int debugfs_xi2c_reg;
++
++      bool debugfs_an_cdr_workaround;
++      bool debugfs_an_cdr_track_early;
+ };
+ 
+ /* Function prototypes*/
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c 
b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+index e368b0237a1b..4a85a24ced1c 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+@@ -2781,6 +2781,7 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int 
vf_id, u8 *mac)
+       int ret = 0;
+       struct hlist_node *h;
+       int bkt;
++      u8 i;
+ 
+       /* validate the request */
+       if (vf_id >= pf->num_alloc_vfs) {
+@@ -2792,6 +2793,16 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int 
vf_id, u8 *mac)
+ 
+       vf = &(pf->vf[vf_id]);
+       vsi = pf->vsi[vf->lan_vsi_idx];
++
++      /* When the VF is resetting wait until it is done.
++       * It can take up to 200 milliseconds,
++       * but wait for up to 300 milliseconds to be safe.
++       */
++      for (i = 0; i < 15; i++) {
++              if (test_bit(I40E_VF_STATE_INIT, &vf->vf_states))
++                      break;
++              msleep(20);
++      }
+       if (!test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) {
+               dev_err(&pf->pdev->dev, "VF %d still in reset. Try again.\n",
+                       vf_id);
+diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
+index a5bb7b19040e..992c43b1868f 100644
+--- a/drivers/net/ethernet/ti/cpsw.c
++++ b/drivers/net/ethernet/ti/cpsw.c
+@@ -124,7 +124,7 @@ do {                                                       
        \
+ 
+ #define RX_PRIORITY_MAPPING   0x76543210
+ #define TX_PRIORITY_MAPPING   0x33221100
+-#define CPDMA_TX_PRIORITY_MAP 0x01234567
++#define CPDMA_TX_PRIORITY_MAP 0x76543210
+ 
+ #define CPSW_VLAN_AWARE               BIT(1)
+ #define CPSW_ALE_VLAN_AWARE   1
+diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
+index 5aa59f41bf8c..71e2aef6b7a1 100644
+--- a/drivers/net/ppp/pppoe.c
++++ b/drivers/net/ppp/pppoe.c
+@@ -620,6 +620,10 @@ static int pppoe_connect(struct socket *sock, struct 
sockaddr *uservaddr,
+       lock_sock(sk);
+ 
+       error = -EINVAL;
++
++      if (sockaddr_len != sizeof(struct sockaddr_pppox))
++              goto end;
++
+       if (sp->sa_protocol != PX_PROTO_OE)
+               goto end;
+ 
+diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
+index 2a366554c503..8a222ae5950e 100644
+--- a/drivers/net/team/team.c
++++ b/drivers/net/team/team.c
+@@ -261,6 +261,17 @@ static void __team_option_inst_mark_removed_port(struct 
team *team,
+       }
+ }
+ 
++static bool __team_option_inst_tmp_find(const struct list_head *opts,
++                                      const struct team_option_inst *needle)
++{
++      struct team_option_inst *opt_inst;
++
++      list_for_each_entry(opt_inst, opts, tmp_list)
++              if (opt_inst == needle)
++                      return true;
++      return false;
++}
++
+ static int __team_options_register(struct team *team,
+                                  const struct team_option *option,
+                                  size_t option_count)
+@@ -1061,14 +1072,11 @@ static void team_port_leave(struct team *team, struct 
team_port *port)
+ }
+ 
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+-static int team_port_enable_netpoll(struct team *team, struct team_port *port)
++static int __team_port_enable_netpoll(struct team_port *port)
+ {
+       struct netpoll *np;
+       int err;
+ 
+-      if (!team->dev->npinfo)
+-              return 0;
+-
+       np = kzalloc(sizeof(*np), GFP_KERNEL);
+       if (!np)
+               return -ENOMEM;
+@@ -1082,6 +1090,14 @@ static int team_port_enable_netpoll(struct team *team, 
struct team_port *port)
+       return err;
+ }
+ 
++static int team_port_enable_netpoll(struct team_port *port)
++{
++      if (!port->team->dev->npinfo)
++              return 0;
++
++      return __team_port_enable_netpoll(port);
++}
++
+ static void team_port_disable_netpoll(struct team_port *port)
+ {
+       struct netpoll *np = port->np;
+@@ -1096,7 +1112,7 @@ static void team_port_disable_netpoll(struct team_port 
*port)
+       kfree(np);
+ }
+ #else
+-static int team_port_enable_netpoll(struct team *team, struct team_port *port)
++static int team_port_enable_netpoll(struct team_port *port)
+ {
+       return 0;
+ }
+@@ -1204,7 +1220,7 @@ static int team_port_add(struct team *team, struct 
net_device *port_dev)
+               goto err_vids_add;
+       }
+ 
+-      err = team_port_enable_netpoll(team, port);
++      err = team_port_enable_netpoll(port);
+       if (err) {
+               netdev_err(dev, "Failed to enable netpoll on device %s\n",
+                          portname);
+@@ -1901,7 +1917,7 @@ static int team_netpoll_setup(struct net_device *dev,
+ 
+       mutex_lock(&team->lock);
+       list_for_each_entry(port, &team->port_list, list) {
+-              err = team_port_enable_netpoll(team, port);
++              err = __team_port_enable_netpoll(port);
+               if (err) {
+                       __team_netpoll_cleanup(team);
+                       break;
+@@ -2561,6 +2577,14 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, 
struct genl_info *info)
+                       if (err)
+                               goto team_put;
+                       opt_inst->changed = true;
++
++                      /* dumb/evil user-space can send us duplicate opt,
++                       * keep only the last one
++                       */
++                      if (__team_option_inst_tmp_find(&opt_inst_list,
++                                                      opt_inst))
++                              continue;
++
+                       list_add(&opt_inst->tmp_list, &opt_inst_list);
+               }
+               if (!opt_found) {
+diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
+index b0a038e6fda0..bb15b3012aa5 100644
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -116,6 +116,17 @@ struct receive_queue {
+       char name[40];
+ };
+ 
++/* Control VQ buffers: protected by the rtnl lock */
++struct control_buf {
++      struct virtio_net_ctrl_hdr hdr;
++      virtio_net_ctrl_ack status;
++      struct virtio_net_ctrl_mq mq;
++      u8 promisc;
++      u8 allmulti;
++      __virtio16 vid;
++      u64 offloads;
++};
++
+ struct virtnet_info {
+       struct virtio_device *vdev;
+       struct virtqueue *cvq;
+@@ -164,14 +175,7 @@ struct virtnet_info {
+       struct hlist_node node;
+       struct hlist_node node_dead;
+ 
+-      /* Control VQ buffers: protected by the rtnl lock */
+-      struct virtio_net_ctrl_hdr ctrl_hdr;
+-      virtio_net_ctrl_ack ctrl_status;
+-      struct virtio_net_ctrl_mq ctrl_mq;
+-      u8 ctrl_promisc;
+-      u8 ctrl_allmulti;
+-      u16 ctrl_vid;
+-      u64 ctrl_offloads;
++      struct control_buf *ctrl;
+ 
+       /* Ethtool settings */
+       u8 duplex;
+@@ -1340,25 +1344,25 @@ static bool virtnet_send_command(struct virtnet_info 
*vi, u8 class, u8 cmd,
+       /* Caller should know better */
+       BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ));
+ 
+-      vi->ctrl_status = ~0;
+-      vi->ctrl_hdr.class = class;
+-      vi->ctrl_hdr.cmd = cmd;
++      vi->ctrl->status = ~0;
++      vi->ctrl->hdr.class = class;
++      vi->ctrl->hdr.cmd = cmd;
+       /* Add header */
+-      sg_init_one(&hdr, &vi->ctrl_hdr, sizeof(vi->ctrl_hdr));
++      sg_init_one(&hdr, &vi->ctrl->hdr, sizeof(vi->ctrl->hdr));
+       sgs[out_num++] = &hdr;
+ 
+       if (out)
+               sgs[out_num++] = out;
+ 
+       /* Add return status. */
+-      sg_init_one(&stat, &vi->ctrl_status, sizeof(vi->ctrl_status));
++      sg_init_one(&stat, &vi->ctrl->status, sizeof(vi->ctrl->status));
+       sgs[out_num] = &stat;
+ 
+       BUG_ON(out_num + 1 > ARRAY_SIZE(sgs));
+       virtqueue_add_sgs(vi->cvq, sgs, out_num, 1, vi, GFP_ATOMIC);
+ 
+       if (unlikely(!virtqueue_kick(vi->cvq)))
+-              return vi->ctrl_status == VIRTIO_NET_OK;
++              return vi->ctrl->status == VIRTIO_NET_OK;
+ 
+       /* Spin for a response, the kick causes an ioport write, trapping
+        * into the hypervisor, so the request should be handled immediately.
+@@ -1367,7 +1371,7 @@ static bool virtnet_send_command(struct virtnet_info 
*vi, u8 class, u8 cmd,
+              !virtqueue_is_broken(vi->cvq))
+               cpu_relax();
+ 
+-      return vi->ctrl_status == VIRTIO_NET_OK;
++      return vi->ctrl->status == VIRTIO_NET_OK;
+ }
+ 
+ static int virtnet_set_mac_address(struct net_device *dev, void *p)
+@@ -1478,8 +1482,8 @@ static int _virtnet_set_queues(struct virtnet_info *vi, 
u16 queue_pairs)
+       if (!vi->has_cvq || !virtio_has_feature(vi->vdev, VIRTIO_NET_F_MQ))
+               return 0;
+ 
+-      vi->ctrl_mq.virtqueue_pairs = cpu_to_virtio16(vi->vdev, queue_pairs);
+-      sg_init_one(&sg, &vi->ctrl_mq, sizeof(vi->ctrl_mq));
++      vi->ctrl->mq.virtqueue_pairs = cpu_to_virtio16(vi->vdev, queue_pairs);
++      sg_init_one(&sg, &vi->ctrl->mq, sizeof(vi->ctrl->mq));
+ 
+       if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MQ,
+                                 VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, &sg)) {
+@@ -1537,22 +1541,22 @@ static void virtnet_set_rx_mode(struct net_device *dev)
+       if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_RX))
+               return;
+ 
+-      vi->ctrl_promisc = ((dev->flags & IFF_PROMISC) != 0);
+-      vi->ctrl_allmulti = ((dev->flags & IFF_ALLMULTI) != 0);
++      vi->ctrl->promisc = ((dev->flags & IFF_PROMISC) != 0);
++      vi->ctrl->allmulti = ((dev->flags & IFF_ALLMULTI) != 0);
+ 
+-      sg_init_one(sg, &vi->ctrl_promisc, sizeof(vi->ctrl_promisc));
++      sg_init_one(sg, &vi->ctrl->promisc, sizeof(vi->ctrl->promisc));
+ 
+       if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
+                                 VIRTIO_NET_CTRL_RX_PROMISC, sg))
+               dev_warn(&dev->dev, "Failed to %sable promisc mode.\n",
+-                       vi->ctrl_promisc ? "en" : "dis");
++                       vi->ctrl->promisc ? "en" : "dis");
+ 
+-      sg_init_one(sg, &vi->ctrl_allmulti, sizeof(vi->ctrl_allmulti));
++      sg_init_one(sg, &vi->ctrl->allmulti, sizeof(vi->ctrl->allmulti));
+ 
+       if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
+                                 VIRTIO_NET_CTRL_RX_ALLMULTI, sg))
+               dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n",
+-                       vi->ctrl_allmulti ? "en" : "dis");
++                       vi->ctrl->allmulti ? "en" : "dis");
+ 
+       uc_count = netdev_uc_count(dev);
+       mc_count = netdev_mc_count(dev);
+@@ -1598,8 +1602,8 @@ static int virtnet_vlan_rx_add_vid(struct net_device 
*dev,
+       struct virtnet_info *vi = netdev_priv(dev);
+       struct scatterlist sg;
+ 
+-      vi->ctrl_vid = vid;
+-      sg_init_one(&sg, &vi->ctrl_vid, sizeof(vi->ctrl_vid));
++      vi->ctrl->vid = cpu_to_virtio16(vi->vdev, vid);
++      sg_init_one(&sg, &vi->ctrl->vid, sizeof(vi->ctrl->vid));
+ 
+       if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
+                                 VIRTIO_NET_CTRL_VLAN_ADD, &sg))
+@@ -1613,8 +1617,8 @@ static int virtnet_vlan_rx_kill_vid(struct net_device 
*dev,
+       struct virtnet_info *vi = netdev_priv(dev);
+       struct scatterlist sg;
+ 
+-      vi->ctrl_vid = vid;
+-      sg_init_one(&sg, &vi->ctrl_vid, sizeof(vi->ctrl_vid));
++      vi->ctrl->vid = cpu_to_virtio16(vi->vdev, vid);
++      sg_init_one(&sg, &vi->ctrl->vid, sizeof(vi->ctrl->vid));
+ 
+       if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
+                                 VIRTIO_NET_CTRL_VLAN_DEL, &sg))
+@@ -1912,9 +1916,9 @@ static int virtnet_restore_up(struct virtio_device *vdev)
+ static int virtnet_set_guest_offloads(struct virtnet_info *vi, u64 offloads)
+ {
+       struct scatterlist sg;
+-      vi->ctrl_offloads = cpu_to_virtio64(vi->vdev, offloads);
++      vi->ctrl->offloads = cpu_to_virtio64(vi->vdev, offloads);
+ 
+-      sg_init_one(&sg, &vi->ctrl_offloads, sizeof(vi->ctrl_offloads));
++      sg_init_one(&sg, &vi->ctrl->offloads, sizeof(vi->ctrl->offloads));
+ 
+       if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_GUEST_OFFLOADS,
+                                 VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET, &sg)) {
+@@ -2134,6 +2138,7 @@ static void virtnet_free_queues(struct virtnet_info *vi)
+ 
+       kfree(vi->rq);
+       kfree(vi->sq);
++      kfree(vi->ctrl);
+ }
+ 
+ static void _free_receive_bufs(struct virtnet_info *vi)
+@@ -2326,6 +2331,9 @@ static int virtnet_alloc_queues(struct virtnet_info *vi)
+ {
+       int i;
+ 
++      vi->ctrl = kzalloc(sizeof(*vi->ctrl), GFP_KERNEL);
++      if (!vi->ctrl)
++              goto err_ctrl;
+       vi->sq = kzalloc(sizeof(*vi->sq) * vi->max_queue_pairs, GFP_KERNEL);
+       if (!vi->sq)
+               goto err_sq;
+@@ -2351,6 +2359,8 @@ static int virtnet_alloc_queues(struct virtnet_info *vi)
+ err_rq:
+       kfree(vi->sq);
+ err_sq:
++      kfree(vi->ctrl);
++err_ctrl:
+       return -ENOMEM;
+ }
+ 
+diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
+index 252c2206cbb5..c1772215702a 100644
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -5955,9 +5955,8 @@ static void ath10k_sta_rc_update_wk(struct work_struct 
*wk)
+                                   sta->addr, smps, err);
+       }
+ 
+-      if (changed & IEEE80211_RC_SUPP_RATES_CHANGED ||
+-          changed & IEEE80211_RC_NSS_CHANGED) {
+-              ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp 
rates/nss\n",
++      if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
++              ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp 
rates\n",
+                          sta->addr);
+ 
+               err = ath10k_station_assoc(ar, arvif->vif, sta, true);
+diff --git a/drivers/pinctrl/intel/pinctrl-intel.c 
b/drivers/pinctrl/intel/pinctrl-intel.c
+index 72b4527d690f..71df0f70b61f 100644
+--- a/drivers/pinctrl/intel/pinctrl-intel.c
++++ b/drivers/pinctrl/intel/pinctrl-intel.c
+@@ -427,18 +427,6 @@ static void __intel_gpio_set_direction(void __iomem 
*padcfg0, bool input)
+       writel(value, padcfg0);
+ }
+ 
+-static void intel_gpio_set_gpio_mode(void __iomem *padcfg0)
+-{
+-      u32 value;
+-
+-      /* Put the pad into GPIO mode */
+-      value = readl(padcfg0) & ~PADCFG0_PMODE_MASK;
+-      /* Disable SCI/SMI/NMI generation */
+-      value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI);
+-      value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI);
+-      writel(value, padcfg0);
+-}
+-
+ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
+                                    struct pinctrl_gpio_range *range,
+                                    unsigned pin)
+@@ -446,6 +434,7 @@ static int intel_gpio_request_enable(struct pinctrl_dev 
*pctldev,
+       struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+       void __iomem *padcfg0;
+       unsigned long flags;
++      u32 value;
+ 
+       raw_spin_lock_irqsave(&pctrl->lock, flags);
+ 
+@@ -455,7 +444,13 @@ static int intel_gpio_request_enable(struct pinctrl_dev 
*pctldev,
+       }
+ 
+       padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
+-      intel_gpio_set_gpio_mode(padcfg0);
++      /* Put the pad into GPIO mode */
++      value = readl(padcfg0) & ~PADCFG0_PMODE_MASK;
++      /* Disable SCI/SMI/NMI generation */
++      value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI);
++      value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI);
++      writel(value, padcfg0);
++
+       /* Disable TX buffer and enable RX (this will be input) */
+       __intel_gpio_set_direction(padcfg0, true);
+ 
+@@ -940,8 +935,6 @@ static int intel_gpio_irq_type(struct irq_data *d, 
unsigned type)
+ 
+       raw_spin_lock_irqsave(&pctrl->lock, flags);
+ 
+-      intel_gpio_set_gpio_mode(reg);
+-
+       value = readl(reg);
+ 
+       value &= ~(PADCFG0_RXEVCFG_MASK | PADCFG0_RXINV);
+diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c
+index 62f5f04d8f61..5e963fe0e38d 100644
+--- a/drivers/s390/block/dasd_alias.c
++++ b/drivers/s390/block/dasd_alias.c
+@@ -592,13 +592,22 @@ static int _schedule_lcu_update(struct alias_lcu *lcu,
+ int dasd_alias_add_device(struct dasd_device *device)
+ {
+       struct dasd_eckd_private *private = device->private;
+-      struct alias_lcu *lcu;
++      __u8 uaddr = private->uid.real_unit_addr;
++      struct alias_lcu *lcu = private->lcu;
+       unsigned long flags;
+       int rc;
+ 
+-      lcu = private->lcu;
+       rc = 0;
+       spin_lock_irqsave(&lcu->lock, flags);
++      /*
++       * Check if device and lcu type differ. If so, the uac data may be
++       * outdated and needs to be updated.
++       */
++      if (private->uid.type !=  lcu->uac->unit[uaddr].ua_type) {
++              lcu->flags |= UPDATE_PENDING;
++              DBF_DEV_EVENT(DBF_WARNING, device, "%s",
++                            "uid type mismatch - trigger rescan");
++      }
+       if (!(lcu->flags & UPDATE_PENDING)) {
+               rc = _add_device_to_lcu(lcu, device, device);
+               if (rc)
+diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
+index 05ac6ba15a53..ecc24a46e71a 100644
+--- a/drivers/s390/char/Makefile
++++ b/drivers/s390/char/Makefile
+@@ -17,6 +17,8 @@ CFLAGS_REMOVE_sclp_early_core.o      += $(CC_FLAGS_MARCH)
+ CFLAGS_sclp_early_core.o              += -march=z900
+ endif
+ 
++CFLAGS_REMOVE_sclp_early_core.o       += $(CC_FLAGS_EXPOLINE)
++
+ obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \
+        sclp_cmd.o sclp_config.o sclp_cpi_sys.o sclp_ocf.o sclp_ctl.o \
+        sclp_early.o sclp_early_core.o
+diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
+index 7b0b295b2313..69687c16a150 100644
+--- a/drivers/s390/cio/chsc.c
++++ b/drivers/s390/cio/chsc.c
+@@ -451,6 +451,7 @@ static void chsc_process_sei_link_incident(struct 
chsc_sei_nt0_area *sei_area)
+ 
+ static void chsc_process_sei_res_acc(struct chsc_sei_nt0_area *sei_area)
+ {
++      struct channel_path *chp;
+       struct chp_link link;
+       struct chp_id chpid;
+       int status;
+@@ -463,10 +464,17 @@ static void chsc_process_sei_res_acc(struct 
chsc_sei_nt0_area *sei_area)
+       chpid.id = sei_area->rsid;
+       /* allocate a new channel path structure, if needed */
+       status = chp_get_status(chpid);
+-      if (status < 0)
+-              chp_new(chpid);
+-      else if (!status)
++      if (!status)
+               return;
++
++      if (status < 0) {
++              chp_new(chpid);
++      } else {
++              chp = chpid_to_chp(chpid);
++              mutex_lock(&chp->lock);
++              chp_update_desc(chp);
++              mutex_unlock(&chp->lock);
++      }
+       memset(&link, 0, sizeof(struct chp_link));
+       link.chpid = chpid;
+       if ((sei_area->vf & 0xc0) != 0) {
+diff --git a/include/linux/fsnotify_backend.h 
b/include/linux/fsnotify_backend.h
+index 3597ef78df4d..ce74278a454a 100644
+--- a/include/linux/fsnotify_backend.h
++++ b/include/linux/fsnotify_backend.h
+@@ -217,12 +217,10 @@ struct fsnotify_mark_connector {
+       union { /* Object pointer [lock] */
+               struct inode *inode;
+               struct vfsmount *mnt;
+-      };
+-      union {
+-              struct hlist_head list;
+               /* Used listing heads to free after srcu period expires */
+               struct fsnotify_mark_connector *destroy_next;
+       };
++      struct hlist_head list;
+ };
+ 
+ /*
+diff --git a/include/linux/hmm.h b/include/linux/hmm.h
+index 8198faf16ed6..96e69979f84d 100644
+--- a/include/linux/hmm.h
++++ b/include/linux/hmm.h
+@@ -498,16 +498,23 @@ struct hmm_device {
+ struct hmm_device *hmm_device_new(void *drvdata);
+ void hmm_device_put(struct hmm_device *hmm_device);
+ #endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */
++#endif /* IS_ENABLED(CONFIG_HMM) */
+ 
+ /* Below are for HMM internal use only! Not to be used by device driver! */
++#if IS_ENABLED(CONFIG_HMM_MIRROR)
+ void hmm_mm_destroy(struct mm_struct *mm);
+ 
+ static inline void hmm_mm_init(struct mm_struct *mm)
+ {
+       mm->hmm = NULL;
+ }
++#else /* IS_ENABLED(CONFIG_HMM_MIRROR) */
++static inline void hmm_mm_destroy(struct mm_struct *mm) {}
++static inline void hmm_mm_init(struct mm_struct *mm) {}
++#endif /* IS_ENABLED(CONFIG_HMM_MIRROR) */
++
++
+ #else /* IS_ENABLED(CONFIG_HMM) */
+ static inline void hmm_mm_destroy(struct mm_struct *mm) {}
+ static inline void hmm_mm_init(struct mm_struct *mm) {}
+-#endif /* IS_ENABLED(CONFIG_HMM) */
+ #endif /* LINUX_HMM_H */
+diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
+index 5e6a2d4dc366..ab927383c99d 100644
+--- a/include/linux/if_vlan.h
++++ b/include/linux/if_vlan.h
+@@ -584,7 +584,7 @@ static inline bool skb_vlan_tagged(const struct sk_buff 
*skb)
+  * Returns true if the skb is tagged with multiple vlan headers, regardless
+  * of whether it is hardware accelerated or not.
+  */
+-static inline bool skb_vlan_tagged_multi(const struct sk_buff *skb)
++static inline bool skb_vlan_tagged_multi(struct sk_buff *skb)
+ {
+       __be16 protocol = skb->protocol;
+ 
+@@ -594,6 +594,9 @@ static inline bool skb_vlan_tagged_multi(const struct 
sk_buff *skb)
+               if (likely(!eth_type_vlan(protocol)))
+                       return false;
+ 
++              if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN)))
++                      return false;
++
+               veh = (struct vlan_ethhdr *)skb->data;
+               protocol = veh->h_vlan_encapsulated_proto;
+       }
+@@ -611,7 +614,7 @@ static inline bool skb_vlan_tagged_multi(const struct 
sk_buff *skb)
+  *
+  * Returns features without unsafe ones if the skb has multiple tags.
+  */
+-static inline netdev_features_t vlan_features_check(const struct sk_buff *skb,
++static inline netdev_features_t vlan_features_check(struct sk_buff *skb,
+                                                   netdev_features_t features)
+ {
+       if (skb_vlan_tagged_multi(skb)) {
+diff --git a/include/linux/tpm.h b/include/linux/tpm.h
+index 881312d85574..2a6c3d96b31f 100644
+--- a/include/linux/tpm.h
++++ b/include/linux/tpm.h
+@@ -49,7 +49,7 @@ struct tpm_class_ops {
+       bool (*update_timeouts)(struct tpm_chip *chip,
+                               unsigned long *timeout_cap);
+       int (*request_locality)(struct tpm_chip *chip, int loc);
+-      void (*relinquish_locality)(struct tpm_chip *chip, int loc);
++      int (*relinquish_locality)(struct tpm_chip *chip, int loc);
+       void (*clk_enable)(struct tpm_chip *chip, bool value);
+ };
+ 
+diff --git a/include/net/ife.h b/include/net/ife.h
+index 44b9c00f7223..e117617e3c34 100644
+--- a/include/net/ife.h
++++ b/include/net/ife.h
+@@ -12,7 +12,8 @@
+ void *ife_encode(struct sk_buff *skb, u16 metalen);
+ void *ife_decode(struct sk_buff *skb, u16 *metalen);
+ 
+-void *ife_tlv_meta_decode(void *skbdata, u16 *attrtype, u16 *dlen, u16 
*totlen);
++void *ife_tlv_meta_decode(void *skbdata, const void *ifehdr_end, u16 
*attrtype,
++                        u16 *dlen, u16 *totlen);
+ int ife_tlv_meta_encode(void *skbdata, u16 attrtype, u16 dlen,
+                       const void *dval);
+ 
+diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h
+index fe994d2e5286..ea985aa7a6c5 100644
+--- a/include/net/llc_conn.h
++++ b/include/net/llc_conn.h
+@@ -97,6 +97,7 @@ static __inline__ char llc_backlog_type(struct sk_buff *skb)
+ 
+ struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority,
+                         struct proto *prot, int kern);
++void llc_sk_stop_all_timers(struct sock *sk, bool sync);
+ void llc_sk_free(struct sock *sk);
+ 
+ void llc_sk_reset(struct sock *sk);
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index d323d4fa742c..fb653736f335 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -1616,6 +1616,7 @@ static inline void tcp_write_queue_purge(struct sock *sk)
+       sk_mem_reclaim(sk);
+       tcp_clear_all_retrans_hints(tcp_sk(sk));
+       tcp_init_send_head(sk);
++      tcp_sk(sk)->packets_out = 0;
+ }
+ 
+ static inline struct sk_buff *tcp_write_queue_head(const struct sock *sk)
+diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
+index 7e99999d6236..857bad91c454 100644
+--- a/include/uapi/linux/kvm.h
++++ b/include/uapi/linux/kvm.h
+@@ -931,6 +931,7 @@ struct kvm_ppc_resize_hpt {
+ #define KVM_CAP_PPC_SMT_POSSIBLE 147
+ #define KVM_CAP_HYPERV_SYNIC2 148
+ #define KVM_CAP_HYPERV_VP_INDEX 149
++#define KVM_CAP_S390_BPB 152
+ 
+ #ifdef KVM_CAP_IRQ_ROUTING
+ 
+diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h
+index e954ae3d82c0..e3a658bac10f 100644
+--- a/kernel/trace/trace_entries.h
++++ b/kernel/trace/trace_entries.h
+@@ -356,7 +356,7 @@ FTRACE_ENTRY(hwlat, hwlat_entry,
+               __field(        unsigned int,           seqnum          )
+       ),
+ 
+-      
F_printk("cnt:%u\tts:%010llu.%010lu\tinner:%llu\touter:%llunmi-ts:%llu\tnmi-count:%u\n",
++      
F_printk("cnt:%u\tts:%010llu.%010lu\tinner:%llu\touter:%llu\tnmi-ts:%llu\tnmi-count:%u\n",
+                __entry->seqnum,
+                __entry->tv_sec,
+                __entry->tv_nsec,
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 4be2a4047640..e7d56c5adde6 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -2903,7 +2903,7 @@ netdev_features_t passthru_features_check(struct sk_buff 
*skb,
+ }
+ EXPORT_SYMBOL(passthru_features_check);
+ 
+-static netdev_features_t dflt_features_check(const struct sk_buff *skb,
++static netdev_features_t dflt_features_check(struct sk_buff *skb,
+                                            struct net_device *dev,
+                                            netdev_features_t features)
+ {
+diff --git a/net/core/neighbour.c b/net/core/neighbour.c
+index 741ae2554190..514d697d4691 100644
+--- a/net/core/neighbour.c
++++ b/net/core/neighbour.c
+@@ -55,7 +55,8 @@ static void neigh_timer_handler(unsigned long arg);
+ static void __neigh_notify(struct neighbour *n, int type, int flags,
+                          u32 pid);
+ static void neigh_update_notify(struct neighbour *neigh, u32 nlmsg_pid);
+-static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
++static int pneigh_ifdown_and_unlock(struct neigh_table *tbl,
++                                  struct net_device *dev);
+ 
+ #ifdef CONFIG_PROC_FS
+ static const struct file_operations neigh_stat_seq_fops;
+@@ -291,8 +292,7 @@ int neigh_ifdown(struct neigh_table *tbl, struct 
net_device *dev)
+ {
+       write_lock_bh(&tbl->lock);
+       neigh_flush_dev(tbl, dev);
+-      pneigh_ifdown(tbl, dev);
+-      write_unlock_bh(&tbl->lock);
++      pneigh_ifdown_and_unlock(tbl, dev);
+ 
+       del_timer_sync(&tbl->proxy_timer);
+       pneigh_queue_purge(&tbl->proxy_queue);
+@@ -681,9 +681,10 @@ int pneigh_delete(struct neigh_table *tbl, struct net 
*net, const void *pkey,
+       return -ENOENT;
+ }
+ 
+-static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
++static int pneigh_ifdown_and_unlock(struct neigh_table *tbl,
++                                  struct net_device *dev)
+ {
+-      struct pneigh_entry *n, **np;
++      struct pneigh_entry *n, **np, *freelist = NULL;
+       u32 h;
+ 
+       for (h = 0; h <= PNEIGH_HASHMASK; h++) {
+@@ -691,16 +692,23 @@ static int pneigh_ifdown(struct neigh_table *tbl, struct 
net_device *dev)
+               while ((n = *np) != NULL) {
+                       if (!dev || n->dev == dev) {
+                               *np = n->next;
+-                              if (tbl->pdestructor)
+-                                      tbl->pdestructor(n);
+-                              if (n->dev)
+-                                      dev_put(n->dev);
+-                              kfree(n);
++                              n->next = freelist;
++                              freelist = n;
+                               continue;
+                       }
+                       np = &n->next;
+               }
+       }
++      write_unlock_bh(&tbl->lock);
++      while ((n = freelist)) {
++              freelist = n->next;
++              n->next = NULL;
++              if (tbl->pdestructor)
++                      tbl->pdestructor(n);
++              if (n->dev)
++                      dev_put(n->dev);
++              kfree(n);
++      }
+       return -ENOENT;
+ }
+ 
+@@ -2323,12 +2331,16 @@ static int neigh_dump_table(struct neigh_table *tbl, 
struct sk_buff *skb,
+ 
+       err = nlmsg_parse(nlh, sizeof(struct ndmsg), tb, NDA_MAX, NULL, NULL);
+       if (!err) {
+-              if (tb[NDA_IFINDEX])
++              if (tb[NDA_IFINDEX]) {
++                      if (nla_len(tb[NDA_IFINDEX]) != sizeof(u32))
++                              return -EINVAL;
+                       filter_idx = nla_get_u32(tb[NDA_IFINDEX]);
+-
+-              if (tb[NDA_MASTER])
++              }
++              if (tb[NDA_MASTER]) {
++                      if (nla_len(tb[NDA_MASTER]) != sizeof(u32))
++                              return -EINVAL;
+                       filter_master_idx = nla_get_u32(tb[NDA_MASTER]);
+-
++              }
+               if (filter_idx || filter_master_idx)
+                       flags |= NLM_F_DUMP_FILTERED;
+       }
+diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
+index e1d4d898a007..f0252768ecf4 100644
+--- a/net/dns_resolver/dns_key.c
++++ b/net/dns_resolver/dns_key.c
+@@ -25,6 +25,7 @@
+ #include <linux/moduleparam.h>
+ #include <linux/slab.h>
+ #include <linux/string.h>
++#include <linux/ratelimit.h>
+ #include <linux/kernel.h>
+ #include <linux/keyctl.h>
+ #include <linux/err.h>
+@@ -91,9 +92,9 @@ dns_resolver_preparse(struct key_preparsed_payload *prep)
+ 
+                       next_opt = memchr(opt, '#', end - opt) ?: end;
+                       opt_len = next_opt - opt;
+-                      if (!opt_len) {
+-                              printk(KERN_WARNING
+-                                     "Empty option to dns_resolver key\n");
++                      if (opt_len <= 0 || opt_len > 128) {
++                              pr_warn_ratelimited("Invalid option length (%d) 
for dns_resolver key\n",
++                                                  opt_len);
+                               return -EINVAL;
+                       }
+ 
+@@ -127,10 +128,8 @@ dns_resolver_preparse(struct key_preparsed_payload *prep)
+                       }
+ 
+               bad_option_value:
+-                      printk(KERN_WARNING
+-                             "Option '%*.*s' to dns_resolver key:"
+-                             " bad/missing value\n",
+-                             opt_nlen, opt_nlen, opt);
++                      pr_warn_ratelimited("Option '%*.*s' to dns_resolver 
key: bad/missing value\n",
++                                          opt_nlen, opt_nlen, opt);
+                       return -EINVAL;
+               } while (opt = next_opt + 1, opt < end);
+       }
+diff --git a/net/ife/ife.c b/net/ife/ife.c
+index 7d1ec76e7f43..13bbf8cb6a39 100644
+--- a/net/ife/ife.c
++++ b/net/ife/ife.c
+@@ -69,6 +69,9 @@ void *ife_decode(struct sk_buff *skb, u16 *metalen)
+       int total_pull;
+       u16 ifehdrln;
+ 
++      if (!pskb_may_pull(skb, skb->dev->hard_header_len + IFE_METAHDRLEN))
++              return NULL;
++
+       ifehdr = (struct ifeheadr *) (skb->data + skb->dev->hard_header_len);
+       ifehdrln = ntohs(ifehdr->metalen);
+       total_pull = skb->dev->hard_header_len + ifehdrln;
+@@ -92,12 +95,43 @@ struct meta_tlvhdr {
+       __be16 len;
+ };
+ 
++static bool __ife_tlv_meta_valid(const unsigned char *skbdata,
++                               const unsigned char *ifehdr_end)
++{
++      const struct meta_tlvhdr *tlv;
++      u16 tlvlen;
++
++      if (unlikely(skbdata + sizeof(*tlv) > ifehdr_end))
++              return false;
++
++      tlv = (const struct meta_tlvhdr *)skbdata;
++      tlvlen = ntohs(tlv->len);
++
++      /* tlv length field is inc header, check on minimum */
++      if (tlvlen < NLA_HDRLEN)
++              return false;
++
++      /* overflow by NLA_ALIGN check */
++      if (NLA_ALIGN(tlvlen) < tlvlen)
++              return false;
++
++      if (unlikely(skbdata + NLA_ALIGN(tlvlen) > ifehdr_end))
++              return false;
++
++      return true;
++}
++
+ /* Caller takes care of presenting data in network order
+  */
+-void *ife_tlv_meta_decode(void *skbdata, u16 *attrtype, u16 *dlen, u16 
*totlen)
++void *ife_tlv_meta_decode(void *skbdata, const void *ifehdr_end, u16 
*attrtype,
++                        u16 *dlen, u16 *totlen)
+ {
+-      struct meta_tlvhdr *tlv = (struct meta_tlvhdr *) skbdata;
++      struct meta_tlvhdr *tlv;
++
++      if (!__ife_tlv_meta_valid(skbdata, ifehdr_end))
++              return NULL;
+ 
++      tlv = (struct meta_tlvhdr *)skbdata;
+       *dlen = ntohs(tlv->len) - NLA_HDRLEN;
+       *attrtype = ntohs(tlv->type);
+ 
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 38b9a6276a9d..d023f879e7bb 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -2354,7 +2354,6 @@ int tcp_disconnect(struct sock *sk, int flags)
+       icsk->icsk_backoff = 0;
+       tp->snd_cwnd = 2;
+       icsk->icsk_probes_out = 0;
+-      tp->packets_out = 0;
+       tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
+       tp->snd_cwnd_cnt = 0;
+       tp->window_clamp = 0;
+@@ -2742,8 +2741,10 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
+ #ifdef CONFIG_TCP_MD5SIG
+       case TCP_MD5SIG:
+       case TCP_MD5SIG_EXT:
+-              /* Read the IP->Key mappings from userspace */
+-              err = tp->af_specific->md5_parse(sk, optname, optval, optlen);
++              if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))
++                      err = tp->af_specific->md5_parse(sk, optname, optval, 
optlen);
++              else
++                      err = -EINVAL;
+               break;
+ #endif
+       case TCP_USER_TIMEOUT:
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index 14474acea0bb..ebbb54bcbcac 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -3892,11 +3892,8 @@ const u8 *tcp_parse_md5sig_option(const struct tcphdr 
*th)
+       int length = (th->doff << 2) - sizeof(*th);
+       const u8 *ptr = (const u8 *)(th + 1);
+ 
+-      /* If the TCP option is too short, we can short cut */
+-      if (length < TCPOLEN_MD5SIG)
+-              return NULL;
+-
+-      while (length > 0) {
++      /* If not enough data remaining, we can short cut */
++      while (length >= TCPOLEN_MD5SIG) {
+               int opcode = *ptr++;
+               int opsize;
+ 
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 0126d9bfa670..e04c534b573e 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -2959,6 +2959,7 @@ void rt6_mtu_change(struct net_device *dev, unsigned int 
mtu)
+ 
+ static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
+       [RTA_GATEWAY]           = { .len = sizeof(struct in6_addr) },
++      [RTA_PREFSRC]           = { .len = sizeof(struct in6_addr) },
+       [RTA_OIF]               = { .type = NLA_U32 },
+       [RTA_IIF]               = { .type = NLA_U32 },
+       [RTA_PRIORITY]          = { .type = NLA_U32 },
+@@ -2970,6 +2971,7 @@ static const struct nla_policy 
rtm_ipv6_policy[RTA_MAX+1] = {
+       [RTA_EXPIRES]           = { .type = NLA_U32 },
+       [RTA_UID]               = { .type = NLA_U32 },
+       [RTA_MARK]              = { .type = NLA_U32 },
++      [RTA_TABLE]             = { .type = NLA_U32 },
+ };
+ 
+ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
+diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c
+index f343e6f0fc95..5fe139484919 100644
+--- a/net/ipv6/seg6_iptunnel.c
++++ b/net/ipv6/seg6_iptunnel.c
+@@ -136,7 +136,7 @@ int seg6_do_srh_encap(struct sk_buff *skb, struct 
ipv6_sr_hdr *osrh, int proto)
+       isrh->nexthdr = proto;
+ 
+       hdr->daddr = isrh->segments[isrh->first_segment];
+-      set_tun_src(net, ip6_dst_idev(dst)->dev, &hdr->daddr, &hdr->saddr);
++      set_tun_src(net, dst->dev, &hdr->daddr, &hdr->saddr);
+ 
+ #ifdef CONFIG_IPV6_SEG6_HMAC
+       if (sr_has_hmac(isrh)) {
+diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
+index 0c2738349442..8bef35aa8786 100644
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -591,6 +591,13 @@ static int pppol2tp_connect(struct socket *sock, struct 
sockaddr *uservaddr,
+       lock_sock(sk);
+ 
+       error = -EINVAL;
++
++      if (sockaddr_len != sizeof(struct sockaddr_pppol2tp) &&
++          sockaddr_len != sizeof(struct sockaddr_pppol2tpv3) &&
++          sockaddr_len != sizeof(struct sockaddr_pppol2tpin6) &&
++          sockaddr_len != sizeof(struct sockaddr_pppol2tpv3in6))
++              goto end;
++
+       if (sp->sa_protocol != PX_PROTO_OL2TP)
+               goto end;
+ 
+diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
+index c38d16f22d2a..cf41d9b4a0b8 100644
+--- a/net/llc/af_llc.c
++++ b/net/llc/af_llc.c
+@@ -199,9 +199,19 @@ static int llc_ui_release(struct socket *sock)
+               llc->laddr.lsap, llc->daddr.lsap);
+       if (!llc_send_disc(sk))
+               llc_ui_wait_for_disc(sk, sk->sk_rcvtimeo);
+-      if (!sock_flag(sk, SOCK_ZAPPED))
++      if (!sock_flag(sk, SOCK_ZAPPED)) {
++              struct llc_sap *sap = llc->sap;
++
++              /* Hold this for release_sock(), so that llc_backlog_rcv()
++               * could still use it.
++               */
++              llc_sap_hold(sap);
+               llc_sap_remove_socket(llc->sap, sk);
+-      release_sock(sk);
++              release_sock(sk);
++              llc_sap_put(sap);
++      } else {
++              release_sock(sk);
++      }
+       if (llc->dev)
+               dev_put(llc->dev);
+       sock_put(sk);
+diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
+index ea225bd2672c..f8d4ab8ca1a5 100644
+--- a/net/llc/llc_c_ac.c
++++ b/net/llc/llc_c_ac.c
+@@ -1096,14 +1096,7 @@ int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct 
sk_buff *skb)
+ 
+ int llc_conn_ac_stop_all_timers(struct sock *sk, struct sk_buff *skb)
+ {
+-      struct llc_sock *llc = llc_sk(sk);
+-
+-      del_timer(&llc->pf_cycle_timer.timer);
+-      del_timer(&llc->ack_timer.timer);
+-      del_timer(&llc->rej_sent_timer.timer);
+-      del_timer(&llc->busy_state_timer.timer);
+-      llc->ack_must_be_send = 0;
+-      llc->ack_pf = 0;
++      llc_sk_stop_all_timers(sk, false);
+       return 0;
+ }
+ 
+diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c
+index 5e91b47f0d2a..9a42448eb182 100644
+--- a/net/llc/llc_conn.c
++++ b/net/llc/llc_conn.c
+@@ -951,6 +951,26 @@ struct sock *llc_sk_alloc(struct net *net, int family, 
gfp_t priority, struct pr
+       return sk;
+ }
+ 
++void llc_sk_stop_all_timers(struct sock *sk, bool sync)
++{
++      struct llc_sock *llc = llc_sk(sk);
++
++      if (sync) {
++              del_timer_sync(&llc->pf_cycle_timer.timer);
++              del_timer_sync(&llc->ack_timer.timer);
++              del_timer_sync(&llc->rej_sent_timer.timer);
++              del_timer_sync(&llc->busy_state_timer.timer);
++      } else {
++              del_timer(&llc->pf_cycle_timer.timer);
++              del_timer(&llc->ack_timer.timer);
++              del_timer(&llc->rej_sent_timer.timer);
++              del_timer(&llc->busy_state_timer.timer);
++      }
++
++      llc->ack_must_be_send = 0;
++      llc->ack_pf = 0;
++}
++
+ /**
+  *    llc_sk_free - Frees a LLC socket
+  *    @sk - socket to free
+@@ -963,7 +983,7 @@ void llc_sk_free(struct sock *sk)
+ 
+       llc->state = LLC_CONN_OUT_OF_SVC;
+       /* Stop all (possibly) running timers */
+-      llc_conn_ac_stop_all_timers(sk, NULL);
++      llc_sk_stop_all_timers(sk, true);
+ #ifdef DEBUG_LLC_CONN_ALLOC
+       printk(KERN_INFO "%s: unackq=%d, txq=%d\n", __func__,
+               skb_queue_len(&llc->pdu_unack_q),
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index f4a0587b7d5e..3994b71f8197 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -331,11 +331,11 @@ static void packet_pick_tx_queue(struct net_device *dev, 
struct sk_buff *skb)
+       skb_set_queue_mapping(skb, queue_index);
+ }
+ 
+-/* register_prot_hook must be invoked with the po->bind_lock held,
++/* __register_prot_hook must be invoked through register_prot_hook
+  * or from a context in which asynchronous accesses to the packet
+  * socket is not possible (packet_create()).
+  */
+-static void register_prot_hook(struct sock *sk)
++static void __register_prot_hook(struct sock *sk)
+ {
+       struct packet_sock *po = pkt_sk(sk);
+ 
+@@ -350,8 +350,13 @@ static void register_prot_hook(struct sock *sk)
+       }
+ }
+ 
+-/* {,__}unregister_prot_hook() must be invoked with the po->bind_lock
+- * held.   If the sync parameter is true, we will temporarily drop
++static void register_prot_hook(struct sock *sk)
++{
++      lockdep_assert_held_once(&pkt_sk(sk)->bind_lock);
++      __register_prot_hook(sk);
++}
++
++/* If the sync parameter is true, we will temporarily drop
+  * the po->bind_lock and do a synchronize_net to make sure no
+  * asynchronous packet processing paths still refer to the elements
+  * of po->prot_hook.  If the sync parameter is false, it is the
+@@ -361,6 +366,8 @@ static void __unregister_prot_hook(struct sock *sk, bool 
sync)
+ {
+       struct packet_sock *po = pkt_sk(sk);
+ 
++      lockdep_assert_held_once(&po->bind_lock);
++
+       po->running = 0;
+ 
+       if (po->fanout)
+@@ -3017,6 +3024,7 @@ static int packet_release(struct socket *sock)
+ 
+       packet_flush_mclist(sk);
+ 
++      lock_sock(sk);
+       if (po->rx_ring.pg_vec) {
+               memset(&req_u, 0, sizeof(req_u));
+               packet_set_ring(sk, &req_u, 1, 0);
+@@ -3026,6 +3034,7 @@ static int packet_release(struct socket *sock)
+               memset(&req_u, 0, sizeof(req_u));
+               packet_set_ring(sk, &req_u, 1, 1);
+       }
++      release_sock(sk);
+ 
+       f = fanout_release(sk);
+ 
+@@ -3259,7 +3268,7 @@ static int packet_create(struct net *net, struct socket 
*sock, int protocol,
+ 
+       if (proto) {
+               po->prot_hook.type = proto;
+-              register_prot_hook(sk);
++              __register_prot_hook(sk);
+       }
+ 
+       mutex_lock(&net->packet.sklist_lock);
+@@ -3654,6 +3663,7 @@ packet_setsockopt(struct socket *sock, int level, int 
optname, char __user *optv
+               union tpacket_req_u req_u;
+               int len;
+ 
++              lock_sock(sk);
+               switch (po->tp_version) {
+               case TPACKET_V1:
+               case TPACKET_V2:
+@@ -3664,12 +3674,17 @@ packet_setsockopt(struct socket *sock, int level, int 
optname, char __user *optv
+                       len = sizeof(req_u.req3);
+                       break;
+               }
+-              if (optlen < len)
+-                      return -EINVAL;
+-              if (copy_from_user(&req_u.req, optval, len))
+-                      return -EFAULT;
+-              return packet_set_ring(sk, &req_u, 0,
+-                      optname == PACKET_TX_RING);
++              if (optlen < len) {
++                      ret = -EINVAL;
++              } else {
++                      if (copy_from_user(&req_u.req, optval, len))
++                              ret = -EFAULT;
++                      else
++                              ret = packet_set_ring(sk, &req_u, 0,
++                                                  optname == PACKET_TX_RING);
++              }
++              release_sock(sk);
++              return ret;
+       }
+       case PACKET_COPY_THRESH:
+       {
+@@ -3735,12 +3750,18 @@ packet_setsockopt(struct socket *sock, int level, int 
optname, char __user *optv
+ 
+               if (optlen != sizeof(val))
+                       return -EINVAL;
+-              if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
+-                      return -EBUSY;
+               if (copy_from_user(&val, optval, sizeof(val)))
+                       return -EFAULT;
+-              po->tp_loss = !!val;
+-              return 0;
++
++              lock_sock(sk);
++              if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
++                      ret = -EBUSY;
++              } else {
++                      po->tp_loss = !!val;
++                      ret = 0;
++              }
++              release_sock(sk);
++              return ret;
+       }
+       case PACKET_AUXDATA:
+       {
+@@ -3751,7 +3772,9 @@ packet_setsockopt(struct socket *sock, int level, int 
optname, char __user *optv
+               if (copy_from_user(&val, optval, sizeof(val)))
+                       return -EFAULT;
+ 
++              lock_sock(sk);
+               po->auxdata = !!val;
++              release_sock(sk);
+               return 0;
+       }
+       case PACKET_ORIGDEV:
+@@ -3763,7 +3786,9 @@ packet_setsockopt(struct socket *sock, int level, int 
optname, char __user *optv
+               if (copy_from_user(&val, optval, sizeof(val)))
+                       return -EFAULT;
+ 
++              lock_sock(sk);
+               po->origdev = !!val;
++              release_sock(sk);
+               return 0;
+       }
+       case PACKET_VNET_HDR:
+@@ -3772,15 +3797,20 @@ packet_setsockopt(struct socket *sock, int level, int 
optname, char __user *optv
+ 
+               if (sock->type != SOCK_RAW)
+                       return -EINVAL;
+-              if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
+-                      return -EBUSY;
+               if (optlen < sizeof(val))
+                       return -EINVAL;
+               if (copy_from_user(&val, optval, sizeof(val)))
+                       return -EFAULT;
+ 
+-              po->has_vnet_hdr = !!val;
+-              return 0;
++              lock_sock(sk);
++              if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
++                      ret = -EBUSY;
++              } else {
++                      po->has_vnet_hdr = !!val;
++                      ret = 0;
++              }
++              release_sock(sk);
++              return ret;
+       }
+       case PACKET_TIMESTAMP:
+       {
+@@ -3818,11 +3848,17 @@ packet_setsockopt(struct socket *sock, int level, int 
optname, char __user *optv
+ 
+               if (optlen != sizeof(val))
+                       return -EINVAL;
+-              if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
+-                      return -EBUSY;
+               if (copy_from_user(&val, optval, sizeof(val)))
+                       return -EFAULT;
+-              po->tp_tx_has_off = !!val;
++
++              lock_sock(sk);
++              if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
++                      ret = -EBUSY;
++              } else {
++                      po->tp_tx_has_off = !!val;
++                      ret = 0;
++              }
++              release_sock(sk);
+               return 0;
+       }
+       case PACKET_QDISC_BYPASS:
+@@ -4219,8 +4255,6 @@ static int packet_set_ring(struct sock *sk, union 
tpacket_req_u *req_u,
+       /* Added to avoid minimal code churn */
+       struct tpacket_req *req = &req_u->req;
+ 
+-      lock_sock(sk);
+-
+       rb = tx_ring ? &po->tx_ring : &po->rx_ring;
+       rb_queue = tx_ring ? &sk->sk_write_queue : &sk->sk_receive_queue;
+ 
+@@ -4358,7 +4392,6 @@ static int packet_set_ring(struct sock *sk, union 
tpacket_req_u *req_u,
+       if (pg_vec)
+               free_pg_vec(pg_vec, order, req->tp_block_nr);
+ out:
+-      release_sock(sk);
+       return err;
+ }
+ 
+diff --git a/net/packet/internal.h b/net/packet/internal.h
+index a1d2b2319ae9..3bb7c5fb3bff 100644
+--- a/net/packet/internal.h
++++ b/net/packet/internal.h
+@@ -112,10 +112,12 @@ struct packet_sock {
+       int                     copy_thresh;
+       spinlock_t              bind_lock;
+       struct mutex            pg_vec_lock;
+-      unsigned int            running:1,      /* prot_hook is attached*/
+-                              auxdata:1,
++      unsigned int            running;        /* bind_lock must be held */
++      unsigned int            auxdata:1,      /* writer must hold sock lock */
+                               origdev:1,
+-                              has_vnet_hdr:1;
++                              has_vnet_hdr:1,
++                              tp_loss:1,
++                              tp_tx_has_off:1;
+       int                     pressure;
+       int                     ifindex;        /* bound device         */
+       __be16                  num;
+@@ -125,8 +127,6 @@ struct packet_sock {
+       enum tpacket_versions   tp_version;
+       unsigned int            tp_hdrlen;
+       unsigned int            tp_reserve;
+-      unsigned int            tp_loss:1;
+-      unsigned int            tp_tx_has_off:1;
+       unsigned int            tp_tstamp;
+       struct net_device __rcu *cached_dev;
+       int                     (*xmit)(struct sk_buff *skb);
+diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
+index 8ccd35825b6b..85757af7f150 100644
+--- a/net/sched/act_ife.c
++++ b/net/sched/act_ife.c
+@@ -605,7 +605,7 @@ static int find_decode_metaid(struct sk_buff *skb, struct 
tcf_ife_info *ife,
+               }
+       }
+ 
+-      return 0;
++      return -ENOENT;
+ }
+ 
+ static int tcf_ife_decode(struct sk_buff *skb, const struct tc_action *a,
+@@ -639,7 +639,12 @@ static int tcf_ife_decode(struct sk_buff *skb, const 
struct tc_action *a,
+               u16 mtype;
+               u16 dlen;
+ 
+-              curr_data = ife_tlv_meta_decode(tlv_data, &mtype, &dlen, NULL);
++              curr_data = ife_tlv_meta_decode(tlv_data, ifehdr_end, &mtype,
++                                              &dlen, NULL);
++              if (!curr_data) {
++                      qstats_drop_inc(this_cpu_ptr(ife->common.cpu_qstats));
++                      return TC_ACT_SHOT;
++              }
+ 
+               if (find_decode_metaid(skb, ife, mtype, dlen, curr_data)) {
+                       /* abuse overlimits to count when we receive metadata
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index 08b5705e7381..7219a1c041f7 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -521,46 +521,49 @@ static void sctp_v6_to_addr(union sctp_addr *addr, 
struct in6_addr *saddr,
+       addr->v6.sin6_scope_id = 0;
+ }
+ 
+-/* Compare addresses exactly.
+- * v4-mapped-v6 is also in consideration.
+- */
+-static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
+-                          const union sctp_addr *addr2)
++static int __sctp_v6_cmp_addr(const union sctp_addr *addr1,
++                            const union sctp_addr *addr2)
+ {
+       if (addr1->sa.sa_family != addr2->sa.sa_family) {
+               if (addr1->sa.sa_family == AF_INET &&
+                   addr2->sa.sa_family == AF_INET6 &&
+-                  ipv6_addr_v4mapped(&addr2->v6.sin6_addr)) {
+-                      if (addr2->v6.sin6_port == addr1->v4.sin_port &&
+-                          addr2->v6.sin6_addr.s6_addr32[3] ==
+-                          addr1->v4.sin_addr.s_addr)
+-                              return 1;
+-              }
++                  ipv6_addr_v4mapped(&addr2->v6.sin6_addr) &&
++                  addr2->v6.sin6_addr.s6_addr32[3] ==
++                  addr1->v4.sin_addr.s_addr)
++                      return 1;
++
+               if (addr2->sa.sa_family == AF_INET &&
+                   addr1->sa.sa_family == AF_INET6 &&
+-                  ipv6_addr_v4mapped(&addr1->v6.sin6_addr)) {
+-                      if (addr1->v6.sin6_port == addr2->v4.sin_port &&
+-                          addr1->v6.sin6_addr.s6_addr32[3] ==
+-                          addr2->v4.sin_addr.s_addr)
+-                              return 1;
+-              }
++                  ipv6_addr_v4mapped(&addr1->v6.sin6_addr) &&
++                  addr1->v6.sin6_addr.s6_addr32[3] ==
++                  addr2->v4.sin_addr.s_addr)
++                      return 1;
++
+               return 0;
+       }
+-      if (addr1->v6.sin6_port != addr2->v6.sin6_port)
+-              return 0;
++
+       if (!ipv6_addr_equal(&addr1->v6.sin6_addr, &addr2->v6.sin6_addr))
+               return 0;
++
+       /* If this is a linklocal address, compare the scope_id. */
+-      if (ipv6_addr_type(&addr1->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) {
+-              if (addr1->v6.sin6_scope_id && addr2->v6.sin6_scope_id &&
+-                  (addr1->v6.sin6_scope_id != addr2->v6.sin6_scope_id)) {
+-                      return 0;
+-              }
+-      }
++      if ((ipv6_addr_type(&addr1->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) &&
++          addr1->v6.sin6_scope_id && addr2->v6.sin6_scope_id &&
++          addr1->v6.sin6_scope_id != addr2->v6.sin6_scope_id)
++              return 0;
+ 
+       return 1;
+ }
+ 
++/* Compare addresses exactly.
++ * v4-mapped-v6 is also in consideration.
++ */
++static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
++                          const union sctp_addr *addr2)
++{
++      return __sctp_v6_cmp_addr(addr1, addr2) &&
++             addr1->v6.sin6_port == addr2->v6.sin6_port;
++}
++
+ /* Initialize addr struct to INADDR_ANY. */
+ static void sctp_v6_inaddr_any(union sctp_addr *addr, __be16 port)
+ {
+@@ -845,8 +848,8 @@ static int sctp_inet6_cmp_addr(const union sctp_addr 
*addr1,
+                              const union sctp_addr *addr2,
+                              struct sctp_sock *opt)
+ {
+-      struct sctp_af *af1, *af2;
+       struct sock *sk = sctp_opt2sk(opt);
++      struct sctp_af *af1, *af2;
+ 
+       af1 = sctp_get_af_specific(addr1->sa.sa_family);
+       af2 = sctp_get_af_specific(addr2->sa.sa_family);
+@@ -862,10 +865,7 @@ static int sctp_inet6_cmp_addr(const union sctp_addr 
*addr1,
+       if (sctp_is_any(sk, addr1) || sctp_is_any(sk, addr2))
+               return 1;
+ 
+-      if (addr1->sa.sa_family != addr2->sa.sa_family)
+-              return 0;
+-
+-      return af1->cmp_addr(addr1, addr2);
++      return __sctp_v6_cmp_addr(addr1, addr2);
+ }
+ 
+ /* Verify that the provided sockaddr looks bindable.   Common verification,
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index a6d604fd9695..f9c289e05707 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -1203,14 +1203,12 @@ static int smc_shutdown(struct socket *sock, int how)
+               rc = smc_close_shutdown_write(smc);
+               break;
+       case SHUT_RD:
+-              if (sk->sk_state == SMC_LISTEN)
+-                      rc = smc_close_active(smc);
+-              else
+-                      rc = 0;
+-                      /* nothing more to do because peer is not involved */
++              rc = 0;
++              /* nothing more to do because peer is not involved */
+               break;
+       }
+-      rc1 = kernel_sock_shutdown(smc->clcsock, how);
++      if (smc->clcsock)
++              rc1 = kernel_sock_shutdown(smc->clcsock, how);
+       /* map sock_shutdown_cmd constants to sk_shutdown value range */
+       sk->sk_shutdown |= how + 1;
+ 
+diff --git a/net/strparser/strparser.c b/net/strparser/strparser.c
+index 4a3a3f1331ee..c741365f77da 100644
+--- a/net/strparser/strparser.c
++++ b/net/strparser/strparser.c
+@@ -67,7 +67,7 @@ static void strp_abort_strp(struct strparser *strp, int err)
+ 
+ static void strp_start_timer(struct strparser *strp, long timeo)
+ {
+-      if (timeo)
++      if (timeo && timeo != LONG_MAX)
+               mod_delayed_work(strp_wq, &strp->msg_timer_work, timeo);
+ }
+ 
+@@ -296,9 +296,9 @@ static int __strp_recv(read_descriptor_t *desc, struct 
sk_buff *orig_skb,
+                                       strp_start_timer(strp, timeo);
+                               }
+ 
++                              stm->accum_len += cand_len;
+                               strp->need_bytes = stm->strp.full_len -
+                                                      stm->accum_len;
+-                              stm->accum_len += cand_len;
+                               stm->early_eaten = cand_len;
+                               STRP_STATS_ADD(strp->stats.bytes, cand_len);
+                               desc->count = 0; /* Stop reading socket */
+@@ -321,6 +321,7 @@ static int __strp_recv(read_descriptor_t *desc, struct 
sk_buff *orig_skb,
+               /* Hurray, we have a new message! */
+               cancel_delayed_work(&strp->msg_timer_work);
+               strp->skb_head = NULL;
++              strp->need_bytes = 0;
+               STRP_STATS_INCR(strp->stats.msgs);
+ 
+               /* Give skb to upper layer */
+@@ -410,9 +411,7 @@ void strp_data_ready(struct strparser *strp)
+               return;
+ 
+       if (strp->need_bytes) {
+-              if (strp_peek_len(strp) >= strp->need_bytes)
+-                      strp->need_bytes = 0;
+-              else
++              if (strp_peek_len(strp) < strp->need_bytes)
+                       return;
+       }
+ 
+diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
+index b76f13f6fea1..d4e0bbeee727 100644
+--- a/net/tipc/netlink.c
++++ b/net/tipc/netlink.c
+@@ -79,7 +79,8 @@ const struct nla_policy 
tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = {
+ 
+ const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = {
+       [TIPC_NLA_NET_UNSPEC]           = { .type = NLA_UNSPEC },
+-      [TIPC_NLA_NET_ID]               = { .type = NLA_U32 }
++      [TIPC_NLA_NET_ID]               = { .type = NLA_U32 },
++      [TIPC_NLA_NET_ADDR]             = { .type = NLA_U32 },
+ };
+ 
+ const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = {
+diff --git a/security/commoncap.c b/security/commoncap.c
+index 7b01431d1e19..1c1f64582bb5 100644
+--- a/security/commoncap.c
++++ b/security/commoncap.c
+@@ -449,6 +449,8 @@ int cap_inode_getsecurity(struct inode *inode, const char 
*name, void **buffer,
+                               magic |= VFS_CAP_FLAGS_EFFECTIVE;
+                       memcpy(&cap->data, &nscap->data, sizeof(__le32) * 2 * 
VFS_CAP_U32);
+                       cap->magic_etc = cpu_to_le32(magic);
++              } else {
++                      size = -ENOMEM;
+               }
+       }
+       kfree(tmpbuf);

Reply via email to