commit:     9be44d2876e04a79365ed86a6cc3fb1ed9c3b492
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sun Aug 11 10:59:36 2019 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:59:36 2019 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=9be44d28

Linux patch 4.9.189

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README              |    4 +
 1188_linux-4.9.189.patch | 1396 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1400 insertions(+)

diff --git a/0000_README b/0000_README
index 6e9f4e5..06f5715 100644
--- a/0000_README
+++ b/0000_README
@@ -795,6 +795,10 @@ Patch:  1187_linux-4.9.188.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.9.188
 
+Patch:  1188_linux-4.9.189.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.9.189
+
 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/1188_linux-4.9.189.patch b/1188_linux-4.9.189.patch
new file mode 100644
index 0000000..3707b77
--- /dev/null
+++ b/1188_linux-4.9.189.patch
@@ -0,0 +1,1396 @@
+diff --git a/Documentation/kernel-parameters.txt 
b/Documentation/kernel-parameters.txt
+index 55a9bbbcf5e1..f4f0a1b9ba29 100644
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -2484,6 +2484,7 @@ bytes respectively. Such letter suffixes can also be 
entirely omitted.
+                               improves system performance, but it may also
+                               expose users to several CPU vulnerabilities.
+                               Equivalent to: nopti [X86]
++                                             nospectre_v1 [X86]
+                                              nospectre_v2 [X86]
+                                              spectre_v2_user=off [X86]
+                                              spec_store_bypass_disable=off 
[X86]
+@@ -2819,10 +2820,6 @@ bytes respectively. Such letter suffixes can also be 
entirely omitted.
+ 
+       nohugeiomap     [KNL,x86] Disable kernel huge I/O mappings.
+ 
+-      nospectre_v1    [PPC] Disable mitigations for Spectre Variant 1 (bounds
+-                      check bypass). With this option data leaks are possible
+-                      in the system.
+-
+       nosmt           [KNL,S390] Disable symmetric multithreading (SMT).
+                       Equivalent to smt=1.
+ 
+@@ -2830,6 +2827,10 @@ bytes respectively. Such letter suffixes can also be 
entirely omitted.
+                       nosmt=force: Force disable SMT, cannot be undone
+                                    via the sysfs control file.
+ 
++      nospectre_v1    [X86,PPC] Disable mitigations for Spectre Variant 1
++                      (bounds check bypass). With this option data leaks are
++                      possible in the system.
++
+       nospectre_v2    [X86,PPC_FSL_BOOK3E] Disable all mitigations for the 
Spectre variant 2
+                       (indirect branch prediction) vulnerability. System may
+                       allow data leaks with this option, which is equivalent
+diff --git a/Makefile b/Makefile
+index b6b54e6f67e8..4fdc9d984f80 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 9
+-SUBLEVEL = 188
++SUBLEVEL = 189
+ EXTRAVERSION =
+ NAME = Roaring Lionus
+ 
+diff --git a/arch/arm/boot/dts/logicpd-som-lv.dtsi 
b/arch/arm/boot/dts/logicpd-som-lv.dtsi
+index 876ed5f2922c..f82f193b8856 100644
+--- a/arch/arm/boot/dts/logicpd-som-lv.dtsi
++++ b/arch/arm/boot/dts/logicpd-som-lv.dtsi
+@@ -108,16 +108,21 @@
+               twl_audio: audio {
+                       compatible = "ti,twl4030-audio";
+                       codec {
++                              ti,hs_extmute_gpio = <&gpio2 25 
GPIO_ACTIVE_HIGH>;
+                       };
+               };
+       };
+ };
+ 
+ &i2c2 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c2_pins>;
+       clock-frequency = <400000>;
+ };
+ 
+ &i2c3 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c3_pins>;
+       clock-frequency = <400000>;
+ };
+ 
+@@ -221,6 +226,7 @@
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x21ba, PIN_INPUT | MUX_MODE0)        
/* i2c1_scl.i2c1_scl */
+                       OMAP3_CORE1_IOPAD(0x21bc, PIN_INPUT | MUX_MODE0)        
/* i2c1_sda.i2c1_sda */
++                      OMAP3_CORE1_IOPAD(0x20ba, PIN_OUTPUT | MUX_MODE4)       
 /* gpmc_ncs6.gpio_57 */
