diff options
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1016_linux-5.0.17.patch | 5008 |
2 files changed, 5012 insertions, 0 deletions
diff --git a/0000_README b/0000_README index b19b3881..d6075dfe 100644 --- a/0000_README +++ b/0000_README @@ -107,6 +107,10 @@ Patch: 1015_linux-5.0.16.patch From: http://www.kernel.org Desc: Linux 5.0.16 +Patch: 1016_linux-5.0.17.patch +From: http://www.kernel.org +Desc: Linux 5.0.17 + 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/1016_linux-5.0.17.patch b/1016_linux-5.0.17.patch new file mode 100644 index 00000000..0bdb22be --- /dev/null +++ b/1016_linux-5.0.17.patch @@ -0,0 +1,5008 @@ +diff --git a/Documentation/devicetree/bindings/net/davinci_emac.txt b/Documentation/devicetree/bindings/net/davinci_emac.txt +index 24c5cdaba8d2..ca83dcc84fb8 100644 +--- a/Documentation/devicetree/bindings/net/davinci_emac.txt ++++ b/Documentation/devicetree/bindings/net/davinci_emac.txt +@@ -20,6 +20,8 @@ Required properties: + Optional properties: + - phy-handle: See ethernet.txt file in the same directory. + If absent, davinci_emac driver defaults to 100/FULL. ++- nvmem-cells: phandle, reference to an nvmem node for the MAC address ++- nvmem-cell-names: string, should be "mac-address" if nvmem is to be used + - ti,davinci-rmii-en: 1 byte, 1 means use RMII + - ti,davinci-no-bd-ram: boolean, does EMAC have BD RAM? + +diff --git a/Documentation/devicetree/bindings/net/ethernet.txt b/Documentation/devicetree/bindings/net/ethernet.txt +index cfc376bc977a..2974e63ba311 100644 +--- a/Documentation/devicetree/bindings/net/ethernet.txt ++++ b/Documentation/devicetree/bindings/net/ethernet.txt +@@ -10,8 +10,6 @@ Documentation/devicetree/bindings/phy/phy-bindings.txt. + the boot program; should be used in cases where the MAC address assigned to + the device by the boot program is different from the "local-mac-address" + property; +-- nvmem-cells: phandle, reference to an nvmem node for the MAC address; +-- nvmem-cell-names: string, should be "mac-address" if nvmem is to be used; + - max-speed: number, specifies maximum speed in Mbit/s supported by the device; + - max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than + the maximum frame size (there's contradiction in the Devicetree +diff --git a/Documentation/devicetree/bindings/net/macb.txt b/Documentation/devicetree/bindings/net/macb.txt +index 3e17ac1d5d58..1a914116f4c2 100644 +--- a/Documentation/devicetree/bindings/net/macb.txt ++++ b/Documentation/devicetree/bindings/net/macb.txt +@@ -26,6 +26,10 @@ Required properties: + Optional elements: 'tsu_clk' + - clocks: Phandles to input clocks. + ++Optional properties: ++- nvmem-cells: phandle, reference to an nvmem node for the MAC address ++- nvmem-cell-names: string, should be "mac-address" if nvmem is to be used ++ + Optional properties for PHY child node: + - reset-gpios : Should specify the gpio for phy reset + - magic-packet : If present, indicates that the hardware supports waking +diff --git a/Makefile b/Makefile +index 95670d520786..6325ac97c7e2 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 0 +-SUBLEVEL = 16 ++SUBLEVEL = 17 + EXTRAVERSION = + NAME = Shy Crocodile + +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index e5d56d9b712c..3b353af9c48d 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -69,7 +69,7 @@ config ARM + select HAVE_EFFICIENT_UNALIGNED_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && MMU + select HAVE_EXIT_THREAD + select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL +- select HAVE_FUNCTION_GRAPH_TRACER if !THUMB2_KERNEL ++ select HAVE_FUNCTION_GRAPH_TRACER if !THUMB2_KERNEL && !CC_IS_CLANG + select HAVE_FUNCTION_TRACER if !XIP_KERNEL + select HAVE_GCC_PLUGINS + select HAVE_GENERIC_DMA_COHERENT +diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug +index 6d6e0330930b..e388af4594a6 100644 +--- a/arch/arm/Kconfig.debug ++++ b/arch/arm/Kconfig.debug +@@ -47,8 +47,8 @@ config DEBUG_WX + + choice + prompt "Choose kernel unwinder" +- default UNWINDER_ARM if AEABI && !FUNCTION_GRAPH_TRACER +- default UNWINDER_FRAME_POINTER if !AEABI || FUNCTION_GRAPH_TRACER ++ default UNWINDER_ARM if AEABI ++ default UNWINDER_FRAME_POINTER if !AEABI + help + This determines which method will be used for unwinding kernel stack + traces for panics, oopses, bugs, warnings, perf, /proc/<pid>/stack, +@@ -65,7 +65,7 @@ config UNWINDER_FRAME_POINTER + + config UNWINDER_ARM + bool "ARM EABI stack unwinder" +- depends on AEABI ++ depends on AEABI && !FUNCTION_GRAPH_TRACER + select ARM_UNWIND + help + This option enables stack unwinding support in the kernel +diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S +index ec29de250076..cab89479d15e 100644 +--- a/arch/arm/kernel/head-nommu.S ++++ b/arch/arm/kernel/head-nommu.S +@@ -133,9 +133,9 @@ __secondary_data: + */ + .text + __after_proc_init: +-#ifdef CONFIG_ARM_MPU + M_CLASS(movw r12, #:lower16:BASEADDR_V7M_SCB) + M_CLASS(movt r12, #:upper16:BASEADDR_V7M_SCB) ++#ifdef CONFIG_ARM_MPU + M_CLASS(ldr r3, [r12, 0x50]) + AR_CLASS(mrc p15, 0, r3, c0, c1, 4) @ Read ID_MMFR0 + and r3, r3, #(MMFR0_PMSA) @ PMSA field +diff --git a/arch/arm64/kernel/ftrace.c b/arch/arm64/kernel/ftrace.c +index 07b298120182..65a51331088e 100644 +--- a/arch/arm64/kernel/ftrace.c ++++ b/arch/arm64/kernel/ftrace.c +@@ -103,10 +103,15 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) + * to be revisited if support for multiple ftrace entry points + * is added in the future, but for now, the pr_err() below + * deals with a theoretical issue only. ++ * ++ * Note that PLTs are place relative, and plt_entries_equal() ++ * checks whether they point to the same target. Here, we need ++ * to check if the actual opcodes are in fact identical, ++ * regardless of the offset in memory so use memcmp() instead. + */ + trampoline = get_plt_entry(addr, mod->arch.ftrace_trampoline); +- if (!plt_entries_equal(mod->arch.ftrace_trampoline, +- &trampoline)) { ++ if (memcmp(mod->arch.ftrace_trampoline, &trampoline, ++ sizeof(trampoline))) { + if (plt_entry_is_initialized(mod->arch.ftrace_trampoline)) { + pr_err("ftrace: far branches to multiple entry points unsupported inside a single module\n"); + return -EINVAL; +diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c +index 9728abcb18fa..c04ae685003f 100644 +--- a/arch/mips/ath79/setup.c ++++ b/arch/mips/ath79/setup.c +@@ -211,12 +211,6 @@ const char *get_system_type(void) + return ath79_sys_type; + } + +-int get_c0_perfcount_int(void) +-{ +- return ATH79_MISC_IRQ(5); +-} +-EXPORT_SYMBOL_GPL(get_c0_perfcount_int); +- + unsigned int get_c0_compare_int(void) + { + return CP0_LEGACY_COMPARE_IRQ; +diff --git a/arch/powerpc/include/asm/book3s/64/pgalloc.h b/arch/powerpc/include/asm/book3s/64/pgalloc.h +index 9c1173283b96..6c6211a82b9a 100644 +--- a/arch/powerpc/include/asm/book3s/64/pgalloc.h ++++ b/arch/powerpc/include/asm/book3s/64/pgalloc.h +@@ -81,6 +81,9 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) + + pgd = kmem_cache_alloc(PGT_CACHE(PGD_INDEX_SIZE), + pgtable_gfp_flags(mm, GFP_KERNEL)); ++ if (unlikely(!pgd)) ++ return pgd; ++ + /* + * Don't scan the PGD for pointers, it contains references to PUDs but + * those references are not full pointers and so can't be recognised by +diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h +index eb2a33d5df26..e382bd6ede84 100644 +--- a/arch/powerpc/include/asm/reg_booke.h ++++ b/arch/powerpc/include/asm/reg_booke.h +@@ -41,7 +41,7 @@ + #if defined(CONFIG_PPC_BOOK3E_64) + #define MSR_64BIT MSR_CM + +-#define MSR_ (MSR_ME | MSR_CE) ++#define MSR_ (MSR_ME | MSR_RI | MSR_CE) + #define MSR_KERNEL (MSR_ | MSR_64BIT) + #define MSR_USER32 (MSR_ | MSR_PR | MSR_EE) + #define MSR_USER64 (MSR_USER32 | MSR_64BIT) +diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S +index 7f5ac2e8581b..36178000a2f2 100644 +--- a/arch/powerpc/kernel/idle_book3s.S ++++ b/arch/powerpc/kernel/idle_book3s.S +@@ -170,6 +170,9 @@ core_idle_lock_held: + bne- core_idle_lock_held + blr + ++/* Reuse an unused pt_regs slot for IAMR */ ++#define PNV_POWERSAVE_IAMR _DAR ++ + /* + * Pass requested state in r3: + * r3 - PNV_THREAD_NAP/SLEEP/WINKLE in POWER8 +@@ -200,6 +203,12 @@ pnv_powersave_common: + /* Continue saving state */ + SAVE_GPR(2, r1) + SAVE_NVGPRS(r1) ++ ++BEGIN_FTR_SECTION ++ mfspr r5, SPRN_IAMR ++ std r5, PNV_POWERSAVE_IAMR(r1) ++END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) ++ + mfcr r5 + std r5,_CCR(r1) + std r1,PACAR1(r13) +@@ -924,6 +933,17 @@ BEGIN_FTR_SECTION + END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) + REST_NVGPRS(r1) + REST_GPR(2, r1) ++ ++BEGIN_FTR_SECTION ++ /* IAMR was saved in pnv_powersave_common() */ ++ ld r5, PNV_POWERSAVE_IAMR(r1) ++ mtspr SPRN_IAMR, r5 ++ /* ++ * We don't need an isync here because the upcoming mtmsrd is ++ * execution synchronizing. ++ */ ++END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) ++ + ld r4,PACAKMSR(r13) + ld r5,_LINK(r1) + ld r6,_CCR(r1) +diff --git a/arch/x86/include/uapi/asm/vmx.h b/arch/x86/include/uapi/asm/vmx.h +index f0b0c90dd398..d213ec5c3766 100644 +--- a/arch/x86/include/uapi/asm/vmx.h ++++ b/arch/x86/include/uapi/asm/vmx.h +@@ -146,6 +146,7 @@ + + #define VMX_ABORT_SAVE_GUEST_MSR_FAIL 1 + #define VMX_ABORT_LOAD_HOST_PDPTE_FAIL 2 ++#define VMX_ABORT_VMCS_CORRUPTED 3 + #define VMX_ABORT_LOAD_HOST_MSR_FAIL 4 + + #endif /* _UAPIVMX_H */ +diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c +index 725624b6c0c0..8fd3cedd9acc 100644 +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -81,6 +81,19 @@ static int __init set_bios_reboot(const struct dmi_system_id *d) + return 0; + } + ++/* ++ * Some machines don't handle the default ACPI reboot method and ++ * require the EFI reboot method: ++ */ ++static int __init set_efi_reboot(const struct dmi_system_id *d) ++{ ++ if (reboot_type != BOOT_EFI && !efi_runtime_disabled()) { ++ reboot_type = BOOT_EFI; ++ pr_info("%s series board detected. Selecting EFI-method for reboot.\n", d->ident); ++ } ++ return 0; ++} ++ + void __noreturn machine_real_restart(unsigned int type) + { + local_irq_disable(); +@@ -166,6 +179,14 @@ static const struct dmi_system_id reboot_dmi_table[] __initconst = { + DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"), + }, + }, ++ { /* Handle reboot issue on Acer TravelMate X514-51T */ ++ .callback = set_efi_reboot, ++ .ident = "Acer TravelMate X514-51T", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate X514-51T"), ++ }, ++ }, + + /* Apple */ + { /* Handle problems with rebooting on Apple MacBook5 */ +diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S +index ee3b5c7d662e..c45214c44e61 100644 +--- a/arch/x86/kernel/vmlinux.lds.S ++++ b/arch/x86/kernel/vmlinux.lds.S +@@ -362,7 +362,7 @@ SECTIONS + .bss : AT(ADDR(.bss) - LOAD_OFFSET) { + __bss_start = .; + *(.bss..page_aligned) +- *(.bss) ++ *(BSS_MAIN) + BSS_DECRYPTED + . = ALIGN(PAGE_SIZE); + __bss_stop = .; +diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c +index 3339697de6e5..235687f3388f 100644 +--- a/arch/x86/kvm/lapic.c ++++ b/arch/x86/kvm/lapic.c +@@ -137,6 +137,7 @@ static inline bool kvm_apic_map_get_logical_dest(struct kvm_apic_map *map, + if (offset <= max_apic_id) { + u8 cluster_size = min(max_apic_id - offset + 1, 16U); + ++ offset = array_index_nospec(offset, map->max_apic_id + 1); + *cluster = &map->phys_map[offset]; + *mask = dest_id & (0xffff >> (16 - cluster_size)); + } else { +@@ -899,7 +900,8 @@ static inline bool kvm_apic_map_get_dest_lapic(struct kvm *kvm, + if (irq->dest_id > map->max_apic_id) { + *bitmap = 0; + } else { +- *dst = &map->phys_map[irq->dest_id]; ++ u32 dest_id = array_index_nospec(irq->dest_id, map->max_apic_id + 1); ++ *dst = &map->phys_map[dest_id]; + *bitmap = 1; + } + return true; +diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h +index 6432d08c7de7..4d47a2631d1f 100644 +--- a/arch/x86/kvm/trace.h ++++ b/arch/x86/kvm/trace.h +@@ -438,13 +438,13 @@ TRACE_EVENT(kvm_apic_ipi, + ); + + TRACE_EVENT(kvm_apic_accept_irq, +- TP_PROTO(__u32 apicid, __u16 dm, __u8 tm, __u8 vec), ++ TP_PROTO(__u32 apicid, __u16 dm, __u16 tm, __u8 vec), + TP_ARGS(apicid, dm, tm, vec), + + TP_STRUCT__entry( + __field( __u32, apicid ) + __field( __u16, dm ) +- __field( __u8, tm ) ++ __field( __u16, tm ) + __field( __u8, vec ) + ), + +diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c +index 8f8c42b04875..2a16bd887729 100644 +--- a/arch/x86/kvm/vmx/nested.c ++++ b/arch/x86/kvm/vmx/nested.c +@@ -3790,8 +3790,18 @@ static void nested_vmx_restore_host_state(struct kvm_vcpu *vcpu) + vmx_set_cr4(vcpu, vmcs_readl(CR4_READ_SHADOW)); + + nested_ept_uninit_mmu_context(vcpu); +- vcpu->arch.cr3 = vmcs_readl(GUEST_CR3); +- __set_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail); ++ ++ /* ++ * This is only valid if EPT is in use, otherwise the vmcs01 GUEST_CR3 ++ * points to shadow pages! Fortunately we only get here after a WARN_ON ++ * if EPT is disabled, so a VMabort is perfectly fine. ++ */ ++ if (enable_ept) { ++ vcpu->arch.cr3 = vmcs_readl(GUEST_CR3); ++ __set_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail); ++ } else { ++ nested_vmx_abort(vcpu, VMX_ABORT_VMCS_CORRUPTED); ++ } + + /* + * Use ept_save_pdptrs(vcpu) to load the MMU's cached PDPTRs +@@ -5739,6 +5749,14 @@ __init int nested_vmx_hardware_setup(int (*exit_handlers[])(struct kvm_vcpu *)) + { + int i; + ++ /* ++ * Without EPT it is not possible to restore L1's CR3 and PDPTR on ++ * VMfail, because they are not available in vmcs01. Just always ++ * use hardware checks. ++ */ ++ if (!enable_ept) ++ nested_early_check = 1; ++ + if (!cpu_has_vmx_shadow_vmcs()) + enable_shadow_vmcs = 0; + if (enable_shadow_vmcs) { +diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c +index e3cdc85ce5b6..84304626b1cb 100644 +--- a/arch/x86/mm/dump_pagetables.c ++++ b/arch/x86/mm/dump_pagetables.c +@@ -259,7 +259,8 @@ static void note_wx(struct pg_state *st) + #endif + /* Account the WX pages */ + st->wx_pages += npages; +- WARN_ONCE(1, "x86/mm: Found insecure W+X mapping at address %pS\n", ++ WARN_ONCE(__supported_pte_mask & _PAGE_NX, ++ "x86/mm: Found insecure W+X mapping at address %pS\n", + (void *)st->start_address); + } + +diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c +index 5378d10f1d31..3b76fe954978 100644 +--- a/arch/x86/mm/ioremap.c ++++ b/arch/x86/mm/ioremap.c +@@ -825,7 +825,7 @@ void __init __early_set_fixmap(enum fixed_addresses idx, + pte = early_ioremap_pte(addr); + + /* Sanitize 'prot' against any unsupported bits: */ +- pgprot_val(flags) &= __default_kernel_pte_mask; ++ pgprot_val(flags) &= __supported_pte_mask; + + if (pgprot_val(flags)) + set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, flags)); +diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c +index 72510c470001..356620414cf9 100644 +--- a/block/bfq-iosched.c ++++ b/block/bfq-iosched.c +@@ -5353,7 +5353,7 @@ static unsigned int bfq_update_depths(struct bfq_data *bfqd, + return min_shallow; + } + +-static int bfq_init_hctx(struct blk_mq_hw_ctx *hctx, unsigned int index) ++static void bfq_depth_updated(struct blk_mq_hw_ctx *hctx) + { + struct bfq_data *bfqd = hctx->queue->elevator->elevator_data; + struct blk_mq_tags *tags = hctx->sched_tags; +@@ -5361,6 +5361,11 @@ static int bfq_init_hctx(struct blk_mq_hw_ctx *hctx, unsigned int index) + + min_shallow = bfq_update_depths(bfqd, &tags->bitmap_tags); + sbitmap_queue_min_shallow_depth(&tags->bitmap_tags, min_shallow); ++} ++ ++static int bfq_init_hctx(struct blk_mq_hw_ctx *hctx, unsigned int index) ++{ ++ bfq_depth_updated(hctx); + return 0; + } + +@@ -5783,6 +5788,7 @@ static struct elevator_type iosched_bfq_mq = { + .requests_merged = bfq_requests_merged, + .request_merged = bfq_request_merged, + .has_work = bfq_has_work, ++ .depth_updated = bfq_depth_updated, + .init_hctx = bfq_init_hctx, + .init_sched = bfq_init_queue, + .exit_sched = bfq_exit_queue, +diff --git a/block/blk-mq.c b/block/blk-mq.c +index 6930c82ab75f..5b920a82bfe6 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -3131,6 +3131,8 @@ int blk_mq_update_nr_requests(struct request_queue *q, unsigned int nr) + } + if (ret) + break; ++ if (q->elevator && q->elevator->type->ops.depth_updated) ++ q->elevator->type->ops.depth_updated(hctx); + } + + if (!ret) +diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c +index 4be4dc3e8aa6..38ec79bb3edd 100644 +--- a/drivers/acpi/nfit/core.c ++++ b/drivers/acpi/nfit/core.c +@@ -563,6 +563,12 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, + goto out; + } + ++ dev_dbg(dev, "%s cmd: %s output length: %d\n", dimm_name, ++ cmd_name, out_obj->buffer.length); ++ print_hex_dump_debug(cmd_name, DUMP_PREFIX_OFFSET, 4, 4, ++ out_obj->buffer.pointer, ++ min_t(u32, 128, out_obj->buffer.length), true); ++ + if (call_pkg) { + call_pkg->nd_fw_size = out_obj->buffer.length; + memcpy(call_pkg->nd_payload + call_pkg->nd_size_in, +@@ -581,12 +587,6 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, + return 0; + } + +- dev_dbg(dev, "%s cmd: %s output length: %d\n", dimm_name, +- cmd_name, out_obj->buffer.length); +- print_hex_dump_debug(cmd_name, DUMP_PREFIX_OFFSET, 4, 4, +- out_obj->buffer.pointer, +- min_t(u32, 128, out_obj->buffer.length), true); +- + for (i = 0, offset = 0; i < desc->out_num; i++) { + u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i, buf, + (u32 *) out_obj->buffer.pointer, +diff --git a/drivers/char/ipmi/ipmi_si_hardcode.c b/drivers/char/ipmi/ipmi_si_hardcode.c +index 1e5783961b0d..ab7180c46d8d 100644 +--- a/drivers/char/ipmi/ipmi_si_hardcode.c ++++ b/drivers/char/ipmi/ipmi_si_hardcode.c +@@ -201,6 +201,8 @@ void __init ipmi_hardcode_init(void) + char *str; + char *si_type[SI_MAX_PARMS]; + ++ memset(si_type, 0, sizeof(si_type)); ++ + /* Parse out the si_type string into its components. */ + str = si_type_str; + if (*str != '\0') { +diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig +index 8dfd3bc448d0..9df90daa9c03 100644 +--- a/drivers/clocksource/Kconfig ++++ b/drivers/clocksource/Kconfig +@@ -144,6 +144,7 @@ config VT8500_TIMER + config NPCM7XX_TIMER + bool "NPCM7xx timer driver" if COMPILE_TEST + depends on HAS_IOMEM ++ select TIMER_OF + select CLKSRC_MMIO + help + Enable 24-bit TIMER0 and TIMER1 counters in the NPCM7xx architecture, +diff --git a/drivers/clocksource/timer-oxnas-rps.c b/drivers/clocksource/timer-oxnas-rps.c +index eed6feff8b5f..30c6f4ce672b 100644 +--- a/drivers/clocksource/timer-oxnas-rps.c ++++ b/drivers/clocksource/timer-oxnas-rps.c +@@ -296,4 +296,4 @@ err_alloc: + TIMER_OF_DECLARE(ox810se_rps, + "oxsemi,ox810se-rps-timer", oxnas_rps_timer_init); + TIMER_OF_DECLARE(ox820_rps, +- "oxsemi,ox820se-rps-timer", oxnas_rps_timer_init); ++ "oxsemi,ox820-rps-timer", oxnas_rps_timer_init); +diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c +index ae10f5614f95..bf5119203637 100644 +--- a/drivers/dma/bcm2835-dma.c ++++ b/drivers/dma/bcm2835-dma.c +@@ -674,7 +674,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg( + d = bcm2835_dma_create_cb_chain(chan, direction, false, + info, extra, + frames, src, dst, 0, 0, +- GFP_KERNEL); ++ GFP_NOWAIT); + if (!d) + return NULL; + +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c +index d1adfdf50fb3..34fbf879411f 100644 +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -1379,7 +1379,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data, + + status = gpiochip_add_irqchip(chip, lock_key, request_key); + if (status) +- goto err_remove_chip; ++ goto err_free_gpiochip_mask; + + status = of_gpiochip_add(chip); + if (status) +@@ -1387,7 +1387,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data, + + status = gpiochip_init_valid_mask(chip); + if (status) +- goto err_remove_chip; ++ goto err_remove_of_chip; + + for (i = 0; i < chip->ngpio; i++) { + struct gpio_desc *desc = &gdev->descs[i]; +@@ -1415,14 +1415,18 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data, + if (gpiolib_initialized) { + status = gpiochip_setup_dev(gdev); + if (status) +- goto err_remove_chip; ++ goto err_remove_acpi_chip; + } + return 0; + +-err_remove_chip: ++err_remove_acpi_chip: + acpi_gpiochip_remove(chip); ++err_remove_of_chip: + gpiochip_free_hogs(chip); + of_gpiochip_remove(chip); ++err_remove_chip: ++ gpiochip_irqchip_remove(chip); ++err_free_gpiochip_mask: + gpiochip_free_valid_mask(chip); + err_remove_irqchip_mask: + gpiochip_irqchip_free_valid_mask(chip); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index d55dd570a702..27baac26d8e9 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -3150,6 +3150,7 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev) + + /* No need to recover an evicted BO */ + if (shadow->tbo.mem.mem_type != TTM_PL_TT || ++ shadow->tbo.mem.start == AMDGPU_BO_INVALID_OFFSET || + shadow->parent->tbo.mem.mem_type != TTM_PL_VRAM) + continue; + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index 1f92e7e8e3d3..5af2ea1f201d 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -1308,6 +1308,11 @@ static enum surface_update_type det_surface_update(const struct dc *dc, + return UPDATE_TYPE_FULL; + } + ++ if (u->surface->force_full_update) { ++ update_flags->bits.full_update = 1; ++ return UPDATE_TYPE_FULL; ++ } ++ + type = get_plane_info_update_type(u); + elevate_update_type(&overall_type, type); + +@@ -1637,6 +1642,14 @@ void dc_commit_updates_for_stream(struct dc *dc, + } + + dc_resource_state_copy_construct(state, context); ++ ++ for (i = 0; i < dc->res_pool->pipe_count; i++) { ++ struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i]; ++ struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i]; ++ ++ if (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state) ++ new_pipe->plane_state->force_full_update = true; ++ } + } + + +@@ -1680,6 +1693,12 @@ void dc_commit_updates_for_stream(struct dc *dc, + dc->current_state = context; + dc_release_state(old); + ++ for (i = 0; i < dc->res_pool->pipe_count; i++) { ++ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; ++ ++ if (pipe_ctx->plane_state && pipe_ctx->stream == stream) ++ pipe_ctx->plane_state->force_full_update = false; ++ } + } + /*let's use current_state to update watermark etc*/ + if (update_type >= UPDATE_TYPE_FULL) +diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h +index 4b5bbb13ce7f..7d5656d7e460 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc.h ++++ b/drivers/gpu/drm/amd/display/dc/dc.h +@@ -496,6 +496,9 @@ struct dc_plane_state { + struct dc_plane_status status; + struct dc_context *ctx; + ++ /* HACK: Workaround for forcing full reprogramming under some conditions */ ++ bool force_full_update; ++ + /* private to dc_surface.c */ + enum dc_irq_source irq_source; + struct kref refcount; +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c +index aaeb7faac0c4..e0fff5744b5f 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c ++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c +@@ -189,6 +189,12 @@ static void submit_channel_request( + 1, + 0); + } ++ ++ REG_UPDATE(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, 1); ++ ++ REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 0, ++ 10, aux110->timeout_period/10); ++ + /* set the delay and the number of bytes to write */ + + /* The length include +@@ -241,9 +247,6 @@ static void submit_channel_request( + } + } + +- REG_UPDATE(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, 1); +- REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 0, +- 10, aux110->timeout_period/10); + REG_UPDATE(AUX_SW_CONTROL, AUX_SW_GO, 1); + } + +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h +index f7caab85dc80..2c6f50b4245a 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h ++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h +@@ -69,11 +69,11 @@ enum { /* This is the timeout as defined in DP 1.2a, + * at most within ~240usec. That means, + * increasing this timeout will not affect normal operation, + * and we'll timeout after +- * SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD = 1600usec. ++ * SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD = 2400usec. + * This timeout is especially important for +- * resume from S3 and CTS. ++ * converters, resume from S3, and CTS. + */ +- SW_AUX_TIMEOUT_PERIOD_MULTIPLIER = 4 ++ SW_AUX_TIMEOUT_PERIOD_MULTIPLIER = 6 + }; + struct aux_engine_dce110 { + struct aux_engine base; +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 64c3cf027518..14223c0ee784 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1655,6 +1655,8 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) + * iteration for others. + * The Amlogic Meson GX SoCs (v2.01a) have been identified as needing + * the workaround with a single iteration. ++ * The Rockchip RK3288 SoC (v2.00a) and RK3328/RK3399 SoCs (v2.11a) have ++ * been identified as needing the workaround with a single iteration. + */ + + switch (hdmi->version) { +@@ -1663,7 +1665,9 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) + break; + case 0x131a: + case 0x132a: ++ case 0x200a: + case 0x201a: ++ case 0x211a: + case 0x212a: + count = 1; + break; +diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c +index 058b53c0aa7e..1bb3e598cb84 100644 +--- a/drivers/gpu/drm/imx/ipuv3-crtc.c ++++ b/drivers/gpu/drm/imx/ipuv3-crtc.c +@@ -70,7 +70,7 @@ static void ipu_crtc_disable_planes(struct ipu_crtc *ipu_crtc, + if (disable_partial) + ipu_plane_disable(ipu_crtc->plane[1], true); + if (disable_full) +- ipu_plane_disable(ipu_crtc->plane[0], false); ++ ipu_plane_disable(ipu_crtc->plane[0], true); + } + + static void ipu_crtc_atomic_disable(struct drm_crtc *crtc, +diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c b/drivers/gpu/drm/rockchip/cdn-dp-reg.c +index 5a485489a1e2..6c8b14fb1d2f 100644 +--- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c ++++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c +@@ -113,7 +113,7 @@ static int cdp_dp_mailbox_write(struct cdn_dp_device *dp, u8 val) + + static int cdn_dp_mailbox_validate_receive(struct cdn_dp_device *dp, + u8 module_id, u8 opcode, +- u8 req_size) ++ u16 req_size) + { + u32 mbox_size, i; + u8 header[4]; +diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c +index 9e4c375ccc96..f8bf5bbec2df 100644 +--- a/drivers/gpu/drm/sun4i/sun4i_drv.c ++++ b/drivers/gpu/drm/sun4i/sun4i_drv.c +@@ -85,6 +85,8 @@ static int sun4i_drv_bind(struct device *dev) + ret = -ENOMEM; + goto free_drm; + } ++ ++ dev_set_drvdata(dev, drm); + drm->dev_private = drv; + INIT_LIST_HEAD(&drv->frontend_list); + INIT_LIST_HEAD(&drv->engine_list); +@@ -144,7 +146,10 @@ static void sun4i_drv_unbind(struct device *dev) + drm_dev_unregister(drm); + drm_kms_helper_poll_fini(drm); + drm_mode_config_cleanup(drm); ++ ++ component_unbind_all(dev, NULL); + of_reserved_mem_device_release(dev); ++ + drm_dev_put(drm); + } + +@@ -393,6 +398,8 @@ static int sun4i_drv_probe(struct platform_device *pdev) + + static int sun4i_drv_remove(struct platform_device *pdev) + { ++ component_master_del(&pdev->dev, &sun4i_drv_master_ops); ++ + return 0; + } + +diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c +index 996cadd83f24..d8e1b3f12904 100644 +--- a/drivers/gpu/drm/ttm/ttm_bo.c ++++ b/drivers/gpu/drm/ttm/ttm_bo.c +@@ -881,8 +881,10 @@ static int ttm_bo_add_move_fence(struct ttm_buffer_object *bo, + reservation_object_add_shared_fence(bo->resv, fence); + + ret = reservation_object_reserve_shared(bo->resv, 1); +- if (unlikely(ret)) ++ if (unlikely(ret)) { ++ dma_fence_put(fence); + return ret; ++ } + + dma_fence_put(bo->moving); + bo->moving = fence; +diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c +index 2d1aaca49105..f7f32a885af7 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_drv.c ++++ b/drivers/gpu/drm/virtio/virtgpu_drv.c +@@ -127,10 +127,14 @@ static struct drm_driver driver = { + #if defined(CONFIG_DEBUG_FS) + .debugfs_init = virtio_gpu_debugfs_init, + #endif ++ .prime_handle_to_fd = drm_gem_prime_handle_to_fd, ++ .prime_fd_to_handle = drm_gem_prime_fd_to_handle, + .gem_prime_export = drm_gem_prime_export, + .gem_prime_import = drm_gem_prime_import, + .gem_prime_pin = virtgpu_gem_prime_pin, + .gem_prime_unpin = virtgpu_gem_prime_unpin, ++ .gem_prime_get_sg_table = virtgpu_gem_prime_get_sg_table, ++ .gem_prime_import_sg_table = virtgpu_gem_prime_import_sg_table, + .gem_prime_vmap = virtgpu_gem_prime_vmap, + .gem_prime_vunmap = virtgpu_gem_prime_vunmap, + .gem_prime_mmap = virtgpu_gem_prime_mmap, +diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h +index 0c15000f926e..1deb41d42ea4 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_drv.h ++++ b/drivers/gpu/drm/virtio/virtgpu_drv.h +@@ -372,6 +372,10 @@ int virtio_gpu_object_wait(struct virtio_gpu_object *bo, bool no_wait); + /* virtgpu_prime.c */ + int virtgpu_gem_prime_pin(struct drm_gem_object *obj); + void virtgpu_gem_prime_unpin(struct drm_gem_object *obj); ++struct sg_table *virtgpu_gem_prime_get_sg_table(struct drm_gem_object *obj); ++struct drm_gem_object *virtgpu_gem_prime_import_sg_table( ++ struct drm_device *dev, struct dma_buf_attachment *attach, ++ struct sg_table *sgt); + void *virtgpu_gem_prime_vmap(struct drm_gem_object *obj); + void virtgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); + int virtgpu_gem_prime_mmap(struct drm_gem_object *obj, +diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c +index c59ec34c80a5..eb51a78e1199 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_prime.c ++++ b/drivers/gpu/drm/virtio/virtgpu_prime.c +@@ -39,6 +39,18 @@ void virtgpu_gem_prime_unpin(struct drm_gem_object *obj) + WARN_ONCE(1, "not implemented"); + } + ++struct sg_table *virtgpu_gem_prime_get_sg_table(struct drm_gem_object *obj) ++{ ++ return ERR_PTR(-ENODEV); ++} ++ ++struct drm_gem_object *virtgpu_gem_prime_import_sg_table( ++ struct drm_device *dev, struct dma_buf_attachment *attach, ++ struct sg_table *table) ++{ ++ return ERR_PTR(-ENODEV); ++} ++ + void *virtgpu_gem_prime_vmap(struct drm_gem_object *obj) + { + struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj); +diff --git a/drivers/gpu/ipu-v3/ipu-dp.c b/drivers/gpu/ipu-v3/ipu-dp.c +index 9b2b3fa479c4..5e44ff1f2085 100644 +--- a/drivers/gpu/ipu-v3/ipu-dp.c ++++ b/drivers/gpu/ipu-v3/ipu-dp.c +@@ -195,7 +195,8 @@ int ipu_dp_setup_channel(struct ipu_dp *dp, + ipu_dp_csc_init(flow, flow->foreground.in_cs, flow->out_cs, + DP_COM_CONF_CSC_DEF_BOTH); + } else { +- if (flow->foreground.in_cs == flow->out_cs) ++ if (flow->foreground.in_cs == IPUV3_COLORSPACE_UNKNOWN || ++ flow->foreground.in_cs == flow->out_cs) + /* + * foreground identical to output, apply color + * conversion on background +@@ -261,6 +262,8 @@ void ipu_dp_disable_channel(struct ipu_dp *dp, bool sync) + struct ipu_dp_priv *priv = flow->priv; + u32 reg, csc; + ++ dp->in_cs = IPUV3_COLORSPACE_UNKNOWN; ++ + if (!dp->foreground) + return; + +@@ -268,8 +271,9 @@ void ipu_dp_disable_channel(struct ipu_dp *dp, bool sync) + + reg = readl(flow->base + DP_COM_CONF); + csc = reg & DP_COM_CONF_CSC_DEF_MASK; +- if (csc == DP_COM_CONF_CSC_DEF_FG) +- reg &= ~DP_COM_CONF_CSC_DEF_MASK; ++ reg &= ~DP_COM_CONF_CSC_DEF_MASK; ++ if (csc == DP_COM_CONF_CSC_DEF_BOTH || csc == DP_COM_CONF_CSC_DEF_BG) ++ reg |= DP_COM_CONF_CSC_DEF_BG; + + reg &= ~DP_COM_CONF_FG_EN; + writel(reg, flow->base + DP_COM_CONF); +@@ -347,6 +351,8 @@ int ipu_dp_init(struct ipu_soc *ipu, struct device *dev, unsigned long base) + mutex_init(&priv->mutex); + + for (i = 0; i < IPUV3_NUM_FLOWS; i++) { ++ priv->flow[i].background.in_cs = IPUV3_COLORSPACE_UNKNOWN; ++ priv->flow[i].foreground.in_cs = IPUV3_COLORSPACE_UNKNOWN; + priv->flow[i].foreground.foreground = true; + priv->flow[i].base = priv->base + ipu_dp_flow_base[i]; + priv->flow[i].priv = priv; +diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c +index ff92a7b2fc89..4f119300ce3f 100644 +--- a/drivers/hid/hid-input.c ++++ b/drivers/hid/hid-input.c +@@ -677,6 +677,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel + break; + } + ++ if ((usage->hid & 0xf0) == 0xb0) { /* SC - Display */ ++ switch (usage->hid & 0xf) { ++ case 0x05: map_key_clear(KEY_SWITCHVIDEOMODE); break; ++ default: goto ignore; ++ } ++ break; ++ } ++ + /* + * Some lazy vendors declare 255 usages for System Control, + * leading to the creation of ABS_X|Y axis and too many others. +@@ -908,6 +916,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel + case 0x074: map_key_clear(KEY_BRIGHTNESS_MAX); break; + case 0x075: map_key_clear(KEY_BRIGHTNESS_AUTO); break; + ++ case 0x079: map_key_clear(KEY_KBDILLUMUP); break; ++ case 0x07a: map_key_clear(KEY_KBDILLUMDOWN); break; ++ case 0x07c: map_key_clear(KEY_KBDILLUMTOGGLE); break; ++ + case 0x082: map_key_clear(KEY_VIDEO_NEXT); break; + case 0x083: map_key_clear(KEY_LAST); break; + case 0x084: map_key_clear(KEY_ENTER); break; +@@ -1042,6 +1054,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel + case 0x2cb: map_key_clear(KEY_KBDINPUTASSIST_ACCEPT); break; + case 0x2cc: map_key_clear(KEY_KBDINPUTASSIST_CANCEL); break; + ++ case 0x29f: map_key_clear(KEY_SCALE); break; ++ + default: map_key_clear(KEY_UNKNOWN); + } + break; +diff --git a/drivers/hwmon/occ/sysfs.c b/drivers/hwmon/occ/sysfs.c +index 743b26ec8e54..f04f502b2e69 100644 +--- a/drivers/hwmon/occ/sysfs.c ++++ b/drivers/hwmon/occ/sysfs.c +@@ -51,16 +51,16 @@ static ssize_t occ_sysfs_show(struct device *dev, + val = !!(header->status & OCC_STAT_ACTIVE); + break; + case 2: +- val = !!(header->status & OCC_EXT_STAT_DVFS_OT); ++ val = !!(header->ext_status & OCC_EXT_STAT_DVFS_OT); + break; + case 3: +- val = !!(header->status & OCC_EXT_STAT_DVFS_POWER); ++ val = !!(header->ext_status & OCC_EXT_STAT_DVFS_POWER); + break; + case 4: +- val = !!(header->status & OCC_EXT_STAT_MEM_THROTTLE); ++ val = !!(header->ext_status & OCC_EXT_STAT_MEM_THROTTLE); + break; + case 5: +- val = !!(header->status & OCC_EXT_STAT_QUICK_DROP); ++ val = !!(header->ext_status & OCC_EXT_STAT_QUICK_DROP); + break; + case 6: + val = header->occ_state; +diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c +index 2c944825026f..af34f7ee1b04 100644 +--- a/drivers/hwmon/pwm-fan.c ++++ b/drivers/hwmon/pwm-fan.c +@@ -254,7 +254,7 @@ static int pwm_fan_probe(struct platform_device *pdev) + + ret = pwm_fan_of_get_cooling_data(&pdev->dev, ctx); + if (ret) +- return ret; ++ goto err_pwm_disable; + + ctx->pwm_fan_state = ctx->pwm_fan_max_state; + if (IS_ENABLED(CONFIG_THERMAL)) { +diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c +index 3f6be5ac049a..1ae86e7359f7 100644 +--- a/drivers/iio/adc/xilinx-xadc-core.c ++++ b/drivers/iio/adc/xilinx-xadc-core.c +@@ -1290,6 +1290,7 @@ static int xadc_probe(struct platform_device *pdev) + + err_free_irq: + free_irq(xadc->irq, indio_dev); ++ cancel_delayed_work_sync(&xadc->zynq_unmask_work); + err_clk_disable_unprepare: + clk_disable_unprepare(xadc->clk); + err_free_samplerate_trigger: +@@ -1319,8 +1320,8 @@ static int xadc_remove(struct platform_device *pdev) + iio_triggered_buffer_cleanup(indio_dev); + } + free_irq(xadc->irq, indio_dev); ++ cancel_delayed_work_sync(&xadc->zynq_unmask_work); + clk_disable_unprepare(xadc->clk); +- cancel_delayed_work(&xadc->zynq_unmask_work); + kfree(xadc->data); + kfree(indio_dev->channels); + +diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c +index 54031c5b53fa..89dd2380fc81 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_qp.c ++++ b/drivers/infiniband/hw/hns/hns_roce_qp.c +@@ -517,7 +517,7 @@ static int hns_roce_set_kernel_sq_size(struct hns_roce_dev *hr_dev, + + static int hns_roce_qp_has_sq(struct ib_qp_init_attr *attr) + { +- if (attr->qp_type == IB_QPT_XRC_TGT) ++ if (attr->qp_type == IB_QPT_XRC_TGT || !attr->cap.max_send_wr) + return 0; + + return 1; +diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c +index 497181f5ba09..c6bdd0d16c4b 100644 +--- a/drivers/infiniband/hw/mlx5/main.c ++++ b/drivers/infiniband/hw/mlx5/main.c +@@ -1025,6 +1025,8 @@ static int mlx5_ib_query_device(struct ib_device *ibdev, + if (MLX5_CAP_GEN(mdev, qp_packet_based)) + resp.flags |= + MLX5_IB_QUERY_DEV_RESP_PACKET_BASED_CREDIT_MODE; ++ ++ resp.flags |= MLX5_IB_QUERY_DEV_RESP_FLAGS_SCAT2CQE_DCT; + } + + if (field_avail(typeof(resp), sw_parsing_caps, +diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c +index 7db778d96ef5..afc88e6e172e 100644 +--- a/drivers/infiniband/hw/mlx5/qp.c ++++ b/drivers/infiniband/hw/mlx5/qp.c +@@ -1724,13 +1724,16 @@ static void configure_responder_scat_cqe(struct ib_qp_init_attr *init_attr, + + rcqe_sz = mlx5_ib_get_cqe_size(init_attr->recv_cq); + +- if (rcqe_sz == 128) { +- MLX5_SET(qpc, qpc, cs_res, MLX5_RES_SCAT_DATA64_CQE); ++ if (init_attr->qp_type == MLX5_IB_QPT_DCT) { ++ if (rcqe_sz == 128) ++ MLX5_SET(dctc, qpc, cs_res, MLX5_RES_SCAT_DATA64_CQE); ++ + return; + } + +- if (init_attr->qp_type != MLX5_IB_QPT_DCT) +- MLX5_SET(qpc, qpc, cs_res, MLX5_RES_SCAT_DATA32_CQE); ++ MLX5_SET(qpc, qpc, cs_res, ++ rcqe_sz == 128 ? MLX5_RES_SCAT_DATA64_CQE : ++ MLX5_RES_SCAT_DATA32_CQE); + } + + static void configure_requester_scat_cqe(struct mlx5_ib_dev *dev, +diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig +index a878351f1643..52d7f55fca32 100644 +--- a/drivers/input/keyboard/Kconfig ++++ b/drivers/input/keyboard/Kconfig +@@ -420,7 +420,7 @@ config KEYBOARD_MPR121 + + config KEYBOARD_SNVS_PWRKEY + tristate "IMX SNVS Power Key Driver" +- depends on SOC_IMX6SX || SOC_IMX7D ++ depends on ARCH_MXC || COMPILE_TEST + depends on OF + help + This is the snvs powerkey driver for the Freescale i.MX application +diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c +index fc3ab93b7aea..7fb358f96195 100644 +--- a/drivers/input/rmi4/rmi_driver.c ++++ b/drivers/input/rmi4/rmi_driver.c +@@ -860,7 +860,7 @@ static int rmi_create_function(struct rmi_device *rmi_dev, + + error = rmi_register_function(fn); + if (error) +- goto err_put_fn; ++ return error; + + if (pdt->function_number == 0x01) + data->f01_container = fn; +@@ -870,10 +870,6 @@ static int rmi_create_function(struct rmi_device *rmi_dev, + list_add_tail(&fn->node, &data->function_list); + + return RMI_SCAN_CONTINUE; +- +-err_put_fn: +- put_device(&fn->dev); +- return error; + } + + void rmi_enable_irq(struct rmi_device *rmi_dev, bool clear_wake) +diff --git a/drivers/irqchip/irq-ath79-misc.c b/drivers/irqchip/irq-ath79-misc.c +index aa7290784636..0390603170b4 100644 +--- a/drivers/irqchip/irq-ath79-misc.c ++++ b/drivers/irqchip/irq-ath79-misc.c +@@ -22,6 +22,15 @@ + #define AR71XX_RESET_REG_MISC_INT_ENABLE 4 + + #define ATH79_MISC_IRQ_COUNT 32 ++#define ATH79_MISC_PERF_IRQ 5 ++ ++static int ath79_perfcount_irq; ++ ++int get_c0_perfcount_int(void) ++{ ++ return ath79_perfcount_irq; ++} ++EXPORT_SYMBOL_GPL(get_c0_perfcount_int); + + static void ath79_misc_irq_handler(struct irq_desc *desc) + { +@@ -113,6 +122,8 @@ static void __init ath79_misc_intc_domain_init( + { + void __iomem *base = domain->host_data; + ++ ath79_perfcount_irq = irq_create_mapping(domain, ATH79_MISC_PERF_IRQ); ++ + /* Disable and clear all interrupts */ + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE); + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); +diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c +index ecdeb89645d0..149b1aca52a2 100644 +--- a/drivers/isdn/gigaset/bas-gigaset.c ++++ b/drivers/isdn/gigaset/bas-gigaset.c +@@ -958,6 +958,7 @@ static void write_iso_callback(struct urb *urb) + */ + static int starturbs(struct bc_state *bcs) + { ++ struct usb_device *udev = bcs->cs->hw.bas->udev; + struct bas_bc_state *ubc = bcs->hw.bas; + struct urb *urb; + int j, k; +@@ -975,8 +976,8 @@ static int starturbs(struct bc_state *bcs) + rc = -EFAULT; + goto error; + } +- usb_fill_int_urb(urb, bcs->cs->hw.bas->udev, +- usb_rcvisocpipe(urb->dev, 3 + 2 * bcs->channel), ++ usb_fill_int_urb(urb, udev, ++ usb_rcvisocpipe(udev, 3 + 2 * bcs->channel), + ubc->isoinbuf + k * BAS_INBUFSIZE, + BAS_INBUFSIZE, read_iso_callback, bcs, + BAS_FRAMETIME); +@@ -1006,8 +1007,8 @@ static int starturbs(struct bc_state *bcs) + rc = -EFAULT; + goto error; + } +- usb_fill_int_urb(urb, bcs->cs->hw.bas->udev, +- usb_sndisocpipe(urb->dev, 4 + 2 * bcs->channel), ++ usb_fill_int_urb(urb, udev, ++ usb_sndisocpipe(udev, 4 + 2 * bcs->channel), + ubc->isooutbuf->data, + sizeof(ubc->isooutbuf->data), + write_iso_callback, &ubc->isoouturbs[k], +diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c +index 15d3ca37669a..04da3a17cd95 100644 +--- a/drivers/isdn/mISDN/socket.c ++++ b/drivers/isdn/mISDN/socket.c +@@ -710,10 +710,10 @@ base_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) + struct sock *sk = sock->sk; + int err = 0; + +- if (!maddr || maddr->family != AF_ISDN) ++ if (addr_len < sizeof(struct sockaddr_mISDN)) + return -EINVAL; + +- if (addr_len < sizeof(struct sockaddr_mISDN)) ++ if (!maddr || maddr->family != AF_ISDN) + return -EINVAL; + + lock_sock(sk); +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index 5b68f2d0da60..3ae13c06b200 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -4233,26 +4233,15 @@ static void handle_parity_checks6(struct r5conf *conf, struct stripe_head *sh, + case check_state_check_result: + sh->check_state = check_state_idle; + ++ if (s->failed > 1) ++ break; + /* handle a successful check operation, if parity is correct + * we are done. Otherwise update the mismatch count and repair + * parity if !MD_RECOVERY_CHECK + */ + if (sh->ops.zero_sum_result == 0) { +- /* both parities are correct */ +- if (!s->failed) +- set_bit(STRIPE_INSYNC, &sh->state); +- else { +- /* in contrast to the raid5 case we can validate +- * parity, but still have a failure to write +- * back +- */ +- sh->check_state = check_state_compute_result; +- /* Returning at this point means that we may go +- * off and bring p and/or q uptodate again so +- * we make sure to check zero_sum_result again +- * to verify if p or q need writeback +- */ +- } ++ /* Any parity checked was correct */ ++ set_bit(STRIPE_INSYNC, &sh->state); + } else { + atomic64_add(STRIPE_SECTORS, &conf->mddev->resync_mismatches); + if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery)) { +diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c +index 4d5d01cb8141..80867bd8f44c 100644 +--- a/drivers/net/bonding/bond_options.c ++++ b/drivers/net/bonding/bond_options.c +@@ -1098,13 +1098,6 @@ static int bond_option_arp_validate_set(struct bonding *bond, + { + netdev_dbg(bond->dev, "Setting arp_validate to %s (%llu)\n", + newval->string, newval->value); +- +- if (bond->dev->flags & IFF_UP) { +- if (!newval->value) +- bond->recv_probe = NULL; +- else if (bond->params.arp_interval) +- bond->recv_probe = bond_arp_rcv; +- } + bond->params.arp_validate = newval->value; + + return 0; +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index 6cbe515bfdeb..8a57888e9765 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -2414,12 +2414,12 @@ static int macb_open(struct net_device *dev) + return err; + } + +- bp->macbgem_ops.mog_init_rings(bp); +- macb_init_hw(bp); +- + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) + napi_enable(&queue->napi); + ++ bp->macbgem_ops.mog_init_rings(bp); ++ macb_init_hw(bp); ++ + /* schedule a link state check */ + phy_start(dev->phydev); + +diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +index dfebc30c4841..d3f2408dc9e8 100644 +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +@@ -1648,7 +1648,7 @@ static struct sk_buff *dpaa_cleanup_tx_fd(const struct dpaa_priv *priv, + qm_sg_entry_get_len(&sgt[0]), dma_dir); + + /* remaining pages were mapped with skb_frag_dma_map() */ +- for (i = 1; i < nr_frags; i++) { ++ for (i = 1; i <= nr_frags; i++) { + WARN_ON(qm_sg_entry_is_ext(&sgt[i])); + + dma_unmap_page(dev, qm_sg_addr(&sgt[i]), +diff --git a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c +index 0beee2cc2ddd..722b6de24816 100644 +--- a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c ++++ b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c +@@ -252,14 +252,12 @@ uec_set_ringparam(struct net_device *netdev, + return -EINVAL; + } + ++ if (netif_running(netdev)) ++ return -EBUSY; ++ + ug_info->bdRingLenRx[queue] = ring->rx_pending; + ug_info->bdRingLenTx[queue] = ring->tx_pending; + +- if (netif_running(netdev)) { +- /* FIXME: restart automatically */ +- netdev_info(netdev, "Please re-open the interface\n"); +- } +- + return ret; + } + +diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +index 931beac3359d..70031e2b2294 100644 +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +@@ -4370,7 +4370,7 @@ static void mvpp2_phylink_validate(struct net_device *dev, + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: +- if (port->gop_id == 0) ++ if (port->priv->hw_version == MVPP22 && port->gop_id == 0) + goto empty_set; + break; + default: +diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c +index 215a45374d7b..0ef95abde6bb 100644 +--- a/drivers/net/ethernet/mscc/ocelot.c ++++ b/drivers/net/ethernet/mscc/ocelot.c +@@ -613,7 +613,7 @@ static int ocelot_mact_mc_add(struct ocelot_port *port, + struct netdev_hw_addr *hw_addr) + { + struct ocelot *ocelot = port->ocelot; +- struct netdev_hw_addr *ha = kzalloc(sizeof(*ha), GFP_KERNEL); ++ struct netdev_hw_addr *ha = kzalloc(sizeof(*ha), GFP_ATOMIC); + + if (!ha) + return -ENOMEM; +diff --git a/drivers/net/ethernet/neterion/vxge/vxge-config.c b/drivers/net/ethernet/neterion/vxge/vxge-config.c +index 7cde387e5ec6..51cd57ab3d95 100644 +--- a/drivers/net/ethernet/neterion/vxge/vxge-config.c ++++ b/drivers/net/ethernet/neterion/vxge/vxge-config.c +@@ -2366,6 +2366,7 @@ static void *__vxge_hw_blockpool_malloc(struct __vxge_hw_device *devh, u32 size, + dma_object->addr))) { + vxge_os_dma_free(devh->pdev, memblock, + &dma_object->acc_handle); ++ memblock = NULL; + goto exit; + } + +diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h +index 2d8a77cc156b..f458c9776a89 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed.h ++++ b/drivers/net/ethernet/qlogic/qed/qed.h +@@ -431,12 +431,16 @@ struct qed_qm_info { + u8 num_pf_rls; + }; + ++#define QED_OVERFLOW_BIT 1 ++ + struct qed_db_recovery_info { + struct list_head list; + + /* Lock to protect the doorbell recovery mechanism list */ + spinlock_t lock; ++ bool dorq_attn; + u32 db_recovery_counter; ++ unsigned long overflow; + }; + + struct storm_stats { +@@ -918,8 +922,7 @@ u16 qed_get_cm_pq_idx_llt_mtc(struct qed_hwfn *p_hwfn, u8 tc); + + /* doorbell recovery mechanism */ + void qed_db_recovery_dp(struct qed_hwfn *p_hwfn); +-void qed_db_recovery_execute(struct qed_hwfn *p_hwfn, +- enum qed_db_rec_exec db_exec); ++void qed_db_recovery_execute(struct qed_hwfn *p_hwfn); + bool qed_edpm_enabled(struct qed_hwfn *p_hwfn); + + /* Other Linux specific common definitions */ +diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c +index 2ecaaaa4469a..228891e459bc 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c +@@ -102,11 +102,15 @@ static void qed_db_recovery_dp_entry(struct qed_hwfn *p_hwfn, + + /* Doorbell address sanity (address within doorbell bar range) */ + static bool qed_db_rec_sanity(struct qed_dev *cdev, +- void __iomem *db_addr, void *db_data) ++ void __iomem *db_addr, ++ enum qed_db_rec_width db_width, ++ void *db_data) + { ++ u32 width = (db_width == DB_REC_WIDTH_32B) ? 32 : 64; ++ + /* Make sure doorbell address is within the doorbell bar */ + if (db_addr < cdev->doorbells || +- (u8 __iomem *)db_addr > ++ (u8 __iomem *)db_addr + width > + (u8 __iomem *)cdev->doorbells + cdev->db_size) { + WARN(true, + "Illegal doorbell address: %p. Legal range for doorbell addresses is [%p..%p]\n", +@@ -159,7 +163,7 @@ int qed_db_recovery_add(struct qed_dev *cdev, + } + + /* Sanitize doorbell address */ +- if (!qed_db_rec_sanity(cdev, db_addr, db_data)) ++ if (!qed_db_rec_sanity(cdev, db_addr, db_width, db_data)) + return -EINVAL; + + /* Obtain hwfn from doorbell address */ +@@ -205,10 +209,6 @@ int qed_db_recovery_del(struct qed_dev *cdev, + return 0; + } + +- /* Sanitize doorbell address */ +- if (!qed_db_rec_sanity(cdev, db_addr, db_data)) +- return -EINVAL; +- + /* Obtain hwfn from doorbell address */ + p_hwfn = qed_db_rec_find_hwfn(cdev, db_addr); + +@@ -300,31 +300,24 @@ void qed_db_recovery_dp(struct qed_hwfn *p_hwfn) + + /* Ring the doorbell of a single doorbell recovery entry */ + static void qed_db_recovery_ring(struct qed_hwfn *p_hwfn, +- struct qed_db_recovery_entry *db_entry, +- enum qed_db_rec_exec db_exec) +-{ +- if (db_exec != DB_REC_ONCE) { +- /* Print according to width */ +- if (db_entry->db_width == DB_REC_WIDTH_32B) { +- DP_VERBOSE(p_hwfn, QED_MSG_SPQ, +- "%s doorbell address %p data %x\n", +- db_exec == DB_REC_DRY_RUN ? +- "would have rung" : "ringing", +- db_entry->db_addr, +- *(u32 *)db_entry->db_data); +- } else { +- DP_VERBOSE(p_hwfn, QED_MSG_SPQ, +- "%s doorbell address %p data %llx\n", +- db_exec == DB_REC_DRY_RUN ? +- "would have rung" : "ringing", +- db_entry->db_addr, +- *(u64 *)(db_entry->db_data)); +- } ++ struct qed_db_recovery_entry *db_entry) ++{ ++ /* Print according to width */ ++ if (db_entry->db_width == DB_REC_WIDTH_32B) { ++ DP_VERBOSE(p_hwfn, QED_MSG_SPQ, ++ "ringing doorbell address %p data %x\n", ++ db_entry->db_addr, ++ *(u32 *)db_entry->db_data); ++ } else { ++ DP_VERBOSE(p_hwfn, QED_MSG_SPQ, ++ "ringing doorbell address %p data %llx\n", ++ db_entry->db_addr, ++ *(u64 *)(db_entry->db_data)); + } + + /* Sanity */ + if (!qed_db_rec_sanity(p_hwfn->cdev, db_entry->db_addr, +- db_entry->db_data)) ++ db_entry->db_width, db_entry->db_data)) + return; + + /* Flush the write combined buffer. Since there are multiple doorbelling +@@ -334,14 +327,12 @@ static void qed_db_recovery_ring(struct qed_hwfn *p_hwfn, + wmb(); + + /* Ring the doorbell */ +- if (db_exec == DB_REC_REAL_DEAL || db_exec == DB_REC_ONCE) { +- if (db_entry->db_width == DB_REC_WIDTH_32B) +- DIRECT_REG_WR(db_entry->db_addr, +- *(u32 *)(db_entry->db_data)); +- else +- DIRECT_REG_WR64(db_entry->db_addr, +- *(u64 *)(db_entry->db_data)); +- } ++ if (db_entry->db_width == DB_REC_WIDTH_32B) ++ DIRECT_REG_WR(db_entry->db_addr, ++ *(u32 *)(db_entry->db_data)); ++ else ++ DIRECT_REG_WR64(db_entry->db_addr, ++ *(u64 *)(db_entry->db_data)); + + /* Flush the write combined buffer. Next doorbell may come from a + * different entity to the same address... +@@ -350,29 +341,21 @@ static void qed_db_recovery_ring(struct qed_hwfn *p_hwfn, + } + + /* Traverse the doorbell recovery entry list and ring all the doorbells */ +-void qed_db_recovery_execute(struct qed_hwfn *p_hwfn, +- enum qed_db_rec_exec db_exec) ++void qed_db_recovery_execute(struct qed_hwfn *p_hwfn) + { + struct qed_db_recovery_entry *db_entry = NULL; + +- if (db_exec != DB_REC_ONCE) { +- DP_NOTICE(p_hwfn, +- "Executing doorbell recovery. Counter was %d\n", +- p_hwfn->db_recovery_info.db_recovery_counter); ++ DP_NOTICE(p_hwfn, "Executing doorbell recovery. Counter was %d\n", ++ p_hwfn->db_recovery_info.db_recovery_counter); + +- /* Track amount of times recovery was executed */ +- p_hwfn->db_recovery_info.db_recovery_counter++; +- } ++ /* Track amount of times recovery was executed */ ++ p_hwfn->db_recovery_info.db_recovery_counter++; + + /* Protect the list */ + spin_lock_bh(&p_hwfn->db_recovery_info.lock); + list_for_each_entry(db_entry, +- &p_hwfn->db_recovery_info.list, list_entry) { +- qed_db_recovery_ring(p_hwfn, db_entry, db_exec); +- if (db_exec == DB_REC_ONCE) +- break; +- } +- ++ &p_hwfn->db_recovery_info.list, list_entry) ++ qed_db_recovery_ring(p_hwfn, db_entry); + spin_unlock_bh(&p_hwfn->db_recovery_info.lock); + } + +diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c b/drivers/net/ethernet/qlogic/qed/qed_int.c +index 92340919d852..a7e95f239317 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_int.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_int.c +@@ -376,6 +376,9 @@ static int qed_db_rec_flush_queue(struct qed_hwfn *p_hwfn, + u32 count = QED_DB_REC_COUNT; + u32 usage = 1; + ++ /* Flush any pending (e)dpms as they may never arrive */ ++ qed_wr(p_hwfn, p_ptt, DORQ_REG_DPM_FORCE_ABORT, 0x1); ++ + /* wait for usage to zero or count to run out. This is necessary since + * EDPM doorbell transactions can take multiple 64b cycles, and as such + * can "split" over the pci. Possibly, the doorbell drop can happen with +@@ -404,51 +407,74 @@ static int qed_db_rec_flush_queue(struct qed_hwfn *p_hwfn, + + int qed_db_rec_handler(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) + { +- u32 overflow; ++ u32 attn_ovfl, cur_ovfl; + int rc; + +- overflow = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY); +- DP_NOTICE(p_hwfn, "PF Overflow sticky 0x%x\n", overflow); +- if (!overflow) { +- qed_db_recovery_execute(p_hwfn, DB_REC_ONCE); ++ attn_ovfl = test_and_clear_bit(QED_OVERFLOW_BIT, ++ &p_hwfn->db_recovery_info.overflow); ++ cur_ovfl = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY); ++ if (!cur_ovfl && !attn_ovfl) + return 0; +- } + +- if (qed_edpm_enabled(p_hwfn)) { ++ DP_NOTICE(p_hwfn, "PF Overflow sticky: attn %u current %u\n", ++ attn_ovfl, cur_ovfl); ++ ++ if (cur_ovfl && !p_hwfn->db_bar_no_edpm) { + rc = qed_db_rec_flush_queue(p_hwfn, p_ptt); + if (rc) + return rc; + } + +- /* Flush any pending (e)dpm as they may never arrive */ +- qed_wr(p_hwfn, p_ptt, DORQ_REG_DPM_FORCE_ABORT, 0x1); +- + /* Release overflow sticky indication (stop silently dropping everything) */ + qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY, 0x0); + + /* Repeat all last doorbells (doorbell drop recovery) */ +- qed_db_recovery_execute(p_hwfn, DB_REC_REAL_DEAL); ++ qed_db_recovery_execute(p_hwfn); + + return 0; + } + +-static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn) ++static void qed_dorq_attn_overflow(struct qed_hwfn *p_hwfn) + { +- u32 int_sts, first_drop_reason, details, address, all_drops_reason; + struct qed_ptt *p_ptt = p_hwfn->p_dpc_ptt; ++ u32 overflow; + int rc; + +- int_sts = qed_rd(p_hwfn, p_ptt, DORQ_REG_INT_STS); +- DP_NOTICE(p_hwfn->cdev, "DORQ attention. int_sts was %x\n", int_sts); ++ overflow = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY); ++ if (!overflow) ++ goto out; ++ ++ /* Run PF doorbell recovery in next periodic handler */ ++ set_bit(QED_OVERFLOW_BIT, &p_hwfn->db_recovery_info.overflow); ++ ++ if (!p_hwfn->db_bar_no_edpm) { ++ rc = qed_db_rec_flush_queue(p_hwfn, p_ptt); ++ if (rc) ++ goto out; ++ } ++ ++ qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY, 0x0); ++out: ++ /* Schedule the handler even if overflow was not detected */ ++ qed_periodic_db_rec_start(p_hwfn); ++} ++ ++static int qed_dorq_attn_int_sts(struct qed_hwfn *p_hwfn) ++{ ++ u32 int_sts, first_drop_reason, details, address, all_drops_reason; ++ struct qed_ptt *p_ptt = p_hwfn->p_dpc_ptt; + + /* int_sts may be zero since all PFs were interrupted for doorbell + * overflow but another one already handled it. Can abort here. If + * This PF also requires overflow recovery we will be interrupted again. + * The masked almost full indication may also be set. Ignoring. + */ ++ int_sts = qed_rd(p_hwfn, p_ptt, DORQ_REG_INT_STS); + if (!(int_sts & ~DORQ_REG_INT_STS_DORQ_FIFO_AFULL)) + return 0; + ++ DP_NOTICE(p_hwfn->cdev, "DORQ attention. int_sts was %x\n", int_sts); ++ + /* check if db_drop or overflow happened */ + if (int_sts & (DORQ_REG_INT_STS_DB_DROP | + DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR)) { +@@ -475,11 +501,6 @@ static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn) + GET_FIELD(details, QED_DORQ_ATTENTION_SIZE) * 4, + first_drop_reason, all_drops_reason); + +- rc = qed_db_rec_handler(p_hwfn, p_ptt); +- qed_periodic_db_rec_start(p_hwfn); +- if (rc) +- return rc; +- + /* Clear the doorbell drop details and prepare for next drop */ + qed_wr(p_hwfn, p_ptt, DORQ_REG_DB_DROP_DETAILS_REL, 0); + +@@ -505,6 +526,25 @@ static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn) + return -EINVAL; + } + ++static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn) ++{ ++ p_hwfn->db_recovery_info.dorq_attn = true; ++ qed_dorq_attn_overflow(p_hwfn); ++ ++ return qed_dorq_attn_int_sts(p_hwfn); ++} ++ ++static void qed_dorq_attn_handler(struct qed_hwfn *p_hwfn) ++{ ++ if (p_hwfn->db_recovery_info.dorq_attn) ++ goto out; ++ ++ /* Call DORQ callback if the attention was missed */ ++ qed_dorq_attn_cb(p_hwfn); ++out: ++ p_hwfn->db_recovery_info.dorq_attn = false; ++} ++ + /* Instead of major changes to the data-structure, we have a some 'special' + * identifiers for sources that changed meaning between adapters. + */ +@@ -1078,6 +1118,9 @@ static int qed_int_deassertion(struct qed_hwfn *p_hwfn, + } + } + ++ /* Handle missed DORQ attention */ ++ qed_dorq_attn_handler(p_hwfn); ++ + /* Clear IGU indication for the deasserted bits */ + DIRECT_REG_WR((u8 __iomem *)p_hwfn->regview + + GTT_BAR0_MAP_REG_IGU_CMD + +diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.h b/drivers/net/ethernet/qlogic/qed/qed_int.h +index d81a62ebd524..df26bf333893 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_int.h ++++ b/drivers/net/ethernet/qlogic/qed/qed_int.h +@@ -192,8 +192,8 @@ void qed_int_disable_post_isr_release(struct qed_dev *cdev); + + /** + * @brief - Doorbell Recovery handler. +- * Run DB_REAL_DEAL doorbell recovery in case of PF overflow +- * (and flush DORQ if needed), otherwise run DB_REC_ONCE. ++ * Run doorbell recovery in case of PF overflow (and flush DORQ if ++ * needed). + * + * @param p_hwfn + * @param p_ptt +diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c +index 6adf5bda9811..26bfcbeebc4c 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_main.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_main.c +@@ -966,7 +966,7 @@ static void qed_update_pf_params(struct qed_dev *cdev, + } + } + +-#define QED_PERIODIC_DB_REC_COUNT 100 ++#define QED_PERIODIC_DB_REC_COUNT 10 + #define QED_PERIODIC_DB_REC_INTERVAL_MS 100 + #define QED_PERIODIC_DB_REC_INTERVAL \ + msecs_to_jiffies(QED_PERIODIC_DB_REC_INTERVAL_MS) +diff --git a/drivers/net/ethernet/qlogic/qede/qede_ptp.c b/drivers/net/ethernet/qlogic/qede/qede_ptp.c +index 5f3f42a25361..bddb2b5982dc 100644 +--- a/drivers/net/ethernet/qlogic/qede/qede_ptp.c ++++ b/drivers/net/ethernet/qlogic/qede/qede_ptp.c +@@ -490,18 +490,17 @@ int qede_ptp_enable(struct qede_dev *edev, bool init_tc) + + ptp->clock = ptp_clock_register(&ptp->clock_info, &edev->pdev->dev); + if (IS_ERR(ptp->clock)) { +- rc = -EINVAL; + DP_ERR(edev, "PTP clock registration failed\n"); ++ qede_ptp_disable(edev); ++ rc = -EINVAL; + goto err2; + } + + return 0; + +-err2: +- qede_ptp_disable(edev); +- ptp->clock = NULL; + err1: + kfree(ptp); ++err2: + edev->ptp = NULL; + + return rc; +diff --git a/drivers/net/ethernet/seeq/sgiseeq.c b/drivers/net/ethernet/seeq/sgiseeq.c +index 70cce63a6081..696037d5ac3d 100644 +--- a/drivers/net/ethernet/seeq/sgiseeq.c ++++ b/drivers/net/ethernet/seeq/sgiseeq.c +@@ -735,6 +735,7 @@ static int sgiseeq_probe(struct platform_device *pdev) + } + + platform_set_drvdata(pdev, dev); ++ SET_NETDEV_DEV(dev, &pdev->dev); + sp = netdev_priv(dev); + + /* Make private data page aligned */ +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +index 0f660af01a4b..49a896a16391 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +@@ -1015,6 +1015,8 @@ static struct mac_device_info *sun8i_dwmac_setup(void *ppriv) + mac->mac = &sun8i_dwmac_ops; + mac->dma = &sun8i_dwmac_dma_ops; + ++ priv->dev->priv_flags |= IFF_UNICAST_FLT; ++ + /* The loopback bit seems to be re-set when link change + * Simply mask it each time + * Speed 10/100/1000 are set in BIT(2)/BIT(3) +diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c +index adf79614c2db..ff2426e00682 100644 +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -2083,11 +2083,14 @@ bool phy_validate_pause(struct phy_device *phydev, + struct ethtool_pauseparam *pp) + { + if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, +- phydev->supported) || +- (!linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, +- phydev->supported) && +- pp->rx_pause != pp->tx_pause)) ++ phydev->supported) && pp->rx_pause) + return false; ++ ++ if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, ++ phydev->supported) && ++ pp->rx_pause != pp->tx_pause) ++ return false; ++ + return true; + } + EXPORT_SYMBOL(phy_validate_pause); +diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c +index f17b3441779b..d8ea4147dfe7 100644 +--- a/drivers/net/phy/spi_ks8995.c ++++ b/drivers/net/phy/spi_ks8995.c +@@ -162,6 +162,14 @@ static const struct spi_device_id ks8995_id[] = { + }; + MODULE_DEVICE_TABLE(spi, ks8995_id); + ++static const struct of_device_id ks8895_spi_of_match[] = { ++ { .compatible = "micrel,ks8995" }, ++ { .compatible = "micrel,ksz8864" }, ++ { .compatible = "micrel,ksz8795" }, ++ { }, ++ }; ++MODULE_DEVICE_TABLE(of, ks8895_spi_of_match); ++ + static inline u8 get_chip_id(u8 val) + { + return (val >> ID1_CHIPID_S) & ID1_CHIPID_M; +@@ -529,6 +537,7 @@ static int ks8995_remove(struct spi_device *spi) + static struct spi_driver ks8995_driver = { + .driver = { + .name = "spi-ks8995", ++ .of_match_table = of_match_ptr(ks8895_spi_of_match), + }, + .probe = ks8995_probe, + .remove = ks8995_remove, +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index 448d5439ff6a..8888c097375b 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -596,13 +596,18 @@ static u16 tun_automq_select_queue(struct tun_struct *tun, struct sk_buff *skb) + static u16 tun_ebpf_select_queue(struct tun_struct *tun, struct sk_buff *skb) + { + struct tun_prog *prog; ++ u32 numqueues; + u16 ret = 0; + ++ numqueues = READ_ONCE(tun->numqueues); ++ if (!numqueues) ++ return 0; ++ + prog = rcu_dereference(tun->steering_prog); + if (prog) + ret = bpf_prog_run_clear_cb(prog->prog, skb); + +- return ret % tun->numqueues; ++ return ret % numqueues; + } + + static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, +@@ -700,6 +705,8 @@ static void __tun_detach(struct tun_file *tfile, bool clean) + tun->tfiles[tun->numqueues - 1]); + ntfile = rtnl_dereference(tun->tfiles[index]); + ntfile->queue_index = index; ++ rcu_assign_pointer(tun->tfiles[tun->numqueues - 1], ++ NULL); + + --tun->numqueues; + if (clean) { +@@ -1082,7 +1089,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) + tfile = rcu_dereference(tun->tfiles[txq]); + + /* Drop packet if interface is not attached */ +- if (txq >= tun->numqueues) ++ if (!tfile) + goto drop; + + if (!rcu_dereference(tun->steering_prog)) +@@ -1305,6 +1312,7 @@ static int tun_xdp_xmit(struct net_device *dev, int n, + + rcu_read_lock(); + ++resample: + numqueues = READ_ONCE(tun->numqueues); + if (!numqueues) { + rcu_read_unlock(); +@@ -1313,6 +1321,8 @@ static int tun_xdp_xmit(struct net_device *dev, int n, + + tfile = rcu_dereference(tun->tfiles[smp_processor_id() % + numqueues]); ++ if (unlikely(!tfile)) ++ goto resample; + + spin_lock(&tfile->tx_ring.producer_lock); + for (i = 0; i < n; i++) { +diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c +index cd15c32b2e43..9ee4d7402ca2 100644 +--- a/drivers/net/vrf.c ++++ b/drivers/net/vrf.c +@@ -875,6 +875,7 @@ static const struct net_device_ops vrf_netdev_ops = { + .ndo_init = vrf_dev_init, + .ndo_uninit = vrf_dev_uninit, + .ndo_start_xmit = vrf_xmit, ++ .ndo_set_mac_address = eth_mac_addr, + .ndo_get_stats64 = vrf_get_stats64, + .ndo_add_slave = vrf_add_slave, + .ndo_del_slave = vrf_del_slave, +@@ -1274,6 +1275,7 @@ static void vrf_setup(struct net_device *dev) + /* default to no qdisc; user can add if desired */ + dev->priv_flags |= IFF_NO_QUEUE; + dev->priv_flags |= IFF_NO_RX_HANDLER; ++ dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; + + /* VRF devices do not care about MTU, but if the MTU is set + * too low then the ipv4 and ipv6 protocols are disabled +diff --git a/drivers/net/wireless/marvell/mwl8k.c b/drivers/net/wireless/marvell/mwl8k.c +index 8e4e9b6919e0..ffc565ac2192 100644 +--- a/drivers/net/wireless/marvell/mwl8k.c ++++ b/drivers/net/wireless/marvell/mwl8k.c +@@ -441,6 +441,9 @@ static const struct ieee80211_rate mwl8k_rates_50[] = { + #define MWL8K_CMD_UPDATE_STADB 0x1123 + #define MWL8K_CMD_BASTREAM 0x1125 + ++#define MWL8K_LEGACY_5G_RATE_OFFSET \ ++ (ARRAY_SIZE(mwl8k_rates_24) - ARRAY_SIZE(mwl8k_rates_50)) ++ + static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize) + { + u16 command = le16_to_cpu(cmd); +@@ -1016,8 +1019,9 @@ mwl8k_rxd_ap_process(void *_rxd, struct ieee80211_rx_status *status, + + if (rxd->channel > 14) { + status->band = NL80211_BAND_5GHZ; +- if (!(status->encoding == RX_ENC_HT)) +- status->rate_idx -= 5; ++ if (!(status->encoding == RX_ENC_HT) && ++ status->rate_idx >= MWL8K_LEGACY_5G_RATE_OFFSET) ++ status->rate_idx -= MWL8K_LEGACY_5G_RATE_OFFSET; + } else { + status->band = NL80211_BAND_2GHZ; + } +@@ -1124,8 +1128,9 @@ mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status, + + if (rxd->channel > 14) { + status->band = NL80211_BAND_5GHZ; +- if (!(status->encoding == RX_ENC_HT)) +- status->rate_idx -= 5; ++ if (!(status->encoding == RX_ENC_HT) && ++ status->rate_idx >= MWL8K_LEGACY_5G_RATE_OFFSET) ++ status->rate_idx -= MWL8K_LEGACY_5G_RATE_OFFSET; + } else { + status->band = NL80211_BAND_2GHZ; + } +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c +index f783e4a8083d..0de7551ae14a 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hw.c +@@ -1697,6 +1697,7 @@ static void _rtl8723e_read_adapter_info(struct ieee80211_hw *hw, + rtlhal->oem_id = RT_CID_819X_LENOVO; + break; + } ++ break; + case 0x1025: + rtlhal->oem_id = RT_CID_819X_ACER; + break; +diff --git a/drivers/net/wireless/st/cw1200/scan.c b/drivers/net/wireless/st/cw1200/scan.c +index 0a9eac93dd01..71e9b91cf15b 100644 +--- a/drivers/net/wireless/st/cw1200/scan.c ++++ b/drivers/net/wireless/st/cw1200/scan.c +@@ -84,8 +84,11 @@ int cw1200_hw_scan(struct ieee80211_hw *hw, + + frame.skb = ieee80211_probereq_get(hw, priv->vif->addr, NULL, 0, + req->ie_len); +- if (!frame.skb) ++ if (!frame.skb) { ++ mutex_unlock(&priv->conf_mutex); ++ up(&priv->scan.lock); + return -ENOMEM; ++ } + + if (req->ie_len) + skb_put_data(frame.skb, req->ie, req->ie_len); +diff --git a/drivers/nfc/st95hf/core.c b/drivers/nfc/st95hf/core.c +index 2b26f762fbc3..01acb6e53365 100644 +--- a/drivers/nfc/st95hf/core.c ++++ b/drivers/nfc/st95hf/core.c +@@ -1074,6 +1074,12 @@ static const struct spi_device_id st95hf_id[] = { + }; + MODULE_DEVICE_TABLE(spi, st95hf_id); + ++static const struct of_device_id st95hf_spi_of_match[] = { ++ { .compatible = "st,st95hf" }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, st95hf_spi_of_match); ++ + static int st95hf_probe(struct spi_device *nfc_spi_dev) + { + int ret; +@@ -1260,6 +1266,7 @@ static struct spi_driver st95hf_driver = { + .driver = { + .name = "st95hf", + .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(st95hf_spi_of_match), + }, + .id_table = st95hf_id, + .probe = st95hf_probe, +diff --git a/drivers/nvdimm/btt_devs.c b/drivers/nvdimm/btt_devs.c +index 795ad4ff35ca..e341498876ca 100644 +--- a/drivers/nvdimm/btt_devs.c ++++ b/drivers/nvdimm/btt_devs.c +@@ -190,14 +190,15 @@ static struct device *__nd_btt_create(struct nd_region *nd_region, + return NULL; + + nd_btt->id = ida_simple_get(&nd_region->btt_ida, 0, 0, GFP_KERNEL); +- if (nd_btt->id < 0) { +- kfree(nd_btt); +- return NULL; +- } ++ if (nd_btt->id < 0) ++ goto out_nd_btt; + + nd_btt->lbasize = lbasize; +- if (uuid) ++ if (uuid) { + uuid = kmemdup(uuid, 16, GFP_KERNEL); ++ if (!uuid) ++ goto out_put_id; ++ } + nd_btt->uuid = uuid; + dev = &nd_btt->dev; + dev_set_name(dev, "btt%d.%d", nd_region->id, nd_btt->id); +@@ -212,6 +213,13 @@ static struct device *__nd_btt_create(struct nd_region *nd_region, + return NULL; + } + return dev; ++ ++out_put_id: ++ ida_simple_remove(&nd_region->btt_ida, nd_btt->id); ++ ++out_nd_btt: ++ kfree(nd_btt); ++ return NULL; + } + + struct device *nd_btt_create(struct nd_region *nd_region) +diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c +index 33a3b23b3db7..e761b29f7160 100644 +--- a/drivers/nvdimm/namespace_devs.c ++++ b/drivers/nvdimm/namespace_devs.c +@@ -2249,9 +2249,12 @@ static struct device *create_namespace_blk(struct nd_region *nd_region, + if (!nsblk->uuid) + goto blk_err; + memcpy(name, nd_label->name, NSLABEL_NAME_LEN); +- if (name[0]) ++ if (name[0]) { + nsblk->alt_name = kmemdup(name, NSLABEL_NAME_LEN, + GFP_KERNEL); ++ if (!nsblk->alt_name) ++ goto blk_err; ++ } + res = nsblk_add_resource(nd_region, ndd, nsblk, + __le64_to_cpu(nd_label->dpa)); + if (!res) +diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c +index bc2f700feef8..0279eb1da3ef 100644 +--- a/drivers/nvdimm/pmem.c ++++ b/drivers/nvdimm/pmem.c +@@ -113,13 +113,13 @@ static void write_pmem(void *pmem_addr, struct page *page, + + while (len) { + mem = kmap_atomic(page); +- chunk = min_t(unsigned int, len, PAGE_SIZE); ++ chunk = min_t(unsigned int, len, PAGE_SIZE - off); + memcpy_flushcache(pmem_addr, mem + off, chunk); + kunmap_atomic(mem); + len -= chunk; + off = 0; + page++; +- pmem_addr += PAGE_SIZE; ++ pmem_addr += chunk; + } + } + +@@ -132,7 +132,7 @@ static blk_status_t read_pmem(struct page *page, unsigned int off, + + while (len) { + mem = kmap_atomic(page); +- chunk = min_t(unsigned int, len, PAGE_SIZE); ++ chunk = min_t(unsigned int, len, PAGE_SIZE - off); + rem = memcpy_mcsafe(mem + off, pmem_addr, chunk); + kunmap_atomic(mem); + if (rem) +@@ -140,7 +140,7 @@ static blk_status_t read_pmem(struct page *page, unsigned int off, + len -= chunk; + off = 0; + page++; +- pmem_addr += PAGE_SIZE; ++ pmem_addr += chunk; + } + return BLK_STS_OK; + } +diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c +index f8bb746a549f..6bea6852bf27 100644 +--- a/drivers/nvdimm/security.c ++++ b/drivers/nvdimm/security.c +@@ -22,6 +22,8 @@ static bool key_revalidate = true; + module_param(key_revalidate, bool, 0444); + MODULE_PARM_DESC(key_revalidate, "Require key validation at init."); + ++static const char zero_key[NVDIMM_PASSPHRASE_LEN]; ++ + static void *key_data(struct key *key) + { + struct encrypted_key_payload *epayload = dereference_key_locked(key); +@@ -286,8 +288,9 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid, + { + struct device *dev = &nvdimm->dev; + struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); +- struct key *key; ++ struct key *key = NULL; + int rc; ++ const void *data; + + /* The bus lock should be held at the top level of the call stack */ + lockdep_assert_held(&nvdimm_bus->reconfig_mutex); +@@ -319,11 +322,15 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid, + return -EOPNOTSUPP; + } + +- key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY); +- if (!key) +- return -ENOKEY; ++ if (keyid != 0) { ++ key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY); ++ if (!key) ++ return -ENOKEY; ++ data = key_data(key); ++ } else ++ data = zero_key; + +- rc = nvdimm->sec.ops->erase(nvdimm, key_data(key), pass_type); ++ rc = nvdimm->sec.ops->erase(nvdimm, data, pass_type); + dev_dbg(dev, "key: %d erase%s: %s\n", key_serial(key), + pass_type == NVDIMM_MASTER ? "(master)" : "(user)", + rc == 0 ? "success" : "fail"); +diff --git a/drivers/of/of_net.c b/drivers/of/of_net.c +index 810ab0fbcccb..d820f3edd431 100644 +--- a/drivers/of/of_net.c ++++ b/drivers/of/of_net.c +@@ -7,7 +7,6 @@ + */ + #include <linux/etherdevice.h> + #include <linux/kernel.h> +-#include <linux/nvmem-consumer.h> + #include <linux/of_net.h> + #include <linux/phy.h> + #include <linux/export.h> +diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c +index 9ba4d12c179c..808a182830e5 100644 +--- a/drivers/pci/controller/pci-hyperv.c ++++ b/drivers/pci/controller/pci-hyperv.c +@@ -1491,6 +1491,21 @@ static void hv_pci_assign_slots(struct hv_pcibus_device *hbus) + } + } + ++/* ++ * Remove entries in sysfs pci slot directory. ++ */ ++static void hv_pci_remove_slots(struct hv_pcibus_device *hbus) ++{ ++ struct hv_pci_dev *hpdev; ++ ++ list_for_each_entry(hpdev, &hbus->children, list_entry) { ++ if (!hpdev->pci_slot) ++ continue; ++ pci_destroy_slot(hpdev->pci_slot); ++ hpdev->pci_slot = NULL; ++ } ++} ++ + /** + * create_root_hv_pci_bus() - Expose a new root PCI bus + * @hbus: Root PCI bus, as understood by this driver +@@ -1766,6 +1781,10 @@ static void pci_devices_present_work(struct work_struct *work) + hpdev = list_first_entry(&removed, struct hv_pci_dev, + list_entry); + list_del(&hpdev->list_entry); ++ ++ if (hpdev->pci_slot) ++ pci_destroy_slot(hpdev->pci_slot); ++ + put_pcichild(hpdev); + } + +@@ -1905,6 +1924,9 @@ static void hv_eject_device_work(struct work_struct *work) + sizeof(*ejct_pkt), (unsigned long)&ctxt.pkt, + VM_PKT_DATA_INBAND, 0); + ++ /* For the get_pcichild() in hv_pci_eject_device() */ ++ put_pcichild(hpdev); ++ /* For the two refs got in new_pcichild_device() */ + put_pcichild(hpdev); + put_pcichild(hpdev); + put_hvpcibus(hpdev->hbus); +@@ -2682,6 +2704,7 @@ static int hv_pci_remove(struct hv_device *hdev) + pci_lock_rescan_remove(); + pci_stop_root_bus(hbus->pci_bus); + pci_remove_root_bus(hbus->pci_bus); ++ hv_pci_remove_slots(hbus); + pci_unlock_rescan_remove(); + hbus->state = hv_pcibus_removed; + } +diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c +index 95e6ca116e00..a561f653cf13 100644 +--- a/drivers/platform/x86/dell-laptop.c ++++ b/drivers/platform/x86/dell-laptop.c +@@ -531,7 +531,7 @@ static void dell_rfkill_query(struct rfkill *rfkill, void *data) + return; + } + +- dell_fill_request(&buffer, 0, 0x2, 0, 0); ++ dell_fill_request(&buffer, 0x2, 0, 0, 0); + ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL); + hwswitch = buffer.output[1]; + +@@ -562,7 +562,7 @@ static int dell_debugfs_show(struct seq_file *s, void *data) + return ret; + status = buffer.output[1]; + +- dell_fill_request(&buffer, 0, 0x2, 0, 0); ++ dell_fill_request(&buffer, 0x2, 0, 0, 0); + hwswitch_ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL); + if (hwswitch_ret) + return hwswitch_ret; +@@ -647,7 +647,7 @@ static void dell_update_rfkill(struct work_struct *ignored) + if (ret != 0) + return; + +- dell_fill_request(&buffer, 0, 0x2, 0, 0); ++ dell_fill_request(&buffer, 0x2, 0, 0, 0); + ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL); + + if (ret == 0 && (status & BIT(0))) +diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c +index b205b037fd61..b50f8f73fb47 100644 +--- a/drivers/platform/x86/sony-laptop.c ++++ b/drivers/platform/x86/sony-laptop.c +@@ -4424,14 +4424,16 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) + } + return AE_OK; + } ++ ++ case ACPI_RESOURCE_TYPE_END_TAG: ++ return AE_OK; ++ + default: + dprintk("Resource %d isn't an IRQ nor an IO port\n", + resource->type); ++ return AE_CTRL_TERMINATE; + +- case ACPI_RESOURCE_TYPE_END_TAG: +- return AE_OK; + } +- return AE_CTRL_TERMINATE; + } + + static int sony_pic_possible_resources(struct acpi_device *device) +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index 726341f2b638..89ce14b35adc 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -79,7 +79,7 @@ + #include <linux/jiffies.h> + #include <linux/workqueue.h> + #include <linux/acpi.h> +-#include <linux/pci_ids.h> ++#include <linux/pci.h> + #include <linux/power_supply.h> + #include <sound/core.h> + #include <sound/control.h> +@@ -4501,6 +4501,74 @@ static void bluetooth_exit(void) + bluetooth_shutdown(); + } + ++static const struct dmi_system_id bt_fwbug_list[] __initconst = { ++ { ++ .ident = "ThinkPad E485", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_BOARD_NAME, "20KU"), ++ }, ++ }, ++ { ++ .ident = "ThinkPad E585", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_BOARD_NAME, "20KV"), ++ }, ++ }, ++ { ++ .ident = "ThinkPad A285 - 20MW", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_BOARD_NAME, "20MW"), ++ }, ++ }, ++ { ++ .ident = "ThinkPad A285 - 20MX", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_BOARD_NAME, "20MX"), ++ }, ++ }, ++ { ++ .ident = "ThinkPad A485 - 20MU", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_BOARD_NAME, "20MU"), ++ }, ++ }, ++ { ++ .ident = "ThinkPad A485 - 20MV", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_BOARD_NAME, "20MV"), ++ }, ++ }, ++ {} ++}; ++ ++static const struct pci_device_id fwbug_cards_ids[] __initconst = { ++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x24F3) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x24FD) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2526) }, ++ {} ++}; ++ ++ ++static int __init have_bt_fwbug(void) ++{ ++ /* ++ * Some AMD based ThinkPads have a firmware bug that calling ++ * "GBDC" will cause bluetooth on Intel wireless cards blocked ++ */ ++ if (dmi_check_system(bt_fwbug_list) && pci_dev_present(fwbug_cards_ids)) { ++ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, ++ FW_BUG "disable bluetooth subdriver for Intel cards\n"); ++ return 1; ++ } else ++ return 0; ++} ++ + static int __init bluetooth_init(struct ibm_init_struct *iibm) + { + int res; +@@ -4513,7 +4581,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm) + + /* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, + G4x, R30, R31, R40e, R50e, T20-22, X20-21 */ +- tp_features.bluetooth = hkey_handle && ++ tp_features.bluetooth = !have_bt_fwbug() && hkey_handle && + acpi_evalf(hkey_handle, &status, "GBDC", "qd"); + + vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, +diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c +index 6e294b4d3635..f89f9d02e788 100644 +--- a/drivers/s390/block/dasd_eckd.c ++++ b/drivers/s390/block/dasd_eckd.c +@@ -2004,14 +2004,14 @@ static int dasd_eckd_end_analysis(struct dasd_block *block) + blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block); + + raw: +- block->blocks = (private->real_cyl * ++ block->blocks = ((unsigned long) private->real_cyl * + private->rdc_data.trk_per_cyl * + blk_per_trk); + + dev_info(&device->cdev->dev, +- "DASD with %d KB/block, %d KB total size, %d KB/track, " ++ "DASD with %u KB/block, %lu KB total size, %u KB/track, " + "%s\n", (block->bp_block >> 10), +- ((private->real_cyl * ++ (((unsigned long) private->real_cyl * + private->rdc_data.trk_per_cyl * + blk_per_trk * (block->bp_block >> 9)) >> 1), + ((blk_per_trk * block->bp_block) >> 10), +diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c +index fd2146bcc0ad..e17364e13d2f 100644 +--- a/drivers/s390/char/con3270.c ++++ b/drivers/s390/char/con3270.c +@@ -629,7 +629,7 @@ con3270_init(void) + (void (*)(unsigned long)) con3270_read_tasklet, + (unsigned long) condev->read); + +- raw3270_add_view(&condev->view, &con3270_fn, 1); ++ raw3270_add_view(&condev->view, &con3270_fn, 1, RAW3270_VIEW_LOCK_IRQ); + + INIT_LIST_HEAD(&condev->freemem); + for (i = 0; i < CON3270_STRING_PAGES; i++) { +diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c +index 8f3a2eeb28dc..8b48ba9c598e 100644 +--- a/drivers/s390/char/fs3270.c ++++ b/drivers/s390/char/fs3270.c +@@ -463,7 +463,8 @@ fs3270_open(struct inode *inode, struct file *filp) + + init_waitqueue_head(&fp->wait); + fp->fs_pid = get_pid(task_pid(current)); +- rc = raw3270_add_view(&fp->view, &fs3270_fn, minor); ++ rc = raw3270_add_view(&fp->view, &fs3270_fn, minor, ++ RAW3270_VIEW_LOCK_BH); + if (rc) { + fs3270_free_view(&fp->view); + goto out; +diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c +index f8cd2935fbfd..63a41b168761 100644 +--- a/drivers/s390/char/raw3270.c ++++ b/drivers/s390/char/raw3270.c +@@ -920,7 +920,7 @@ raw3270_deactivate_view(struct raw3270_view *view) + * Add view to device with minor "minor". + */ + int +-raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor) ++raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor, int subclass) + { + unsigned long flags; + struct raw3270 *rp; +@@ -942,6 +942,7 @@ raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor) + view->cols = rp->cols; + view->ascebc = rp->ascebc; + spin_lock_init(&view->lock); ++ lockdep_set_subclass(&view->lock, subclass); + list_add(&view->list, &rp->view_list); + rc = 0; + spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags); +diff --git a/drivers/s390/char/raw3270.h b/drivers/s390/char/raw3270.h +index 114ca7cbf889..3afaa35f7351 100644 +--- a/drivers/s390/char/raw3270.h ++++ b/drivers/s390/char/raw3270.h +@@ -150,6 +150,8 @@ struct raw3270_fn { + struct raw3270_view { + struct list_head list; + spinlock_t lock; ++#define RAW3270_VIEW_LOCK_IRQ 0 ++#define RAW3270_VIEW_LOCK_BH 1 + atomic_t ref_count; + struct raw3270 *dev; + struct raw3270_fn *fn; +@@ -158,7 +160,7 @@ struct raw3270_view { + unsigned char *ascebc; /* ascii -> ebcdic table */ + }; + +-int raw3270_add_view(struct raw3270_view *, struct raw3270_fn *, int); ++int raw3270_add_view(struct raw3270_view *, struct raw3270_fn *, int, int); + int raw3270_activate_view(struct raw3270_view *); + void raw3270_del_view(struct raw3270_view *); + void raw3270_deactivate_view(struct raw3270_view *); +diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c +index 2b0c36c2c568..98d7fc152e32 100644 +--- a/drivers/s390/char/tty3270.c ++++ b/drivers/s390/char/tty3270.c +@@ -980,7 +980,8 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty) + return PTR_ERR(tp); + + rc = raw3270_add_view(&tp->view, &tty3270_fn, +- tty->index + RAW3270_FIRSTMINOR); ++ tty->index + RAW3270_FIRSTMINOR, ++ RAW3270_VIEW_LOCK_BH); + if (rc) { + tty3270_free_view(tp); + return rc; +diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c +index 2f92bbed4bf6..097e890e0d6d 100644 +--- a/drivers/s390/crypto/pkey_api.c ++++ b/drivers/s390/crypto/pkey_api.c +@@ -51,7 +51,8 @@ static debug_info_t *debug_info; + + static void __init pkey_debug_init(void) + { +- debug_info = debug_register("pkey", 1, 1, 4 * sizeof(long)); ++ /* 5 arguments per dbf entry (including the format string ptr) */ ++ debug_info = debug_register("pkey", 1, 1, 5 * sizeof(long)); + debug_register_view(debug_info, &debug_sprintf_view); + debug_set_level(debug_info, 3); + } +diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c +index 7617d21cb296..f63c5c871d3d 100644 +--- a/drivers/s390/net/ctcm_main.c ++++ b/drivers/s390/net/ctcm_main.c +@@ -1595,6 +1595,7 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev) + if (priv->channel[direction] == NULL) { + if (direction == CTCM_WRITE) + channel_free(priv->channel[CTCM_READ]); ++ result = -ENODEV; + goto out_dev; + } + priv->channel[direction]->netdev = dev; +diff --git a/drivers/scsi/aic7xxx/aic7770_osm.c b/drivers/scsi/aic7xxx/aic7770_osm.c +index 3d401d02c019..bdd177e3d762 100644 +--- a/drivers/scsi/aic7xxx/aic7770_osm.c ++++ b/drivers/scsi/aic7xxx/aic7770_osm.c +@@ -91,6 +91,7 @@ aic7770_probe(struct device *dev) + ahc = ahc_alloc(&aic7xxx_driver_template, name); + if (ahc == NULL) + return (ENOMEM); ++ ahc->dev = dev; + error = aic7770_config(ahc, aic7770_ident_table + edev->id.driver_data, + eisaBase); + if (error != 0) { +diff --git a/drivers/scsi/aic7xxx/aic7xxx.h b/drivers/scsi/aic7xxx/aic7xxx.h +index 5614921b4041..88b90f9806c9 100644 +--- a/drivers/scsi/aic7xxx/aic7xxx.h ++++ b/drivers/scsi/aic7xxx/aic7xxx.h +@@ -943,6 +943,7 @@ struct ahc_softc { + * Platform specific device information. + */ + ahc_dev_softc_t dev_softc; ++ struct device *dev; + + /* + * Bus specific device information. +diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c +index 3c9c17450bb3..d5c4a0d23706 100644 +--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c ++++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c +@@ -860,8 +860,8 @@ int + ahc_dmamem_alloc(struct ahc_softc *ahc, bus_dma_tag_t dmat, void** vaddr, + int flags, bus_dmamap_t *mapp) + { +- *vaddr = pci_alloc_consistent(ahc->dev_softc, +- dmat->maxsize, mapp); ++ /* XXX: check if we really need the GFP_ATOMIC and unwind this mess! */ ++ *vaddr = dma_alloc_coherent(ahc->dev, dmat->maxsize, mapp, GFP_ATOMIC); + if (*vaddr == NULL) + return ENOMEM; + return 0; +@@ -871,8 +871,7 @@ void + ahc_dmamem_free(struct ahc_softc *ahc, bus_dma_tag_t dmat, + void* vaddr, bus_dmamap_t map) + { +- pci_free_consistent(ahc->dev_softc, dmat->maxsize, +- vaddr, map); ++ dma_free_coherent(ahc->dev, dmat->maxsize, vaddr, map); + } + + int +@@ -1123,8 +1122,7 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa + + host->transportt = ahc_linux_transport_template; + +- retval = scsi_add_host(host, +- (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); ++ retval = scsi_add_host(host, ahc->dev); + if (retval) { + printk(KERN_WARNING "aic7xxx: scsi_add_host failed\n"); + scsi_host_put(host); +diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +index 0fc14dac7070..717d8d1082ce 100644 +--- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c ++++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +@@ -250,6 +250,7 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + } + } + ahc->dev_softc = pci; ++ ahc->dev = &pci->dev; + error = ahc_pci_config(ahc, entry); + if (error != 0) { + ahc_free(ahc); +diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c +index 2274d9625f63..0fff4968ea1b 100644 +--- a/drivers/usb/serial/generic.c ++++ b/drivers/usb/serial/generic.c +@@ -376,6 +376,7 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb) + struct usb_serial_port *port = urb->context; + unsigned char *data = urb->transfer_buffer; + unsigned long flags; ++ bool stopped = false; + int status = urb->status; + int i; + +@@ -383,33 +384,51 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb) + if (urb == port->read_urbs[i]) + break; + } +- set_bit(i, &port->read_urbs_free); + + dev_dbg(&port->dev, "%s - urb %d, len %d\n", __func__, i, + urb->actual_length); + switch (status) { + case 0: ++ usb_serial_debug_data(&port->dev, __func__, urb->actual_length, ++ data); ++ port->serial->type->process_read_urb(urb); + break; + case -ENOENT: + case -ECONNRESET: + case -ESHUTDOWN: + dev_dbg(&port->dev, "%s - urb stopped: %d\n", + __func__, status); +- return; ++ stopped = true; ++ break; + case -EPIPE: + dev_err(&port->dev, "%s - urb stopped: %d\n", + __func__, status); +- return; ++ stopped = true; ++ break; + default: + dev_dbg(&port->dev, "%s - nonzero urb status: %d\n", + __func__, status); +- goto resubmit; ++ break; + } + +- usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); +- port->serial->type->process_read_urb(urb); ++ /* ++ * Make sure URB processing is done before marking as free to avoid ++ * racing with unthrottle() on another CPU. Matches the barriers ++ * implied by the test_and_clear_bit() in ++ * usb_serial_generic_submit_read_urb(). ++ */ ++ smp_mb__before_atomic(); ++ set_bit(i, &port->read_urbs_free); ++ /* ++ * Make sure URB is marked as free before checking the throttled flag ++ * to avoid racing with unthrottle() on another CPU. Matches the ++ * smp_mb() in unthrottle(). ++ */ ++ smp_mb__after_atomic(); ++ ++ if (stopped) ++ return; + +-resubmit: + /* Throttle the device if requested by tty */ + spin_lock_irqsave(&port->lock, flags); + port->throttled = port->throttle_req; +@@ -484,6 +503,12 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty) + port->throttled = port->throttle_req = 0; + spin_unlock_irq(&port->lock); + ++ /* ++ * Matches the smp_mb__after_atomic() in ++ * usb_serial_generic_read_bulk_callback(). ++ */ ++ smp_mb(); ++ + if (was_throttled) + usb_serial_generic_submit_read_urbs(port, GFP_KERNEL); + } +diff --git a/drivers/virt/fsl_hypervisor.c b/drivers/virt/fsl_hypervisor.c +index 8ba726e600e9..1bbd910d4ddb 100644 +--- a/drivers/virt/fsl_hypervisor.c ++++ b/drivers/virt/fsl_hypervisor.c +@@ -215,6 +215,9 @@ static long ioctl_memcpy(struct fsl_hv_ioctl_memcpy __user *p) + * hypervisor. + */ + lb_offset = param.local_vaddr & (PAGE_SIZE - 1); ++ if (param.count == 0 || ++ param.count > U64_MAX - lb_offset - PAGE_SIZE + 1) ++ return -EINVAL; + num_pages = (param.count + lb_offset + PAGE_SIZE - 1) >> PAGE_SHIFT; + + /* Allocate the buffers we need */ +@@ -331,8 +334,8 @@ static long ioctl_dtprop(struct fsl_hv_ioctl_prop __user *p, int set) + struct fsl_hv_ioctl_prop param; + char __user *upath, *upropname; + void __user *upropval; +- char *path = NULL, *propname = NULL; +- void *propval = NULL; ++ char *path, *propname; ++ void *propval; + int ret = 0; + + /* Get the parameters from the user. */ +@@ -344,32 +347,30 @@ static long ioctl_dtprop(struct fsl_hv_ioctl_prop __user *p, int set) + upropval = (void __user *)(uintptr_t)param.propval; + + path = strndup_user(upath, FH_DTPROP_MAX_PATHLEN); +- if (IS_ERR(path)) { +- ret = PTR_ERR(path); +- goto out; +- } ++ if (IS_ERR(path)) ++ return PTR_ERR(path); + + propname = strndup_user(upropname, FH_DTPROP_MAX_PATHLEN); + if (IS_ERR(propname)) { + ret = PTR_ERR(propname); +- goto out; ++ goto err_free_path; + } + + if (param.proplen > FH_DTPROP_MAX_PROPLEN) { + ret = -EINVAL; +- goto out; ++ goto err_free_propname; + } + + propval = kmalloc(param.proplen, GFP_KERNEL); + if (!propval) { + ret = -ENOMEM; +- goto out; ++ goto err_free_propname; + } + + if (set) { + if (copy_from_user(propval, upropval, param.proplen)) { + ret = -EFAULT; +- goto out; ++ goto err_free_propval; + } + + param.ret = fh_partition_set_dtprop(param.handle, +@@ -388,7 +389,7 @@ static long ioctl_dtprop(struct fsl_hv_ioctl_prop __user *p, int set) + if (copy_to_user(upropval, propval, param.proplen) || + put_user(param.proplen, &p->proplen)) { + ret = -EFAULT; +- goto out; ++ goto err_free_propval; + } + } + } +@@ -396,10 +397,12 @@ static long ioctl_dtprop(struct fsl_hv_ioctl_prop __user *p, int set) + if (put_user(param.ret, &p->ret)) + ret = -EFAULT; + +-out: +- kfree(path); ++err_free_propval: + kfree(propval); ++err_free_propname: + kfree(propname); ++err_free_path: ++ kfree(path); + + return ret; + } +diff --git a/drivers/virt/vboxguest/vboxguest_core.c b/drivers/virt/vboxguest/vboxguest_core.c +index 1475ed5ffcde..0afef60d0638 100644 +--- a/drivers/virt/vboxguest/vboxguest_core.c ++++ b/drivers/virt/vboxguest/vboxguest_core.c +@@ -1263,6 +1263,20 @@ static int vbg_ioctl_hgcm_disconnect(struct vbg_dev *gdev, + return ret; + } + ++static bool vbg_param_valid(enum vmmdev_hgcm_function_parameter_type type) ++{ ++ switch (type) { ++ case VMMDEV_HGCM_PARM_TYPE_32BIT: ++ case VMMDEV_HGCM_PARM_TYPE_64BIT: ++ case VMMDEV_HGCM_PARM_TYPE_LINADDR: ++ case VMMDEV_HGCM_PARM_TYPE_LINADDR_IN: ++ case VMMDEV_HGCM_PARM_TYPE_LINADDR_OUT: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static int vbg_ioctl_hgcm_call(struct vbg_dev *gdev, + struct vbg_session *session, bool f32bit, + struct vbg_ioctl_hgcm_call *call) +@@ -1298,6 +1312,23 @@ static int vbg_ioctl_hgcm_call(struct vbg_dev *gdev, + } + call->hdr.size_out = actual_size; + ++ /* Validate parameter types */ ++ if (f32bit) { ++ struct vmmdev_hgcm_function_parameter32 *parm = ++ VBG_IOCTL_HGCM_CALL_PARMS32(call); ++ ++ for (i = 0; i < call->parm_count; i++) ++ if (!vbg_param_valid(parm[i].type)) ++ return -EINVAL; ++ } else { ++ struct vmmdev_hgcm_function_parameter *parm = ++ VBG_IOCTL_HGCM_CALL_PARMS(call); ++ ++ for (i = 0; i < call->parm_count; i++) ++ if (!vbg_param_valid(parm[i].type)) ++ return -EINVAL; ++ } ++ + /* + * Validate the client id. + */ +diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c +index a38b65b97be0..a659e52cf79c 100644 +--- a/drivers/virtio/virtio_ring.c ++++ b/drivers/virtio/virtio_ring.c +@@ -993,6 +993,7 @@ static int virtqueue_add_indirect_packed(struct vring_virtqueue *vq, + + if (unlikely(vq->vq.num_free < 1)) { + pr_debug("Can't add buf len 1 - avail = 0\n"); ++ kfree(desc); + END_USE(vq); + return -ENOSPC; + } +diff --git a/fs/afs/callback.c b/fs/afs/callback.c +index 1c7955f5cdaf..128f2dbe256a 100644 +--- a/fs/afs/callback.c ++++ b/fs/afs/callback.c +@@ -203,8 +203,7 @@ void afs_put_cb_interest(struct afs_net *net, struct afs_cb_interest *cbi) + */ + void afs_init_callback_state(struct afs_server *server) + { +- if (!test_and_clear_bit(AFS_SERVER_FL_NEW, &server->flags)) +- server->cb_s_break++; ++ server->cb_s_break++; + } + + /* +diff --git a/fs/afs/internal.h b/fs/afs/internal.h +index 8871b9e8645f..465526f495b0 100644 +--- a/fs/afs/internal.h ++++ b/fs/afs/internal.h +@@ -475,7 +475,6 @@ struct afs_server { + time64_t put_time; /* Time at which last put */ + time64_t update_at; /* Time at which to next update the record */ + unsigned long flags; +-#define AFS_SERVER_FL_NEW 0 /* New server, don't inc cb_s_break */ + #define AFS_SERVER_FL_NOT_READY 1 /* The record is not ready for use */ + #define AFS_SERVER_FL_NOT_FOUND 2 /* VL server says no such server */ + #define AFS_SERVER_FL_VL_FAIL 3 /* Failed to access VL server */ +@@ -828,7 +827,7 @@ static inline struct afs_cb_interest *afs_get_cb_interest(struct afs_cb_interest + + static inline unsigned int afs_calc_vnode_cb_break(struct afs_vnode *vnode) + { +- return vnode->cb_break + vnode->cb_s_break + vnode->cb_v_break; ++ return vnode->cb_break + vnode->cb_v_break; + } + + static inline bool afs_cb_is_broken(unsigned int cb_break, +@@ -836,7 +835,6 @@ static inline bool afs_cb_is_broken(unsigned int cb_break, + const struct afs_cb_interest *cbi) + { + return !cbi || cb_break != (vnode->cb_break + +- cbi->server->cb_s_break + + vnode->volume->cb_v_break); + } + +diff --git a/fs/afs/server.c b/fs/afs/server.c +index 642afa2e9783..65b33b6da48b 100644 +--- a/fs/afs/server.c ++++ b/fs/afs/server.c +@@ -226,7 +226,6 @@ static struct afs_server *afs_alloc_server(struct afs_net *net, + RCU_INIT_POINTER(server->addresses, alist); + server->addr_version = alist->version; + server->uuid = *uuid; +- server->flags = (1UL << AFS_SERVER_FL_NEW); + server->update_at = ktime_get_real_seconds() + afs_server_update_delay; + rwlock_init(&server->fs_lock); + INIT_HLIST_HEAD(&server->cb_volumes); +diff --git a/fs/afs/write.c b/fs/afs/write.c +index 72efcfcf9f95..0122d7445fba 100644 +--- a/fs/afs/write.c ++++ b/fs/afs/write.c +@@ -264,6 +264,7 @@ static void afs_kill_pages(struct address_space *mapping, + first = page->index + 1; + lock_page(page); + generic_error_remove_page(mapping, page); ++ unlock_page(page); + } + + __pagevec_release(&pv); +diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c +index f7f9e305aaf8..fd3db2e112d6 100644 +--- a/fs/ceph/inode.c ++++ b/fs/ceph/inode.c +@@ -1152,6 +1152,19 @@ static int splice_dentry(struct dentry **pdn, struct inode *in) + return 0; + } + ++static int d_name_cmp(struct dentry *dentry, const char *name, size_t len) ++{ ++ int ret; ++ ++ /* take d_lock to ensure dentry->d_name stability */ ++ spin_lock(&dentry->d_lock); ++ ret = dentry->d_name.len - len; ++ if (!ret) ++ ret = memcmp(dentry->d_name.name, name, len); ++ spin_unlock(&dentry->d_lock); ++ return ret; ++} ++ + /* + * Incorporate results into the local cache. This is either just + * one inode, or a directory, dentry, and possibly linked-to inode (e.g., +@@ -1401,7 +1414,8 @@ retry_lookup: + err = splice_dentry(&req->r_dentry, in); + if (err < 0) + goto done; +- } else if (rinfo->head->is_dentry) { ++ } else if (rinfo->head->is_dentry && ++ !d_name_cmp(req->r_dentry, rinfo->dname, rinfo->dname_len)) { + struct ceph_vino *ptvino = NULL; + + if ((le32_to_cpu(rinfo->diri.in->cap.caps) & CEPH_CAP_FILE_SHARED) || +diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c +index c99aab23efea..6e598dd85fb5 100644 +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -218,12 +218,14 @@ struct block_device *f2fs_target_device(struct f2fs_sb_info *sbi, + struct block_device *bdev = sbi->sb->s_bdev; + int i; + +- for (i = 0; i < sbi->s_ndevs; i++) { +- if (FDEV(i).start_blk <= blk_addr && +- FDEV(i).end_blk >= blk_addr) { +- blk_addr -= FDEV(i).start_blk; +- bdev = FDEV(i).bdev; +- break; ++ if (f2fs_is_multi_device(sbi)) { ++ for (i = 0; i < sbi->s_ndevs; i++) { ++ if (FDEV(i).start_blk <= blk_addr && ++ FDEV(i).end_blk >= blk_addr) { ++ blk_addr -= FDEV(i).start_blk; ++ bdev = FDEV(i).bdev; ++ break; ++ } + } + } + if (bio) { +@@ -237,6 +239,9 @@ int f2fs_target_device_index(struct f2fs_sb_info *sbi, block_t blkaddr) + { + int i; + ++ if (!f2fs_is_multi_device(sbi)) ++ return 0; ++ + for (i = 0; i < sbi->s_ndevs; i++) + if (FDEV(i).start_blk <= blkaddr && FDEV(i).end_blk >= blkaddr) + return i; +diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h +index 6d9186a6528c..48f1bbf3e87e 100644 +--- a/fs/f2fs/f2fs.h ++++ b/fs/f2fs/f2fs.h +@@ -1364,6 +1364,17 @@ static inline bool time_to_inject(struct f2fs_sb_info *sbi, int type) + } + #endif + ++/* ++ * Test if the mounted volume is a multi-device volume. ++ * - For a single regular disk volume, sbi->s_ndevs is 0. ++ * - For a single zoned disk volume, sbi->s_ndevs is 1. ++ * - For a multi-device volume, sbi->s_ndevs is always 2 or more. ++ */ ++static inline bool f2fs_is_multi_device(struct f2fs_sb_info *sbi) ++{ ++ return sbi->s_ndevs > 1; ++} ++ + /* For write statistics. Suppose sector size is 512 bytes, + * and the return value is in kbytes. s is of struct f2fs_sb_info. + */ +@@ -3612,7 +3623,7 @@ static inline bool f2fs_force_buffered_io(struct inode *inode, + + if (f2fs_post_read_required(inode)) + return true; +- if (sbi->s_ndevs) ++ if (f2fs_is_multi_device(sbi)) + return true; + /* + * for blkzoned device, fallback direct IO to buffered IO, so +diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c +index 30ed43bce110..bc078aea60ae 100644 +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -2570,7 +2570,7 @@ static int f2fs_ioc_flush_device(struct file *filp, unsigned long arg) + sizeof(range))) + return -EFAULT; + +- if (sbi->s_ndevs <= 1 || sbi->s_ndevs - 1 <= range.dev_num || ++ if (!f2fs_is_multi_device(sbi) || sbi->s_ndevs - 1 <= range.dev_num || + __is_large_section(sbi)) { + f2fs_msg(sbi->sb, KERN_WARNING, + "Can't flush %u in %d for segs_per_sec %u != 1\n", +diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c +index 195cf0f9d9ef..ab764bd106de 100644 +--- a/fs/f2fs/gc.c ++++ b/fs/f2fs/gc.c +@@ -1346,7 +1346,7 @@ void f2fs_build_gc_manager(struct f2fs_sb_info *sbi) + sbi->gc_pin_file_threshold = DEF_GC_FAILED_PINNED_FILES; + + /* give warm/cold data area from slower device */ +- if (sbi->s_ndevs && !__is_large_section(sbi)) ++ if (f2fs_is_multi_device(sbi) && !__is_large_section(sbi)) + SIT_I(sbi)->last_victim[ALLOC_NEXT] = + GET_SEGNO(sbi, FDEV(0).end_blk) + 1; + } +diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c +index b6c8b0696ef6..2b809b54d81b 100644 +--- a/fs/f2fs/segment.c ++++ b/fs/f2fs/segment.c +@@ -576,7 +576,7 @@ static int submit_flush_wait(struct f2fs_sb_info *sbi, nid_t ino) + int ret = 0; + int i; + +- if (!sbi->s_ndevs) ++ if (!f2fs_is_multi_device(sbi)) + return __submit_flush_wait(sbi, sbi->sb->s_bdev); + + for (i = 0; i < sbi->s_ndevs; i++) { +@@ -644,7 +644,8 @@ int f2fs_issue_flush(struct f2fs_sb_info *sbi, nid_t ino) + return ret; + } + +- if (atomic_inc_return(&fcc->queued_flush) == 1 || sbi->s_ndevs > 1) { ++ if (atomic_inc_return(&fcc->queued_flush) == 1 || ++ f2fs_is_multi_device(sbi)) { + ret = submit_flush_wait(sbi, ino); + atomic_dec(&fcc->queued_flush); + +@@ -750,7 +751,7 @@ int f2fs_flush_device_cache(struct f2fs_sb_info *sbi) + { + int ret = 0, i; + +- if (!sbi->s_ndevs) ++ if (!f2fs_is_multi_device(sbi)) + return 0; + + for (i = 1; i < sbi->s_ndevs; i++) { +@@ -1359,7 +1360,7 @@ static int __queue_discard_cmd(struct f2fs_sb_info *sbi, + + trace_f2fs_queue_discard(bdev, blkstart, blklen); + +- if (sbi->s_ndevs) { ++ if (f2fs_is_multi_device(sbi)) { + int devi = f2fs_target_device_index(sbi, blkstart); + + blkstart -= FDEV(devi).start_blk; +@@ -1714,7 +1715,7 @@ static int __f2fs_issue_discard_zone(struct f2fs_sb_info *sbi, + block_t lblkstart = blkstart; + int devi = 0; + +- if (sbi->s_ndevs) { ++ if (f2fs_is_multi_device(sbi)) { + devi = f2fs_target_device_index(sbi, blkstart); + blkstart -= FDEV(devi).start_blk; + } +@@ -3071,7 +3072,7 @@ static void update_device_state(struct f2fs_io_info *fio) + struct f2fs_sb_info *sbi = fio->sbi; + unsigned int devidx; + +- if (!sbi->s_ndevs) ++ if (!f2fs_is_multi_device(sbi)) + return; + + devidx = f2fs_target_device_index(sbi, fio->new_blkaddr); +diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c +index 4ca0b5c18192..853a69e493f5 100644 +--- a/fs/kernfs/dir.c ++++ b/fs/kernfs/dir.c +@@ -650,11 +650,10 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root, + kn->id.generation = gen; + + /* +- * set ino first. This barrier is paired with atomic_inc_not_zero in ++ * set ino first. This RELEASE is paired with atomic_inc_not_zero in + * kernfs_find_and_get_node_by_ino + */ +- smp_mb__before_atomic(); +- atomic_set(&kn->count, 1); ++ atomic_set_release(&kn->count, 1); + atomic_set(&kn->active, KN_DEACTIVATED_BIAS); + RB_CLEAR_NODE(&kn->rb); + +diff --git a/include/linux/efi.h b/include/linux/efi.h +index a86485ac7c87..de05a4302529 100644 +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -1598,7 +1598,12 @@ efi_status_t efi_setup_gop(efi_system_table_t *sys_table_arg, + struct screen_info *si, efi_guid_t *proto, + unsigned long size); + +-bool efi_runtime_disabled(void); ++#ifdef CONFIG_EFI ++extern bool efi_runtime_disabled(void); ++#else ++static inline bool efi_runtime_disabled(void) { return true; } ++#endif ++ + extern void efi_call_virt_check_flags(unsigned long flags, const char *call); + + enum efi_secureboot_mode { +diff --git a/include/linux/elevator.h b/include/linux/elevator.h +index 2e9e2763bf47..6e8bc53740f0 100644 +--- a/include/linux/elevator.h ++++ b/include/linux/elevator.h +@@ -31,6 +31,7 @@ struct elevator_mq_ops { + void (*exit_sched)(struct elevator_queue *); + int (*init_hctx)(struct blk_mq_hw_ctx *, unsigned int); + void (*exit_hctx)(struct blk_mq_hw_ctx *, unsigned int); ++ void (*depth_updated)(struct blk_mq_hw_ctx *); + + bool (*allow_merge)(struct request_queue *, struct request *, struct bio *); + bool (*bio_merge)(struct blk_mq_hw_ctx *, struct bio *); +diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h +index cf761ff58224..e41503b2c5a1 100644 +--- a/include/linux/kvm_host.h ++++ b/include/linux/kvm_host.h +@@ -28,6 +28,7 @@ + #include <linux/irqbypass.h> + #include <linux/swait.h> + #include <linux/refcount.h> ++#include <linux/nospec.h> + #include <asm/signal.h> + + #include <linux/kvm.h> +@@ -492,10 +493,10 @@ static inline struct kvm_io_bus *kvm_get_bus(struct kvm *kvm, enum kvm_bus idx) + + static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i) + { +- /* Pairs with smp_wmb() in kvm_vm_ioctl_create_vcpu, in case +- * the caller has read kvm->online_vcpus before (as is the case +- * for kvm_for_each_vcpu, for example). +- */ ++ int num_vcpus = atomic_read(&kvm->online_vcpus); ++ i = array_index_nospec(i, num_vcpus); ++ ++ /* Pairs with smp_wmb() in kvm_vm_ioctl_create_vcpu. */ + smp_rmb(); + return kvm->vcpus[i]; + } +@@ -579,6 +580,7 @@ void kvm_put_kvm(struct kvm *kvm); + + static inline struct kvm_memslots *__kvm_memslots(struct kvm *kvm, int as_id) + { ++ as_id = array_index_nospec(as_id, KVM_ADDRESS_SPACE_NUM); + return srcu_dereference_check(kvm->memslots[as_id], &kvm->srcu, + lockdep_is_held(&kvm->slots_lock) || + !refcount_read(&kvm->users_count)); +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index bdb9563c64a0..b8679dcba96f 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -4212,10 +4212,10 @@ static inline bool skb_is_gso_sctp(const struct sk_buff *skb) + return skb_shinfo(skb)->gso_type & SKB_GSO_SCTP; + } + ++/* Note: Should be called only if skb_is_gso(skb) is true */ + static inline bool skb_is_gso_tcp(const struct sk_buff *skb) + { +- return skb_is_gso(skb) && +- skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6); ++ return skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6); + } + + static inline void skb_gso_reset(struct sk_buff *skb) +diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h +index 249d0a5b12b8..63fd47e924b9 100644 +--- a/include/net/netfilter/nf_conntrack.h ++++ b/include/net/netfilter/nf_conntrack.h +@@ -318,6 +318,8 @@ struct nf_conn *nf_ct_tmpl_alloc(struct net *net, + gfp_t flags); + void nf_ct_tmpl_free(struct nf_conn *tmpl); + ++u32 nf_ct_get_id(const struct nf_conn *ct); ++ + static inline void + nf_ct_set(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info info) + { +diff --git a/include/uapi/rdma/mlx5-abi.h b/include/uapi/rdma/mlx5-abi.h +index 87b3198f4b5d..f4d4010b7e3e 100644 +--- a/include/uapi/rdma/mlx5-abi.h ++++ b/include/uapi/rdma/mlx5-abi.h +@@ -238,6 +238,7 @@ enum mlx5_ib_query_dev_resp_flags { + MLX5_IB_QUERY_DEV_RESP_FLAGS_CQE_128B_COMP = 1 << 0, + MLX5_IB_QUERY_DEV_RESP_FLAGS_CQE_128B_PAD = 1 << 1, + MLX5_IB_QUERY_DEV_RESP_PACKET_BASED_CREDIT_MODE = 1 << 2, ++ MLX5_IB_QUERY_DEV_RESP_FLAGS_SCAT2CQE_DCT = 1 << 3, + }; + + enum mlx5_ib_tunnel_offloads { +diff --git a/init/main.c b/init/main.c +index c86a1c8f19f4..7ae824545265 100644 +--- a/init/main.c ++++ b/init/main.c +@@ -574,6 +574,8 @@ asmlinkage __visible void __init start_kernel(void) + page_alloc_init(); + + pr_notice("Kernel command line: %s\n", boot_command_line); ++ /* parameters may set static keys */ ++ jump_label_init(); + parse_early_param(); + after_dashes = parse_args("Booting kernel", + static_command_line, __start___param, +@@ -583,8 +585,6 @@ asmlinkage __visible void __init start_kernel(void) + parse_args("Setting init args", after_dashes, NULL, 0, -1, -1, + NULL, set_init_arg); + +- jump_label_init(); +- + /* + * These use large bootmem allocations and must precede + * kmem_cache_init() +diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c +index 11593a03c051..7493f50ee880 100644 +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -858,6 +858,7 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_typ + */ + mem = find_memory_block(__pfn_to_section(pfn)); + nid = mem->nid; ++ put_device(&mem->dev); + + /* associate pfn range with the zone */ + zone = move_pfn_range(online_type, nid, pfn, nr_pages); +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 318ef6ccdb3b..d59be95ba45c 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -3385,6 +3385,9 @@ alloc_flags_nofragment(struct zone *zone, gfp_t gfp_mask) + alloc_flags |= ALLOC_KSWAPD; + + #ifdef CONFIG_ZONE_DMA32 ++ if (!zone) ++ return alloc_flags; ++ + if (zone_idx(zone) != ZONE_NORMAL) + goto out; + +@@ -7945,7 +7948,10 @@ void *__init alloc_large_system_hash(const char *tablename, + bool has_unmovable_pages(struct zone *zone, struct page *page, int count, + int migratetype, int flags) + { +- unsigned long pfn, iter, found; ++ unsigned long found; ++ unsigned long iter = 0; ++ unsigned long pfn = page_to_pfn(page); ++ const char *reason = "unmovable page"; + + /* + * TODO we could make this much more efficient by not checking every +@@ -7955,17 +7961,20 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count, + * can still lead to having bootmem allocations in zone_movable. + */ + +- /* +- * CMA allocations (alloc_contig_range) really need to mark isolate +- * CMA pageblocks even when they are not movable in fact so consider +- * them movable here. +- */ +- if (is_migrate_cma(migratetype) && +- is_migrate_cma(get_pageblock_migratetype(page))) +- return false; ++ if (is_migrate_cma_page(page)) { ++ /* ++ * CMA allocations (alloc_contig_range) really need to mark ++ * isolate CMA pageblocks even when they are not movable in fact ++ * so consider them movable here. ++ */ ++ if (is_migrate_cma(migratetype)) ++ return false; ++ ++ reason = "CMA page"; ++ goto unmovable; ++ } + +- pfn = page_to_pfn(page); +- for (found = 0, iter = 0; iter < pageblock_nr_pages; iter++) { ++ for (found = 0; iter < pageblock_nr_pages; iter++) { + unsigned long check = pfn + iter; + + if (!pfn_valid_within(check)) +@@ -8045,7 +8054,7 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count, + unmovable: + WARN_ON_ONCE(zone_idx(zone) == ZONE_MOVABLE); + if (flags & REPORT_FAILURE) +- dump_page(pfn_to_page(pfn+iter), "unmovable page"); ++ dump_page(pfn_to_page(pfn + iter), reason); + return true; + } + +diff --git a/mm/slab.c b/mm/slab.c +index 188c4b65255d..f4bbc53008f3 100644 +--- a/mm/slab.c ++++ b/mm/slab.c +@@ -2371,7 +2371,6 @@ static void *alloc_slabmgmt(struct kmem_cache *cachep, + /* Slab management obj is off-slab. */ + freelist = kmem_cache_alloc_node(cachep->freelist_cache, + local_flags, nodeid); +- freelist = kasan_reset_tag(freelist); + if (!freelist) + return NULL; + } else { +diff --git a/mm/vmscan.c b/mm/vmscan.c +index e979705bbf32..022afabac3f6 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -2199,7 +2199,6 @@ static void shrink_active_list(unsigned long nr_to_scan, + * 10TB 320 32GB + */ + static bool inactive_list_is_low(struct lruvec *lruvec, bool file, +- struct mem_cgroup *memcg, + struct scan_control *sc, bool actual_reclaim) + { + enum lru_list active_lru = file * LRU_FILE + LRU_ACTIVE; +@@ -2220,16 +2219,12 @@ static bool inactive_list_is_low(struct lruvec *lruvec, bool file, + inactive = lruvec_lru_size(lruvec, inactive_lru, sc->reclaim_idx); + active = lruvec_lru_size(lruvec, active_lru, sc->reclaim_idx); + +- if (memcg) +- refaults = memcg_page_state(memcg, WORKINGSET_ACTIVATE); +- else +- refaults = node_page_state(pgdat, WORKINGSET_ACTIVATE); +- + /* + * When refaults are being observed, it means a new workingset + * is being established. Disable active list protection to get + * rid of the stale workingset quickly. + */ ++ refaults = lruvec_page_state(lruvec, WORKINGSET_ACTIVATE); + if (file && actual_reclaim && lruvec->refaults != refaults) { + inactive_ratio = 0; + } else { +@@ -2250,12 +2245,10 @@ static bool inactive_list_is_low(struct lruvec *lruvec, bool file, + } + + static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan, +- struct lruvec *lruvec, struct mem_cgroup *memcg, +- struct scan_control *sc) ++ struct lruvec *lruvec, struct scan_control *sc) + { + if (is_active_lru(lru)) { +- if (inactive_list_is_low(lruvec, is_file_lru(lru), +- memcg, sc, true)) ++ if (inactive_list_is_low(lruvec, is_file_lru(lru), sc, true)) + shrink_active_list(nr_to_scan, lruvec, sc, lru); + return 0; + } +@@ -2355,7 +2348,7 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, + * anonymous pages on the LRU in eligible zones. + * Otherwise, the small LRU gets thrashed. + */ +- if (!inactive_list_is_low(lruvec, false, memcg, sc, false) && ++ if (!inactive_list_is_low(lruvec, false, sc, false) && + lruvec_lru_size(lruvec, LRU_INACTIVE_ANON, sc->reclaim_idx) + >> sc->priority) { + scan_balance = SCAN_ANON; +@@ -2373,7 +2366,7 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, + * lruvec even if it has plenty of old anonymous pages unless the + * system is under heavy pressure. + */ +- if (!inactive_list_is_low(lruvec, true, memcg, sc, false) && ++ if (!inactive_list_is_low(lruvec, true, sc, false) && + lruvec_lru_size(lruvec, LRU_INACTIVE_FILE, sc->reclaim_idx) >> sc->priority) { + scan_balance = SCAN_FILE; + goto out; +@@ -2526,7 +2519,7 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc + nr[lru] -= nr_to_scan; + + nr_reclaimed += shrink_list(lru, nr_to_scan, +- lruvec, memcg, sc); ++ lruvec, sc); + } + } + +@@ -2593,7 +2586,7 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc + * Even if we did not try to evict anon pages at all, we want to + * rebalance the anon lru active/inactive ratio. + */ +- if (inactive_list_is_low(lruvec, false, memcg, sc, true)) ++ if (inactive_list_is_low(lruvec, false, sc, true)) + shrink_active_list(SWAP_CLUSTER_MAX, lruvec, + sc, LRU_ACTIVE_ANON); + } +@@ -2993,12 +2986,8 @@ static void snapshot_refaults(struct mem_cgroup *root_memcg, pg_data_t *pgdat) + unsigned long refaults; + struct lruvec *lruvec; + +- if (memcg) +- refaults = memcg_page_state(memcg, WORKINGSET_ACTIVATE); +- else +- refaults = node_page_state(pgdat, WORKINGSET_ACTIVATE); +- + lruvec = mem_cgroup_lruvec(pgdat, memcg); ++ refaults = lruvec_page_state(lruvec, WORKINGSET_ACTIVATE); + lruvec->refaults = refaults; + } while ((memcg = mem_cgroup_iter(root_memcg, memcg, NULL))); + } +@@ -3363,7 +3352,7 @@ static void age_active_anon(struct pglist_data *pgdat, + do { + struct lruvec *lruvec = mem_cgroup_lruvec(pgdat, memcg); + +- if (inactive_list_is_low(lruvec, false, memcg, sc, true)) ++ if (inactive_list_is_low(lruvec, false, sc, true)) + shrink_active_list(SWAP_CLUSTER_MAX, lruvec, + sc, LRU_ACTIVE_ANON); + +diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c +index b2d9c8f27cd7..1991ce2eb268 100644 +--- a/net/8021q/vlan_dev.c ++++ b/net/8021q/vlan_dev.c +@@ -368,10 +368,12 @@ static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) + ifrr.ifr_ifru = ifr->ifr_ifru; + + switch (cmd) { ++ case SIOCSHWTSTAMP: ++ if (!net_eq(dev_net(dev), &init_net)) ++ break; + case SIOCGMIIPHY: + case SIOCGMIIREG: + case SIOCSMIIREG: +- case SIOCSHWTSTAMP: + case SIOCGHWTSTAMP: + if (netif_device_present(real_dev) && ops->ndo_do_ioctl) + err = ops->ndo_do_ioctl(real_dev, &ifrr, cmd); +diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c +index 41f0a696a65f..0cb0aa0313a8 100644 +--- a/net/bridge/br_if.c ++++ b/net/bridge/br_if.c +@@ -602,13 +602,15 @@ int br_add_if(struct net_bridge *br, struct net_device *dev, + call_netdevice_notifiers(NETDEV_JOIN, dev); + + err = dev_set_allmulti(dev, 1); +- if (err) +- goto put_back; ++ if (err) { ++ kfree(p); /* kobject not yet init'd, manually free */ ++ goto err1; ++ } + + err = kobject_init_and_add(&p->kobj, &brport_ktype, &(dev->dev.kobj), + SYSFS_BRIDGE_PORT_ATTR); + if (err) +- goto err1; ++ goto err2; + + err = br_sysfs_addif(p); + if (err) +@@ -700,12 +702,9 @@ err3: + sysfs_remove_link(br->ifobj, p->dev->name); + err2: + kobject_put(&p->kobj); +- p = NULL; /* kobject_put frees */ +-err1: + dev_set_allmulti(dev, -1); +-put_back: ++err1: + dev_put(dev); +- kfree(p); + return err; + } + +diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c +index ffbb827723a2..c49b752ea7eb 100644 +--- a/net/core/fib_rules.c ++++ b/net/core/fib_rules.c +@@ -756,9 +756,9 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh, + if (err) + goto errout; + +- if ((nlh->nlmsg_flags & NLM_F_EXCL) && +- rule_exists(ops, frh, tb, rule)) { +- err = -EEXIST; ++ if (rule_exists(ops, frh, tb, rule)) { ++ if (nlh->nlmsg_flags & NLM_F_EXCL) ++ err = -EEXIST; + goto errout_free; + } + +diff --git a/net/core/filter.c b/net/core/filter.c +index f7d0004fc160..ff07996515f2 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -2789,7 +2789,7 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb) + u32 off = skb_mac_header_len(skb); + int ret; + +- if (!skb_is_gso_tcp(skb)) ++ if (skb_is_gso(skb) && !skb_is_gso_tcp(skb)) + return -ENOTSUPP; + + ret = skb_cow(skb, len_diff); +@@ -2830,7 +2830,7 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb) + u32 off = skb_mac_header_len(skb); + int ret; + +- if (!skb_is_gso_tcp(skb)) ++ if (skb_is_gso(skb) && !skb_is_gso_tcp(skb)) + return -ENOTSUPP; + + ret = skb_unclone(skb, GFP_ATOMIC); +@@ -2955,7 +2955,7 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 len_diff) + u32 off = skb_mac_header_len(skb) + bpf_skb_net_base_len(skb); + int ret; + +- if (!skb_is_gso_tcp(skb)) ++ if (skb_is_gso(skb) && !skb_is_gso_tcp(skb)) + return -ENOTSUPP; + + ret = skb_cow(skb, len_diff); +@@ -2984,7 +2984,7 @@ static int bpf_skb_net_shrink(struct sk_buff *skb, u32 len_diff) + u32 off = skb_mac_header_len(skb) + bpf_skb_net_base_len(skb); + int ret; + +- if (!skb_is_gso_tcp(skb)) ++ if (skb_is_gso(skb) && !skb_is_gso_tcp(skb)) + return -ENOTSUPP; + + ret = skb_unclone(skb, GFP_ATOMIC); +diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c +index 9f2840510e63..afc6e025c85c 100644 +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -786,7 +786,10 @@ bool __skb_flow_dissect(const struct sk_buff *skb, + flow_keys.thoff = nhoff; + + bpf_compute_data_pointers((struct sk_buff *)skb); ++ ++ preempt_disable(); + result = BPF_PROG_RUN(attached, skb); ++ preempt_enable(); + + /* Restore state */ + memcpy(cb, &cb_saved, sizeof(cb_saved)); +diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c +index aee909bcddc4..41d534d3f42b 100644 +--- a/net/dsa/dsa.c ++++ b/net/dsa/dsa.c +@@ -342,15 +342,22 @@ static int __init dsa_init_module(void) + + rc = dsa_slave_register_notifier(); + if (rc) +- return rc; ++ goto register_notifier_fail; + + rc = dsa_legacy_register(); + if (rc) +- return rc; ++ goto legacy_register_fail; + + dev_add_pack(&dsa_pack_type); + + return 0; ++ ++legacy_register_fail: ++ dsa_slave_unregister_notifier(); ++register_notifier_fail: ++ destroy_workqueue(dsa_owq); ++ ++ return rc; + } + module_init(dsa_init_module); + +diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c +index c55a5432cf37..dc91c27bb788 100644 +--- a/net/ipv4/raw.c ++++ b/net/ipv4/raw.c +@@ -173,6 +173,7 @@ static int icmp_filter(const struct sock *sk, const struct sk_buff *skb) + static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash) + { + int sdif = inet_sdif(skb); ++ int dif = inet_iif(skb); + struct sock *sk; + struct hlist_head *head; + int delivered = 0; +@@ -185,8 +186,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash) + + net = dev_net(skb->dev); + sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol, +- iph->saddr, iph->daddr, +- skb->dev->ifindex, sdif); ++ iph->saddr, iph->daddr, dif, sdif); + + while (sk) { + delivered = 1; +diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c +index b2109b74857d..971d60bf9640 100644 +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -1084,7 +1084,7 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev) + if (!tdev && tunnel->parms.link) + tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link); + +- if (tdev) { ++ if (tdev && !netif_is_l3_master(tdev)) { + int t_hlen = tunnel->hlen + sizeof(struct iphdr); + + dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr); +diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c +index 88a6d5e18ccc..ac1f5db52994 100644 +--- a/net/mac80211/mesh_pathtbl.c ++++ b/net/mac80211/mesh_pathtbl.c +@@ -23,7 +23,7 @@ static void mesh_path_free_rcu(struct mesh_table *tbl, struct mesh_path *mpath); + static u32 mesh_table_hash(const void *addr, u32 len, u32 seed) + { + /* Use last four bytes of hw addr as hash index */ +- return jhash_1word(*(u32 *)(addr+2), seed); ++ return jhash_1word(__get_unaligned_cpu32((u8 *)addr + 2), seed); + } + + static const struct rhashtable_params mesh_rht_params = { +diff --git a/net/mac80211/trace_msg.h b/net/mac80211/trace_msg.h +index 366b9e6f043e..40141df09f25 100644 +--- a/net/mac80211/trace_msg.h ++++ b/net/mac80211/trace_msg.h +@@ -1,4 +1,9 @@ + /* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Portions of this file ++ * Copyright (C) 2019 Intel Corporation ++ */ ++ + #ifdef CONFIG_MAC80211_MESSAGE_TRACING + + #if !defined(__MAC80211_MSG_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ) +@@ -11,7 +16,7 @@ + #undef TRACE_SYSTEM + #define TRACE_SYSTEM mac80211_msg + +-#define MAX_MSG_LEN 100 ++#define MAX_MSG_LEN 120 + + DECLARE_EVENT_CLASS(mac80211_msg_event, + TP_PROTO(struct va_format *vaf), +diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c +index 928f13a208b0..714d80e48a10 100644 +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -3214,6 +3214,7 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata, + u8 max_subframes = sta->sta.max_amsdu_subframes; + int max_frags = local->hw.max_tx_fragments; + int max_amsdu_len = sta->sta.max_amsdu_len; ++ int orig_truesize; + __be16 len; + void *data; + bool ret = false; +@@ -3254,6 +3255,7 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata, + if (!head || skb_is_gso(head)) + goto out; + ++ orig_truesize = head->truesize; + orig_len = head->len; + + if (skb->len + head->len > max_amsdu_len) +@@ -3311,6 +3313,7 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata, + *frag_tail = skb; + + out_recalc: ++ fq->memory_usage += head->truesize - orig_truesize; + if (head->len != orig_len) { + flow->backlog += head->len - orig_len; + tin->backlog_bytes += head->len - orig_len; +diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c +index 235205c93e14..df112b27246a 100644 +--- a/net/netfilter/ipvs/ip_vs_core.c ++++ b/net/netfilter/ipvs/ip_vs_core.c +@@ -1647,7 +1647,7 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related, + if (!cp) { + int v; + +- if (!sysctl_schedule_icmp(ipvs)) ++ if (ipip || !sysctl_schedule_icmp(ipvs)) + return NF_ACCEPT; + + if (!ip_vs_try_to_schedule(ipvs, AF_INET, skb, pd, &v, &cp, &ciph)) +diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c +index 9dd4c2048a2b..d7ac2f82bb6d 100644 +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -25,6 +25,7 @@ + #include <linux/slab.h> + #include <linux/random.h> + #include <linux/jhash.h> ++#include <linux/siphash.h> + #include <linux/err.h> + #include <linux/percpu.h> + #include <linux/moduleparam.h> +@@ -424,6 +425,40 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse, + } + EXPORT_SYMBOL_GPL(nf_ct_invert_tuple); + ++/* Generate a almost-unique pseudo-id for a given conntrack. ++ * ++ * intentionally doesn't re-use any of the seeds used for hash ++ * table location, we assume id gets exposed to userspace. ++ * ++ * Following nf_conn items do not change throughout lifetime ++ * of the nf_conn after it has been committed to main hash table: ++ * ++ * 1. nf_conn address ++ * 2. nf_conn->ext address ++ * 3. nf_conn->master address (normally NULL) ++ * 4. tuple ++ * 5. the associated net namespace ++ */ ++u32 nf_ct_get_id(const struct nf_conn *ct) ++{ ++ static __read_mostly siphash_key_t ct_id_seed; ++ unsigned long a, b, c, d; ++ ++ net_get_random_once(&ct_id_seed, sizeof(ct_id_seed)); ++ ++ a = (unsigned long)ct; ++ b = (unsigned long)ct->master ^ net_hash_mix(nf_ct_net(ct)); ++ c = (unsigned long)ct->ext; ++ d = (unsigned long)siphash(&ct->tuplehash, sizeof(ct->tuplehash), ++ &ct_id_seed); ++#ifdef CONFIG_64BIT ++ return siphash_4u64((u64)a, (u64)b, (u64)c, (u64)d, &ct_id_seed); ++#else ++ return siphash_4u32((u32)a, (u32)b, (u32)c, (u32)d, &ct_id_seed); ++#endif ++} ++EXPORT_SYMBOL_GPL(nf_ct_get_id); ++ + static void + clean_from_lists(struct nf_conn *ct) + { +@@ -948,12 +983,9 @@ __nf_conntrack_confirm(struct sk_buff *skb) + + /* set conntrack timestamp, if enabled. */ + tstamp = nf_conn_tstamp_find(ct); +- if (tstamp) { +- if (skb->tstamp == 0) +- __net_timestamp(skb); ++ if (tstamp) ++ tstamp->start = ktime_get_real_ns(); + +- tstamp->start = ktime_to_ns(skb->tstamp); +- } + /* Since the lookup is lockless, hash insertion must be done after + * starting the timer and setting the CONFIRMED bit. The RCU barriers + * guarantee that no other CPU can find the conntrack before the above +diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c +index 1213beb5a714..36619ad8ab8c 100644 +--- a/net/netfilter/nf_conntrack_netlink.c ++++ b/net/netfilter/nf_conntrack_netlink.c +@@ -29,6 +29,7 @@ + #include <linux/spinlock.h> + #include <linux/interrupt.h> + #include <linux/slab.h> ++#include <linux/siphash.h> + + #include <linux/netfilter.h> + #include <net/netlink.h> +@@ -485,7 +486,9 @@ nla_put_failure: + + static int ctnetlink_dump_id(struct sk_buff *skb, const struct nf_conn *ct) + { +- if (nla_put_be32(skb, CTA_ID, htonl((unsigned long)ct))) ++ __be32 id = (__force __be32)nf_ct_get_id(ct); ++ ++ if (nla_put_be32(skb, CTA_ID, id)) + goto nla_put_failure; + return 0; + +@@ -1286,8 +1289,9 @@ static int ctnetlink_del_conntrack(struct net *net, struct sock *ctnl, + } + + if (cda[CTA_ID]) { +- u_int32_t id = ntohl(nla_get_be32(cda[CTA_ID])); +- if (id != (u32)(unsigned long)ct) { ++ __be32 id = nla_get_be32(cda[CTA_ID]); ++ ++ if (id != (__force __be32)nf_ct_get_id(ct)) { + nf_ct_put(ct); + return -ENOENT; + } +@@ -2694,6 +2698,25 @@ nla_put_failure: + + static const union nf_inet_addr any_addr; + ++static __be32 nf_expect_get_id(const struct nf_conntrack_expect *exp) ++{ ++ static __read_mostly siphash_key_t exp_id_seed; ++ unsigned long a, b, c, d; ++ ++ net_get_random_once(&exp_id_seed, sizeof(exp_id_seed)); ++ ++ a = (unsigned long)exp; ++ b = (unsigned long)exp->helper; ++ c = (unsigned long)exp->master; ++ d = (unsigned long)siphash(&exp->tuple, sizeof(exp->tuple), &exp_id_seed); ++ ++#ifdef CONFIG_64BIT ++ return (__force __be32)siphash_4u64((u64)a, (u64)b, (u64)c, (u64)d, &exp_id_seed); ++#else ++ return (__force __be32)siphash_4u32((u32)a, (u32)b, (u32)c, (u32)d, &exp_id_seed); ++#endif ++} ++ + static int + ctnetlink_exp_dump_expect(struct sk_buff *skb, + const struct nf_conntrack_expect *exp) +@@ -2741,7 +2764,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, + } + #endif + if (nla_put_be32(skb, CTA_EXPECT_TIMEOUT, htonl(timeout)) || +- nla_put_be32(skb, CTA_EXPECT_ID, htonl((unsigned long)exp)) || ++ nla_put_be32(skb, CTA_EXPECT_ID, nf_expect_get_id(exp)) || + nla_put_be32(skb, CTA_EXPECT_FLAGS, htonl(exp->flags)) || + nla_put_be32(skb, CTA_EXPECT_CLASS, htonl(exp->class))) + goto nla_put_failure; +@@ -3046,7 +3069,8 @@ static int ctnetlink_get_expect(struct net *net, struct sock *ctnl, + + if (cda[CTA_EXPECT_ID]) { + __be32 id = nla_get_be32(cda[CTA_EXPECT_ID]); +- if (ntohl(id) != (u32)(unsigned long)exp) { ++ ++ if (id != nf_expect_get_id(exp)) { + nf_ct_expect_put(exp); + return -ENOENT; + } +diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c +index 859f5d07a915..78361e462e80 100644 +--- a/net/netfilter/nf_conntrack_proto.c ++++ b/net/netfilter/nf_conntrack_proto.c +@@ -86,7 +86,7 @@ void nf_l4proto_log_invalid(const struct sk_buff *skb, + struct va_format vaf; + va_list args; + +- if (net->ct.sysctl_log_invalid != protonum || ++ if (net->ct.sysctl_log_invalid != protonum && + net->ct.sysctl_log_invalid != IPPROTO_RAW) + return; + +diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c +index d159e9e7835b..ade527565127 100644 +--- a/net/netfilter/nf_nat_core.c ++++ b/net/netfilter/nf_nat_core.c +@@ -358,9 +358,14 @@ static void nf_nat_l4proto_unique_tuple(struct nf_conntrack_tuple *tuple, + case IPPROTO_ICMPV6: + /* id is same for either direction... */ + keyptr = &tuple->src.u.icmp.id; +- min = range->min_proto.icmp.id; +- range_size = ntohs(range->max_proto.icmp.id) - +- ntohs(range->min_proto.icmp.id) + 1; ++ if (!(range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)) { ++ min = 0; ++ range_size = 65536; ++ } else { ++ min = ntohs(range->min_proto.icmp.id); ++ range_size = ntohs(range->max_proto.icmp.id) - ++ ntohs(range->min_proto.icmp.id) + 1; ++ } + goto find_free_id; + #if IS_ENABLED(CONFIG_NF_CT_PROTO_GRE) + case IPPROTO_GRE: +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index e2aac80f9b7b..25c2b98b9a96 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -1502,7 +1502,7 @@ static int nft_chain_parse_hook(struct net *net, + if (IS_ERR(type)) + return PTR_ERR(type); + } +- if (!(type->hook_mask & (1 << hook->num))) ++ if (hook->num > NF_MAX_HOOKS || !(type->hook_mask & (1 << hook->num))) + return -EOPNOTSUPP; + + if (type->type == NFT_CHAIN_T_NAT && +diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c +index b1f9c5303f02..0b3347570265 100644 +--- a/net/netfilter/nfnetlink_log.c ++++ b/net/netfilter/nfnetlink_log.c +@@ -540,7 +540,7 @@ __build_packet_message(struct nfnl_log_net *log, + goto nla_put_failure; + } + +- if (skb->tstamp) { ++ if (hooknum <= NF_INET_FORWARD && skb->tstamp) { + struct nfulnl_msg_packet_timestamp ts; + struct timespec64 kts = ktime_to_timespec64(skb->tstamp); + ts.sec = cpu_to_be64(kts.tv_sec); +diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c +index 0dcc3592d053..e057b2961d31 100644 +--- a/net/netfilter/nfnetlink_queue.c ++++ b/net/netfilter/nfnetlink_queue.c +@@ -582,7 +582,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, + if (nfqnl_put_bridge(entry, skb) < 0) + goto nla_put_failure; + +- if (entskb->tstamp) { ++ if (entry->state.hook <= NF_INET_FORWARD && entskb->tstamp) { + struct nfqnl_msg_packet_timestamp ts; + struct timespec64 kts = ktime_to_timespec64(entskb->tstamp); + +diff --git a/net/netfilter/xt_time.c b/net/netfilter/xt_time.c +index c13bcd0ab491..8dbb4d48f2ed 100644 +--- a/net/netfilter/xt_time.c ++++ b/net/netfilter/xt_time.c +@@ -163,19 +163,24 @@ time_mt(const struct sk_buff *skb, struct xt_action_param *par) + s64 stamp; + + /* +- * We cannot use get_seconds() instead of __net_timestamp() here. ++ * We need real time here, but we can neither use skb->tstamp ++ * nor __net_timestamp(). ++ * ++ * skb->tstamp and skb->skb_mstamp_ns overlap, however, they ++ * use different clock types (real vs monotonic). ++ * + * Suppose you have two rules: +- * 1. match before 13:00 +- * 2. match after 13:00 ++ * 1. match before 13:00 ++ * 2. match after 13:00 ++ * + * If you match against processing time (get_seconds) it + * may happen that the same packet matches both rules if +- * it arrived at the right moment before 13:00. ++ * it arrived at the right moment before 13:00, so it would be ++ * better to check skb->tstamp and set it via __net_timestamp() ++ * if needed. This however breaks outgoing packets tx timestamp, ++ * and causes them to get delayed forever by fq packet scheduler. + */ +- if (skb->tstamp == 0) +- __net_timestamp((struct sk_buff *)skb); +- +- stamp = ktime_to_ns(skb->tstamp); +- stamp = div_s64(stamp, NSEC_PER_SEC); ++ stamp = get_seconds(); + + if (info->flags & XT_TIME_LOCAL_TZ) + /* Adjust for local timezone */ +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index faa2bc50cfa0..b6c23af4a315 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -4604,14 +4604,29 @@ static void __exit packet_exit(void) + + static int __init packet_init(void) + { +- int rc = proto_register(&packet_proto, 0); ++ int rc; + +- if (rc != 0) ++ rc = proto_register(&packet_proto, 0); ++ if (rc) + goto out; ++ rc = sock_register(&packet_family_ops); ++ if (rc) ++ goto out_proto; ++ rc = register_pernet_subsys(&packet_net_ops); ++ if (rc) ++ goto out_sock; ++ rc = register_netdevice_notifier(&packet_netdev_notifier); ++ if (rc) ++ goto out_pernet; + +- sock_register(&packet_family_ops); +- register_pernet_subsys(&packet_net_ops); +- register_netdevice_notifier(&packet_netdev_notifier); ++ return 0; ++ ++out_pernet: ++ unregister_pernet_subsys(&packet_net_ops); ++out_sock: ++ sock_unregister(PF_PACKET); ++out_proto: ++ proto_unregister(&packet_proto); + out: + return rc; + } +diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c +index c8cf4d10c435..971dc03304f4 100644 +--- a/net/sched/act_mirred.c ++++ b/net/sched/act_mirred.c +@@ -159,6 +159,9 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, + } + m = to_mirred(*a); + ++ if (ret == ACT_P_CREATED) ++ INIT_LIST_HEAD(&m->tcfm_list); ++ + spin_lock_bh(&m->tcf_lock); + m->tcf_action = parm->action; + m->tcfm_eaction = parm->eaction; +diff --git a/net/tipc/socket.c b/net/tipc/socket.c +index 4dca9161f99b..020477ff91a2 100644 +--- a/net/tipc/socket.c ++++ b/net/tipc/socket.c +@@ -734,11 +734,11 @@ static __poll_t tipc_poll(struct file *file, struct socket *sock, + + switch (sk->sk_state) { + case TIPC_ESTABLISHED: +- case TIPC_CONNECTING: + if (!tsk->cong_link_cnt && !tsk_conn_cong(tsk)) + revents |= EPOLLOUT; + /* fall thru' */ + case TIPC_LISTEN: ++ case TIPC_CONNECTING: + if (!skb_queue_empty(&sk->sk_receive_queue)) + revents |= EPOLLIN | EPOLLRDNORM; + break; +@@ -2041,7 +2041,7 @@ static bool tipc_sk_filter_connect(struct tipc_sock *tsk, struct sk_buff *skb) + if (msg_data_sz(hdr)) + return true; + /* Empty ACK-, - wake up sleeping connect() and drop */ +- sk->sk_data_ready(sk); ++ sk->sk_state_change(sk); + msg_set_dest_droppable(hdr, 1); + return false; + } +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index d91a408db113..156ce708b533 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -13596,7 +13596,8 @@ static const struct genl_ops nl80211_ops[] = { + .policy = nl80211_policy, + .flags = GENL_UNS_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | +- NL80211_FLAG_NEED_RTNL, ++ NL80211_FLAG_NEED_RTNL | ++ NL80211_FLAG_CLEAR_SKB, + }, + { + .cmd = NL80211_CMD_DEAUTHENTICATE, +@@ -13647,7 +13648,8 @@ static const struct genl_ops nl80211_ops[] = { + .policy = nl80211_policy, + .flags = GENL_UNS_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | +- NL80211_FLAG_NEED_RTNL, ++ NL80211_FLAG_NEED_RTNL | ++ NL80211_FLAG_CLEAR_SKB, + }, + { + .cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS, +@@ -13655,7 +13657,8 @@ static const struct genl_ops nl80211_ops[] = { + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | +- NL80211_FLAG_NEED_RTNL, ++ NL80211_FLAG_NEED_RTNL | ++ NL80211_FLAG_CLEAR_SKB, + }, + { + .cmd = NL80211_CMD_DISCONNECT, +@@ -13684,7 +13687,8 @@ static const struct genl_ops nl80211_ops[] = { + .policy = nl80211_policy, + .flags = GENL_UNS_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | +- NL80211_FLAG_NEED_RTNL, ++ NL80211_FLAG_NEED_RTNL | ++ NL80211_FLAG_CLEAR_SKB, + }, + { + .cmd = NL80211_CMD_DEL_PMKSA, +@@ -14036,7 +14040,8 @@ static const struct genl_ops nl80211_ops[] = { + .policy = nl80211_policy, + .flags = GENL_UNS_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_WIPHY | +- NL80211_FLAG_NEED_RTNL, ++ NL80211_FLAG_NEED_RTNL | ++ NL80211_FLAG_CLEAR_SKB, + }, + { + .cmd = NL80211_CMD_SET_QOS_MAP, +@@ -14091,7 +14096,8 @@ static const struct genl_ops nl80211_ops[] = { + .doit = nl80211_set_pmk, + .policy = nl80211_policy, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | +- NL80211_FLAG_NEED_RTNL, ++ NL80211_FLAG_NEED_RTNL | ++ NL80211_FLAG_CLEAR_SKB, + }, + { + .cmd = NL80211_CMD_DEL_PMK, +diff --git a/net/wireless/reg.c b/net/wireless/reg.c +index dd58b9909ac9..649c89946dec 100644 +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -1298,6 +1298,16 @@ reg_intersect_dfs_region(const enum nl80211_dfs_regions dfs_region1, + return dfs_region1; + } + ++static void reg_wmm_rules_intersect(const struct ieee80211_wmm_ac *wmm_ac1, ++ const struct ieee80211_wmm_ac *wmm_ac2, ++ struct ieee80211_wmm_ac *intersect) ++{ ++ intersect->cw_min = max_t(u16, wmm_ac1->cw_min, wmm_ac2->cw_min); ++ intersect->cw_max = max_t(u16, wmm_ac1->cw_max, wmm_ac2->cw_max); ++ intersect->cot = min_t(u16, wmm_ac1->cot, wmm_ac2->cot); ++ intersect->aifsn = max_t(u8, wmm_ac1->aifsn, wmm_ac2->aifsn); ++} ++ + /* + * Helper for regdom_intersect(), this does the real + * mathematical intersection fun +@@ -1312,6 +1322,8 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1, + struct ieee80211_freq_range *freq_range; + const struct ieee80211_power_rule *power_rule1, *power_rule2; + struct ieee80211_power_rule *power_rule; ++ const struct ieee80211_wmm_rule *wmm_rule1, *wmm_rule2; ++ struct ieee80211_wmm_rule *wmm_rule; + u32 freq_diff, max_bandwidth1, max_bandwidth2; + + freq_range1 = &rule1->freq_range; +@@ -1322,6 +1334,10 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1, + power_rule2 = &rule2->power_rule; + power_rule = &intersected_rule->power_rule; + ++ wmm_rule1 = &rule1->wmm_rule; ++ wmm_rule2 = &rule2->wmm_rule; ++ wmm_rule = &intersected_rule->wmm_rule; ++ + freq_range->start_freq_khz = max(freq_range1->start_freq_khz, + freq_range2->start_freq_khz); + freq_range->end_freq_khz = min(freq_range1->end_freq_khz, +@@ -1365,6 +1381,29 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1, + intersected_rule->dfs_cac_ms = max(rule1->dfs_cac_ms, + rule2->dfs_cac_ms); + ++ if (rule1->has_wmm && rule2->has_wmm) { ++ u8 ac; ++ ++ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { ++ reg_wmm_rules_intersect(&wmm_rule1->client[ac], ++ &wmm_rule2->client[ac], ++ &wmm_rule->client[ac]); ++ reg_wmm_rules_intersect(&wmm_rule1->ap[ac], ++ &wmm_rule2->ap[ac], ++ &wmm_rule->ap[ac]); ++ } ++ ++ intersected_rule->has_wmm = true; ++ } else if (rule1->has_wmm) { ++ *wmm_rule = *wmm_rule1; ++ intersected_rule->has_wmm = true; ++ } else if (rule2->has_wmm) { ++ *wmm_rule = *wmm_rule2; ++ intersected_rule->has_wmm = true; ++ } else { ++ intersected_rule->has_wmm = false; ++ } ++ + if (!is_valid_reg_rule(intersected_rule)) + return -EINVAL; + +diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c +index b005283f0090..bc4aec97723a 100644 +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -4586,7 +4586,7 @@ static int selinux_socket_connect_helper(struct socket *sock, + struct lsm_network_audit net = {0,}; + struct sockaddr_in *addr4 = NULL; + struct sockaddr_in6 *addr6 = NULL; +- unsigned short snum; ++ unsigned short snum = 0; + u32 sid, perm; + + /* sctp_connectx(3) calls via selinux_sctp_bind_connect() +@@ -4609,12 +4609,12 @@ static int selinux_socket_connect_helper(struct socket *sock, + break; + default: + /* Note that SCTP services expect -EINVAL, whereas +- * others expect -EAFNOSUPPORT. ++ * others must handle this at the protocol level: ++ * connect(AF_UNSPEC) on a connected socket is ++ * a documented way disconnect the socket. + */ + if (sksec->sclass == SECCLASS_SCTP_SOCKET) + return -EINVAL; +- else +- return -EAFNOSUPPORT; + } + + err = sel_netport_sid(sk->sk_protocol, snum, &sid); +diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c +index 87494c7c619d..981c6ce2da2c 100644 +--- a/tools/lib/traceevent/event-parse.c ++++ b/tools/lib/traceevent/event-parse.c +@@ -2233,7 +2233,7 @@ eval_type_str(unsigned long long val, const char *type, int pointer) + return val & 0xffffffff; + + if (strcmp(type, "u64") == 0 || +- strcmp(type, "s64")) ++ strcmp(type, "s64") == 0) + return val; + + if (strcmp(type, "s8") == 0) +diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c +index 616408251e25..63750a711123 100644 +--- a/tools/perf/builtin-top.c ++++ b/tools/perf/builtin-top.c +@@ -1393,6 +1393,7 @@ int cmd_top(int argc, const char **argv) + * */ + .overwrite = 0, + .sample_time = true, ++ .sample_time_set = true, + }, + .max_stack = sysctl__max_stack(), + .annotation_opts = annotation__default_options, +diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c +index 2b37f56f0549..e33f20d16c8d 100644 +--- a/tools/perf/util/map.c ++++ b/tools/perf/util/map.c +@@ -904,10 +904,8 @@ static void __maps__insert_name(struct maps *maps, struct map *map) + rc = strcmp(m->dso->short_name, map->dso->short_name); + if (rc < 0) + p = &(*p)->rb_left; +- else if (rc > 0) +- p = &(*p)->rb_right; + else +- return; ++ p = &(*p)->rb_right; + } + rb_link_node(&map->rb_node_name, parent, p); + rb_insert_color(&map->rb_node_name, &maps->names); +diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c +index b579f962451d..85ffdcfa596b 100644 +--- a/tools/testing/nvdimm/test/nfit.c ++++ b/tools/testing/nvdimm/test/nfit.c +@@ -146,6 +146,7 @@ static int dimm_fail_cmd_code[ARRAY_SIZE(handle)]; + struct nfit_test_sec { + u8 state; + u8 ext_state; ++ u8 old_state; + u8 passphrase[32]; + u8 master_passphrase[32]; + u64 overwrite_end_time; +@@ -225,6 +226,8 @@ static struct workqueue_struct *nfit_wq; + + static struct gen_pool *nfit_pool; + ++static const char zero_key[NVDIMM_PASSPHRASE_LEN]; ++ + static struct nfit_test *to_nfit_test(struct device *dev) + { + struct platform_device *pdev = to_platform_device(dev); +@@ -1059,8 +1062,7 @@ static int nd_intel_test_cmd_secure_erase(struct nfit_test *t, + struct device *dev = &t->pdev.dev; + struct nfit_test_sec *sec = &dimm_sec_info[dimm]; + +- if (!(sec->state & ND_INTEL_SEC_STATE_ENABLED) || +- (sec->state & ND_INTEL_SEC_STATE_FROZEN)) { ++ if (sec->state & ND_INTEL_SEC_STATE_FROZEN) { + nd_cmd->status = ND_INTEL_STATUS_INVALID_STATE; + dev_dbg(dev, "secure erase: wrong security state\n"); + } else if (memcmp(nd_cmd->passphrase, sec->passphrase, +@@ -1068,6 +1070,12 @@ static int nd_intel_test_cmd_secure_erase(struct nfit_test *t, + nd_cmd->status = ND_INTEL_STATUS_INVALID_PASS; + dev_dbg(dev, "secure erase: wrong passphrase\n"); + } else { ++ if (!(sec->state & ND_INTEL_SEC_STATE_ENABLED) ++ && (memcmp(nd_cmd->passphrase, zero_key, ++ ND_INTEL_PASSPHRASE_SIZE) != 0)) { ++ dev_dbg(dev, "invalid zero key\n"); ++ return 0; ++ } + memset(sec->passphrase, 0, ND_INTEL_PASSPHRASE_SIZE); + memset(sec->master_passphrase, 0, ND_INTEL_PASSPHRASE_SIZE); + sec->state = 0; +@@ -1093,7 +1101,7 @@ static int nd_intel_test_cmd_overwrite(struct nfit_test *t, + return 0; + } + +- memset(sec->passphrase, 0, ND_INTEL_PASSPHRASE_SIZE); ++ sec->old_state = sec->state; + sec->state = ND_INTEL_SEC_STATE_OVERWRITE; + dev_dbg(dev, "overwrite progressing.\n"); + sec->overwrite_end_time = get_jiffies_64() + 5 * HZ; +@@ -1115,7 +1123,8 @@ static int nd_intel_test_cmd_query_overwrite(struct nfit_test *t, + + if (time_is_before_jiffies64(sec->overwrite_end_time)) { + sec->overwrite_end_time = 0; +- sec->state = 0; ++ sec->state = sec->old_state; ++ sec->old_state = 0; + sec->ext_state = ND_INTEL_SEC_ESTATE_ENABLED; + dev_dbg(dev, "overwrite is complete\n"); + } else +diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh +index 1080ff55a788..0d2a5f4f1e63 100755 +--- a/tools/testing/selftests/net/fib_tests.sh ++++ b/tools/testing/selftests/net/fib_tests.sh +@@ -605,6 +605,39 @@ run_cmd() + return $rc + } + ++check_expected() ++{ ++ local out="$1" ++ local expected="$2" ++ local rc=0 ++ ++ [ "${out}" = "${expected}" ] && return 0 ++ ++ if [ -z "${out}" ]; then ++ if [ "$VERBOSE" = "1" ]; then ++ printf "\nNo route entry found\n" ++ printf "Expected:\n" ++ printf " ${expected}\n" ++ fi ++ return 1 ++ fi ++ ++ # tricky way to convert output to 1-line without ip's ++ # messy '\'; this drops all extra white space ++ out=$(echo ${out}) ++ if [ "${out}" != "${expected}" ]; then ++ rc=1 ++ if [ "${VERBOSE}" = "1" ]; then ++ printf " Unexpected route entry. Have:\n" ++ printf " ${out}\n" ++ printf " Expected:\n" ++ printf " ${expected}\n\n" ++ fi ++ fi ++ ++ return $rc ++} ++ + # add route for a prefix, flushing any existing routes first + # expected to be the first step of a test + add_route6() +@@ -652,31 +685,7 @@ check_route6() + pfx=$1 + + out=$($IP -6 ro ls match ${pfx} | sed -e 's/ pref medium//') +- [ "${out}" = "${expected}" ] && return 0 +- +- if [ -z "${out}" ]; then +- if [ "$VERBOSE" = "1" ]; then +- printf "\nNo route entry found\n" +- printf "Expected:\n" +- printf " ${expected}\n" +- fi +- return 1 +- fi +- +- # tricky way to convert output to 1-line without ip's +- # messy '\'; this drops all extra white space +- out=$(echo ${out}) +- if [ "${out}" != "${expected}" ]; then +- rc=1 +- if [ "${VERBOSE}" = "1" ]; then +- printf " Unexpected route entry. Have:\n" +- printf " ${out}\n" +- printf " Expected:\n" +- printf " ${expected}\n\n" +- fi +- fi +- +- return $rc ++ check_expected "${out}" "${expected}" + } + + route_cleanup() +@@ -725,7 +734,7 @@ route_setup() + ip -netns ns2 addr add 172.16.103.2/24 dev veth4 + ip -netns ns2 addr add 172.16.104.1/24 dev dummy1 + +- set +ex ++ set +e + } + + # assumption is that basic add of a single path route works +@@ -960,7 +969,8 @@ ipv6_addr_metric_test() + run_cmd "$IP li set dev dummy2 down" + rc=$? + if [ $rc -eq 0 ]; then +- check_route6 "" ++ out=$($IP -6 ro ls match 2001:db8:104::/64) ++ check_expected "${out}" "" + rc=$? + fi + log_test $rc 0 "Prefix route removed on link down" +@@ -1091,38 +1101,13 @@ check_route() + local pfx + local expected="$1" + local out +- local rc=0 + + set -- $expected + pfx=$1 + [ "${pfx}" = "unreachable" ] && pfx=$2 + + out=$($IP ro ls match ${pfx}) +- [ "${out}" = "${expected}" ] && return 0 +- +- if [ -z "${out}" ]; then +- if [ "$VERBOSE" = "1" ]; then +- printf "\nNo route entry found\n" +- printf "Expected:\n" +- printf " ${expected}\n" +- fi +- return 1 +- fi +- +- # tricky way to convert output to 1-line without ip's +- # messy '\'; this drops all extra white space +- out=$(echo ${out}) +- if [ "${out}" != "${expected}" ]; then +- rc=1 +- if [ "${VERBOSE}" = "1" ]; then +- printf " Unexpected route entry. Have:\n" +- printf " ${out}\n" +- printf " Expected:\n" +- printf " ${expected}\n\n" +- fi +- fi +- +- return $rc ++ check_expected "${out}" "${expected}" + } + + # assumption is that basic add of a single path route works +@@ -1387,7 +1372,8 @@ ipv4_addr_metric_test() + run_cmd "$IP li set dev dummy2 down" + rc=$? + if [ $rc -eq 0 ]; then +- check_route "" ++ out=$($IP ro ls match 172.16.104.0/24) ++ check_expected "${out}" "" + rc=$? + fi + log_test $rc 0 "Prefix route removed on link down" +diff --git a/tools/testing/selftests/net/run_afpackettests b/tools/testing/selftests/net/run_afpackettests +index 2dc95fda7ef7..ea5938ec009a 100755 +--- a/tools/testing/selftests/net/run_afpackettests ++++ b/tools/testing/selftests/net/run_afpackettests +@@ -6,12 +6,14 @@ if [ $(id -u) != 0 ]; then + exit 0 + fi + ++ret=0 + echo "--------------------" + echo "running psock_fanout test" + echo "--------------------" + ./in_netns.sh ./psock_fanout + if [ $? -ne 0 ]; then + echo "[FAIL]" ++ ret=1 + else + echo "[PASS]" + fi +@@ -22,6 +24,7 @@ echo "--------------------" + ./in_netns.sh ./psock_tpacket + if [ $? -ne 0 ]; then + echo "[FAIL]" ++ ret=1 + else + echo "[PASS]" + fi +@@ -32,6 +35,8 @@ echo "--------------------" + ./in_netns.sh ./txring_overwrite + if [ $? -ne 0 ]; then + echo "[FAIL]" ++ ret=1 + else + echo "[PASS]" + fi ++exit $ret +diff --git a/tools/testing/selftests/net/run_netsocktests b/tools/testing/selftests/net/run_netsocktests +index b093f39c298c..14e41faf2c57 100755 +--- a/tools/testing/selftests/net/run_netsocktests ++++ b/tools/testing/selftests/net/run_netsocktests +@@ -7,7 +7,7 @@ echo "--------------------" + ./socket + if [ $? -ne 0 ]; then + echo "[FAIL]" ++ exit 1 + else + echo "[PASS]" + fi +- +diff --git a/tools/testing/selftests/netfilter/Makefile b/tools/testing/selftests/netfilter/Makefile +index c9ff2b47bd1c..a37cb1192c6a 100644 +--- a/tools/testing/selftests/netfilter/Makefile ++++ b/tools/testing/selftests/netfilter/Makefile +@@ -1,6 +1,6 @@ + # SPDX-License-Identifier: GPL-2.0 + # Makefile for netfilter selftests + +-TEST_PROGS := nft_trans_stress.sh nft_nat.sh ++TEST_PROGS := nft_trans_stress.sh nft_nat.sh conntrack_icmp_related.sh + + include ../lib.mk +diff --git a/tools/testing/selftests/netfilter/conntrack_icmp_related.sh b/tools/testing/selftests/netfilter/conntrack_icmp_related.sh +new file mode 100755 +index 000000000000..b48e1833bc89 +--- /dev/null ++++ b/tools/testing/selftests/netfilter/conntrack_icmp_related.sh +@@ -0,0 +1,283 @@ ++#!/bin/bash ++# ++# check that ICMP df-needed/pkttoobig icmp are set are set as related ++# state ++# ++# Setup is: ++# ++# nsclient1 -> nsrouter1 -> nsrouter2 -> nsclient2 ++# MTU 1500, except for nsrouter2 <-> nsclient2 link (1280). ++# ping nsclient2 from nsclient1, checking that conntrack did set RELATED ++# 'fragmentation needed' icmp packet. ++# ++# In addition, nsrouter1 will perform IP masquerading, i.e. also ++# check the icmp errors are propagated to the correct host as per ++# nat of "established" icmp-echo "connection". ++ ++# Kselftest framework requirement - SKIP code is 4. ++ksft_skip=4 ++ret=0 ++ ++nft --version > /dev/null 2>&1 ++if [ $? -ne 0 ];then ++ echo "SKIP: Could not run test without nft tool" ++ exit $ksft_skip ++fi ++ ++ip -Version > /dev/null 2>&1 ++if [ $? -ne 0 ];then ++ echo "SKIP: Could not run test without ip tool" ++ exit $ksft_skip ++fi ++ ++cleanup() { ++ for i in 1 2;do ip netns del nsclient$i;done ++ for i in 1 2;do ip netns del nsrouter$i;done ++} ++ ++ipv4() { ++ echo -n 192.168.$1.2 ++} ++ ++ipv6 () { ++ echo -n dead:$1::2 ++} ++ ++check_counter() ++{ ++ ns=$1 ++ name=$2 ++ expect=$3 ++ local lret=0 ++ ++ cnt=$(ip netns exec $ns nft list counter inet filter "$name" | grep -q "$expect") ++ if [ $? -ne 0 ]; then ++ echo "ERROR: counter $name in $ns has unexpected value (expected $expect)" 1>&2 ++ ip netns exec $ns nft list counter inet filter "$name" 1>&2 ++ lret=1 ++ fi ++ ++ return $lret ++} ++ ++check_unknown() ++{ ++ expect="packets 0 bytes 0" ++ for n in nsclient1 nsclient2 nsrouter1 nsrouter2; do ++ check_counter $n "unknown" "$expect" ++ if [ $? -ne 0 ] ;then ++ return 1 ++ fi ++ done ++ ++ return 0 ++} ++ ++for n in nsclient1 nsclient2 nsrouter1 nsrouter2; do ++ ip netns add $n ++ ip -net $n link set lo up ++done ++ ++DEV=veth0 ++ip link add $DEV netns nsclient1 type veth peer name eth1 netns nsrouter1 ++DEV=veth0 ++ip link add $DEV netns nsclient2 type veth peer name eth1 netns nsrouter2 ++ ++DEV=veth0 ++ip link add $DEV netns nsrouter1 type veth peer name eth2 netns nsrouter2 ++ ++DEV=veth0 ++for i in 1 2; do ++ ip -net nsclient$i link set $DEV up ++ ip -net nsclient$i addr add $(ipv4 $i)/24 dev $DEV ++ ip -net nsclient$i addr add $(ipv6 $i)/64 dev $DEV ++done ++ ++ip -net nsrouter1 link set eth1 up ++ip -net nsrouter1 link set veth0 up ++ ++ip -net nsrouter2 link set eth1 up ++ip -net nsrouter2 link set eth2 up ++ ++ip -net nsclient1 route add default via 192.168.1.1 ++ip -net nsclient1 -6 route add default via dead:1::1 ++ ++ip -net nsclient2 route add default via 192.168.2.1 ++ip -net nsclient2 route add default via dead:2::1 ++ ++i=3 ++ip -net nsrouter1 addr add 192.168.1.1/24 dev eth1 ++ip -net nsrouter1 addr add 192.168.3.1/24 dev veth0 ++ip -net nsrouter1 addr add dead:1::1/64 dev eth1 ++ip -net nsrouter1 addr add dead:3::1/64 dev veth0 ++ip -net nsrouter1 route add default via 192.168.3.10 ++ip -net nsrouter1 -6 route add default via dead:3::10 ++ ++ip -net nsrouter2 addr add 192.168.2.1/24 dev eth1 ++ip -net nsrouter2 addr add 192.168.3.10/24 dev eth2 ++ip -net nsrouter2 addr add dead:2::1/64 dev eth1 ++ip -net nsrouter2 addr add dead:3::10/64 dev eth2 ++ip -net nsrouter2 route add default via 192.168.3.1 ++ip -net nsrouter2 route add default via dead:3::1 ++ ++sleep 2 ++for i in 4 6; do ++ ip netns exec nsrouter1 sysctl -q net.ipv$i.conf.all.forwarding=1 ++ ip netns exec nsrouter2 sysctl -q net.ipv$i.conf.all.forwarding=1 ++done ++ ++for netns in nsrouter1 nsrouter2; do ++ip netns exec $netns nft -f - <<EOF ++table inet filter { ++ counter unknown { } ++ counter related { } ++ chain forward { ++ type filter hook forward priority 0; policy accept; ++ meta l4proto icmpv6 icmpv6 type "packet-too-big" ct state "related" counter name "related" accept ++ meta l4proto icmp icmp type "destination-unreachable" ct state "related" counter name "related" accept ++ meta l4proto { icmp, icmpv6 } ct state new,established accept ++ counter name "unknown" drop ++ } ++} ++EOF ++done ++ ++ip netns exec nsclient1 nft -f - <<EOF ++table inet filter { ++ counter unknown { } ++ counter related { } ++ chain input { ++ type filter hook input priority 0; policy accept; ++ meta l4proto { icmp, icmpv6 } ct state established,untracked accept ++ ++ meta l4proto { icmp, icmpv6 } ct state "related" counter name "related" accept ++ counter name "unknown" drop ++ } ++} ++EOF ++ ++ip netns exec nsclient2 nft -f - <<EOF ++table inet filter { ++ counter unknown { } ++ counter new { } ++ counter established { } ++ ++ chain input { ++ type filter hook input priority 0; policy accept; ++ meta l4proto { icmp, icmpv6 } ct state established,untracked accept ++ ++ meta l4proto { icmp, icmpv6 } ct state "new" counter name "new" accept ++ meta l4proto { icmp, icmpv6 } ct state "established" counter name "established" accept ++ counter name "unknown" drop ++ } ++ chain output { ++ type filter hook output priority 0; policy accept; ++ meta l4proto { icmp, icmpv6 } ct state established,untracked accept ++ ++ meta l4proto { icmp, icmpv6 } ct state "new" counter name "new" ++ meta l4proto { icmp, icmpv6 } ct state "established" counter name "established" ++ counter name "unknown" drop ++ } ++} ++EOF ++ ++ ++# make sure NAT core rewrites adress of icmp error if nat is used according to ++# conntrack nat information (icmp error will be directed at nsrouter1 address, ++# but it needs to be routed to nsclient1 address). ++ip netns exec nsrouter1 nft -f - <<EOF ++table ip nat { ++ chain postrouting { ++ type nat hook postrouting priority 0; policy accept; ++ ip protocol icmp oifname "veth0" counter masquerade ++ } ++} ++table ip6 nat { ++ chain postrouting { ++ type nat hook postrouting priority 0; policy accept; ++ ip6 nexthdr icmpv6 oifname "veth0" counter masquerade ++ } ++} ++EOF ++ ++ip netns exec nsrouter2 ip link set eth1 mtu 1280 ++ip netns exec nsclient2 ip link set veth0 mtu 1280 ++sleep 1 ++ ++ip netns exec nsclient1 ping -c 1 -s 1000 -q -M do 192.168.2.2 >/dev/null ++if [ $? -ne 0 ]; then ++ echo "ERROR: netns ip routing/connectivity broken" 1>&2 ++ cleanup ++ exit 1 ++fi ++ip netns exec nsclient1 ping6 -q -c 1 -s 1000 dead:2::2 >/dev/null ++if [ $? -ne 0 ]; then ++ echo "ERROR: netns ipv6 routing/connectivity broken" 1>&2 ++ cleanup ++ exit 1 ++fi ++ ++check_unknown ++if [ $? -ne 0 ]; then ++ ret=1 ++fi ++ ++expect="packets 0 bytes 0" ++for netns in nsrouter1 nsrouter2 nsclient1;do ++ check_counter "$netns" "related" "$expect" ++ if [ $? -ne 0 ]; then ++ ret=1 ++ fi ++done ++ ++expect="packets 2 bytes 2076" ++check_counter nsclient2 "new" "$expect" ++if [ $? -ne 0 ]; then ++ ret=1 ++fi ++ ++ip netns exec nsclient1 ping -q -c 1 -s 1300 -M do 192.168.2.2 > /dev/null ++if [ $? -eq 0 ]; then ++ echo "ERROR: ping should have failed with PMTU too big error" 1>&2 ++ ret=1 ++fi ++ ++# nsrouter2 should have generated the icmp error, so ++# related counter should be 0 (its in forward). ++expect="packets 0 bytes 0" ++check_counter "nsrouter2" "related" "$expect" ++if [ $? -ne 0 ]; then ++ ret=1 ++fi ++ ++# but nsrouter1 should have seen it, same for nsclient1. ++expect="packets 1 bytes 576" ++for netns in nsrouter1 nsclient1;do ++ check_counter "$netns" "related" "$expect" ++ if [ $? -ne 0 ]; then ++ ret=1 ++ fi ++done ++ ++ip netns exec nsclient1 ping6 -c 1 -s 1300 dead:2::2 > /dev/null ++if [ $? -eq 0 ]; then ++ echo "ERROR: ping6 should have failed with PMTU too big error" 1>&2 ++ ret=1 ++fi ++ ++expect="packets 2 bytes 1856" ++for netns in nsrouter1 nsclient1;do ++ check_counter "$netns" "related" "$expect" ++ if [ $? -ne 0 ]; then ++ ret=1 ++ fi ++done ++ ++if [ $ret -eq 0 ];then ++ echo "PASS: icmp mtu error had RELATED state" ++else ++ echo "ERROR: icmp error RELATED state test has failed" ++fi ++ ++cleanup ++exit $ret +diff --git a/tools/testing/selftests/netfilter/nft_nat.sh b/tools/testing/selftests/netfilter/nft_nat.sh +index 8ec76681605c..3194007cf8d1 100755 +--- a/tools/testing/selftests/netfilter/nft_nat.sh ++++ b/tools/testing/selftests/netfilter/nft_nat.sh +@@ -321,6 +321,7 @@ EOF + + test_masquerade6() + { ++ local natflags=$1 + local lret=0 + + ip netns exec ns0 sysctl net.ipv6.conf.all.forwarding=1 > /dev/null +@@ -354,13 +355,13 @@ ip netns exec ns0 nft -f - <<EOF + table ip6 nat { + chain postrouting { + type nat hook postrouting priority 0; policy accept; +- meta oif veth0 masquerade ++ meta oif veth0 masquerade $natflags + } + } + EOF + ip netns exec ns2 ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1 + if [ $? -ne 0 ] ; then +- echo "ERROR: cannot ping ns1 from ns2 with active ipv6 masquerading" ++ echo "ERROR: cannot ping ns1 from ns2 with active ipv6 masquerade $natflags" + lret=1 + fi + +@@ -397,19 +398,26 @@ EOF + fi + done + ++ ip netns exec ns2 ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1 ++ if [ $? -ne 0 ] ; then ++ echo "ERROR: cannot ping ns1 from ns2 with active ipv6 masquerade $natflags (attempt 2)" ++ lret=1 ++ fi ++ + ip netns exec ns0 nft flush chain ip6 nat postrouting + if [ $? -ne 0 ]; then + echo "ERROR: Could not flush ip6 nat postrouting" 1>&2 + lret=1 + fi + +- test $lret -eq 0 && echo "PASS: IPv6 masquerade for ns2" ++ test $lret -eq 0 && echo "PASS: IPv6 masquerade $natflags for ns2" + + return $lret + } + + test_masquerade() + { ++ local natflags=$1 + local lret=0 + + ip netns exec ns0 sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null +@@ -417,7 +425,7 @@ test_masquerade() + + ip netns exec ns2 ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 + if [ $? -ne 0 ] ; then +- echo "ERROR: canot ping ns1 from ns2" ++ echo "ERROR: cannot ping ns1 from ns2 $natflags" + lret=1 + fi + +@@ -443,13 +451,13 @@ ip netns exec ns0 nft -f - <<EOF + table ip nat { + chain postrouting { + type nat hook postrouting priority 0; policy accept; +- meta oif veth0 masquerade ++ meta oif veth0 masquerade $natflags + } + } + EOF + ip netns exec ns2 ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 + if [ $? -ne 0 ] ; then +- echo "ERROR: cannot ping ns1 from ns2 with active ip masquerading" ++ echo "ERROR: cannot ping ns1 from ns2 with active ip masquere $natflags" + lret=1 + fi + +@@ -485,13 +493,19 @@ EOF + fi + done + ++ ip netns exec ns2 ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1 ++ if [ $? -ne 0 ] ; then ++ echo "ERROR: cannot ping ns1 from ns2 with active ip masquerade $natflags (attempt 2)" ++ lret=1 ++ fi ++ + ip netns exec ns0 nft flush chain ip nat postrouting + if [ $? -ne 0 ]; then + echo "ERROR: Could not flush nat postrouting" 1>&2 + lret=1 + fi + +- test $lret -eq 0 && echo "PASS: IP masquerade for ns2" ++ test $lret -eq 0 && echo "PASS: IP masquerade $natflags for ns2" + + return $lret + } +@@ -750,8 +764,12 @@ test_local_dnat + test_local_dnat6 + + reset_counters +-test_masquerade +-test_masquerade6 ++test_masquerade "" ++test_masquerade6 "" ++ ++reset_counters ++test_masquerade "fully-random" ++test_masquerade6 "fully-random" + + reset_counters + test_redirect +diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c +index 1c2509104924..408431744d06 100644 +--- a/tools/testing/selftests/seccomp/seccomp_bpf.c ++++ b/tools/testing/selftests/seccomp/seccomp_bpf.c +@@ -3089,9 +3089,9 @@ TEST(user_notification_basic) + + /* Check that we get -ENOSYS with no listener attached */ + if (pid == 0) { +- if (user_trap_syscall(__NR_getpid, 0) < 0) ++ if (user_trap_syscall(__NR_getppid, 0) < 0) + exit(1); +- ret = syscall(__NR_getpid); ++ ret = syscall(__NR_getppid); + exit(ret >= 0 || errno != ENOSYS); + } + +@@ -3106,12 +3106,12 @@ TEST(user_notification_basic) + EXPECT_EQ(seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog), 0); + + /* Check that the basic notification machinery works */ +- listener = user_trap_syscall(__NR_getpid, ++ listener = user_trap_syscall(__NR_getppid, + SECCOMP_FILTER_FLAG_NEW_LISTENER); + ASSERT_GE(listener, 0); + + /* Installing a second listener in the chain should EBUSY */ +- EXPECT_EQ(user_trap_syscall(__NR_getpid, ++ EXPECT_EQ(user_trap_syscall(__NR_getppid, + SECCOMP_FILTER_FLAG_NEW_LISTENER), + -1); + EXPECT_EQ(errno, EBUSY); +@@ -3120,7 +3120,7 @@ TEST(user_notification_basic) + ASSERT_GE(pid, 0); + + if (pid == 0) { +- ret = syscall(__NR_getpid); ++ ret = syscall(__NR_getppid); + exit(ret != USER_NOTIF_MAGIC); + } + +@@ -3138,7 +3138,7 @@ TEST(user_notification_basic) + EXPECT_GT(poll(&pollfd, 1, -1), 0); + EXPECT_EQ(pollfd.revents, POLLOUT); + +- EXPECT_EQ(req.data.nr, __NR_getpid); ++ EXPECT_EQ(req.data.nr, __NR_getppid); + + resp.id = req.id; + resp.error = 0; +@@ -3165,7 +3165,7 @@ TEST(user_notification_kill_in_middle) + struct seccomp_notif req = {}; + struct seccomp_notif_resp resp = {}; + +- listener = user_trap_syscall(__NR_getpid, ++ listener = user_trap_syscall(__NR_getppid, + SECCOMP_FILTER_FLAG_NEW_LISTENER); + ASSERT_GE(listener, 0); + +@@ -3177,7 +3177,7 @@ TEST(user_notification_kill_in_middle) + ASSERT_GE(pid, 0); + + if (pid == 0) { +- ret = syscall(__NR_getpid); ++ ret = syscall(__NR_getppid); + exit(ret != USER_NOTIF_MAGIC); + } + +@@ -3277,7 +3277,7 @@ TEST(user_notification_closed_listener) + long ret; + int status, listener; + +- listener = user_trap_syscall(__NR_getpid, ++ listener = user_trap_syscall(__NR_getppid, + SECCOMP_FILTER_FLAG_NEW_LISTENER); + ASSERT_GE(listener, 0); + +@@ -3288,7 +3288,7 @@ TEST(user_notification_closed_listener) + ASSERT_GE(pid, 0); + if (pid == 0) { + close(listener); +- ret = syscall(__NR_getpid); ++ ret = syscall(__NR_getppid); + exit(ret != -1 && errno != ENOSYS); + } + +@@ -3311,14 +3311,15 @@ TEST(user_notification_child_pid_ns) + + ASSERT_EQ(unshare(CLONE_NEWPID), 0); + +- listener = user_trap_syscall(__NR_getpid, SECCOMP_FILTER_FLAG_NEW_LISTENER); ++ listener = user_trap_syscall(__NR_getppid, ++ SECCOMP_FILTER_FLAG_NEW_LISTENER); + ASSERT_GE(listener, 0); + + pid = fork(); + ASSERT_GE(pid, 0); + + if (pid == 0) +- exit(syscall(__NR_getpid) != USER_NOTIF_MAGIC); ++ exit(syscall(__NR_getppid) != USER_NOTIF_MAGIC); + + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); + EXPECT_EQ(req.pid, pid); +@@ -3346,7 +3347,8 @@ TEST(user_notification_sibling_pid_ns) + struct seccomp_notif req = {}; + struct seccomp_notif_resp resp = {}; + +- listener = user_trap_syscall(__NR_getpid, SECCOMP_FILTER_FLAG_NEW_LISTENER); ++ listener = user_trap_syscall(__NR_getppid, ++ SECCOMP_FILTER_FLAG_NEW_LISTENER); + ASSERT_GE(listener, 0); + + pid = fork(); +@@ -3359,7 +3361,7 @@ TEST(user_notification_sibling_pid_ns) + ASSERT_GE(pid2, 0); + + if (pid2 == 0) +- exit(syscall(__NR_getpid) != USER_NOTIF_MAGIC); ++ exit(syscall(__NR_getppid) != USER_NOTIF_MAGIC); + + EXPECT_EQ(waitpid(pid2, &status, 0), pid2); + EXPECT_EQ(true, WIFEXITED(status)); +@@ -3368,11 +3370,11 @@ TEST(user_notification_sibling_pid_ns) + } + + /* Create the sibling ns, and sibling in it. */ +- EXPECT_EQ(unshare(CLONE_NEWPID), 0); +- EXPECT_EQ(errno, 0); ++ ASSERT_EQ(unshare(CLONE_NEWPID), 0); ++ ASSERT_EQ(errno, 0); + + pid2 = fork(); +- EXPECT_GE(pid2, 0); ++ ASSERT_GE(pid2, 0); + + if (pid2 == 0) { + ASSERT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req), 0); +@@ -3380,7 +3382,7 @@ TEST(user_notification_sibling_pid_ns) + * The pid should be 0, i.e. the task is in some namespace that + * we can't "see". + */ +- ASSERT_EQ(req.pid, 0); ++ EXPECT_EQ(req.pid, 0); + + resp.id = req.id; + resp.error = 0; +@@ -3408,14 +3410,15 @@ TEST(user_notification_fault_recv) + struct seccomp_notif req = {}; + struct seccomp_notif_resp resp = {}; + +- listener = user_trap_syscall(__NR_getpid, SECCOMP_FILTER_FLAG_NEW_LISTENER); ++ listener = user_trap_syscall(__NR_getppid, ++ SECCOMP_FILTER_FLAG_NEW_LISTENER); + ASSERT_GE(listener, 0); + + pid = fork(); + ASSERT_GE(pid, 0); + + if (pid == 0) +- exit(syscall(__NR_getpid) != USER_NOTIF_MAGIC); ++ exit(syscall(__NR_getppid) != USER_NOTIF_MAGIC); + + /* Do a bad recv() */ + EXPECT_EQ(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, NULL), -1); +diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c +index b1286c4e0712..0bd0683640bd 100644 +--- a/virt/kvm/irqchip.c ++++ b/virt/kvm/irqchip.c +@@ -144,18 +144,19 @@ static int setup_routing_entry(struct kvm *kvm, + { + struct kvm_kernel_irq_routing_entry *ei; + int r; ++ u32 gsi = array_index_nospec(ue->gsi, KVM_MAX_IRQ_ROUTES); + + /* + * Do not allow GSI to be mapped to the same irqchip more than once. + * Allow only one to one mapping between GSI and non-irqchip routing. + */ +- hlist_for_each_entry(ei, &rt->map[ue->gsi], link) ++ hlist_for_each_entry(ei, &rt->map[gsi], link) + if (ei->type != KVM_IRQ_ROUTING_IRQCHIP || + ue->type != KVM_IRQ_ROUTING_IRQCHIP || + ue->u.irqchip.irqchip == ei->irqchip.irqchip) + return -EINVAL; + +- e->gsi = ue->gsi; ++ e->gsi = gsi; + e->type = ue->type; + r = kvm_set_routing_entry(kvm, e, ue); + if (r) +diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c +index b4f2d892a1d3..ff68b07e94e9 100644 +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -2974,12 +2974,14 @@ static int kvm_ioctl_create_device(struct kvm *kvm, + struct kvm_device_ops *ops = NULL; + struct kvm_device *dev; + bool test = cd->flags & KVM_CREATE_DEVICE_TEST; ++ int type; + int ret; + + if (cd->type >= ARRAY_SIZE(kvm_device_ops_table)) + return -ENODEV; + +- ops = kvm_device_ops_table[cd->type]; ++ type = array_index_nospec(cd->type, ARRAY_SIZE(kvm_device_ops_table)); ++ ops = kvm_device_ops_table[type]; + if (ops == NULL) + return -ENODEV; + +@@ -2994,7 +2996,7 @@ static int kvm_ioctl_create_device(struct kvm *kvm, + dev->kvm = kvm; + + mutex_lock(&kvm->lock); +- ret = ops->create(dev, cd->type); ++ ret = ops->create(dev, type); + if (ret < 0) { + mutex_unlock(&kvm->lock); + kfree(dev); |