diff options
author | Mike Pagano <mpagano@gentoo.org> | 2019-08-11 06:59:36 -0400 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2019-08-11 06:59:36 -0400 |
commit | 9be44d2876e04a79365ed86a6cc3fb1ed9c3b492 (patch) | |
tree | 4c2b610651f0e8fb1670b55ca0f4b9b37b2ae55b | |
parent | Linux patch 4.9.188 (diff) | |
download | linux-patches-9be44d2876e04a79365ed86a6cc3fb1ed9c3b492.tar.gz linux-patches-9be44d2876e04a79365ed86a6cc3fb1ed9c3b492.tar.bz2 linux-patches-9be44d2876e04a79365ed86a6cc3fb1ed9c3b492.zip |
Linux patch 4.9.1894.9-194
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1188_linux-4.9.189.patch | 1396 |
2 files changed, 1400 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 6e9f4e5f..06f57156 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 00000000..3707b770 --- /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) |