+               >;
+       };
+ };
+@@ -239,6 +245,18 @@
+                       OMAP3_WKUP_IOPAD(0x2a0c, PIN_OUTPUT | MUX_MODE4)        
/* sys_boot1.gpio_3 */
+               >;
+       };
++      i2c2_pins: pinmux_i2c2_pins {
++              pinctrl-single,pins = <
++                      OMAP3_CORE1_IOPAD(0x21be, PIN_INPUT | MUX_MODE0)        
/* i2c2_scl */
++                      OMAP3_CORE1_IOPAD(0x21c0, PIN_INPUT | MUX_MODE0)        
/* i2c2_sda */
++              >;
++      };
++      i2c3_pins: pinmux_i2c3_pins {
++              pinctrl-single,pins = <
++                      OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT | MUX_MODE0)        
/* i2c3_scl */
++                      OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT | MUX_MODE0)        
/* i2c3_sda */
++              >;
++      };
+ };
+ 
+ &omap3_pmx_core2 {
+diff --git a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi 
b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
+index 08f0a35dc0d1..ceb49d15d243 100644
+--- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
++++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi
+@@ -117,10 +117,14 @@
+ };
+ 
+ &i2c2 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c2_pins>;
+       clock-frequency = <400000>;
+ };
+ 
+ &i2c3 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c3_pins>;
+       clock-frequency = <400000>;
+       at24@50 {
+               compatible = "atmel,24c64";
+@@ -215,6 +219,18 @@
+                       OMAP3_CORE1_IOPAD(0x21bc, PIN_INPUT | MUX_MODE0)        
/* i2c1_sda.i2c1_sda */
+               >;
+       };
++      i2c2_pins: pinmux_i2c2_pins {
++              pinctrl-single,pins = <
++                      OMAP3_CORE1_IOPAD(0x21be, PIN_INPUT | MUX_MODE0)        
/* i2c2_scl */
++                      OMAP3_CORE1_IOPAD(0x21c0, PIN_INPUT | MUX_MODE0)        
/* i2c2_sda */
++              >;
++      };
++      i2c3_pins: pinmux_i2c3_pins {
++              pinctrl-single,pins = <
++                      OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT | MUX_MODE0)        
/* i2c3_scl */
++                      OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT | MUX_MODE0)        
/* i2c3_sda */
++              >;
++      };
+ };
+ 
+ &uart2 {
+diff --git a/arch/arm64/include/asm/cpufeature.h 
b/arch/arm64/include/asm/cpufeature.h
+index 15868eca58de..e7bef3d936d8 100644
+--- a/arch/arm64/include/asm/cpufeature.h
++++ b/arch/arm64/include/asm/cpufeature.h
+@@ -31,9 +31,10 @@
+ 
+ /* CPU feature register tracking */
+ enum ftr_type {
+-      FTR_EXACT,      /* Use a predefined safe value */
+-      FTR_LOWER_SAFE, /* Smaller value is safe */
+-      FTR_HIGHER_SAFE,/* Bigger value is safe */
++      FTR_EXACT,                      /* Use a predefined safe value */
++      FTR_LOWER_SAFE,                 /* Smaller value is safe */
++      FTR_HIGHER_SAFE,                /* Bigger value is safe */
++      FTR_HIGHER_OR_ZERO_SAFE,        /* Bigger value is safe, but 0 is 
biggest */
+ };
+ 
+ #define FTR_STRICT    true    /* SANITY check strict matching required */
+diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
+index a3ab7dfad50a..9a8e45dc36bd 100644
+--- a/arch/arm64/kernel/cpufeature.c
++++ b/arch/arm64/kernel/cpufeature.c
+@@ -148,10 +148,12 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr2[] = {
+ };
+ 
+ static const struct arm64_ftr_bits ftr_ctr[] = {
+-      ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 31, 1, 1),        /* RAO */
+-      ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 28, 3, 0),
+-      ARM64_FTR_BITS(FTR_STRICT, FTR_HIGHER_SAFE, 24, 4, 0),  /* CWG */
+-      ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 20, 4, 0),   /* ERG */
++      ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 31, 1, 1),        /* RES1 */
++      ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 30, 1, 0),
++      ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 29, 1, 1),   /* DIC */
++      ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 28, 1, 1),   /* IDC */
++      ARM64_FTR_BITS(FTR_STRICT, FTR_HIGHER_OR_ZERO_SAFE, 24, 4, 0),  /* CWG 
*/
++      ARM64_FTR_BITS(FTR_STRICT, FTR_HIGHER_OR_ZERO_SAFE, 20, 4, 0),  /* ERG 
*/
+       ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, CTR_DMINLINE_SHIFT, 4, 1),
+       /*
+        * Linux can handle differing I-cache policies. Userspace JITs will
+@@ -390,6 +392,10 @@ static s64 arm64_ftr_safe_value(const struct 
arm64_ftr_bits *ftrp, s64 new,
+       case FTR_LOWER_SAFE:
+               ret = new < cur ? new : cur;
+               break;
++      case FTR_HIGHER_OR_ZERO_SAFE:
++              if (!cur || !new)
++                      break;
++              /* Fallthrough */
+       case FTR_HIGHER_SAFE:
+               ret = new > cur ? new : cur;
+               break;
+diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
+index 9a9e5884066c..8af8c070f213 100644
+--- a/arch/x86/entry/calling.h
++++ b/arch/x86/entry/calling.h
+@@ -1,4 +1,5 @@
+ #include <linux/jump_label.h>
++#include <asm/cpufeatures.h>
+ 
+ /*
+ 
+@@ -201,6 +202,23 @@ For 32-bit we have the following conventions - kernel is 
built with
+       .byte 0xf1
+       .endm
+ 
++/*
++ * Mitigate Spectre v1 for conditional swapgs code paths.
++ *
++ * FENCE_SWAPGS_USER_ENTRY is used in the user entry swapgs code path, to
++ * prevent a speculative swapgs when coming from kernel space.
++ *
++ * FENCE_SWAPGS_KERNEL_ENTRY is used in the kernel entry non-swapgs code path,
++ * to prevent the swapgs from getting speculatively skipped when coming from
++ * user space.
++ */
++.macro FENCE_SWAPGS_USER_ENTRY
++      ALTERNATIVE "", "lfence", X86_FEATURE_FENCE_SWAPGS_USER
++.endm
++.macro FENCE_SWAPGS_KERNEL_ENTRY
++      ALTERNATIVE "", "lfence", X86_FEATURE_FENCE_SWAPGS_KERNEL
++.endm
++
+ #endif /* CONFIG_X86_64 */
+ 
+ /*
+diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
+index 8252d9dc48eb..10ecfba43dff 100644
+--- a/arch/x86/entry/entry_64.S
++++ b/arch/x86/entry/entry_64.S
+@@ -420,6 +420,7 @@ END(irq_entries_start)
+        * tracking that we're in kernel mode.
+        */
+       SWAPGS
++      FENCE_SWAPGS_USER_ENTRY
+       SWITCH_KERNEL_CR3
+ 
+       /*
+@@ -433,8 +434,10 @@ END(irq_entries_start)
+       TRACE_IRQS_OFF
+ 
+       CALL_enter_from_user_mode
+-
++      jmp     2f
+ 1:
++      FENCE_SWAPGS_KERNEL_ENTRY
++2:
+       /*
+        * Save previous stack pointer, optionally switch to interrupt stack.
+        * irq_count is used to check if a CPU is already on an interrupt stack
+@@ -1004,6 +1007,13 @@ ENTRY(paranoid_entry)
+       movq    %rax, %cr3
+ 2:
+ #endif
++      /*
++       * The above doesn't do an unconditional CR3 write, even in the PTI
++       * case.  So do an lfence to prevent GS speculation, regardless of
++       * whether PTI is enabled.
++       */
++      FENCE_SWAPGS_KERNEL_ENTRY
++
+       ret
+ END(paranoid_entry)
+ 
+@@ -1065,6 +1075,7 @@ ENTRY(error_entry)
+        * from user mode due to an IRET fault.
+        */
+       SWAPGS
++      FENCE_SWAPGS_USER_ENTRY
+ 
+ .Lerror_entry_from_usermode_after_swapgs:
+       /*
+@@ -1076,6 +1087,8 @@ ENTRY(error_entry)
+       CALL_enter_from_user_mode
+       ret
+ 
++.Lerror_entry_done_lfence:
++      FENCE_SWAPGS_KERNEL_ENTRY
+ .Lerror_entry_done:
+       TRACE_IRQS_OFF
+       ret
+@@ -1094,7 +1107,7 @@ ENTRY(error_entry)
+       cmpq    %rax, RIP+8(%rsp)
+       je      .Lbstep_iret
+       cmpq    $.Lgs_change, RIP+8(%rsp)
+-      jne     .Lerror_entry_done
++      jne     .Lerror_entry_done_lfence
+ 
+       /*
+        * hack: .Lgs_change can fail with user gsbase.  If this happens, fix up
+@@ -1102,6 +1115,7 @@ ENTRY(error_entry)
+        * .Lgs_change's error handler with kernel gsbase.
+        */
+       SWAPGS
++      FENCE_SWAPGS_USER_ENTRY
+       jmp .Lerror_entry_done
+ 
+ .Lbstep_iret:
+@@ -1115,6 +1129,7 @@ ENTRY(error_entry)
+        * Switch to kernel gsbase:
+        */
+       SWAPGS
++      FENCE_SWAPGS_USER_ENTRY
+ 
+       /*
+        * Pretend that the exception came from user mode: set up pt_regs
+@@ -1211,6 +1226,7 @@ ENTRY(nmi)
+        * to switch CR3 here.
+        */
+       cld
++      FENCE_SWAPGS_USER_ENTRY
+       movq    %rsp, %rdx
+       movq    PER_CPU_VAR(cpu_current_top_of_stack), %rsp
+       pushq   5*8(%rdx)       /* pt_regs->ss */
+@@ -1499,6 +1515,7 @@ end_repeat_nmi:
+       movq    %rax, %cr3
+ 2:
+ #endif
++      FENCE_SWAPGS_KERNEL_ENTRY
+ 
+       /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */
+       call    do_nmi
+diff --git a/arch/x86/include/asm/cpufeatures.h 
b/arch/x86/include/asm/cpufeatures.h
+index 06de338be0d8..3a972da155d6 100644
+--- a/arch/x86/include/asm/cpufeatures.h
++++ b/arch/x86/include/asm/cpufeatures.h
+@@ -192,7 +192,8 @@
+ 
+ #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */
+ #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
+-
++#define X86_FEATURE_FENCE_SWAPGS_USER ( 7*32+10) /* "" LFENCE in user entry 
SWAPGS path */
++#define X86_FEATURE_FENCE_SWAPGS_KERNEL       ( 7*32+11) /* "" LFENCE in 
kernel entry SWAPGS path */
+ #define X86_FEATURE_RETPOLINE ( 7*32+12) /* "" Generic Retpoline mitigation 
for Spectre variant 2 */
+ #define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* "" AMD Retpoline mitigation 
for Spectre variant 2 */
+ 
+@@ -201,9 +202,6 @@
+ 
+ #define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */
+ 
+-/* Because the ALTERNATIVE scheme is for members of the X86_FEATURE club... */
+-#define X86_FEATURE_KAISER    ( 7*32+31) /* CONFIG_PAGE_TABLE_ISOLATION w/o 
nokaiser */
+-
+ #define X86_FEATURE_USE_IBPB  ( 7*32+21) /* "" Indirect Branch Prediction 
Barrier enabled */
+ #define X86_FEATURE_USE_IBRS_FW       ( 7*32+22) /* "" Use IBRS during 
runtime firmware calls */
+ #define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* "" Disable 
Speculative Store Bypass. */
+@@ -214,6 +212,7 @@
+ #define X86_FEATURE_ZEN               ( 7*32+28) /* "" CPU is AMD family 0x17 
(Zen) */
+ #define X86_FEATURE_L1TF_PTEINV       ( 7*32+29) /* "" L1TF workaround PTE 
inversion */
+ #define X86_FEATURE_IBRS_ENHANCED     ( 7*32+30) /* Enhanced IBRS */
++#define X86_FEATURE_KAISER    ( 7*32+31) /* CONFIG_PAGE_TABLE_ISOLATION w/o 
nokaiser */
+ 
+ /* Virtualization flags: Linux defined, word 8 */
+ #define X86_FEATURE_TPR_SHADOW  ( 8*32+ 0) /* Intel TPR Shadow */
+@@ -357,5 +356,6 @@
+ #define X86_BUG_L1TF          X86_BUG(18) /* CPU is affected by L1 Terminal 
Fault */
+ #define X86_BUG_MDS           X86_BUG(19) /* CPU is affected by 
Microarchitectural data sampling */
+ #define X86_BUG_MSBDS_ONLY    X86_BUG(20) /* CPU is only affected by the  
MSDBS variant of BUG_MDS */
++#define X86_BUG_SWAPGS                X86_BUG(21) /* CPU is affected by 
speculation through SWAPGS */
+ 
+ #endif /* _ASM_X86_CPUFEATURES_H */
+diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
+index a4f343ac042e..2a42fef275ad 100644
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -31,6 +31,7 @@
+ #include <asm/intel-family.h>
+ #include <asm/e820.h>
+ 
++static void __init spectre_v1_select_mitigation(void);
+ static void __init spectre_v2_select_mitigation(void);
+ static void __init ssb_select_mitigation(void);
+ static void __init l1tf_select_mitigation(void);
+@@ -95,17 +96,11 @@ void __init check_bugs(void)
+       if (boot_cpu_has(X86_FEATURE_STIBP))
+               x86_spec_ctrl_mask |= SPEC_CTRL_STIBP;
+ 
+-      /* Select the proper spectre mitigation before patching alternatives */
++      /* Select the proper CPU mitigations before patching alternatives: */
++      spectre_v1_select_mitigation();
+       spectre_v2_select_mitigation();
+-
+-      /*
+-       * Select proper mitigation for any exposure to the Speculative Store
+-       * Bypass vulnerability.
+-       */
+       ssb_select_mitigation();
+-
+       l1tf_select_mitigation();
+-
+       mds_select_mitigation();
+ 
+       arch_smt_update();
+@@ -270,6 +265,98 @@ static int __init mds_cmdline(char *str)
+ }
+ early_param("mds", mds_cmdline);
+ 
++#undef pr_fmt
++#define pr_fmt(fmt)     "Spectre V1 : " fmt
++
++enum spectre_v1_mitigation {
++      SPECTRE_V1_MITIGATION_NONE,
++      SPECTRE_V1_MITIGATION_AUTO,
++};
++
++static enum spectre_v1_mitigation spectre_v1_mitigation __ro_after_init =
++      SPECTRE_V1_MITIGATION_AUTO;
++
++static const char * const spectre_v1_strings[] = {
++      [SPECTRE_V1_MITIGATION_NONE] = "Vulnerable: __user pointer sanitization 
and usercopy barriers only; no swapgs barriers",
++      [SPECTRE_V1_MITIGATION_AUTO] = "Mitigation: usercopy/swapgs barriers 
and __user pointer sanitization",
++};
++
++/*
++ * Does SMAP provide full mitigation against speculative kernel access to
++ * userspace?
++ */
++static bool smap_works_speculatively(void)
++{
++      if (!boot_cpu_has(X86_FEATURE_SMAP))
++              return false;
++
++      /*
++       * On CPUs which are vulnerable to Meltdown, SMAP does not
++       * prevent speculative access to user data in the L1 cache.
++       * Consider SMAP to be non-functional as a mitigation on these
++       * CPUs.
++       */
++      if (boot_cpu_has(X86_BUG_CPU_MELTDOWN))
++              return false;
++
++      return true;
++}
++
++static void __init spectre_v1_select_mitigation(void)
++{
++      if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V1) || cpu_mitigations_off()) {
++              spectre_v1_mitigation = SPECTRE_V1_MITIGATION_NONE;
++              return;
++      }
++
++      if (spectre_v1_mitigation == SPECTRE_V1_MITIGATION_AUTO) {
++              /*
++               * With Spectre v1, a user can speculatively control either
++               * path of a conditional swapgs with a user-controlled GS
++               * value.  The mitigation is to add lfences to both code paths.
++               *
++               * If FSGSBASE is enabled, the user can put a kernel address in
++               * GS, in which case SMAP provides no protection.
++               *
++               * [ NOTE: Don't check for X86_FEATURE_FSGSBASE until the
++               *         FSGSBASE enablement patches have been merged. ]
++               *
++               * If FSGSBASE is disabled, the user can only put a user space
++               * address in GS.  That makes an attack harder, but still
++               * possible if there's no SMAP protection.
++               */
++              if (!smap_works_speculatively()) {
++                      /*
++                       * Mitigation can be provided from SWAPGS itself or
++                       * PTI as the CR3 write in the Meltdown mitigation
++                       * is serializing.
++                       *
++                       * If neither is there, mitigate with an LFENCE to
++                       * stop speculation through swapgs.
++                       */
++                      if (boot_cpu_has_bug(X86_BUG_SWAPGS) &&
++                          !boot_cpu_has(X86_FEATURE_KAISER))
++                              
setup_force_cpu_cap(X86_FEATURE_FENCE_SWAPGS_USER);
++
++                      /*
++                       * Enable lfences in the kernel entry (non-swapgs)
++                       * paths, to prevent user entry from speculatively
++                       * skipping swapgs.
++                       */
++                      setup_force_cpu_cap(X86_FEATURE_FENCE_SWAPGS_KERNEL);
++              }
++      }
++
++      pr_info("%s\n", spectre_v1_strings[spectre_v1_mitigation]);
++}
++
++static int __init nospectre_v1_cmdline(char *str)
++{
++      spectre_v1_mitigation = SPECTRE_V1_MITIGATION_NONE;
++      return 0;
++}
++early_param("nospectre_v1", nospectre_v1_cmdline);
++
+ #undef pr_fmt
+ #define pr_fmt(fmt)     "Spectre V2 : " fmt
+ 
+@@ -1265,7 +1352,7 @@ static ssize_t cpu_show_common(struct device *dev, 
struct device_attribute *attr
+               break;
+ 
+       case X86_BUG_SPECTRE_V1:
+-              return sprintf(buf, "Mitigation: __user pointer 
sanitization\n");
++              return sprintf(buf, "%s\n", 
spectre_v1_strings[spectre_v1_mitigation]);
+ 
+       case X86_BUG_SPECTRE_V2:
+               return sprintf(buf, "%s%s%s%s%s%s\n", 
spectre_v2_strings[spectre_v2_enabled],
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index cda130dc56b9..12fa16051871 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -897,6 +897,7 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 
*c)
+ #define NO_L1TF               BIT(3)
+ #define NO_MDS                BIT(4)
+ #define MSBDS_ONLY    BIT(5)
++#define NO_SWAPGS     BIT(6)
+ 
+ #define VULNWL(_vendor, _family, _model, _whitelist)  \
+       { X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist }
+@@ -920,29 +921,37 @@ static const __initconst struct x86_cpu_id 
cpu_vuln_whitelist[] = {
+       VULNWL_INTEL(ATOM_BONNELL,              NO_SPECULATION),
+       VULNWL_INTEL(ATOM_BONNELL_MID,          NO_SPECULATION),
+ 
+-      VULNWL_INTEL(ATOM_SILVERMONT,           NO_SSB | NO_L1TF | MSBDS_ONLY),
+-      VULNWL_INTEL(ATOM_SILVERMONT_X,         NO_SSB | NO_L1TF | MSBDS_ONLY),
+-      VULNWL_INTEL(ATOM_SILVERMONT_MID,       NO_SSB | NO_L1TF | MSBDS_ONLY),
+-      VULNWL_INTEL(ATOM_AIRMONT,              NO_SSB | NO_L1TF | MSBDS_ONLY),
+-      VULNWL_INTEL(XEON_PHI_KNL,              NO_SSB | NO_L1TF | MSBDS_ONLY),
+-      VULNWL_INTEL(XEON_PHI_KNM,              NO_SSB | NO_L1TF | MSBDS_ONLY),
++      VULNWL_INTEL(ATOM_SILVERMONT,           NO_SSB | NO_L1TF | MSBDS_ONLY | 
NO_SWAPGS),
++      VULNWL_INTEL(ATOM_SILVERMONT_X,         NO_SSB | NO_L1TF | MSBDS_ONLY | 
NO_SWAPGS),
++      VULNWL_INTEL(ATOM_SILVERMONT_MID,       NO_SSB | NO_L1TF | MSBDS_ONLY | 
NO_SWAPGS),
++      VULNWL_INTEL(ATOM_AIRMONT,              NO_SSB | NO_L1TF | MSBDS_ONLY | 
NO_SWAPGS),
++      VULNWL_INTEL(XEON_PHI_KNL,              NO_SSB | NO_L1TF | MSBDS_ONLY | 
NO_SWAPGS),
++      VULNWL_INTEL(XEON_PHI_KNM,              NO_SSB | NO_L1TF | MSBDS_ONLY | 
NO_SWAPGS),
+ 
+       VULNWL_INTEL(CORE_YONAH,                NO_SSB),
+ 
+-      VULNWL_INTEL(ATOM_AIRMONT_MID,          NO_L1TF | MSBDS_ONLY),
++      VULNWL_INTEL(ATOM_AIRMONT_MID,          NO_L1TF | MSBDS_ONLY | 
NO_SWAPGS),
+ 
+-      VULNWL_INTEL(ATOM_GOLDMONT,             NO_MDS | NO_L1TF),
+-      VULNWL_INTEL(ATOM_GOLDMONT_X,           NO_MDS | NO_L1TF),
+-      VULNWL_INTEL(ATOM_GOLDMONT_PLUS,        NO_MDS | NO_L1TF),
++      VULNWL_INTEL(ATOM_GOLDMONT,             NO_MDS | NO_L1TF | NO_SWAPGS),
++      VULNWL_INTEL(ATOM_GOLDMONT_X,           NO_MDS | NO_L1TF | NO_SWAPGS),
++      VULNWL_INTEL(ATOM_GOLDMONT_PLUS,        NO_MDS | NO_L1TF | NO_SWAPGS),
++
++      /*
++       * Technically, swapgs isn't serializing on AMD (despite it previously
++       * being documented as such in the APM).  But according to AMD, %gs is
++       * updated non-speculatively, and the issuing of %gs-relative memory
++       * operands will be blocked until the %gs update completes, which is
++       * good enough for our purposes.
++       */
+ 
+       /* AMD Family 0xf - 0x12 */
+-      VULNWL_AMD(0x0f,        NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
+-      VULNWL_AMD(0x10,        NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
+-      VULNWL_AMD(0x11,        NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
+-      VULNWL_AMD(0x12,        NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
++      VULNWL_AMD(0x0f,        NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | 
NO_SWAPGS),
++      VULNWL_AMD(0x10,        NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | 
NO_SWAPGS),
++      VULNWL_AMD(0x11,        NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | 
NO_SWAPGS),
++      VULNWL_AMD(0x12,        NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | 
NO_SWAPGS),
+ 
+       /* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */
+-      VULNWL_AMD(X86_FAMILY_ANY,      NO_MELTDOWN | NO_L1TF | NO_MDS),
++      VULNWL_AMD(X86_FAMILY_ANY,      NO_MELTDOWN | NO_L1TF | NO_MDS | 
NO_SWAPGS),
+       {}
+ };
+ 
+@@ -979,6 +988,9 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
+                       setup_force_cpu_bug(X86_BUG_MSBDS_ONLY);
+       }
+ 
++      if (!cpu_matches(NO_SWAPGS))
++              setup_force_cpu_bug(X86_BUG_SWAPGS);
++
+       if (cpu_matches(NO_MELTDOWN))
+               return;
+ 
+diff --git a/block/blk-core.c b/block/blk-core.c
+index 77b99bf16c83..bdb906bbfe19 100644
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -881,6 +881,7 @@ blk_init_allocated_queue(struct request_queue *q, 
request_fn_proc *rfn,
+ 
+ fail:
+       blk_free_flush_queue(q->fq);
++      q->fq = NULL;
+       return NULL;
+ }
+ EXPORT_SYMBOL(blk_init_allocated_queue);
+diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
+index b2756765950e..fe47c924dc64 100644
+--- a/drivers/atm/iphase.c
++++ b/drivers/atm/iphase.c
+@@ -63,6 +63,7 @@
+ #include <asm/byteorder.h>  
+ #include <linux/vmalloc.h>
+ #include <linux/jiffies.h>
++#include <linux/nospec.h>
+ #include "iphase.h"             
+ #include "suni.h"               
+ #define swap_byte_order(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8))
+@@ -2760,8 +2761,11 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int 
cmd, void __user *arg)
+    }
+    if (copy_from_user(&ia_cmds, arg, sizeof ia_cmds)) return -EFAULT; 
+    board = ia_cmds.status;
+-   if ((board < 0) || (board > iadev_count))
+-         board = 0;    
++
++      if ((board < 0) || (board > iadev_count))
++              board = 0;
++      board = array_index_nospec(board, iadev_count + 1);
++
+    iadev = ia_dev[board];
+    switch (ia_cmds.cmd) {
+    case MEMDUMP:
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 6f4c84d824e6..25c006338100 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -509,6 +509,7 @@
+ #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A 0x0a4a
+ #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A 0x0b4a
+ #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE                0x134a
++#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641   0x0641
+ 
+ #define USB_VENDOR_ID_HUION           0x256c
+ #define USB_DEVICE_ID_HUION_TABLET    0x006e
+diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
+index 617ae294a318..e851926be8b0 100644
+--- a/drivers/hid/usbhid/hid-quirks.c
++++ b/drivers/hid/usbhid/hid-quirks.c
+@@ -98,6 +98,7 @@ static const struct hid_blacklist {
+       { USB_VENDOR_ID_HP, 
USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL },
+       { USB_VENDOR_ID_HP, 
USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL },
+       { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, 
HID_QUIRK_ALWAYS_POLL },
++      { USB_VENDOR_ID_HP, 
USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641, HID_QUIRK_ALWAYS_POLL },
+       { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, 
HID_QUIRK_ALWAYS_POLL },
+       { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS, 
HID_QUIRK_NOGET },
+       { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C01A, 
HID_QUIRK_ALWAYS_POLL },
+diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
+index b1ad378cb2a6..6c3bf8846b52 100644
+--- a/drivers/hid/wacom_wac.c
++++ b/drivers/hid/wacom_wac.c
+@@ -529,14 +529,14 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
+                */
+               buttons = (data[4] << 1) | (data[3] & 0x01);
+       } else if (features->type == CINTIQ_COMPANION_2) {
+-              /* d-pad right  -> data[4] & 0x10
+-               * d-pad up     -> data[4] & 0x20
+-               * d-pad left   -> data[4] & 0x40
+-               * d-pad down   -> data[4] & 0x80
+-               * d-pad center -> data[3] & 0x01
++              /* d-pad right  -> data[2] & 0x10
++               * d-pad up     -> data[2] & 0x20
++               * d-pad left   -> data[2] & 0x40
++               * d-pad down   -> data[2] & 0x80
++               * d-pad center -> data[1] & 0x01
+                */
+               buttons = ((data[2] >> 4) << 7) |
+-                        ((data[1] & 0x04) << 6) |
++                        ((data[1] & 0x04) << 4) |
+                         ((data[2] & 0x0F) << 2) |
+                         (data[1] & 0x03);
+       } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) {
+diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
+index 978b8d94f9a4..1baa25e82bdd 100644
+--- a/drivers/infiniband/core/addr.c
++++ b/drivers/infiniband/core/addr.c
+@@ -735,14 +735,13 @@ int rdma_addr_find_l2_eth_by_grh(const union ib_gid 
*sgid,
+       struct net_device *dev;
+ 
+       union {
+-              struct sockaddr     _sockaddr;
+               struct sockaddr_in  _sockaddr_in;
+               struct sockaddr_in6 _sockaddr_in6;
+       } sgid_addr, dgid_addr;
+ 
+ 
+-      rdma_gid2ip(&sgid_addr._sockaddr, sgid);
+-      rdma_gid2ip(&dgid_addr._sockaddr, dgid);
++      rdma_gid2ip((struct sockaddr *)&sgid_addr, sgid);
++      rdma_gid2ip((struct sockaddr *)&dgid_addr, dgid);
+ 
+       memset(&dev_addr, 0, sizeof(dev_addr));
+       if (if_index)
+@@ -751,8 +750,9 @@ int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid,
+ 
+       ctx.addr = &dev_addr;
+       init_completion(&ctx.comp);
+-      ret = rdma_resolve_ip(&self, &sgid_addr._sockaddr, &dgid_addr._sockaddr,
+-                      &dev_addr, 1000, resolve_cb, &ctx);
++      ret = rdma_resolve_ip(&self, (struct sockaddr *)&sgid_addr,
++                            (struct sockaddr *)&dgid_addr, &dev_addr, 1000,
++                            resolve_cb, &ctx);
+       if (ret)
+               return ret;
+ 
+@@ -782,16 +782,15 @@ int rdma_addr_find_smac_by_sgid(union ib_gid *sgid, u8 
*smac, u16 *vlan_id)
+       int ret = 0;
+       struct rdma_dev_addr dev_addr;
+       union {
+-              struct sockaddr     _sockaddr;
+               struct sockaddr_in  _sockaddr_in;
+               struct sockaddr_in6 _sockaddr_in6;
+       } gid_addr;
+ 
+-      rdma_gid2ip(&gid_addr._sockaddr, sgid);
++      rdma_gid2ip((struct sockaddr *)&gid_addr, sgid);
+ 
+       memset(&dev_addr, 0, sizeof(dev_addr));
+       dev_addr.net = &init_net;
+-      ret = rdma_translate_ip(&gid_addr._sockaddr, &dev_addr, vlan_id);
++      ret = rdma_translate_ip((struct sockaddr *)&gid_addr, &dev_addr, 
vlan_id);
+       if (ret)
+               return ret;
+ 
+diff --git a/drivers/infiniband/core/sa_query.c 
b/drivers/infiniband/core/sa_query.c
+index 4baf3b864a57..5879a06ada93 100644
+--- a/drivers/infiniband/core/sa_query.c
++++ b/drivers/infiniband/core/sa_query.c
+@@ -1109,7 +1109,6 @@ int ib_init_ah_from_path(struct ib_device *device, u8 
port_num,
+                                                .net = rec->net ? rec->net :
+                                                        &init_net};
+               union {
+-                      struct sockaddr     _sockaddr;
+                       struct sockaddr_in  _sockaddr_in;
+                       struct sockaddr_in6 _sockaddr_in6;
+               } sgid_addr, dgid_addr;
+@@ -1117,12 +1116,13 @@ int ib_init_ah_from_path(struct ib_device *device, u8 
port_num,
+               if (!device->get_netdev)
+                       return -EOPNOTSUPP;
+ 
+-              rdma_gid2ip(&sgid_addr._sockaddr, &rec->sgid);
+-              rdma_gid2ip(&dgid_addr._sockaddr, &rec->dgid);
++              rdma_gid2ip((struct sockaddr *)&sgid_addr, &rec->sgid);
++              rdma_gid2ip((struct sockaddr *)&dgid_addr, &rec->dgid);
+ 
+               /* validate the route */
+-              ret = rdma_resolve_ip_route(&sgid_addr._sockaddr,
+-                                          &dgid_addr._sockaddr, &dev_addr);
++              ret = rdma_resolve_ip_route((struct sockaddr *)&sgid_addr,
++                                          (struct sockaddr *)&dgid_addr,
++                                          &dev_addr);
+               if (ret)
+                       return ret;
+ 
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c 
b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
+index 797362a297b2..35efd40ba47f 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
+@@ -82,7 +82,6 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct 
ocrdma_ah *ah,
+       u8 nxthdr = 0x11;
+       struct iphdr ipv4;
+       union {
+-              struct sockaddr     _sockaddr;
+               struct sockaddr_in  _sockaddr_in;
+               struct sockaddr_in6 _sockaddr_in6;
+       } sgid_addr, dgid_addr;
+@@ -131,9 +130,9 @@ static inline int set_av_attr(struct ocrdma_dev *dev, 
struct ocrdma_ah *ah,
+               ipv4.tot_len = htons(0);
+               ipv4.ttl = attr->grh.hop_limit;
+               ipv4.protocol = nxthdr;
+-              rdma_gid2ip(&sgid_addr._sockaddr, sgid);
++              rdma_gid2ip((struct sockaddr *)&sgid_addr, sgid);
+               ipv4.saddr = sgid_addr._sockaddr_in.sin_addr.s_addr;
+-              rdma_gid2ip(&dgid_addr._sockaddr, &attr->grh.dgid);
++              rdma_gid2ip((struct sockaddr *)&dgid_addr, &attr->grh.dgid);
+               ipv4.daddr = dgid_addr._sockaddr_in.sin_addr.s_addr;
+               memcpy((u8 *)ah->av + eth_sz, &ipv4, sizeof(struct iphdr));
+       } else {
+diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c 
b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+index 67fc0b6857e1..edfa22847724 100644
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+@@ -2505,7 +2505,6 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp,
+       u32 vlan_id = 0xFFFF;
+       u8 mac_addr[6], hdr_type;
+       union {
+-              struct sockaddr     _sockaddr;
+               struct sockaddr_in  _sockaddr_in;
+               struct sockaddr_in6 _sockaddr_in6;
+       } sgid_addr, dgid_addr;
+@@ -2550,8 +2549,8 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp,
+ 
+       hdr_type = ib_gid_to_network_type(sgid_attr.gid_type, &sgid);
+       if (hdr_type == RDMA_NETWORK_IPV4) {
+-              rdma_gid2ip(&sgid_addr._sockaddr, &sgid);
+-              rdma_gid2ip(&dgid_addr._sockaddr, &ah_attr->grh.dgid);
++              rdma_gid2ip((struct sockaddr *)&sgid_addr, &sgid);
++              rdma_gid2ip((struct sockaddr *)&dgid_addr, &ah_attr->grh.dgid);
+               memcpy(&cmd->params.dgid[0],
+                      &dgid_addr._sockaddr_in.sin_addr.s_addr, 4);
+               memcpy(&cmd->params.sgid[0],
+diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c 
b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+index 6167bb0c71ed..53a71166e784 100644
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+@@ -1939,7 +1939,7 @@ u16 bnx2x_select_queue(struct net_device *dev, struct 
sk_buff *skb,
+       }
+ 
+       /* select a non-FCoE queue */
+-      return fallback(dev, skb) % (BNX2X_NUM_ETH_QUEUES(bp) * bp->max_cos);
++      return fallback(dev, skb) % (BNX2X_NUM_ETH_QUEUES(bp));
+ }
+ 
+ void bnx2x_set_num_queues(struct bnx2x *bp)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dev.c 
b/drivers/net/ethernet/mellanox/mlx5/core/dev.c
+index 524fff2b3dc6..2e6d6dfdcc80 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/dev.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/dev.c
+@@ -207,7 +207,7 @@ void mlx5_unregister_device(struct mlx5_core_dev *dev)
+       struct mlx5_interface *intf;
+ 
+       mutex_lock(&mlx5_intf_mutex);
+-      list_for_each_entry(intf, &intf_list, list)
++      list_for_each_entry_reverse(intf, &intf_list, list)
+               mlx5_remove_device(intf, priv);
+       list_del(&priv->dev_list);
+       mutex_unlock(&mlx5_intf_mutex);
+diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
+index 8c93ed5c9763..fa8f7c40a384 100644
+--- a/drivers/net/ppp/pppoe.c
++++ b/drivers/net/ppp/pppoe.c
+@@ -1134,6 +1134,9 @@ static const struct proto_ops pppoe_ops = {
+       .recvmsg        = pppoe_recvmsg,
+       .mmap           = sock_no_mmap,
+       .ioctl          = pppox_ioctl,
++#ifdef CONFIG_COMPAT
++      .compat_ioctl   = pppox_compat_ioctl,
++#endif
+ };
+ 
+ static const struct pppox_proto pppoe_proto = {
+diff --git a/drivers/net/ppp/pppox.c b/drivers/net/ppp/pppox.c
+index b9c8be6283d3..50856f9fe08a 100644
+--- a/drivers/net/ppp/pppox.c
++++ b/drivers/net/ppp/pppox.c
+@@ -22,6 +22,7 @@
+ #include <linux/string.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
++#include <linux/compat.h>
+ #include <linux/errno.h>
+ #include <linux/netdevice.h>
+ #include <linux/net.h>
+@@ -103,6 +104,18 @@ int pppox_ioctl(struct socket *sock, unsigned int cmd, 
unsigned long arg)
+ 
+ EXPORT_SYMBOL(pppox_ioctl);
+ 
++#ifdef CONFIG_COMPAT
++int pppox_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long 
arg)
++{
++      if (cmd == PPPOEIOCSFWD32)
++              cmd = PPPOEIOCSFWD;
++
++      return pppox_ioctl(sock, cmd, (unsigned long)compat_ptr(arg));
++}
++
++EXPORT_SYMBOL(pppox_compat_ioctl);
++#endif
++
+ static int pppox_create(struct net *net, struct socket *sock, int protocol,
+                       int kern)
+ {
+diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
+index 5a8befdfa5e4..fa14a67fb09a 100644
+--- a/drivers/net/ppp/pptp.c
++++ b/drivers/net/ppp/pptp.c
+@@ -638,6 +638,9 @@ static const struct proto_ops pptp_ops = {
+       .recvmsg    = sock_no_recvmsg,
+       .mmap       = sock_no_mmap,
+       .ioctl      = pppox_ioctl,
++#ifdef CONFIG_COMPAT
++      .compat_ioctl = pppox_compat_ioctl,
++#endif
+ };
+ 
+ static const struct pppox_proto pppox_pptp_proto = {
+diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c
+index cc3994d4e7bc..3c2f34db937b 100644
+--- a/drivers/scsi/fcoe/fcoe_ctlr.c
++++ b/drivers/scsi/fcoe/fcoe_ctlr.c
+@@ -1984,7 +1984,7 @@ EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac);
+  */
+ static inline struct fcoe_rport *fcoe_ctlr_rport(struct fc_rport_priv *rdata)
+ {
+-      return (struct fcoe_rport *)(rdata + 1);
++      return container_of(rdata, struct fcoe_rport, rdata);
+ }
+ 
+ /**
+@@ -2244,7 +2244,7 @@ static void fcoe_ctlr_vn_start(struct fcoe_ctlr *fip)
+  */
+ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip,
+                             struct sk_buff *skb,
+-                            struct fc_rport_priv *rdata)
++                            struct fcoe_rport *frport)
+ {
+       struct fip_header *fiph;
+       struct fip_desc *desc = NULL;
+@@ -2252,16 +2252,12 @@ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip,
+       struct fip_wwn_desc *wwn = NULL;
+       struct fip_vn_desc *vn = NULL;
+       struct fip_size_desc *size = NULL;
+-      struct fcoe_rport *frport;
+       size_t rlen;
+       size_t dlen;
+       u32 desc_mask = 0;
+       u32 dtype;
+       u8 sub;
+ 
+-      memset(rdata, 0, sizeof(*rdata) + sizeof(*frport));
+-      frport = fcoe_ctlr_rport(rdata);
+-
+       fiph = (struct fip_header *)skb->data;
+       frport->flags = ntohs(fiph->fip_flags);
+ 
+@@ -2324,15 +2320,17 @@ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip,
+                       if (dlen != sizeof(struct fip_wwn_desc))
+                               goto len_err;
+                       wwn = (struct fip_wwn_desc *)desc;
+-                      rdata->ids.node_name = get_unaligned_be64(&wwn->fd_wwn);
++                      frport->rdata.ids.node_name =
++                              get_unaligned_be64(&wwn->fd_wwn);
+                       break;
+               case FIP_DT_VN_ID:
+                       if (dlen != sizeof(struct fip_vn_desc))
+                               goto len_err;
+                       vn = (struct fip_vn_desc *)desc;
+                       memcpy(frport->vn_mac, vn->fd_mac, ETH_ALEN);
+-                      rdata->ids.port_id = ntoh24(vn->fd_fc_id);
+-                      rdata->ids.port_name = get_unaligned_be64(&vn->fd_wwpn);
++                      frport->rdata.ids.port_id = ntoh24(vn->fd_fc_id);
++                      frport->rdata.ids.port_name =
++                              get_unaligned_be64(&vn->fd_wwpn);
+                       break;
+               case FIP_DT_FC4F:
+                       if (dlen != sizeof(struct fip_fc4_feat))
+@@ -2670,16 +2668,13 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, 
struct sk_buff *skb)
+ {
+       struct fip_header *fiph;
+       enum fip_vn2vn_subcode sub;
+-      struct {
+-              struct fc_rport_priv rdata;
+-              struct fcoe_rport frport;
+-      } buf;
++      struct fcoe_rport frport = { };
+       int rc;
+ 
+       fiph = (struct fip_header *)skb->data;
+       sub = fiph->fip_subcode;
+ 
+-      rc = fcoe_ctlr_vn_parse(fip, skb, &buf.rdata);
++      rc = fcoe_ctlr_vn_parse(fip, skb, &frport);
+       if (rc) {
+               LIBFCOE_FIP_DBG(fip, "vn_recv vn_parse error %d\n", rc);
+               goto drop;
+@@ -2688,19 +2683,19 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, 
struct sk_buff *skb)
+       mutex_lock(&fip->ctlr_mutex);
+       switch (sub) {
+       case FIP_SC_VN_PROBE_REQ:
+-              fcoe_ctlr_vn_probe_req(fip, &buf.rdata);
++              fcoe_ctlr_vn_probe_req(fip, &frport.rdata);
+               break;
+       case FIP_SC_VN_PROBE_REP:
+-              fcoe_ctlr_vn_probe_reply(fip, &buf.rdata);
++              fcoe_ctlr_vn_probe_reply(fip, &frport.rdata);
+               break;
+       case FIP_SC_VN_CLAIM_NOTIFY:
+-              fcoe_ctlr_vn_claim_notify(fip, &buf.rdata);
++              fcoe_ctlr_vn_claim_notify(fip, &frport.rdata);
+               break;
+       case FIP_SC_VN_CLAIM_REP:
+-              fcoe_ctlr_vn_claim_resp(fip, &buf.rdata);
++              fcoe_ctlr_vn_claim_resp(fip, &frport.rdata);
+               break;
+       case FIP_SC_VN_BEACON:
+-              fcoe_ctlr_vn_beacon(fip, &buf.rdata);
++              fcoe_ctlr_vn_beacon(fip, &frport.rdata);
+               break;
+       default:
+               LIBFCOE_FIP_DBG(fip, "vn_recv unknown subcode %d\n", sub);
+@@ -2724,22 +2719,18 @@ drop:
+  */
+ static int fcoe_ctlr_vlan_parse(struct fcoe_ctlr *fip,
+                             struct sk_buff *skb,
+-                            struct fc_rport_priv *rdata)
++                            struct fcoe_rport *frport)
+ {
+       struct fip_header *fiph;
+       struct fip_desc *desc = NULL;
+       struct fip_mac_desc *macd = NULL;
+       struct fip_wwn_desc *wwn = NULL;
+-      struct fcoe_rport *frport;
+       size_t rlen;
+       size_t dlen;
+       u32 desc_mask = 0;
+       u32 dtype;
+       u8 sub;
+ 
+-      memset(rdata, 0, sizeof(*rdata) + sizeof(*frport));
+-      frport = fcoe_ctlr_rport(rdata);
+-
+       fiph = (struct fip_header *)skb->data;
+       frport->flags = ntohs(fiph->fip_flags);
+ 
+@@ -2793,7 +2784,8 @@ static int fcoe_ctlr_vlan_parse(struct fcoe_ctlr *fip,
+                       if (dlen != sizeof(struct fip_wwn_desc))
+                               goto len_err;
+                       wwn = (struct fip_wwn_desc *)desc;
+-                      rdata->ids.node_name = get_unaligned_be64(&wwn->fd_wwn);
++                      frport->rdata.ids.node_name =
++                              get_unaligned_be64(&wwn->fd_wwn);
+                       break;
+               default:
+                       LIBFCOE_FIP_DBG(fip, "unexpected descriptor type %x "
+@@ -2904,22 +2896,19 @@ static int fcoe_ctlr_vlan_recv(struct fcoe_ctlr *fip, 
struct sk_buff *skb)
+ {
+       struct fip_header *fiph;
+       enum fip_vlan_subcode sub;
+-      struct {
+-              struct fc_rport_priv rdata;
+-              struct fcoe_rport frport;
+-      } buf;
++      struct fcoe_rport frport = { };
+       int rc;
+ 
+       fiph = (struct fip_header *)skb->data;
+       sub = fiph->fip_subcode;
+-      rc = fcoe_ctlr_vlan_parse(fip, skb, &buf.rdata);
++      rc = fcoe_ctlr_vlan_parse(fip, skb, &frport);
+       if (rc) {
+               LIBFCOE_FIP_DBG(fip, "vlan_recv vlan_parse error %d\n", rc);
+               goto drop;
+       }
+       mutex_lock(&fip->ctlr_mutex);
+       if (sub == FIP_SC_VL_REQ)
+-              fcoe_ctlr_vlan_disc_reply(fip, &buf.rdata);
++              fcoe_ctlr_vlan_disc_reply(fip, &frport.rdata);
+       mutex_unlock(&fip->ctlr_mutex);
+ 
+ drop:
+diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
+index 97aeaddd600d..70e2958a69a0 100644
+--- a/drivers/scsi/libfc/fc_rport.c
++++ b/drivers/scsi/libfc/fc_rport.c
+@@ -127,12 +127,15 @@ static struct fc_rport_priv *fc_rport_create(struct 
fc_lport *lport,
+                                            u32 port_id)
+ {
+       struct fc_rport_priv *rdata;
++      size_t rport_priv_size = sizeof(*rdata);
+ 
+       rdata = lport->tt.rport_lookup(lport, port_id);
+       if (rdata)
+               return rdata;
+ 
+-      rdata = kzalloc(sizeof(*rdata) + lport->rport_priv_size, GFP_KERNEL);
++      if (lport->rport_priv_size > 0)
++              rport_priv_size = lport->rport_priv_size;
++      rdata = kzalloc(rport_priv_size, GFP_KERNEL);
+       if (!rdata)
+               return NULL;
+ 
+diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
+index 25abf2d1732a..eab27d41ba83 100644
+--- a/drivers/spi/spi-bcm2835.c
++++ b/drivers/spi/spi-bcm2835.c
+@@ -554,7 +554,8 @@ static int bcm2835_spi_transfer_one(struct spi_master 
*master,
+       bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv);
+ 
+       /* handle all the 3-wire mode */
+-      if ((spi->mode & SPI_3WIRE) && (tfr->rx_buf))
++      if (spi->mode & SPI_3WIRE && tfr->rx_buf &&
++          tfr->rx_buf != master->dummy_rx)
+               cs |= BCM2835_SPI_CS_REN;
+       else
+               cs &= ~BCM2835_SPI_CS_REN;
+diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
+index 93c8e4a4bbd3..4b7da4409c60 100644
+--- a/fs/compat_ioctl.c
++++ b/fs/compat_ioctl.c
+@@ -1038,9 +1038,6 @@ COMPATIBLE_IOCTL(PPPIOCDISCONN)
+ COMPATIBLE_IOCTL(PPPIOCATTCHAN)
+ COMPATIBLE_IOCTL(PPPIOCGCHAN)
+ COMPATIBLE_IOCTL(PPPIOCGL2TPSTATS)
+-/* PPPOX */
+-COMPATIBLE_IOCTL(PPPOEIOCSFWD)
+-COMPATIBLE_IOCTL(PPPOEIOCDFWD)
+ /* Big A */
+ /* sparc only */
+ /* Big Q for sound/OSS */
+diff --git a/include/linux/ceph/ceph_debug.h b/include/linux/ceph/ceph_debug.h
+index aa2e19182d99..51c5bd64bd00 100644
+--- a/include/linux/ceph/ceph_debug.h
++++ b/include/linux/ceph/ceph_debug.h
+@@ -3,6 +3,8 @@
+ 
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+ 
++#include <linux/string.h>
++
+ #ifdef CONFIG_CEPH_LIB_PRETTYDEBUG
+ 
+ /*
+@@ -12,12 +14,10 @@
+  */
+ 
+ # if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
+-extern const char *ceph_file_part(const char *s, int len);
+ #  define dout(fmt, ...)                                              \
+       pr_debug("%.*s %12.12s:%-4d : " fmt,                            \
+                8 - (int)sizeof(KBUILD_MODNAME), "    ",               \
+-               ceph_file_part(__FILE__, sizeof(__FILE__)),            \
+-               __LINE__, ##__VA_ARGS__)
++               kbasename(__FILE__), __LINE__, ##__VA_ARGS__)
+ # else
+ /* faux printk call just to see any compiler warnings. */
+ #  define dout(fmt, ...)      do {                            \
+diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h
+index ba7a9b0c7c57..24e9b360da65 100644
+--- a/include/linux/if_pppox.h
++++ b/include/linux/if_pppox.h
+@@ -84,6 +84,9 @@ extern int register_pppox_proto(int proto_num, const struct 
pppox_proto *pp);
+ extern void unregister_pppox_proto(int proto_num);
+ extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding 
*/
+ extern int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long 
arg);
++extern int pppox_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned 
long arg);
++
++#define PPPOEIOCSFWD32    _IOW(0xB1 ,0, compat_size_t)
+ 
+ /* PPPoX socket states */
+ enum {
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index 1eda31f7f013..a474213ca015 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -1595,6 +1595,23 @@ static inline void tcp_check_send_head(struct sock *sk, 
struct sk_buff *skb_unli
+               tcp_sk(sk)->highest_sack = NULL;
+ }
+ 
++static inline struct sk_buff *tcp_rtx_queue_head(const struct sock *sk)
++{
++      struct sk_buff *skb = tcp_write_queue_head(sk);
++
++      if (skb == tcp_send_head(sk))
++              skb = NULL;
++
++      return skb;
++}
++
++static inline struct sk_buff *tcp_rtx_queue_tail(const struct sock *sk)
++{
++      struct sk_buff *skb = tcp_send_head(sk);
++
++      return skb ? tcp_write_queue_prev(sk, skb) : tcp_write_queue_tail(sk);
++}
++
+ static inline void __tcp_add_write_queue_tail(struct sock *sk, struct sk_buff 
*skb)
+ {
+       __skb_queue_tail(&sk->sk_write_queue, skb);
+diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
+index 722d3264d3bf..6be92eede5c0 100644
+--- a/include/scsi/libfcoe.h
++++ b/include/scsi/libfcoe.h
+@@ -241,6 +241,7 @@ struct fcoe_fcf {
+  * @vn_mac:   VN_Node assigned MAC address for data
+  */
+ struct fcoe_rport {
++      struct fc_rport_priv rdata;
+       unsigned long time;
+       u16 fcoe_len;
+       u16 flags;
+diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
+index 3626174456b7..80c81c7e3cf9 100644
+--- a/net/bridge/br_multicast.c
++++ b/net/bridge/br_multicast.c
+@@ -1489,6 +1489,9 @@ br_multicast_leave_group(struct net_bridge *br,
+                       if (p->port != port)
+                               continue;
+ 
++                      if (p->flags & MDB_PG_FLAGS_PERMANENT)
++                              break;
++
+                       rcu_assign_pointer(*pp, p->next);
+                       hlist_del_init(&p->mglist);
+                       del_timer(&p->timer);
+diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
+index b6de4f457161..5172caac645c 100644
+--- a/net/bridge/br_vlan.c
++++ b/net/bridge/br_vlan.c
+@@ -622,6 +622,11 @@ void br_vlan_flush(struct net_bridge *br)
+ 
+       ASSERT_RTNL();
+ 
++      /* delete auto-added default pvid local fdb before flushing vlans
++       * otherwise it will be leaked on bridge device init failure
++       */
++      br_fdb_delete_by_port(br, NULL, 0, 1);
++
+       vg = br_vlan_group(br);
+       __vlan_flush(vg);
+       RCU_INIT_POINTER(br->vlgrp, NULL);
+diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
+index bf0294cf4d22..18c4b34bd6e0 100644
+--- a/net/ceph/ceph_common.c
++++ b/net/ceph/ceph_common.c
+@@ -45,19 +45,6 @@ bool libceph_compatible(void *data)
+ }
+ EXPORT_SYMBOL(libceph_compatible);
+ 
+-/*
+- * find filename portion of a path (/foo/bar/baz -> baz)
+- */
+-const char *ceph_file_part(const char *s, int len)
+-{
+-      const char *e = s + len;
+-
+-      while (e != s && *(e-1) != '/')
+-              e--;
+-      return e;
+-}
+-EXPORT_SYMBOL(ceph_file_part);
+-
+ const char *ceph_msg_type_name(int type)
+ {
+       switch (type) {
+diff --git a/net/core/dev.c b/net/core/dev.c
+index f693afe608d7..08bcbce16e12 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -8296,6 +8296,8 @@ static void __net_exit default_device_exit(struct net 
*net)
+ 
+               /* Push remaining network devices to init_net */
+               snprintf(fb_name, IFNAMSIZ, "dev%d", dev->ifindex);
++              if (__dev_get_by_name(&init_net, fb_name))
++                      snprintf(fb_name, IFNAMSIZ, "dev%%d");
+               err = dev_change_net_namespace(dev, &init_net, fb_name);
+               if (err) {
+                       pr_emerg("%s: failed to move %s to init_net: %d\n",
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 0c195b0f4216..9ddb05b98312 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -1175,6 +1175,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, 
u32 len,
+       struct tcp_sock *tp = tcp_sk(sk);
+       struct sk_buff *buff;
+       int nsize, old_factor;
++      long limit;
+       int nlen;
+       u8 flags;
+ 
+@@ -1185,7 +1186,15 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, 
u32 len,
+       if (nsize < 0)
+               nsize = 0;
+ 
+-      if (unlikely((sk->sk_wmem_queued >> 1) > sk->sk_sndbuf + 0x20000)) {
++      /* tcp_sendmsg() can overshoot sk_wmem_queued by one full size skb.
++       * We need some allowance to not penalize applications setting small
++       * SO_SNDBUF values.
++       * Also allow first and last skb in retransmit queue to be split.
++       */
++      limit = sk->sk_sndbuf + 2 * SKB_TRUESIZE(GSO_MAX_SIZE);
++      if (unlikely((sk->sk_wmem_queued >> 1) > limit &&
++                   skb != tcp_rtx_queue_head(sk) &&
++                   skb != tcp_rtx_queue_tail(sk))) {
+               NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPWQUEUETOOBIG);
+               return -ENOMEM;
+       }
+diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
+index 42f363661d25..cc28b8646986 100644
+--- a/net/ipv6/ip6_tunnel.c
++++ b/net/ipv6/ip6_tunnel.c
+@@ -1275,11 +1275,11 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device 
*dev)
+                       fl6.flowi6_mark = skb->mark;
+       }
+ 
++      dsfield = INET_ECN_encapsulate(dsfield, ipv4_get_dsfield(iph));
++
+       if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6))
+               return -1;
+ 
+-      dsfield = INET_ECN_encapsulate(dsfield, ipv4_get_dsfield(iph));
+-
+       skb_set_inner_ipproto(skb, IPPROTO_IPIP);
+ 
+       err = ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu,
+@@ -1362,11 +1362,11 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device 
*dev)
+                       fl6.flowi6_mark = skb->mark;
+       }
+ 
++      dsfield = INET_ECN_encapsulate(dsfield, ipv6_get_dsfield(ipv6h));
++
+       if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6))
+               return -1;
+ 
+-      dsfield = INET_ECN_encapsulate(dsfield, ipv6_get_dsfield(ipv6h));
+-
+       skb_set_inner_ipproto(skb, IPPROTO_IPV6);
+ 
+       err = ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu,
+diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
+index 9b214f313cc0..16b63e60396f 100644
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -1790,6 +1790,9 @@ static const struct proto_ops pppol2tp_ops = {
+       .recvmsg        = pppol2tp_recvmsg,
+       .mmap           = sock_no_mmap,
+       .ioctl          = pppox_ioctl,
++#ifdef CONFIG_COMPAT
++      .compat_ioctl = pppox_compat_ioctl,
++#endif
+ };
+ 
+ static const struct pppox_proto pppol2tp_proto = {
+diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
+index d2932dc4c83d..36e4dcdac8dc 100644
+--- a/net/sched/act_ife.c
++++ b/net/sched/act_ife.c
+@@ -477,6 +477,9 @@ static int tcf_ife_init(struct net *net, struct nlattr 
*nla,
+       int ret = 0;
+       int err;
+ 
++      if (!nla)
++              return -EINVAL;
++
+       err = nla_parse_nested(tb, TCA_IFE_MAX, nla, ife_policy);
+       if (err < 0)
+               return err;
+diff --git a/net/sched/sch_codel.c b/net/sched/sch_codel.c
+index 5bfa79ee657c..17a0838f8074 100644
+--- a/net/sched/sch_codel.c
++++ b/net/sched/sch_codel.c
+@@ -71,10 +71,10 @@ static struct sk_buff *dequeue_func(struct codel_vars 
*vars, void *ctx)
+       struct Qdisc *sch = ctx;
+       struct sk_buff *skb = __qdisc_dequeue_head(&sch->q);
+ 
+-      if (skb)
++      if (skb) {
+               sch->qstats.backlog -= qdisc_pkt_len(skb);
+-
+-      prefetch(&skb->end); /* we'll need skb_shinfo() */
++              prefetch(&skb->end); /* we'll need skb_shinfo() */
++      }
+       return skb;
+ }
+ 
+diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
+index b7c539a51da3..63a913b23873 100644
+--- a/net/tipc/netlink_compat.c
++++ b/net/tipc/netlink_compat.c
+@@ -55,6 +55,7 @@ struct tipc_nl_compat_msg {
+       int rep_type;
+       int rep_size;
+       int req_type;
++      int req_size;
+       struct net *net;
+       struct sk_buff *rep;
+       struct tlv_desc *req;
+@@ -252,7 +253,8 @@ static int tipc_nl_compat_dumpit(struct 
tipc_nl_compat_cmd_dump *cmd,
+       int err;
+       struct sk_buff *arg;
+ 
+-      if (msg->req_type && !TLV_CHECK_TYPE(msg->req, msg->req_type))
++      if (msg->req_type && (!msg->req_size ||
++                            !TLV_CHECK_TYPE(msg->req, msg->req_type)))
+               return -EINVAL;
+ 
+       msg->rep = tipc_tlv_alloc(msg->rep_size);
+@@ -345,7 +347,8 @@ static int tipc_nl_compat_doit(struct 
tipc_nl_compat_cmd_doit *cmd,
+ {
+       int err;
+ 
+-      if (msg->req_type && !TLV_CHECK_TYPE(msg->req, msg->req_type))
++      if (msg->req_type && (!msg->req_size ||
++                            !TLV_CHECK_TYPE(msg->req, msg->req_type)))
+               return -EINVAL;
+ 
+       err = __tipc_nl_compat_doit(cmd, msg);
+@@ -1267,8 +1270,8 @@ static int tipc_nl_compat_recv(struct sk_buff *skb, 
struct genl_info *info)
+               goto send;
+       }
+ 
+-      len = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN);
+-      if (!len || !TLV_OK(msg.req, len)) {
++      msg.req_size = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN);
++      if (msg.req_size && !TLV_OK(msg.req, msg.req_size)) {
+               msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED);
+               err = -EOPNOTSUPP;
+               goto send;
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index 95326c6a7a24..09782ff427d0 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -165,6 +165,8 @@ static int __dead_end_function(struct objtool_file *file, 
struct symbol *func,
+               "__reiserfs_panic",
+               "lbug_with_loc",
+               "fortify_panic",
++              "machine_real_restart",
++              "rewind_stack_do_exit",
+       };
+ 
+       if (func->bind == STB_WEAK)

Reply via email to