diff options
author | 2017-06-17 08:40:44 +0100 | |
---|---|---|
committer | 2017-06-17 08:40:44 +0100 | |
commit | 08e2cefd4bd002235d8ec5b4114ad64098f8ac00 (patch) | |
tree | 06743afec500dc649ea971977222fdf28935d0ec | |
parent | linux 4.9.32 (diff) | |
download | linux-patches-08e2cefd4bd002235d8ec5b4114ad64098f8ac00.tar.gz linux-patches-08e2cefd4bd002235d8ec5b4114ad64098f8ac00.tar.bz2 linux-patches-08e2cefd4bd002235d8ec5b4114ad64098f8ac00.zip |
linux kernel 4.9.334.9-34
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1032_linux-4.9.33.patch | 5398 |
2 files changed, 5402 insertions, 0 deletions
diff --git a/0000_README b/0000_README index ff8e1bf6..fb4f697d 100644 --- a/0000_README +++ b/0000_README @@ -171,6 +171,10 @@ Patch: 1031_linux-4.9.32.patch From: http://www.kernel.org Desc: Linux 4.9.32 +Patch: 1032_linux-4.9.33.patch +From: http://www.kernel.org +Desc: Linux 4.9.33 + 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/1032_linux-4.9.33.patch b/1032_linux-4.9.33.patch new file mode 100644 index 00000000..929dadea --- /dev/null +++ b/1032_linux-4.9.33.patch @@ -0,0 +1,5398 @@ +diff --git a/Makefile b/Makefile +index 3d8781997968..8470d81d5cc2 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 9 +-SUBLEVEL = 32 ++SUBLEVEL = 33 + EXTRAVERSION = + NAME = Roaring Lionus + +@@ -797,7 +797,7 @@ KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types) + KBUILD_ARFLAGS := $(call ar-option,D) + + # check for 'asm goto' +-ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(CC)), y) ++ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(CC) $(KBUILD_CFLAGS)), y) + KBUILD_CFLAGS += -DCC_HAVE_ASM_GOTO + KBUILD_AFLAGS += -DCC_HAVE_ASM_GOTO + endif +diff --git a/arch/arc/kernel/head.S b/arch/arc/kernel/head.S +index 689dd867fdff..8b90d25a15cc 100644 +--- a/arch/arc/kernel/head.S ++++ b/arch/arc/kernel/head.S +@@ -71,14 +71,14 @@ ENTRY(stext) + GET_CPU_ID r5 + cmp r5, 0 + mov.nz r0, r5 +-#ifdef CONFIG_ARC_SMP_HALT_ON_RESET +- ; Non-Master can proceed as system would be booted sufficiently +- jnz first_lines_of_secondary +-#else ++ bz .Lmaster_proceed ++ + ; Non-Masters wait for Master to boot enough and bring them up +- jnz arc_platform_smp_wait_to_boot +-#endif +- ; Master falls thru ++ ; when they resume, tail-call to entry point ++ mov blink, @first_lines_of_secondary ++ j arc_platform_smp_wait_to_boot ++ ++.Lmaster_proceed: + #endif + + ; Clear BSS before updating any globals +diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c +index 88674d972c9d..2afbafadb6ab 100644 +--- a/arch/arc/kernel/smp.c ++++ b/arch/arc/kernel/smp.c +@@ -90,22 +90,37 @@ void __init smp_cpus_done(unsigned int max_cpus) + */ + static volatile int wake_flag; + ++#ifdef CONFIG_ISA_ARCOMPACT ++ ++#define __boot_read(f) f ++#define __boot_write(f, v) f = v ++ ++#else ++ ++#define __boot_read(f) arc_read_uncached_32(&f) ++#define __boot_write(f, v) arc_write_uncached_32(&f, v) ++ ++#endif ++ + static void arc_default_smp_cpu_kick(int cpu, unsigned long pc) + { + BUG_ON(cpu == 0); +- wake_flag = cpu; ++ ++ __boot_write(wake_flag, cpu); + } + + void arc_platform_smp_wait_to_boot(int cpu) + { +- while (wake_flag != cpu) ++ /* for halt-on-reset, we've waited already */ ++ if (IS_ENABLED(CONFIG_ARC_SMP_HALT_ON_RESET)) ++ return; ++ ++ while (__boot_read(wake_flag) != cpu) + ; + +- wake_flag = 0; +- __asm__ __volatile__("j @first_lines_of_secondary \n"); ++ __boot_write(wake_flag, 0); + } + +- + const char *arc_platform_smp_cpuinfo(void) + { + return plat_smp_ops.info ? : ""; +diff --git a/arch/arm/configs/ezx_defconfig b/arch/arm/configs/ezx_defconfig +index ea316c4b890e..d3f1768840e2 100644 +--- a/arch/arm/configs/ezx_defconfig ++++ b/arch/arm/configs/ezx_defconfig +@@ -64,8 +64,8 @@ CONFIG_NETFILTER=y + CONFIG_NETFILTER_NETLINK_QUEUE=m + CONFIG_NF_CONNTRACK=m + CONFIG_NF_CONNTRACK_EVENTS=y +-CONFIG_NF_CT_PROTO_SCTP=m +-CONFIG_NF_CT_PROTO_UDPLITE=m ++CONFIG_NF_CT_PROTO_SCTP=y ++CONFIG_NF_CT_PROTO_UDPLITE=y + CONFIG_NF_CONNTRACK_AMANDA=m + CONFIG_NF_CONNTRACK_FTP=m + CONFIG_NF_CONNTRACK_H323=m +diff --git a/arch/arm/configs/imote2_defconfig b/arch/arm/configs/imote2_defconfig +index 18e59feaa307..7f479cdb3479 100644 +--- a/arch/arm/configs/imote2_defconfig ++++ b/arch/arm/configs/imote2_defconfig +@@ -56,8 +56,8 @@ CONFIG_NETFILTER=y + CONFIG_NETFILTER_NETLINK_QUEUE=m + CONFIG_NF_CONNTRACK=m + CONFIG_NF_CONNTRACK_EVENTS=y +-CONFIG_NF_CT_PROTO_SCTP=m +-CONFIG_NF_CT_PROTO_UDPLITE=m ++CONFIG_NF_CT_PROTO_SCTP=y ++CONFIG_NF_CT_PROTO_UDPLITE=y + CONFIG_NF_CONNTRACK_AMANDA=m + CONFIG_NF_CONNTRACK_FTP=m + CONFIG_NF_CONNTRACK_H323=m +diff --git a/arch/frv/include/asm/atomic.h b/arch/frv/include/asm/atomic.h +index 1c2a5e264fc7..e93c9494503a 100644 +--- a/arch/frv/include/asm/atomic.h ++++ b/arch/frv/include/asm/atomic.h +@@ -139,7 +139,7 @@ static inline void atomic64_dec(atomic64_t *v) + #define atomic64_sub_and_test(i,v) (atomic64_sub_return((i), (v)) == 0) + #define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0) + #define atomic64_inc_and_test(v) (atomic64_inc_return((v)) == 0) +- ++#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) + + #define atomic_cmpxchg(v, old, new) (cmpxchg(&(v)->counter, old, new)) + #define atomic_xchg(v, new) (xchg(&(v)->counter, new)) +@@ -161,6 +161,39 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) + return c; + } + ++static inline int atomic64_add_unless(atomic64_t *v, long long i, long long u) ++{ ++ long long c, old; ++ ++ c = atomic64_read(v); ++ for (;;) { ++ if (unlikely(c == u)) ++ break; ++ old = atomic64_cmpxchg(v, c, c + i); ++ if (likely(old == c)) ++ break; ++ c = old; ++ } ++ return c != u; ++} ++ ++static inline long long atomic64_dec_if_positive(atomic64_t *v) ++{ ++ long long c, old, dec; ++ ++ c = atomic64_read(v); ++ for (;;) { ++ dec = c - 1; ++ if (unlikely(dec < 0)) ++ break; ++ old = atomic64_cmpxchg((v), c, dec); ++ if (likely(old == c)) ++ break; ++ c = old; ++ } ++ return dec; ++} ++ + #define ATOMIC_OP(op) \ + static inline int atomic_fetch_##op(int i, atomic_t *v) \ + { \ +diff --git a/arch/mn10300/include/asm/switch_to.h b/arch/mn10300/include/asm/switch_to.h +index 393d311735c8..67e333aa7629 100644 +--- a/arch/mn10300/include/asm/switch_to.h ++++ b/arch/mn10300/include/asm/switch_to.h +@@ -16,7 +16,7 @@ + struct task_struct; + struct thread_struct; + +-#if !defined(CONFIG_LAZY_SAVE_FPU) ++#if defined(CONFIG_FPU) && !defined(CONFIG_LAZY_SAVE_FPU) + struct fpu_state_struct; + extern asmlinkage void fpu_save(struct fpu_state_struct *); + #define switch_fpu(prev, next) \ +diff --git a/arch/powerpc/sysdev/xics/icp-opal.c b/arch/powerpc/sysdev/xics/icp-opal.c +index 32c46b424dd0..b53f80f0b4d8 100644 +--- a/arch/powerpc/sysdev/xics/icp-opal.c ++++ b/arch/powerpc/sysdev/xics/icp-opal.c +@@ -130,14 +130,16 @@ static void icp_opal_cause_ipi(int cpu, unsigned long data) + { + int hw_cpu = get_hard_smp_processor_id(cpu); + ++ kvmppc_set_host_ipi(cpu, 1); + opal_int_set_mfrr(hw_cpu, IPI_PRIORITY); + } + + static irqreturn_t icp_opal_ipi_action(int irq, void *dev_id) + { +- int hw_cpu = hard_smp_processor_id(); ++ int cpu = smp_processor_id(); + +- opal_int_set_mfrr(hw_cpu, 0xff); ++ kvmppc_set_host_ipi(cpu, 0); ++ opal_int_set_mfrr(get_hard_smp_processor_id(cpu), 0xff); + + return smp_ipi_demux(); + } +diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S +index c43816886839..3bc2825173ef 100644 +--- a/arch/s390/kernel/entry.S ++++ b/arch/s390/kernel/entry.S +@@ -240,12 +240,17 @@ ENTRY(sie64a) + lctlg %c1,%c1,__LC_USER_ASCE # load primary asce + .Lsie_done: + # some program checks are suppressing. C code (e.g. do_protection_exception) +-# will rewind the PSW by the ILC, which is 4 bytes in case of SIE. Other +-# instructions between sie64a and .Lsie_done should not cause program +-# interrupts. So lets use a nop (47 00 00 00) as a landing pad. ++# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There ++# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable. ++# Other instructions between sie64a and .Lsie_done should not cause program ++# interrupts. So lets use 3 nops as a landing pad for all possible rewinds. + # See also .Lcleanup_sie +-.Lrewind_pad: +- nop 0 ++.Lrewind_pad6: ++ nopr 7 ++.Lrewind_pad4: ++ nopr 7 ++.Lrewind_pad2: ++ nopr 7 + .globl sie_exit + sie_exit: + lg %r14,__SF_EMPTY+8(%r15) # load guest register save area +@@ -258,7 +263,9 @@ sie_exit: + stg %r14,__SF_EMPTY+16(%r15) # set exit reason code + j sie_exit + +- EX_TABLE(.Lrewind_pad,.Lsie_fault) ++ EX_TABLE(.Lrewind_pad6,.Lsie_fault) ++ EX_TABLE(.Lrewind_pad4,.Lsie_fault) ++ EX_TABLE(.Lrewind_pad2,.Lsie_fault) + EX_TABLE(sie_exit,.Lsie_fault) + EXPORT_SYMBOL(sie64a) + EXPORT_SYMBOL(sie_exit) +diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c +index 4094a51b1970..496fa926e1e0 100644 +--- a/arch/sparc/kernel/traps_64.c ++++ b/arch/sparc/kernel/traps_64.c +@@ -85,7 +85,7 @@ static void dump_tl1_traplog(struct tl1_traplog *p) + + void bad_trap(struct pt_regs *regs, long lvl) + { +- char buffer[32]; ++ char buffer[36]; + siginfo_t info; + + if (notify_die(DIE_TRAP, "bad trap", regs, +@@ -116,7 +116,7 @@ void bad_trap(struct pt_regs *regs, long lvl) + + void bad_trap_tl1(struct pt_regs *regs, long lvl) + { +- char buffer[32]; ++ char buffer[36]; + + if (notify_die(DIE_TRAP_TL1, "bad trap tl1", regs, + 0, lvl, SIGTRAP) == NOTIFY_STOP) +diff --git a/arch/xtensa/include/asm/irq.h b/arch/xtensa/include/asm/irq.h +index f71f88ea7646..19707db966f1 100644 +--- a/arch/xtensa/include/asm/irq.h ++++ b/arch/xtensa/include/asm/irq.h +@@ -29,7 +29,8 @@ static inline void variant_irq_disable(unsigned int irq) { } + # define PLATFORM_NR_IRQS 0 + #endif + #define XTENSA_NR_IRQS XCHAL_NUM_INTERRUPTS +-#define NR_IRQS (XTENSA_NR_IRQS + VARIANT_NR_IRQS + PLATFORM_NR_IRQS) ++#define NR_IRQS (XTENSA_NR_IRQS + VARIANT_NR_IRQS + PLATFORM_NR_IRQS + 1) ++#define XTENSA_PIC_LINUX_IRQ(hwirq) ((hwirq) + 1) + + #if VARIANT_NR_IRQS == 0 + static inline void variant_init_irq(void) { } +diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c +index 4ac3d23161cf..441694464b1e 100644 +--- a/arch/xtensa/kernel/irq.c ++++ b/arch/xtensa/kernel/irq.c +@@ -34,11 +34,6 @@ asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs) + { + int irq = irq_find_mapping(NULL, hwirq); + +- if (hwirq >= NR_IRQS) { +- printk(KERN_EMERG "%s: cannot handle IRQ %d\n", +- __func__, hwirq); +- } +- + #ifdef CONFIG_DEBUG_STACKOVERFLOW + /* Debugging check for stack overflow: is there less than 1KB free? */ + { +diff --git a/arch/xtensa/platforms/xtfpga/include/platform/hardware.h b/arch/xtensa/platforms/xtfpga/include/platform/hardware.h +index dbeea2b440a1..1fda7e20dfcb 100644 +--- a/arch/xtensa/platforms/xtfpga/include/platform/hardware.h ++++ b/arch/xtensa/platforms/xtfpga/include/platform/hardware.h +@@ -24,16 +24,18 @@ + + /* Interrupt configuration. */ + +-#define PLATFORM_NR_IRQS 10 ++#define PLATFORM_NR_IRQS 0 + + /* Default assignment of LX60 devices to external interrupts. */ + + #ifdef CONFIG_XTENSA_MX + #define DUART16552_INTNUM XCHAL_EXTINT3_NUM + #define OETH_IRQ XCHAL_EXTINT4_NUM ++#define C67X00_IRQ XCHAL_EXTINT8_NUM + #else + #define DUART16552_INTNUM XCHAL_EXTINT0_NUM + #define OETH_IRQ XCHAL_EXTINT1_NUM ++#define C67X00_IRQ XCHAL_EXTINT5_NUM + #endif + + /* +@@ -63,5 +65,5 @@ + + #define C67X00_PADDR (XCHAL_KIO_PADDR + 0x0D0D0000) + #define C67X00_SIZE 0x10 +-#define C67X00_IRQ 5 ++ + #endif /* __XTENSA_XTAVNET_HARDWARE_H */ +diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c +index 779be723eb2b..42285f35d313 100644 +--- a/arch/xtensa/platforms/xtfpga/setup.c ++++ b/arch/xtensa/platforms/xtfpga/setup.c +@@ -175,8 +175,8 @@ static struct resource ethoc_res[] = { + .flags = IORESOURCE_MEM, + }, + [2] = { /* IRQ number */ +- .start = OETH_IRQ, +- .end = OETH_IRQ, ++ .start = XTENSA_PIC_LINUX_IRQ(OETH_IRQ), ++ .end = XTENSA_PIC_LINUX_IRQ(OETH_IRQ), + .flags = IORESOURCE_IRQ, + }, + }; +@@ -213,8 +213,8 @@ static struct resource c67x00_res[] = { + .flags = IORESOURCE_MEM, + }, + [1] = { /* IRQ number */ +- .start = C67X00_IRQ, +- .end = C67X00_IRQ, ++ .start = XTENSA_PIC_LINUX_IRQ(C67X00_IRQ), ++ .end = XTENSA_PIC_LINUX_IRQ(C67X00_IRQ), + .flags = IORESOURCE_IRQ, + }, + }; +@@ -247,7 +247,7 @@ static struct resource serial_resource = { + static struct plat_serial8250_port serial_platform_data[] = { + [0] = { + .mapbase = DUART16552_PADDR, +- .irq = DUART16552_INTNUM, ++ .irq = XTENSA_PIC_LINUX_IRQ(DUART16552_INTNUM), + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = XCHAL_HAVE_BE ? UPIO_MEM32BE : UPIO_MEM32, +diff --git a/block/partitions/msdos.c b/block/partitions/msdos.c +index 93e7c1b32edd..5610cd537da7 100644 +--- a/block/partitions/msdos.c ++++ b/block/partitions/msdos.c +@@ -300,6 +300,8 @@ static void parse_bsd(struct parsed_partitions *state, + continue; + bsd_start = le32_to_cpu(p->p_offset); + bsd_size = le32_to_cpu(p->p_size); ++ if (memcmp(flavour, "bsd\0", 4) == 0) ++ bsd_start += offset; + if (offset == bsd_start && size == bsd_size) + /* full parent partition, we have it already */ + continue; +diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c +index 23f3b95a1158..147d2e3678aa 100644 +--- a/drivers/base/power/runtime.c ++++ b/drivers/base/power/runtime.c +@@ -889,13 +889,13 @@ int __pm_runtime_idle(struct device *dev, int rpmflags) + unsigned long flags; + int retval; + +- might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe); +- + if (rpmflags & RPM_GET_PUT) { + if (!atomic_dec_and_test(&dev->power.usage_count)) + return 0; + } + ++ might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe); ++ + spin_lock_irqsave(&dev->power.lock, flags); + retval = rpm_idle(dev, rpmflags); + spin_unlock_irqrestore(&dev->power.lock, flags); +@@ -921,13 +921,13 @@ int __pm_runtime_suspend(struct device *dev, int rpmflags) + unsigned long flags; + int retval; + +- might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe); +- + if (rpmflags & RPM_GET_PUT) { + if (!atomic_dec_and_test(&dev->power.usage_count)) + return 0; + } + ++ might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe); ++ + spin_lock_irqsave(&dev->power.lock, flags); + retval = rpm_suspend(dev, rpmflags); + spin_unlock_irqrestore(&dev->power.lock, flags); +@@ -952,7 +952,8 @@ int __pm_runtime_resume(struct device *dev, int rpmflags) + unsigned long flags; + int retval; + +- might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe); ++ might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe && ++ dev->power.runtime_status != RPM_ACTIVE); + + if (rpmflags & RPM_GET_PUT) + atomic_inc(&dev->power.usage_count); +diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h +index 908011d2c8f5..7abda94fc2cf 100644 +--- a/drivers/gpu/drm/ast/ast_drv.h ++++ b/drivers/gpu/drm/ast/ast_drv.h +@@ -113,6 +113,7 @@ struct ast_private { + struct ttm_bo_kmap_obj cache_kmap; + int next_cursor; + bool support_wide_screen; ++ bool DisableP2A; + + enum ast_tx_chip tx_chip_type; + u8 dp501_maxclk; +diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c +index f75c6421db62..533e762d036d 100644 +--- a/drivers/gpu/drm/ast/ast_main.c ++++ b/drivers/gpu/drm/ast/ast_main.c +@@ -124,6 +124,12 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) + } else + *need_post = false; + ++ /* Check P2A Access */ ++ ast->DisableP2A = true; ++ data = ast_read32(ast, 0xf004); ++ if (data != 0xFFFFFFFF) ++ ast->DisableP2A = false; ++ + /* Check if we support wide screen */ + switch (ast->chip) { + case AST1180: +@@ -140,15 +146,17 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) + ast->support_wide_screen = true; + else { + ast->support_wide_screen = false; +- /* Read SCU7c (silicon revision register) */ +- ast_write32(ast, 0xf004, 0x1e6e0000); +- ast_write32(ast, 0xf000, 0x1); +- data = ast_read32(ast, 0x1207c); +- data &= 0x300; +- if (ast->chip == AST2300 && data == 0x0) /* ast1300 */ +- ast->support_wide_screen = true; +- if (ast->chip == AST2400 && data == 0x100) /* ast1400 */ +- ast->support_wide_screen = true; ++ if (ast->DisableP2A == false) { ++ /* Read SCU7c (silicon revision register) */ ++ ast_write32(ast, 0xf004, 0x1e6e0000); ++ ast_write32(ast, 0xf000, 0x1); ++ data = ast_read32(ast, 0x1207c); ++ data &= 0x300; ++ if (ast->chip == AST2300 && data == 0x0) /* ast1300 */ ++ ast->support_wide_screen = true; ++ if (ast->chip == AST2400 && data == 0x100) /* ast1400 */ ++ ast->support_wide_screen = true; ++ } + } + break; + } +@@ -216,80 +224,81 @@ static int ast_get_dram_info(struct drm_device *dev) + uint32_t data, data2; + uint32_t denum, num, div, ref_pll; + +- ast_write32(ast, 0xf004, 0x1e6e0000); +- ast_write32(ast, 0xf000, 0x1); +- +- +- ast_write32(ast, 0x10000, 0xfc600309); +- +- do { +- if (pci_channel_offline(dev->pdev)) +- return -EIO; +- } while (ast_read32(ast, 0x10000) != 0x01); +- data = ast_read32(ast, 0x10004); +- +- if (data & 0x40) ++ if (ast->DisableP2A) ++ { + ast->dram_bus_width = 16; ++ ast->dram_type = AST_DRAM_1Gx16; ++ ast->mclk = 396; ++ } + else +- ast->dram_bus_width = 32; ++ { ++ ast_write32(ast, 0xf004, 0x1e6e0000); ++ ast_write32(ast, 0xf000, 0x1); ++ data = ast_read32(ast, 0x10004); ++ ++ if (data & 0x40) ++ ast->dram_bus_width = 16; ++ else ++ ast->dram_bus_width = 32; ++ ++ if (ast->chip == AST2300 || ast->chip == AST2400) { ++ switch (data & 0x03) { ++ case 0: ++ ast->dram_type = AST_DRAM_512Mx16; ++ break; ++ default: ++ case 1: ++ ast->dram_type = AST_DRAM_1Gx16; ++ break; ++ case 2: ++ ast->dram_type = AST_DRAM_2Gx16; ++ break; ++ case 3: ++ ast->dram_type = AST_DRAM_4Gx16; ++ break; ++ } ++ } else { ++ switch (data & 0x0c) { ++ case 0: ++ case 4: ++ ast->dram_type = AST_DRAM_512Mx16; ++ break; ++ case 8: ++ if (data & 0x40) ++ ast->dram_type = AST_DRAM_1Gx16; ++ else ++ ast->dram_type = AST_DRAM_512Mx32; ++ break; ++ case 0xc: ++ ast->dram_type = AST_DRAM_1Gx32; ++ break; ++ } ++ } + +- if (ast->chip == AST2300 || ast->chip == AST2400) { +- switch (data & 0x03) { +- case 0: +- ast->dram_type = AST_DRAM_512Mx16; +- break; +- default: +- case 1: +- ast->dram_type = AST_DRAM_1Gx16; +- break; +- case 2: +- ast->dram_type = AST_DRAM_2Gx16; +- break; ++ data = ast_read32(ast, 0x10120); ++ data2 = ast_read32(ast, 0x10170); ++ if (data2 & 0x2000) ++ ref_pll = 14318; ++ else ++ ref_pll = 12000; ++ ++ denum = data & 0x1f; ++ num = (data & 0x3fe0) >> 5; ++ data = (data & 0xc000) >> 14; ++ switch (data) { + case 3: +- ast->dram_type = AST_DRAM_4Gx16; +- break; +- } +- } else { +- switch (data & 0x0c) { +- case 0: +- case 4: +- ast->dram_type = AST_DRAM_512Mx16; ++ div = 0x4; + break; +- case 8: +- if (data & 0x40) +- ast->dram_type = AST_DRAM_1Gx16; +- else +- ast->dram_type = AST_DRAM_512Mx32; ++ case 2: ++ case 1: ++ div = 0x2; + break; +- case 0xc: +- ast->dram_type = AST_DRAM_1Gx32; ++ default: ++ div = 0x1; + break; + } ++ ast->mclk = ref_pll * (num + 2) / (denum + 2) * (div * 1000); + } +- +- data = ast_read32(ast, 0x10120); +- data2 = ast_read32(ast, 0x10170); +- if (data2 & 0x2000) +- ref_pll = 14318; +- else +- ref_pll = 12000; +- +- denum = data & 0x1f; +- num = (data & 0x3fe0) >> 5; +- data = (data & 0xc000) >> 14; +- switch (data) { +- case 3: +- div = 0x4; +- break; +- case 2: +- case 1: +- div = 0x2; +- break; +- default: +- div = 0x1; +- break; +- } +- ast->mclk = ref_pll * (num + 2) / (denum + 2) * (div * 1000); + return 0; + } + +diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c +index 30672a3df8a9..270e8fb2803f 100644 +--- a/drivers/gpu/drm/ast/ast_post.c ++++ b/drivers/gpu/drm/ast/ast_post.c +@@ -375,12 +375,20 @@ void ast_post_gpu(struct drm_device *dev) + ast_enable_mmio(dev); + ast_set_def_ext_reg(dev); + +- if (ast->chip == AST2300 || ast->chip == AST2400) +- ast_init_dram_2300(dev); +- else +- ast_init_dram_reg(dev); ++ if (ast->DisableP2A == false) ++ { ++ if (ast->chip == AST2300 || ast->chip == AST2400) ++ ast_init_dram_2300(dev); ++ else ++ ast_init_dram_reg(dev); + +- ast_init_3rdtx(dev); ++ ast_init_3rdtx(dev); ++ } ++ else ++ { ++ if (ast->tx_chip_type != AST_TX_NONE) ++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80); /* Enable DVO */ ++ } + } + + /* AST 2300 DRAM settings */ +diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c +index 2db7fb510b6c..0e934a9ac63c 100644 +--- a/drivers/gpu/drm/drm_connector.c ++++ b/drivers/gpu/drm/drm_connector.c +@@ -225,6 +225,7 @@ int drm_connector_init(struct drm_device *dev, + + INIT_LIST_HEAD(&connector->probed_modes); + INIT_LIST_HEAD(&connector->modes); ++ mutex_init(&connector->mutex); + connector->edid_blob_ptr = NULL; + connector->status = connector_status_unknown; + +@@ -359,6 +360,8 @@ void drm_connector_cleanup(struct drm_connector *connector) + connector->funcs->atomic_destroy_state(connector, + connector->state); + ++ mutex_destroy(&connector->mutex); ++ + memset(connector, 0, sizeof(*connector)); + } + EXPORT_SYMBOL(drm_connector_cleanup); +@@ -374,14 +377,18 @@ EXPORT_SYMBOL(drm_connector_cleanup); + */ + int drm_connector_register(struct drm_connector *connector) + { +- int ret; ++ int ret = 0; + +- if (connector->registered) ++ if (!connector->dev->registered) + return 0; + ++ mutex_lock(&connector->mutex); ++ if (connector->registered) ++ goto unlock; ++ + ret = drm_sysfs_connector_add(connector); + if (ret) +- return ret; ++ goto unlock; + + ret = drm_debugfs_connector_add(connector); + if (ret) { +@@ -397,12 +404,14 @@ int drm_connector_register(struct drm_connector *connector) + drm_mode_object_register(connector->dev, &connector->base); + + connector->registered = true; +- return 0; ++ goto unlock; + + err_debugfs: + drm_debugfs_connector_remove(connector); + err_sysfs: + drm_sysfs_connector_remove(connector); ++unlock: ++ mutex_unlock(&connector->mutex); + return ret; + } + EXPORT_SYMBOL(drm_connector_register); +@@ -415,8 +424,11 @@ EXPORT_SYMBOL(drm_connector_register); + */ + void drm_connector_unregister(struct drm_connector *connector) + { +- if (!connector->registered) ++ mutex_lock(&connector->mutex); ++ if (!connector->registered) { ++ mutex_unlock(&connector->mutex); + return; ++ } + + if (connector->funcs->early_unregister) + connector->funcs->early_unregister(connector); +@@ -425,6 +437,7 @@ void drm_connector_unregister(struct drm_connector *connector) + drm_debugfs_connector_remove(connector); + + connector->registered = false; ++ mutex_unlock(&connector->mutex); + } + EXPORT_SYMBOL(drm_connector_unregister); + +diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c +index 0f2fa9044668..362b8cd68a24 100644 +--- a/drivers/gpu/drm/drm_drv.c ++++ b/drivers/gpu/drm/drm_drv.c +@@ -710,6 +710,8 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) + if (ret) + goto err_minors; + ++ dev->registered = true; ++ + if (dev->driver->load) { + ret = dev->driver->load(dev, flags); + if (ret) +@@ -749,6 +751,8 @@ void drm_dev_unregister(struct drm_device *dev) + + drm_lastclose(dev); + ++ dev->registered = false; ++ + if (drm_core_check_feature(dev, DRIVER_MODESET)) + drm_modeset_unregister_all(dev); + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index ca6efb69ef66..7513e7678263 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -1199,6 +1199,15 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent) + goto out_free_priv; + + pci_set_drvdata(pdev, &dev_priv->drm); ++ /* ++ * Disable the system suspend direct complete optimization, which can ++ * leave the device suspended skipping the driver's suspend handlers ++ * if the device was already runtime suspended. This is needed due to ++ * the difference in our runtime and system suspend sequence and ++ * becaue the HDA driver may require us to enable the audio power ++ * domain during system suspend. ++ */ ++ pdev->dev_flags |= PCI_DEV_FLAGS_NEEDS_RESUME; + + ret = i915_driver_init_early(dev_priv, ent); + if (ret < 0) +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 5dc6082639db..f8efd20e4a90 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -2253,6 +2253,9 @@ void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation) + intel_fill_fb_ggtt_view(&view, fb, rotation); + vma = i915_gem_object_to_ggtt(obj, &view); + ++ if (WARN_ON_ONCE(!vma)) ++ return; ++ + i915_vma_unpin_fence(vma); + i915_gem_object_unpin_from_display_plane(vma); + } +@@ -13764,6 +13767,15 @@ static void update_scanline_offset(struct intel_crtc *crtc) + * type. For DP ports it behaves like most other platforms, but on HDMI + * there's an extra 1 line difference. So we need to add two instead of + * one to the value. ++ * ++ * On VLV/CHV DSI the scanline counter would appear to increment ++ * approx. 1/3 of a scanline before start of vblank. Unfortunately ++ * that means we can't tell whether we're in vblank or not while ++ * we're on that particular line. We must still set scanline_offset ++ * to 1 so that the vblank timestamps come out correct when we query ++ * the scanline counter from within the vblank interrupt handler. ++ * However if queried just before the start of vblank we'll get an ++ * answer that's slightly in the future. + */ + if (IS_GEN2(dev)) { + const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 2c6d59d4b6d3..49de4760cc16 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4114,11 +4114,19 @@ skl_compute_wm(struct drm_atomic_state *state) + struct drm_crtc_state *cstate; + struct intel_atomic_state *intel_state = to_intel_atomic_state(state); + struct skl_wm_values *results = &intel_state->wm_results; ++ struct drm_device *dev = state->dev; + struct skl_pipe_wm *pipe_wm; + bool changed = false; + int ret, i; + + /* ++ * When we distrust bios wm we always need to recompute to set the ++ * expected DDB allocations for each CRTC. ++ */ ++ if (to_i915(dev)->wm.distrust_bios_wm) ++ changed = true; ++ ++ /* + * If this transaction isn't actually touching any CRTC's, don't + * bother with watermark calculation. Note that if we pass this + * test, we're guaranteed to hold at least one CRTC state mutex, +@@ -4128,6 +4136,7 @@ skl_compute_wm(struct drm_atomic_state *state) + */ + for_each_crtc_in_state(state, crtc, cstate, i) + changed = true; ++ + if (!changed) + return 0; + +diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c +index dbed12c484c9..64f4e2e18594 100644 +--- a/drivers/gpu/drm/i915/intel_sprite.c ++++ b/drivers/gpu/drm/i915/intel_sprite.c +@@ -81,10 +81,13 @@ int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, + */ + void intel_pipe_update_start(struct intel_crtc *crtc) + { ++ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; + long timeout = msecs_to_jiffies_timeout(1); + int scanline, min, max, vblank_start; + wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base); ++ bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && ++ intel_crtc_has_type(crtc->config, INTEL_OUTPUT_DSI); + DEFINE_WAIT(wait); + + vblank_start = adjusted_mode->crtc_vblank_start; +@@ -136,6 +139,24 @@ void intel_pipe_update_start(struct intel_crtc *crtc) + + drm_crtc_vblank_put(&crtc->base); + ++ /* ++ * On VLV/CHV DSI the scanline counter would appear to ++ * increment approx. 1/3 of a scanline before start of vblank. ++ * The registers still get latched at start of vblank however. ++ * This means we must not write any registers on the first ++ * line of vblank (since not the whole line is actually in ++ * vblank). And unfortunately we can't use the interrupt to ++ * wait here since it will fire too soon. We could use the ++ * frame start interrupt instead since it will fire after the ++ * critical scanline, but that would require more changes ++ * in the interrupt code. So for now we'll just do the nasty ++ * thing and poll for the bad scanline to pass us by. ++ * ++ * FIXME figure out if BXT+ DSI suffers from this as well ++ */ ++ while (need_vlv_dsi_wa && scanline == vblank_start) ++ scanline = intel_get_crtc_scanline(crtc); ++ + crtc->debug.scanline_start = scanline; + crtc->debug.start_vbl_time = ktime_get(); + crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc); +diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c +index afbf557b23d4..2c2b86d68129 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_display.c ++++ b/drivers/gpu/drm/nouveau/nouveau_display.c +@@ -24,6 +24,7 @@ + * + */ + ++#include <acpi/video.h> + #include <drm/drmP.h> + #include <drm/drm_crtc_helper.h> + +@@ -358,6 +359,57 @@ static struct nouveau_drm_prop_enum_list dither_depth[] = { + } \ + } while(0) + ++static void ++nouveau_display_hpd_work(struct work_struct *work) ++{ ++ struct nouveau_drm *drm = container_of(work, typeof(*drm), hpd_work); ++ ++ pm_runtime_get_sync(drm->dev->dev); ++ ++ drm_helper_hpd_irq_event(drm->dev); ++ /* enable polling for external displays */ ++ drm_kms_helper_poll_enable(drm->dev); ++ ++ pm_runtime_mark_last_busy(drm->dev->dev); ++ pm_runtime_put_sync(drm->dev->dev); ++} ++ ++#ifdef CONFIG_ACPI ++ ++/* ++ * Hans de Goede: This define belongs in acpi/video.h, I've submitted a patch ++ * to the acpi subsys to move it there from drivers/acpi/acpi_video.c . ++ * This should be dropped once that is merged. ++ */ ++#ifndef ACPI_VIDEO_NOTIFY_PROBE ++#define ACPI_VIDEO_NOTIFY_PROBE 0x81 ++#endif ++ ++static int ++nouveau_display_acpi_ntfy(struct notifier_block *nb, unsigned long val, ++ void *data) ++{ ++ struct nouveau_drm *drm = container_of(nb, typeof(*drm), acpi_nb); ++ struct acpi_bus_event *info = data; ++ ++ if (!strcmp(info->device_class, ACPI_VIDEO_CLASS)) { ++ if (info->type == ACPI_VIDEO_NOTIFY_PROBE) { ++ /* ++ * This may be the only indication we receive of a ++ * connector hotplug on a runtime suspended GPU, ++ * schedule hpd_work to check. ++ */ ++ schedule_work(&drm->hpd_work); ++ ++ /* acpi-video should not generate keypresses for this */ ++ return NOTIFY_BAD; ++ } ++ } ++ ++ return NOTIFY_DONE; ++} ++#endif ++ + int + nouveau_display_init(struct drm_device *dev) + { +@@ -370,9 +422,6 @@ nouveau_display_init(struct drm_device *dev) + if (ret) + return ret; + +- /* enable polling for external displays */ +- drm_kms_helper_poll_enable(dev); +- + /* enable hotplug interrupts */ + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct nouveau_connector *conn = nouveau_connector(connector); +@@ -537,6 +586,12 @@ nouveau_display_create(struct drm_device *dev) + } + + nouveau_backlight_init(dev); ++ INIT_WORK(&drm->hpd_work, nouveau_display_hpd_work); ++#ifdef CONFIG_ACPI ++ drm->acpi_nb.notifier_call = nouveau_display_acpi_ntfy; ++ register_acpi_notifier(&drm->acpi_nb); ++#endif ++ + return 0; + + vblank_err: +@@ -552,6 +607,9 @@ nouveau_display_destroy(struct drm_device *dev) + { + struct nouveau_display *disp = nouveau_display(dev); + ++#ifdef CONFIG_ACPI ++ unregister_acpi_notifier(&nouveau_drm(dev)->acpi_nb); ++#endif + nouveau_backlight_exit(dev); + nouveau_display_vblank_fini(dev); + +diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c +index 3100fd88a015..42829a942e33 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_drm.c ++++ b/drivers/gpu/drm/nouveau/nouveau_drm.c +@@ -483,6 +483,9 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) + pm_runtime_allow(dev->dev); + pm_runtime_mark_last_busy(dev->dev); + pm_runtime_put(dev->dev); ++ } else { ++ /* enable polling for external displays */ ++ drm_kms_helper_poll_enable(dev); + } + return 0; + +@@ -761,7 +764,7 @@ nouveau_pmops_runtime_resume(struct device *dev) + pci_set_master(pdev); + + ret = nouveau_do_resume(drm_dev, true); +- drm_kms_helper_poll_enable(drm_dev); ++ + /* do magic */ + nvif_mask(&device->object, 0x088488, (1 << 25), (1 << 25)); + vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON); +diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h +index 822a0212cd48..1e7f1e326b3c 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_drv.h ++++ b/drivers/gpu/drm/nouveau/nouveau_drv.h +@@ -37,6 +37,8 @@ + * - implemented limited ABI16/NVIF interop + */ + ++#include <linux/notifier.h> ++ + #include <nvif/client.h> + #include <nvif/device.h> + #include <nvif/ioctl.h> +@@ -161,6 +163,12 @@ struct nouveau_drm { + struct nvbios vbios; + struct nouveau_display *display; + struct backlight_device *backlight; ++ struct work_struct hpd_work; ++ struct work_struct fbcon_work; ++ int fbcon_new_state; ++#ifdef CONFIG_ACPI ++ struct notifier_block acpi_nb; ++#endif + + /* power management */ + struct nouveau_hwmon *hwmon; +diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c +index 9f5692726c16..2b79e27dd89c 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c ++++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c +@@ -491,19 +491,43 @@ static const struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = { + .fb_probe = nouveau_fbcon_create, + }; + ++static void ++nouveau_fbcon_set_suspend_work(struct work_struct *work) ++{ ++ struct nouveau_drm *drm = container_of(work, typeof(*drm), fbcon_work); ++ int state = READ_ONCE(drm->fbcon_new_state); ++ ++ if (state == FBINFO_STATE_RUNNING) ++ pm_runtime_get_sync(drm->dev->dev); ++ ++ console_lock(); ++ if (state == FBINFO_STATE_RUNNING) ++ nouveau_fbcon_accel_restore(drm->dev); ++ drm_fb_helper_set_suspend(&drm->fbcon->helper, state); ++ if (state != FBINFO_STATE_RUNNING) ++ nouveau_fbcon_accel_save_disable(drm->dev); ++ console_unlock(); ++ ++ if (state == FBINFO_STATE_RUNNING) { ++ pm_runtime_mark_last_busy(drm->dev->dev); ++ pm_runtime_put_sync(drm->dev->dev); ++ } ++} ++ + void + nouveau_fbcon_set_suspend(struct drm_device *dev, int state) + { + struct nouveau_drm *drm = nouveau_drm(dev); +- if (drm->fbcon) { +- console_lock(); +- if (state == FBINFO_STATE_RUNNING) +- nouveau_fbcon_accel_restore(dev); +- drm_fb_helper_set_suspend(&drm->fbcon->helper, state); +- if (state != FBINFO_STATE_RUNNING) +- nouveau_fbcon_accel_save_disable(dev); +- console_unlock(); +- } ++ ++ if (!drm->fbcon) ++ return; ++ ++ drm->fbcon_new_state = state; ++ /* Since runtime resume can happen as a result of a sysfs operation, ++ * it's possible we already have the console locked. So handle fbcon ++ * init/deinit from a seperate work thread ++ */ ++ schedule_work(&drm->fbcon_work); + } + + int +@@ -524,6 +548,7 @@ nouveau_fbcon_init(struct drm_device *dev) + + fbcon->dev = dev; + drm->fbcon = fbcon; ++ INIT_WORK(&drm->fbcon_work, nouveau_fbcon_set_suspend_work); + + drm_fb_helper_prepare(dev, &fbcon->helper, &nouveau_fbcon_helper_funcs); + +diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h +index 64c4ce7115ad..75e1f09484ff 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_fence.h ++++ b/drivers/gpu/drm/nouveau/nouveau_fence.h +@@ -100,6 +100,7 @@ struct nv84_fence_priv { + struct nouveau_bo *bo; + struct nouveau_bo *bo_gart; + u32 *suspend; ++ struct mutex mutex; + }; + + u64 nv84_fence_crtc(struct nouveau_channel *, int); +diff --git a/drivers/gpu/drm/nouveau/nouveau_usif.c b/drivers/gpu/drm/nouveau/nouveau_usif.c +index 08f9c6fa0f7f..1fba38622744 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_usif.c ++++ b/drivers/gpu/drm/nouveau/nouveau_usif.c +@@ -313,7 +313,8 @@ usif_ioctl(struct drm_file *filp, void __user *user, u32 argc) + if (!(ret = nvif_unpack(-ENOSYS, &data, &size, argv->v0, 0, 0, true))) { + /* block access to objects not created via this interface */ + owner = argv->v0.owner; +- if (argv->v0.object == 0ULL) ++ if (argv->v0.object == 0ULL && ++ argv->v0.type != NVIF_IOCTL_V0_DEL) + argv->v0.owner = NVDRM_OBJECT_ANY; /* except client */ + else + argv->v0.owner = NVDRM_OBJECT_USIF; +diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c +index 18bde9d8e6d6..90a5dd6311c6 100644 +--- a/drivers/gpu/drm/nouveau/nv84_fence.c ++++ b/drivers/gpu/drm/nouveau/nv84_fence.c +@@ -121,8 +121,10 @@ nv84_fence_context_del(struct nouveau_channel *chan) + } + + nouveau_bo_wr32(priv->bo, chan->chid * 16 / 4, fctx->base.sequence); ++ mutex_lock(&priv->mutex); + nouveau_bo_vma_del(priv->bo, &fctx->vma_gart); + nouveau_bo_vma_del(priv->bo, &fctx->vma); ++ mutex_unlock(&priv->mutex); + nouveau_fence_context_del(&fctx->base); + chan->fence = NULL; + nouveau_fence_context_free(&fctx->base); +@@ -148,11 +150,13 @@ nv84_fence_context_new(struct nouveau_channel *chan) + fctx->base.sync32 = nv84_fence_sync32; + fctx->base.sequence = nv84_fence_read(chan); + ++ mutex_lock(&priv->mutex); + ret = nouveau_bo_vma_add(priv->bo, cli->vm, &fctx->vma); + if (ret == 0) { + ret = nouveau_bo_vma_add(priv->bo_gart, cli->vm, + &fctx->vma_gart); + } ++ mutex_unlock(&priv->mutex); + + /* map display semaphore buffers into channel's vm */ + for (i = 0; !ret && i < chan->drm->dev->mode_config.num_crtc; i++) { +@@ -232,6 +236,8 @@ nv84_fence_create(struct nouveau_drm *drm) + priv->base.context_base = fence_context_alloc(priv->base.contexts); + priv->base.uevent = true; + ++ mutex_init(&priv->mutex); ++ + /* Use VRAM if there is any ; otherwise fallback to system memory */ + domain = drm->device.info.ram_size != 0 ? TTM_PL_FLAG_VRAM : + /* +diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c +index e34d82e79b98..c21ca7bf2efe 100644 +--- a/drivers/i2c/busses/i2c-piix4.c ++++ b/drivers/i2c/busses/i2c-piix4.c +@@ -58,7 +58,7 @@ + #define SMBSLVDAT (0xC + piix4_smba) + + /* count for request_region */ +-#define SMBIOSIZE 8 ++#define SMBIOSIZE 9 + + /* PCI Address Constants */ + #define SMBBA 0x090 +@@ -592,6 +592,8 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, + u8 port; + int retval; + ++ mutex_lock(&piix4_mutex_sb800); ++ + /* Request the SMBUS semaphore, avoid conflicts with the IMC */ + smbslvcnt = inb_p(SMBSLVCNT); + do { +@@ -605,10 +607,10 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, + usleep_range(1000, 2000); + } while (--retries); + /* SMBus is still owned by the IMC, we give up */ +- if (!retries) ++ if (!retries) { ++ mutex_unlock(&piix4_mutex_sb800); + return -EBUSY; +- +- mutex_lock(&piix4_mutex_sb800); ++ } + + outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX); + smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); +@@ -623,11 +625,11 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, + + outb_p(smba_en_lo, SB800_PIIX4_SMB_IDX + 1); + +- mutex_unlock(&piix4_mutex_sb800); +- + /* Release the semaphore */ + outb_p(smbslvcnt | 0x20, SMBSLVCNT); + ++ mutex_unlock(&piix4_mutex_sb800); ++ + return retval; + } + +diff --git a/drivers/infiniband/hw/qedr/main.c b/drivers/infiniband/hw/qedr/main.c +index 7b74d09a8217..58e92bce6825 100644 +--- a/drivers/infiniband/hw/qedr/main.c ++++ b/drivers/infiniband/hw/qedr/main.c +@@ -792,6 +792,9 @@ static struct qedr_dev *qedr_add(struct qed_dev *cdev, struct pci_dev *pdev, + if (device_create_file(&dev->ibdev.dev, qedr_attributes[i])) + goto sysfs_err; + ++ if (!test_and_set_bit(QEDR_ENET_STATE_BIT, &dev->enet_state)) ++ qedr_ib_dispatch_event(dev, QEDR_PORT, IB_EVENT_PORT_ACTIVE); ++ + DP_DEBUG(dev, QEDR_MSG_INIT, "qedr driver loaded successfully\n"); + return dev; + +@@ -824,11 +827,10 @@ static void qedr_remove(struct qedr_dev *dev) + ib_dealloc_device(&dev->ibdev); + } + +-static int qedr_close(struct qedr_dev *dev) ++static void qedr_close(struct qedr_dev *dev) + { +- qedr_ib_dispatch_event(dev, 1, IB_EVENT_PORT_ERR); +- +- return 0; ++ if (test_and_clear_bit(QEDR_ENET_STATE_BIT, &dev->enet_state)) ++ qedr_ib_dispatch_event(dev, QEDR_PORT, IB_EVENT_PORT_ERR); + } + + static void qedr_shutdown(struct qedr_dev *dev) +@@ -837,6 +839,12 @@ static void qedr_shutdown(struct qedr_dev *dev) + qedr_remove(dev); + } + ++static void qedr_open(struct qedr_dev *dev) ++{ ++ if (!test_and_set_bit(QEDR_ENET_STATE_BIT, &dev->enet_state)) ++ qedr_ib_dispatch_event(dev, QEDR_PORT, IB_EVENT_PORT_ACTIVE); ++} ++ + static void qedr_mac_address_change(struct qedr_dev *dev) + { + union ib_gid *sgid = &dev->sgid_tbl[0]; +@@ -863,7 +871,7 @@ static void qedr_mac_address_change(struct qedr_dev *dev) + + ether_addr_copy(dev->gsi_ll2_mac_address, dev->ndev->dev_addr); + +- qedr_ib_dispatch_event(dev, 1, IB_EVENT_GID_CHANGE); ++ qedr_ib_dispatch_event(dev, QEDR_PORT, IB_EVENT_GID_CHANGE); + + if (rc) + DP_ERR(dev, "Error updating mac filter\n"); +@@ -877,7 +885,7 @@ static void qedr_notify(struct qedr_dev *dev, enum qede_roce_event event) + { + switch (event) { + case QEDE_UP: +- qedr_ib_dispatch_event(dev, 1, IB_EVENT_PORT_ACTIVE); ++ qedr_open(dev); + break; + case QEDE_DOWN: + qedr_close(dev); +diff --git a/drivers/infiniband/hw/qedr/qedr.h b/drivers/infiniband/hw/qedr/qedr.h +index 620badd7d4fb..f669d0bb697e 100644 +--- a/drivers/infiniband/hw/qedr/qedr.h ++++ b/drivers/infiniband/hw/qedr/qedr.h +@@ -113,6 +113,8 @@ struct qedr_device_attr { + struct qed_rdma_events events; + }; + ++#define QEDR_ENET_STATE_BIT (0) ++ + struct qedr_dev { + struct ib_device ibdev; + struct qed_dev *cdev; +@@ -153,6 +155,8 @@ struct qedr_dev { + struct qedr_cq *gsi_sqcq; + struct qedr_cq *gsi_rqcq; + struct qedr_qp *gsi_qp; ++ ++ unsigned long enet_state; + }; + + #define QEDR_MAX_SQ_PBL (0x8000) +@@ -188,6 +192,7 @@ struct qedr_dev { + #define QEDR_ROCE_MAX_CNQ_SIZE (0x4000) + + #define QEDR_MAX_PORT (1) ++#define QEDR_PORT (1) + + #define QEDR_UVERBS(CMD_NAME) (1ull << IB_USER_VERBS_CMD_##CMD_NAME) + +diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c +index a61514296767..4ba019e3dc56 100644 +--- a/drivers/infiniband/hw/qedr/verbs.c ++++ b/drivers/infiniband/hw/qedr/verbs.c +@@ -471,8 +471,6 @@ struct ib_pd *qedr_alloc_pd(struct ib_device *ibdev, + struct ib_ucontext *context, struct ib_udata *udata) + { + struct qedr_dev *dev = get_qedr_dev(ibdev); +- struct qedr_ucontext *uctx = NULL; +- struct qedr_alloc_pd_uresp uresp; + struct qedr_pd *pd; + u16 pd_id; + int rc; +@@ -489,21 +487,33 @@ struct ib_pd *qedr_alloc_pd(struct ib_device *ibdev, + if (!pd) + return ERR_PTR(-ENOMEM); + +- dev->ops->rdma_alloc_pd(dev->rdma_ctx, &pd_id); ++ rc = dev->ops->rdma_alloc_pd(dev->rdma_ctx, &pd_id); ++ if (rc) ++ goto err; + +- uresp.pd_id = pd_id; + pd->pd_id = pd_id; + + if (udata && context) { ++ struct qedr_alloc_pd_uresp uresp; ++ ++ uresp.pd_id = pd_id; ++ + rc = ib_copy_to_udata(udata, &uresp, sizeof(uresp)); +- if (rc) ++ if (rc) { + DP_ERR(dev, "copy error pd_id=0x%x.\n", pd_id); +- uctx = get_qedr_ucontext(context); +- uctx->pd = pd; +- pd->uctx = uctx; ++ dev->ops->rdma_dealloc_pd(dev->rdma_ctx, pd_id); ++ goto err; ++ } ++ ++ pd->uctx = get_qedr_ucontext(context); ++ pd->uctx->pd = pd; + } + + return &pd->ibpd; ++ ++err: ++ kfree(pd); ++ return ERR_PTR(rc); + } + + int qedr_dealloc_pd(struct ib_pd *ibpd) +@@ -1719,6 +1729,14 @@ static int qedr_update_qp_state(struct qedr_dev *dev, + /* ERR->XXX */ + switch (new_state) { + case QED_ROCE_QP_STATE_RESET: ++ if ((qp->rq.prod != qp->rq.cons) || ++ (qp->sq.prod != qp->sq.cons)) { ++ DP_NOTICE(dev, ++ "Error->Reset with rq/sq not empty rq.prod=%x rq.cons=%x sq.prod=%x sq.cons=%x\n", ++ qp->rq.prod, qp->rq.cons, qp->sq.prod, ++ qp->sq.cons); ++ status = -EINVAL; ++ } + break; + default: + status = -EINVAL; +@@ -2014,7 +2032,7 @@ int qedr_query_qp(struct ib_qp *ibqp, + qp_attr->cap.max_recv_wr = qp->rq.max_wr; + qp_attr->cap.max_send_sge = qp->sq.max_sges; + qp_attr->cap.max_recv_sge = qp->rq.max_sges; +- qp_attr->cap.max_inline_data = qp->max_inline_data; ++ qp_attr->cap.max_inline_data = ROCE_REQ_MAX_INLINE_DATA_SIZE; + qp_init_attr->cap = qp_attr->cap; + + memcpy(&qp_attr->ah_attr.grh.dgid.raw[0], ¶ms.dgid.bytes[0], +@@ -3220,9 +3238,10 @@ static int qedr_poll_cq_req(struct qedr_dev *dev, + IB_WC_SUCCESS, 0); + break; + case RDMA_CQE_REQ_STS_WORK_REQUEST_FLUSHED_ERR: +- DP_ERR(dev, +- "Error: POLL CQ with RDMA_CQE_REQ_STS_WORK_REQUEST_FLUSHED_ERR. CQ icid=0x%x, QP icid=0x%x\n", +- cq->icid, qp->icid); ++ if (qp->state != QED_ROCE_QP_STATE_ERR) ++ DP_ERR(dev, ++ "Error: POLL CQ with RDMA_CQE_REQ_STS_WORK_REQUEST_FLUSHED_ERR. CQ icid=0x%x, QP icid=0x%x\n", ++ cq->icid, qp->icid); + cnt = process_req(dev, qp, cq, num_entries, wc, req->sq_cons, + IB_WC_WR_FLUSH_ERR, 0); + break; +diff --git a/drivers/irqchip/irq-xtensa-mx.c b/drivers/irqchip/irq-xtensa-mx.c +index bb3ac5fe5846..72a391e01011 100644 +--- a/drivers/irqchip/irq-xtensa-mx.c ++++ b/drivers/irqchip/irq-xtensa-mx.c +@@ -142,7 +142,7 @@ static struct irq_chip xtensa_mx_irq_chip = { + int __init xtensa_mx_init_legacy(struct device_node *interrupt_parent) + { + struct irq_domain *root_domain = +- irq_domain_add_legacy(NULL, NR_IRQS, 0, 0, ++ irq_domain_add_legacy(NULL, NR_IRQS - 1, 1, 0, + &xtensa_mx_irq_domain_ops, + &xtensa_mx_irq_chip); + irq_set_default_host(root_domain); +diff --git a/drivers/irqchip/irq-xtensa-pic.c b/drivers/irqchip/irq-xtensa-pic.c +index 472ae1770964..f728755fa292 100644 +--- a/drivers/irqchip/irq-xtensa-pic.c ++++ b/drivers/irqchip/irq-xtensa-pic.c +@@ -89,7 +89,7 @@ static struct irq_chip xtensa_irq_chip = { + int __init xtensa_pic_init_legacy(struct device_node *interrupt_parent) + { + struct irq_domain *root_domain = +- irq_domain_add_legacy(NULL, NR_IRQS, 0, 0, ++ irq_domain_add_legacy(NULL, NR_IRQS - 1, 1, 0, + &xtensa_irq_domain_ops, &xtensa_irq_chip); + irq_set_default_host(root_domain); + return 0; +diff --git a/drivers/net/ethernet/adaptec/starfire.c b/drivers/net/ethernet/adaptec/starfire.c +index 8af2c88d5b33..45bb0fe50917 100644 +--- a/drivers/net/ethernet/adaptec/starfire.c ++++ b/drivers/net/ethernet/adaptec/starfire.c +@@ -1153,6 +1153,12 @@ static void init_ring(struct net_device *dev) + if (skb == NULL) + break; + np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE); ++ if (pci_dma_mapping_error(np->pci_dev, ++ np->rx_info[i].mapping)) { ++ dev_kfree_skb(skb); ++ np->rx_info[i].skb = NULL; ++ break; ++ } + /* Grrr, we cannot offset to correctly align the IP header. */ + np->rx_ring[i].rxaddr = cpu_to_dma(np->rx_info[i].mapping | RxDescValid); + } +@@ -1183,8 +1189,9 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev) + { + struct netdev_private *np = netdev_priv(dev); + unsigned int entry; ++ unsigned int prev_tx; + u32 status; +- int i; ++ int i, j; + + /* + * be cautious here, wrapping the queue has weird semantics +@@ -1202,6 +1209,7 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev) + } + #endif /* ZEROCOPY && HAS_BROKEN_FIRMWARE */ + ++ prev_tx = np->cur_tx; + entry = np->cur_tx % TX_RING_SIZE; + for (i = 0; i < skb_num_frags(skb); i++) { + int wrap_ring = 0; +@@ -1235,6 +1243,11 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev) + skb_frag_size(this_frag), + PCI_DMA_TODEVICE); + } ++ if (pci_dma_mapping_error(np->pci_dev, ++ np->tx_info[entry].mapping)) { ++ dev->stats.tx_dropped++; ++ goto err_out; ++ } + + np->tx_ring[entry].addr = cpu_to_dma(np->tx_info[entry].mapping); + np->tx_ring[entry].status = cpu_to_le32(status); +@@ -1269,8 +1282,30 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev) + netif_stop_queue(dev); + + return NETDEV_TX_OK; +-} + ++err_out: ++ entry = prev_tx % TX_RING_SIZE; ++ np->tx_info[entry].skb = NULL; ++ if (i > 0) { ++ pci_unmap_single(np->pci_dev, ++ np->tx_info[entry].mapping, ++ skb_first_frag_len(skb), ++ PCI_DMA_TODEVICE); ++ np->tx_info[entry].mapping = 0; ++ entry = (entry + np->tx_info[entry].used_slots) % TX_RING_SIZE; ++ for (j = 1; j < i; j++) { ++ pci_unmap_single(np->pci_dev, ++ np->tx_info[entry].mapping, ++ skb_frag_size( ++ &skb_shinfo(skb)->frags[j-1]), ++ PCI_DMA_TODEVICE); ++ entry++; ++ } ++ } ++ dev_kfree_skb_any(skb); ++ np->cur_tx = prev_tx; ++ return NETDEV_TX_OK; ++} + + /* The interrupt handler does all of the Rx thread work and cleans up + after the Tx thread. */ +@@ -1570,6 +1605,12 @@ static void refill_rx_ring(struct net_device *dev) + break; /* Better luck next round. */ + np->rx_info[entry].mapping = + pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE); ++ if (pci_dma_mapping_error(np->pci_dev, ++ np->rx_info[entry].mapping)) { ++ dev_kfree_skb(skb); ++ np->rx_info[entry].skb = NULL; ++ break; ++ } + np->rx_ring[entry].rxaddr = + cpu_to_dma(np->rx_info[entry].mapping | RxDescValid); + } +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 48ee4110ef6e..5cc0f8cfec87 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -1499,6 +1499,7 @@ static int bnxt_async_event_process(struct bnxt *bp, + netdev_warn(bp->dev, "Link speed %d no longer supported\n", + speed); + } ++ set_bit(BNXT_LINK_SPEED_CHNG_SP_EVENT, &bp->sp_event); + /* fall thru */ + } + case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE: +@@ -5110,6 +5111,7 @@ static int bnxt_update_link(struct bnxt *bp, bool chng_link_state) + struct hwrm_port_phy_qcfg_input req = {0}; + struct hwrm_port_phy_qcfg_output *resp = bp->hwrm_cmd_resp_addr; + u8 link_up = link_info->link_up; ++ u16 diff; + + bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_PHY_QCFG, -1, -1); + +@@ -5197,6 +5199,18 @@ static int bnxt_update_link(struct bnxt *bp, bool chng_link_state) + link_info->link_up = 0; + } + mutex_unlock(&bp->hwrm_cmd_lock); ++ ++ diff = link_info->support_auto_speeds ^ link_info->advertising; ++ if ((link_info->support_auto_speeds | diff) != ++ link_info->support_auto_speeds) { ++ /* An advertised speed is no longer supported, so we need to ++ * update the advertisement settings. Caller holds RTNL ++ * so we can modify link settings. ++ */ ++ link_info->advertising = link_info->support_auto_speeds; ++ if (link_info->autoneg & BNXT_AUTONEG_SPEED) ++ bnxt_hwrm_set_link_setting(bp, true, false); ++ } + return 0; + } + +@@ -6080,29 +6094,37 @@ static void bnxt_timer(unsigned long data) + mod_timer(&bp->timer, jiffies + bp->current_interval); + } + +-/* Only called from bnxt_sp_task() */ +-static void bnxt_reset(struct bnxt *bp, bool silent) ++static void bnxt_rtnl_lock_sp(struct bnxt *bp) + { +- /* bnxt_reset_task() calls bnxt_close_nic() which waits +- * for BNXT_STATE_IN_SP_TASK to clear. +- * If there is a parallel dev_close(), bnxt_close() may be holding ++ /* We are called from bnxt_sp_task which has BNXT_STATE_IN_SP_TASK ++ * set. If the device is being closed, bnxt_close() may be holding + * rtnl() and waiting for BNXT_STATE_IN_SP_TASK to clear. So we + * must clear BNXT_STATE_IN_SP_TASK before holding rtnl(). + */ + clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state); + rtnl_lock(); +- if (test_bit(BNXT_STATE_OPEN, &bp->state)) +- bnxt_reset_task(bp, silent); ++} ++ ++static void bnxt_rtnl_unlock_sp(struct bnxt *bp) ++{ + set_bit(BNXT_STATE_IN_SP_TASK, &bp->state); + rtnl_unlock(); + } + ++/* Only called from bnxt_sp_task() */ ++static void bnxt_reset(struct bnxt *bp, bool silent) ++{ ++ bnxt_rtnl_lock_sp(bp); ++ if (test_bit(BNXT_STATE_OPEN, &bp->state)) ++ bnxt_reset_task(bp, silent); ++ bnxt_rtnl_unlock_sp(bp); ++} ++ + static void bnxt_cfg_ntp_filters(struct bnxt *); + + static void bnxt_sp_task(struct work_struct *work) + { + struct bnxt *bp = container_of(work, struct bnxt, sp_task); +- int rc; + + set_bit(BNXT_STATE_IN_SP_TASK, &bp->state); + smp_mb__after_atomic(); +@@ -6116,12 +6138,6 @@ static void bnxt_sp_task(struct work_struct *work) + + if (test_and_clear_bit(BNXT_RX_NTP_FLTR_SP_EVENT, &bp->sp_event)) + bnxt_cfg_ntp_filters(bp); +- if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) { +- rc = bnxt_update_link(bp, true); +- if (rc) +- netdev_err(bp->dev, "SP task can't update link (rc: %x)\n", +- rc); +- } + if (test_and_clear_bit(BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT, &bp->sp_event)) + bnxt_hwrm_exec_fwd_req(bp); + if (test_and_clear_bit(BNXT_VXLAN_ADD_PORT_SP_EVENT, &bp->sp_event)) { +@@ -6142,18 +6158,39 @@ static void bnxt_sp_task(struct work_struct *work) + bnxt_hwrm_tunnel_dst_port_free( + bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE); + } ++ if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event)) ++ bnxt_hwrm_port_qstats(bp); ++ ++ /* These functions below will clear BNXT_STATE_IN_SP_TASK. They ++ * must be the last functions to be called before exiting. ++ */ ++ if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) { ++ int rc = 0; ++ ++ if (test_and_clear_bit(BNXT_LINK_SPEED_CHNG_SP_EVENT, ++ &bp->sp_event)) ++ bnxt_hwrm_phy_qcaps(bp); ++ ++ bnxt_rtnl_lock_sp(bp); ++ if (test_bit(BNXT_STATE_OPEN, &bp->state)) ++ rc = bnxt_update_link(bp, true); ++ bnxt_rtnl_unlock_sp(bp); ++ if (rc) ++ netdev_err(bp->dev, "SP task can't update link (rc: %x)\n", ++ rc); ++ } ++ if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event)) { ++ bnxt_rtnl_lock_sp(bp); ++ if (test_bit(BNXT_STATE_OPEN, &bp->state)) ++ bnxt_get_port_module_status(bp); ++ bnxt_rtnl_unlock_sp(bp); ++ } + if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event)) + bnxt_reset(bp, false); + + if (test_and_clear_bit(BNXT_RESET_TASK_SILENT_SP_EVENT, &bp->sp_event)) + bnxt_reset(bp, true); + +- if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event)) +- bnxt_get_port_module_status(bp); +- +- if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event)) +- bnxt_hwrm_port_qstats(bp); +- + smp_mb__before_atomic(); + clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state); + } +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h +index 51b164a0e844..666bc0608ed7 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h +@@ -1089,6 +1089,7 @@ struct bnxt { + #define BNXT_RESET_TASK_SILENT_SP_EVENT 11 + #define BNXT_GENEVE_ADD_PORT_SP_EVENT 12 + #define BNXT_GENEVE_DEL_PORT_SP_EVENT 13 ++#define BNXT_LINK_SPEED_CHNG_SP_EVENT 14 + + struct bnxt_pf_info pf; + #ifdef CONFIG_BNXT_SRIOV +diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c +index 050e21fbb147..679679a4ccb2 100644 +--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c ++++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c +@@ -31,6 +31,7 @@ struct lmac { + u8 lmac_type; + u8 lane_to_sds; + bool use_training; ++ bool autoneg; + bool link_up; + int lmacid; /* ID within BGX */ + int lmacid_bd; /* ID on board */ +@@ -418,7 +419,17 @@ static int bgx_lmac_sgmii_init(struct bgx *bgx, struct lmac *lmac) + /* power down, reset autoneg, autoneg enable */ + cfg = bgx_reg_read(bgx, lmacid, BGX_GMP_PCS_MRX_CTL); + cfg &= ~PCS_MRX_CTL_PWR_DN; +- cfg |= (PCS_MRX_CTL_RST_AN | PCS_MRX_CTL_AN_EN); ++ cfg |= PCS_MRX_CTL_RST_AN; ++ if (lmac->phydev) { ++ cfg |= PCS_MRX_CTL_AN_EN; ++ } else { ++ /* In scenarios where PHY driver is not present or it's a ++ * non-standard PHY, FW sets AN_EN to inform Linux driver ++ * to do auto-neg and link polling or not. ++ */ ++ if (cfg & PCS_MRX_CTL_AN_EN) ++ lmac->autoneg = true; ++ } + bgx_reg_write(bgx, lmacid, BGX_GMP_PCS_MRX_CTL, cfg); + + if (lmac->lmac_type == BGX_MODE_QSGMII) { +@@ -429,7 +440,7 @@ static int bgx_lmac_sgmii_init(struct bgx *bgx, struct lmac *lmac) + return 0; + } + +- if (lmac->lmac_type == BGX_MODE_SGMII) { ++ if ((lmac->lmac_type == BGX_MODE_SGMII) && lmac->phydev) { + if (bgx_poll_reg(bgx, lmacid, BGX_GMP_PCS_MRX_STATUS, + PCS_MRX_STATUS_AN_CPT, false)) { + dev_err(&bgx->pdev->dev, "BGX AN_CPT not completed\n"); +@@ -623,12 +634,71 @@ static int bgx_xaui_check_link(struct lmac *lmac) + return -1; + } + ++static void bgx_poll_for_sgmii_link(struct lmac *lmac) ++{ ++ u64 pcs_link, an_result; ++ u8 speed; ++ ++ pcs_link = bgx_reg_read(lmac->bgx, lmac->lmacid, ++ BGX_GMP_PCS_MRX_STATUS); ++ ++ /*Link state bit is sticky, read it again*/ ++ if (!(pcs_link & PCS_MRX_STATUS_LINK)) ++ pcs_link = bgx_reg_read(lmac->bgx, lmac->lmacid, ++ BGX_GMP_PCS_MRX_STATUS); ++ ++ if (bgx_poll_reg(lmac->bgx, lmac->lmacid, BGX_GMP_PCS_MRX_STATUS, ++ PCS_MRX_STATUS_AN_CPT, false)) { ++ lmac->link_up = false; ++ lmac->last_speed = SPEED_UNKNOWN; ++ lmac->last_duplex = DUPLEX_UNKNOWN; ++ goto next_poll; ++ } ++ ++ lmac->link_up = ((pcs_link & PCS_MRX_STATUS_LINK) != 0) ? true : false; ++ an_result = bgx_reg_read(lmac->bgx, lmac->lmacid, ++ BGX_GMP_PCS_ANX_AN_RESULTS); ++ ++ speed = (an_result >> 3) & 0x3; ++ lmac->last_duplex = (an_result >> 1) & 0x1; ++ switch (speed) { ++ case 0: ++ lmac->last_speed = 10; ++ break; ++ case 1: ++ lmac->last_speed = 100; ++ break; ++ case 2: ++ lmac->last_speed = 1000; ++ break; ++ default: ++ lmac->link_up = false; ++ lmac->last_speed = SPEED_UNKNOWN; ++ lmac->last_duplex = DUPLEX_UNKNOWN; ++ break; ++ } ++ ++next_poll: ++ ++ if (lmac->last_link != lmac->link_up) { ++ if (lmac->link_up) ++ bgx_sgmii_change_link_state(lmac); ++ lmac->last_link = lmac->link_up; ++ } ++ ++ queue_delayed_work(lmac->check_link, &lmac->dwork, HZ * 3); ++} ++ + static void bgx_poll_for_link(struct work_struct *work) + { + struct lmac *lmac; + u64 spu_link, smu_link; + + lmac = container_of(work, struct lmac, dwork.work); ++ if (lmac->is_sgmii) { ++ bgx_poll_for_sgmii_link(lmac); ++ return; ++ } + + /* Receive link is latching low. Force it high and verify it */ + bgx_reg_modify(lmac->bgx, lmac->lmacid, +@@ -720,9 +790,21 @@ static int bgx_lmac_enable(struct bgx *bgx, u8 lmacid) + (lmac->lmac_type != BGX_MODE_XLAUI) && + (lmac->lmac_type != BGX_MODE_40G_KR) && + (lmac->lmac_type != BGX_MODE_10G_KR)) { +- if (!lmac->phydev) +- return -ENODEV; +- ++ if (!lmac->phydev) { ++ if (lmac->autoneg) { ++ bgx_reg_write(bgx, lmacid, ++ BGX_GMP_PCS_LINKX_TIMER, ++ PCS_LINKX_TIMER_COUNT); ++ goto poll; ++ } else { ++ /* Default to below link speed and duplex */ ++ lmac->link_up = true; ++ lmac->last_speed = 1000; ++ lmac->last_duplex = 1; ++ bgx_sgmii_change_link_state(lmac); ++ return 0; ++ } ++ } + lmac->phydev->dev_flags = 0; + + if (phy_connect_direct(&lmac->netdev, lmac->phydev, +@@ -731,15 +813,17 @@ static int bgx_lmac_enable(struct bgx *bgx, u8 lmacid) + return -ENODEV; + + phy_start_aneg(lmac->phydev); +- } else { +- lmac->check_link = alloc_workqueue("check_link", WQ_UNBOUND | +- WQ_MEM_RECLAIM, 1); +- if (!lmac->check_link) +- return -ENOMEM; +- INIT_DELAYED_WORK(&lmac->dwork, bgx_poll_for_link); +- queue_delayed_work(lmac->check_link, &lmac->dwork, 0); ++ return 0; + } + ++poll: ++ lmac->check_link = alloc_workqueue("check_link", WQ_UNBOUND | ++ WQ_MEM_RECLAIM, 1); ++ if (!lmac->check_link) ++ return -ENOMEM; ++ INIT_DELAYED_WORK(&lmac->dwork, bgx_poll_for_link); ++ queue_delayed_work(lmac->check_link, &lmac->dwork, 0); ++ + return 0; + } + +diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h +index 01cc7c859131..1143e9575e53 100644 +--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h ++++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h +@@ -144,10 +144,15 @@ + #define PCS_MRX_CTL_LOOPBACK1 BIT_ULL(14) + #define PCS_MRX_CTL_RESET BIT_ULL(15) + #define BGX_GMP_PCS_MRX_STATUS 0x30008 ++#define PCS_MRX_STATUS_LINK BIT_ULL(2) + #define PCS_MRX_STATUS_AN_CPT BIT_ULL(5) ++#define BGX_GMP_PCS_ANX_ADV 0x30010 + #define BGX_GMP_PCS_ANX_AN_RESULTS 0x30020 ++#define BGX_GMP_PCS_LINKX_TIMER 0x30040 ++#define PCS_LINKX_TIMER_COUNT 0x1E84 + #define BGX_GMP_PCS_SGM_AN_ADV 0x30068 + #define BGX_GMP_PCS_MISCX_CTL 0x30078 ++#define PCS_MISC_CTL_MODE BIT_ULL(8) + #define PCS_MISC_CTL_DISP_EN BIT_ULL(13) + #define PCS_MISC_CTL_GMX_ENO BIT_ULL(11) + #define PCS_MISC_CTL_SAMP_PT_MASK 0x7Full +diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c +index 9061c2f82b9c..d391beebe591 100644 +--- a/drivers/net/ethernet/freescale/gianfar.c ++++ b/drivers/net/ethernet/freescale/gianfar.c +@@ -2007,8 +2007,8 @@ static void free_skb_rx_queue(struct gfar_priv_rx_q *rx_queue) + if (!rxb->page) + continue; + +- dma_unmap_single(rx_queue->dev, rxb->dma, +- PAGE_SIZE, DMA_FROM_DEVICE); ++ dma_unmap_page(rx_queue->dev, rxb->dma, ++ PAGE_SIZE, DMA_FROM_DEVICE); + __free_page(rxb->page); + + rxb->page = NULL; +diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c +index dff7b60345d8..c06845b7b666 100644 +--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c +@@ -304,8 +304,8 @@ int hns_nic_net_xmit_hw(struct net_device *ndev, + struct hns_nic_ring_data *ring_data) + { + struct hns_nic_priv *priv = netdev_priv(ndev); +- struct device *dev = priv->dev; + struct hnae_ring *ring = ring_data->ring; ++ struct device *dev = ring_to_dev(ring); + struct netdev_queue *dev_queue; + struct skb_frag_struct *frag; + int buf_num; +diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c +index 0fbf686f5e7c..9f2184be55dc 100644 +--- a/drivers/net/ethernet/ibm/ibmvnic.c ++++ b/drivers/net/ethernet/ibm/ibmvnic.c +@@ -189,9 +189,10 @@ static int alloc_long_term_buff(struct ibmvnic_adapter *adapter, + } + ltb->map_id = adapter->map_id; + adapter->map_id++; ++ ++ init_completion(&adapter->fw_done); + send_request_map(adapter, ltb->addr, + ltb->size, ltb->map_id); +- init_completion(&adapter->fw_done); + wait_for_completion(&adapter->fw_done); + return 0; + } +@@ -505,7 +506,7 @@ static int ibmvnic_open(struct net_device *netdev) + adapter->rx_pool = NULL; + rx_pool_arr_alloc_failed: + for (i = 0; i < adapter->req_rx_queues; i++) +- napi_enable(&adapter->napi[i]); ++ napi_disable(&adapter->napi[i]); + alloc_napi_failed: + return -ENOMEM; + } +@@ -1133,10 +1134,10 @@ static void ibmvnic_get_ethtool_stats(struct net_device *dev, + crq.request_statistics.ioba = cpu_to_be32(adapter->stats_token); + crq.request_statistics.len = + cpu_to_be32(sizeof(struct ibmvnic_statistics)); +- ibmvnic_send_crq(adapter, &crq); + + /* Wait for data to be written */ + init_completion(&adapter->stats_done); ++ ibmvnic_send_crq(adapter, &crq); + wait_for_completion(&adapter->stats_done); + + for (i = 0; i < ARRAY_SIZE(ibmvnic_stats); i++) +@@ -2197,12 +2198,12 @@ static void handle_error_info_rsp(union ibmvnic_crq *crq, + + if (!found) { + dev_err(dev, "Couldn't find error id %x\n", +- crq->request_error_rsp.error_id); ++ be32_to_cpu(crq->request_error_rsp.error_id)); + return; + } + + dev_err(dev, "Detailed info for error id %x:", +- crq->request_error_rsp.error_id); ++ be32_to_cpu(crq->request_error_rsp.error_id)); + + for (i = 0; i < error_buff->len; i++) { + pr_cont("%02x", (int)error_buff->buff[i]); +@@ -2281,8 +2282,8 @@ static void handle_error_indication(union ibmvnic_crq *crq, + dev_err(dev, "Firmware reports %serror id %x, cause %d\n", + crq->error_indication. + flags & IBMVNIC_FATAL_ERROR ? "FATAL " : "", +- crq->error_indication.error_id, +- crq->error_indication.error_cause); ++ be32_to_cpu(crq->error_indication.error_id), ++ be16_to_cpu(crq->error_indication.error_cause)); + + error_buff = kmalloc(sizeof(*error_buff), GFP_ATOMIC); + if (!error_buff) +@@ -2400,10 +2401,10 @@ static void handle_request_cap_rsp(union ibmvnic_crq *crq, + case PARTIALSUCCESS: + dev_info(dev, "req=%lld, rsp=%ld in %s queue, retrying.\n", + *req_value, +- (long int)be32_to_cpu(crq->request_capability_rsp. ++ (long int)be64_to_cpu(crq->request_capability_rsp. + number), name); + release_sub_crqs_no_irqs(adapter); +- *req_value = be32_to_cpu(crq->request_capability_rsp.number); ++ *req_value = be64_to_cpu(crq->request_capability_rsp.number); + init_sub_crqs(adapter, 1); + return; + default: +@@ -2809,9 +2810,9 @@ static ssize_t trace_read(struct file *file, char __user *user_buf, size_t len, + crq.collect_fw_trace.correlator = adapter->ras_comps[num].correlator; + crq.collect_fw_trace.ioba = cpu_to_be32(trace_tok); + crq.collect_fw_trace.len = adapter->ras_comps[num].trace_buff_size; +- ibmvnic_send_crq(adapter, &crq); + + init_completion(&adapter->fw_done); ++ ibmvnic_send_crq(adapter, &crq); + wait_for_completion(&adapter->fw_done); + + if (*ppos + len > be32_to_cpu(adapter->ras_comps[num].trace_buff_size)) +@@ -3591,9 +3592,9 @@ static int ibmvnic_dump_show(struct seq_file *seq, void *v) + memset(&crq, 0, sizeof(crq)); + crq.request_dump_size.first = IBMVNIC_CRQ_CMD; + crq.request_dump_size.cmd = REQUEST_DUMP_SIZE; +- ibmvnic_send_crq(adapter, &crq); + + init_completion(&adapter->fw_done); ++ ibmvnic_send_crq(adapter, &crq); + wait_for_completion(&adapter->fw_done); + + seq_write(seq, adapter->dump_data, adapter->dump_data_size); +@@ -3639,8 +3640,8 @@ static void handle_crq_init_rsp(struct work_struct *work) + } + } + +- send_version_xchg(adapter); + reinit_completion(&adapter->init_done); ++ send_version_xchg(adapter); + if (!wait_for_completion_timeout(&adapter->init_done, timeout)) { + dev_err(dev, "Passive init timeout\n"); + goto task_failed; +@@ -3650,9 +3651,9 @@ static void handle_crq_init_rsp(struct work_struct *work) + if (adapter->renegotiate) { + adapter->renegotiate = false; + release_sub_crqs_no_irqs(adapter); +- send_cap_queries(adapter); + + reinit_completion(&adapter->init_done); ++ send_cap_queries(adapter); + if (!wait_for_completion_timeout(&adapter->init_done, + timeout)) { + dev_err(dev, "Passive init timeout\n"); +@@ -3780,9 +3781,9 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) + adapter->debugfs_dump = ent; + } + } +- ibmvnic_send_crq_init(adapter); + + init_completion(&adapter->init_done); ++ ibmvnic_send_crq_init(adapter); + if (!wait_for_completion_timeout(&adapter->init_done, timeout)) + return 0; + +@@ -3790,9 +3791,9 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) + if (adapter->renegotiate) { + adapter->renegotiate = false; + release_sub_crqs_no_irqs(adapter); +- send_cap_queries(adapter); + + reinit_completion(&adapter->init_done); ++ send_cap_queries(adapter); + if (!wait_for_completion_timeout(&adapter->init_done, + timeout)) + return 0; +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 86a89cbd3ec9..4832223f1500 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -2518,7 +2518,7 @@ static int mtk_remove(struct platform_device *pdev) + } + + const struct of_device_id of_mtk_match[] = { +- { .compatible = "mediatek,mt7623-eth" }, ++ { .compatible = "mediatek,mt2701-eth" }, + {}, + }; + MODULE_DEVICE_TABLE(of, of_mtk_match); +diff --git a/drivers/net/ethernet/mellanox/mlx4/catas.c b/drivers/net/ethernet/mellanox/mlx4/catas.c +index c7e939945259..53daa6ca5d83 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/catas.c ++++ b/drivers/net/ethernet/mellanox/mlx4/catas.c +@@ -158,7 +158,7 @@ static int mlx4_reset_slave(struct mlx4_dev *dev) + return -ETIMEDOUT; + } + +-static int mlx4_comm_internal_err(u32 slave_read) ++int mlx4_comm_internal_err(u32 slave_read) + { + return (u32)COMM_CHAN_EVENT_INTERNAL_ERR == + (slave_read & (u32)COMM_CHAN_EVENT_INTERNAL_ERR) ? 1 : 0; +diff --git a/drivers/net/ethernet/mellanox/mlx4/intf.c b/drivers/net/ethernet/mellanox/mlx4/intf.c +index 0e8b7c44931f..8258d08acd8c 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/intf.c ++++ b/drivers/net/ethernet/mellanox/mlx4/intf.c +@@ -222,6 +222,18 @@ void mlx4_unregister_device(struct mlx4_dev *dev) + return; + + mlx4_stop_catas_poll(dev); ++ if (dev->persist->interface_state & MLX4_INTERFACE_STATE_DELETION && ++ mlx4_is_slave(dev)) { ++ /* In mlx4_remove_one on a VF */ ++ u32 slave_read = ++ swab32(readl(&mlx4_priv(dev)->mfunc.comm->slave_read)); ++ ++ if (mlx4_comm_internal_err(slave_read)) { ++ mlx4_dbg(dev, "%s: comm channel is down, entering error state.\n", ++ __func__); ++ mlx4_enter_error_state(dev->persist); ++ } ++ } + mutex_lock(&intf_mutex); + + list_for_each_entry(intf, &intf_list, list) +diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h +index 88ee7d8a5923..086920b615af 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h ++++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h +@@ -1220,6 +1220,7 @@ void mlx4_qp_event(struct mlx4_dev *dev, u32 qpn, int event_type); + void mlx4_srq_event(struct mlx4_dev *dev, u32 srqn, int event_type); + + void mlx4_enter_error_state(struct mlx4_dev_persistent *persist); ++int mlx4_comm_internal_err(u32 slave_read); + + int mlx4_SENSE_PORT(struct mlx4_dev *dev, int port, + enum mlx4_port_type *type); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c +index 36fbc6b21a33..8cd7227fbdfc 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c +@@ -1081,7 +1081,7 @@ int mlx5e_create_flow_steering(struct mlx5e_priv *priv) + MLX5_FLOW_NAMESPACE_KERNEL); + + if (!priv->fs.ns) +- return -EINVAL; ++ return -EOPNOTSUPP; + + err = mlx5e_arfs_create_tables(priv); + if (err) { +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +index c7011ef4e351..a8966e6dbe1b 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +@@ -352,7 +352,7 @@ static int esw_create_legacy_fdb_table(struct mlx5_eswitch *esw, int nvports) + root_ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_FDB); + if (!root_ns) { + esw_warn(dev, "Failed to get FDB flow namespace\n"); +- return -ENOMEM; ++ return -EOPNOTSUPP; + } + + flow_group_in = mlx5_vzalloc(inlen); +@@ -961,7 +961,7 @@ static int esw_vport_enable_egress_acl(struct mlx5_eswitch *esw, + root_ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_ESW_EGRESS); + if (!root_ns) { + esw_warn(dev, "Failed to get E-Switch egress flow namespace\n"); +- return -EIO; ++ return -EOPNOTSUPP; + } + + flow_group_in = mlx5_vzalloc(inlen); +@@ -1078,7 +1078,7 @@ static int esw_vport_enable_ingress_acl(struct mlx5_eswitch *esw, + root_ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_ESW_INGRESS); + if (!root_ns) { + esw_warn(dev, "Failed to get E-Switch ingress flow namespace\n"); +- return -EIO; ++ return -EOPNOTSUPP; + } + + flow_group_in = mlx5_vzalloc(inlen); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +index d239f5d0ea36..b08b9e2c6a76 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +@@ -414,6 +414,7 @@ static int esw_create_offloads_fdb_table(struct mlx5_eswitch *esw, int nvports) + root_ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_FDB); + if (!root_ns) { + esw_warn(dev, "Failed to get FDB flow namespace\n"); ++ err = -EOPNOTSUPP; + goto ns_err; + } + +@@ -520,7 +521,7 @@ static int esw_create_offloads_table(struct mlx5_eswitch *esw) + ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_OFFLOADS); + if (!ns) { + esw_warn(esw->dev, "Failed to get offloads flow namespace\n"); +- return -ENOMEM; ++ return -EOPNOTSUPP; + } + + ft_offloads = mlx5_create_flow_table(ns, 0, dev->priv.sriov.num_vfs + 2, 0); +@@ -639,7 +640,7 @@ static int esw_offloads_start(struct mlx5_eswitch *esw) + esw_warn(esw->dev, "Failed setting eswitch to offloads, err %d\n", err); + err1 = mlx5_eswitch_enable_sriov(esw, num_vfs, SRIOV_LEGACY); + if (err1) +- esw_warn(esw->dev, "Failed setting eswitch back to legacy, err %d\n", err); ++ esw_warn(esw->dev, "Failed setting eswitch back to legacy, err %d\n", err1); + } + return err; + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +index 7e20e4bc4cc7..4de3c28b0547 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +@@ -1678,7 +1678,7 @@ static int create_anchor_flow_table(struct mlx5_flow_steering *steering) + struct mlx5_flow_table *ft; + + ns = mlx5_get_flow_namespace(steering->dev, MLX5_FLOW_NAMESPACE_ANCHOR); +- if (!ns) ++ if (WARN_ON(!ns)) + return -EINVAL; + ft = mlx5_create_flow_table(ns, ANCHOR_PRIO, ANCHOR_SIZE, ANCHOR_LEVEL); + if (IS_ERR(ft)) { +diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c +index 862f18ed6022..510ff62584d6 100644 +--- a/drivers/net/ethernet/renesas/ravb_main.c ++++ b/drivers/net/ethernet/renesas/ravb_main.c +@@ -179,6 +179,49 @@ static struct mdiobb_ops bb_ops = { + .get_mdio_data = ravb_get_mdio_data, + }; + ++/* Free TX skb function for AVB-IP */ ++static int ravb_tx_free(struct net_device *ndev, int q, bool free_txed_only) ++{ ++ struct ravb_private *priv = netdev_priv(ndev); ++ struct net_device_stats *stats = &priv->stats[q]; ++ struct ravb_tx_desc *desc; ++ int free_num = 0; ++ int entry; ++ u32 size; ++ ++ for (; priv->cur_tx[q] - priv->dirty_tx[q] > 0; priv->dirty_tx[q]++) { ++ bool txed; ++ ++ entry = priv->dirty_tx[q] % (priv->num_tx_ring[q] * ++ NUM_TX_DESC); ++ desc = &priv->tx_ring[q][entry]; ++ txed = desc->die_dt == DT_FEMPTY; ++ if (free_txed_only && !txed) ++ break; ++ /* Descriptor type must be checked before all other reads */ ++ dma_rmb(); ++ size = le16_to_cpu(desc->ds_tagl) & TX_DS; ++ /* Free the original skb. */ ++ if (priv->tx_skb[q][entry / NUM_TX_DESC]) { ++ dma_unmap_single(ndev->dev.parent, le32_to_cpu(desc->dptr), ++ size, DMA_TO_DEVICE); ++ /* Last packet descriptor? */ ++ if (entry % NUM_TX_DESC == NUM_TX_DESC - 1) { ++ entry /= NUM_TX_DESC; ++ dev_kfree_skb_any(priv->tx_skb[q][entry]); ++ priv->tx_skb[q][entry] = NULL; ++ if (txed) ++ stats->tx_packets++; ++ } ++ free_num++; ++ } ++ if (txed) ++ stats->tx_bytes += size; ++ desc->die_dt = DT_EEMPTY; ++ } ++ return free_num; ++} ++ + /* Free skb's and DMA buffers for Ethernet AVB */ + static void ravb_ring_free(struct net_device *ndev, int q) + { +@@ -194,19 +237,21 @@ static void ravb_ring_free(struct net_device *ndev, int q) + kfree(priv->rx_skb[q]); + priv->rx_skb[q] = NULL; + +- /* Free TX skb ringbuffer */ +- if (priv->tx_skb[q]) { +- for (i = 0; i < priv->num_tx_ring[q]; i++) +- dev_kfree_skb(priv->tx_skb[q][i]); +- } +- kfree(priv->tx_skb[q]); +- priv->tx_skb[q] = NULL; +- + /* Free aligned TX buffers */ + kfree(priv->tx_align[q]); + priv->tx_align[q] = NULL; + + if (priv->rx_ring[q]) { ++ for (i = 0; i < priv->num_rx_ring[q]; i++) { ++ struct ravb_ex_rx_desc *desc = &priv->rx_ring[q][i]; ++ ++ if (!dma_mapping_error(ndev->dev.parent, ++ le32_to_cpu(desc->dptr))) ++ dma_unmap_single(ndev->dev.parent, ++ le32_to_cpu(desc->dptr), ++ PKT_BUF_SZ, ++ DMA_FROM_DEVICE); ++ } + ring_size = sizeof(struct ravb_ex_rx_desc) * + (priv->num_rx_ring[q] + 1); + dma_free_coherent(ndev->dev.parent, ring_size, priv->rx_ring[q], +@@ -215,12 +260,20 @@ static void ravb_ring_free(struct net_device *ndev, int q) + } + + if (priv->tx_ring[q]) { ++ ravb_tx_free(ndev, q, false); ++ + ring_size = sizeof(struct ravb_tx_desc) * + (priv->num_tx_ring[q] * NUM_TX_DESC + 1); + dma_free_coherent(ndev->dev.parent, ring_size, priv->tx_ring[q], + priv->tx_desc_dma[q]); + priv->tx_ring[q] = NULL; + } ++ ++ /* Free TX skb ringbuffer. ++ * SKBs are freed by ravb_tx_free() call above. ++ */ ++ kfree(priv->tx_skb[q]); ++ priv->tx_skb[q] = NULL; + } + + /* Format skb and descriptor buffer for Ethernet AVB */ +@@ -431,44 +484,6 @@ static int ravb_dmac_init(struct net_device *ndev) + return 0; + } + +-/* Free TX skb function for AVB-IP */ +-static int ravb_tx_free(struct net_device *ndev, int q) +-{ +- struct ravb_private *priv = netdev_priv(ndev); +- struct net_device_stats *stats = &priv->stats[q]; +- struct ravb_tx_desc *desc; +- int free_num = 0; +- int entry; +- u32 size; +- +- for (; priv->cur_tx[q] - priv->dirty_tx[q] > 0; priv->dirty_tx[q]++) { +- entry = priv->dirty_tx[q] % (priv->num_tx_ring[q] * +- NUM_TX_DESC); +- desc = &priv->tx_ring[q][entry]; +- if (desc->die_dt != DT_FEMPTY) +- break; +- /* Descriptor type must be checked before all other reads */ +- dma_rmb(); +- size = le16_to_cpu(desc->ds_tagl) & TX_DS; +- /* Free the original skb. */ +- if (priv->tx_skb[q][entry / NUM_TX_DESC]) { +- dma_unmap_single(ndev->dev.parent, le32_to_cpu(desc->dptr), +- size, DMA_TO_DEVICE); +- /* Last packet descriptor? */ +- if (entry % NUM_TX_DESC == NUM_TX_DESC - 1) { +- entry /= NUM_TX_DESC; +- dev_kfree_skb_any(priv->tx_skb[q][entry]); +- priv->tx_skb[q][entry] = NULL; +- stats->tx_packets++; +- } +- free_num++; +- } +- stats->tx_bytes += size; +- desc->die_dt = DT_EEMPTY; +- } +- return free_num; +-} +- + static void ravb_get_tx_tstamp(struct net_device *ndev) + { + struct ravb_private *priv = netdev_priv(ndev); +@@ -902,7 +917,7 @@ static int ravb_poll(struct napi_struct *napi, int budget) + spin_lock_irqsave(&priv->lock, flags); + /* Clear TX interrupt */ + ravb_write(ndev, ~mask, TIS); +- ravb_tx_free(ndev, q); ++ ravb_tx_free(ndev, q, true); + netif_wake_subqueue(ndev, q); + mmiowb(); + spin_unlock_irqrestore(&priv->lock, flags); +@@ -1571,7 +1586,8 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev) + + priv->cur_tx[q] += NUM_TX_DESC; + if (priv->cur_tx[q] - priv->dirty_tx[q] > +- (priv->num_tx_ring[q] - 1) * NUM_TX_DESC && !ravb_tx_free(ndev, q)) ++ (priv->num_tx_ring[q] - 1) * NUM_TX_DESC && ++ !ravb_tx_free(ndev, q, true)) + netif_stop_subqueue(ndev, q); + + exit: +diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +index 93dc10b10c09..aa02a03a6d8d 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c ++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +@@ -100,6 +100,14 @@ + /* BUFFER_ALIGN(adr) calculates the number of bytes to the next alignment. */ + #define BUFFER_ALIGN(adr) ((ALIGNMENT - ((u32) adr)) % ALIGNMENT) + ++#ifdef __BIG_ENDIAN ++#define xemaclite_readl ioread32be ++#define xemaclite_writel iowrite32be ++#else ++#define xemaclite_readl ioread32 ++#define xemaclite_writel iowrite32 ++#endif ++ + /** + * struct net_local - Our private per device data + * @ndev: instance of the network device +@@ -156,15 +164,15 @@ static void xemaclite_enable_interrupts(struct net_local *drvdata) + u32 reg_data; + + /* Enable the Tx interrupts for the first Buffer */ +- reg_data = __raw_readl(drvdata->base_addr + XEL_TSR_OFFSET); +- __raw_writel(reg_data | XEL_TSR_XMIT_IE_MASK, +- drvdata->base_addr + XEL_TSR_OFFSET); ++ reg_data = xemaclite_readl(drvdata->base_addr + XEL_TSR_OFFSET); ++ xemaclite_writel(reg_data | XEL_TSR_XMIT_IE_MASK, ++ drvdata->base_addr + XEL_TSR_OFFSET); + + /* Enable the Rx interrupts for the first buffer */ +- __raw_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr + XEL_RSR_OFFSET); ++ xemaclite_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr + XEL_RSR_OFFSET); + + /* Enable the Global Interrupt Enable */ +- __raw_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET); ++ xemaclite_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET); + } + + /** +@@ -179,17 +187,17 @@ static void xemaclite_disable_interrupts(struct net_local *drvdata) + u32 reg_data; + + /* Disable the Global Interrupt Enable */ +- __raw_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET); ++ xemaclite_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET); + + /* Disable the Tx interrupts for the first buffer */ +- reg_data = __raw_readl(drvdata->base_addr + XEL_TSR_OFFSET); +- __raw_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK), +- drvdata->base_addr + XEL_TSR_OFFSET); ++ reg_data = xemaclite_readl(drvdata->base_addr + XEL_TSR_OFFSET); ++ xemaclite_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK), ++ drvdata->base_addr + XEL_TSR_OFFSET); + + /* Disable the Rx interrupts for the first buffer */ +- reg_data = __raw_readl(drvdata->base_addr + XEL_RSR_OFFSET); +- __raw_writel(reg_data & (~XEL_RSR_RECV_IE_MASK), +- drvdata->base_addr + XEL_RSR_OFFSET); ++ reg_data = xemaclite_readl(drvdata->base_addr + XEL_RSR_OFFSET); ++ xemaclite_writel(reg_data & (~XEL_RSR_RECV_IE_MASK), ++ drvdata->base_addr + XEL_RSR_OFFSET); + } + + /** +@@ -321,7 +329,7 @@ static int xemaclite_send_data(struct net_local *drvdata, u8 *data, + byte_count = ETH_FRAME_LEN; + + /* Check if the expected buffer is available */ +- reg_data = __raw_readl(addr + XEL_TSR_OFFSET); ++ reg_data = xemaclite_readl(addr + XEL_TSR_OFFSET); + if ((reg_data & (XEL_TSR_XMIT_BUSY_MASK | + XEL_TSR_XMIT_ACTIVE_MASK)) == 0) { + +@@ -334,7 +342,7 @@ static int xemaclite_send_data(struct net_local *drvdata, u8 *data, + + addr = (void __iomem __force *)((u32 __force)addr ^ + XEL_BUFFER_OFFSET); +- reg_data = __raw_readl(addr + XEL_TSR_OFFSET); ++ reg_data = xemaclite_readl(addr + XEL_TSR_OFFSET); + + if ((reg_data & (XEL_TSR_XMIT_BUSY_MASK | + XEL_TSR_XMIT_ACTIVE_MASK)) != 0) +@@ -345,16 +353,16 @@ static int xemaclite_send_data(struct net_local *drvdata, u8 *data, + /* Write the frame to the buffer */ + xemaclite_aligned_write(data, (u32 __force *) addr, byte_count); + +- __raw_writel((byte_count & XEL_TPLR_LENGTH_MASK), +- addr + XEL_TPLR_OFFSET); ++ xemaclite_writel((byte_count & XEL_TPLR_LENGTH_MASK), ++ addr + XEL_TPLR_OFFSET); + + /* Update the Tx Status Register to indicate that there is a + * frame to send. Set the XEL_TSR_XMIT_ACTIVE_MASK flag which + * is used by the interrupt handler to check whether a frame + * has been transmitted */ +- reg_data = __raw_readl(addr + XEL_TSR_OFFSET); ++ reg_data = xemaclite_readl(addr + XEL_TSR_OFFSET); + reg_data |= (XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_XMIT_ACTIVE_MASK); +- __raw_writel(reg_data, addr + XEL_TSR_OFFSET); ++ xemaclite_writel(reg_data, addr + XEL_TSR_OFFSET); + + return 0; + } +@@ -369,7 +377,7 @@ static int xemaclite_send_data(struct net_local *drvdata, u8 *data, + * + * Return: Total number of bytes received + */ +-static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data) ++static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data, int maxlen) + { + void __iomem *addr; + u16 length, proto_type; +@@ -379,7 +387,7 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data) + addr = (drvdata->base_addr + drvdata->next_rx_buf_to_use); + + /* Verify which buffer has valid data */ +- reg_data = __raw_readl(addr + XEL_RSR_OFFSET); ++ reg_data = xemaclite_readl(addr + XEL_RSR_OFFSET); + + if ((reg_data & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) { + if (drvdata->rx_ping_pong != 0) +@@ -396,27 +404,28 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data) + return 0; /* No data was available */ + + /* Verify that buffer has valid data */ +- reg_data = __raw_readl(addr + XEL_RSR_OFFSET); ++ reg_data = xemaclite_readl(addr + XEL_RSR_OFFSET); + if ((reg_data & XEL_RSR_RECV_DONE_MASK) != + XEL_RSR_RECV_DONE_MASK) + return 0; /* No data was available */ + } + + /* Get the protocol type of the ethernet frame that arrived */ +- proto_type = ((ntohl(__raw_readl(addr + XEL_HEADER_OFFSET + ++ proto_type = ((ntohl(xemaclite_readl(addr + XEL_HEADER_OFFSET + + XEL_RXBUFF_OFFSET)) >> XEL_HEADER_SHIFT) & + XEL_RPLR_LENGTH_MASK); + + /* Check if received ethernet frame is a raw ethernet frame + * or an IP packet or an ARP packet */ +- if (proto_type > (ETH_FRAME_LEN + ETH_FCS_LEN)) { ++ if (proto_type > ETH_DATA_LEN) { + + if (proto_type == ETH_P_IP) { +- length = ((ntohl(__raw_readl(addr + ++ length = ((ntohl(xemaclite_readl(addr + + XEL_HEADER_IP_LENGTH_OFFSET + + XEL_RXBUFF_OFFSET)) >> + XEL_HEADER_SHIFT) & + XEL_RPLR_LENGTH_MASK); ++ length = min_t(u16, length, ETH_DATA_LEN); + length += ETH_HLEN + ETH_FCS_LEN; + + } else if (proto_type == ETH_P_ARP) +@@ -429,14 +438,17 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data) + /* Use the length in the frame, plus the header and trailer */ + length = proto_type + ETH_HLEN + ETH_FCS_LEN; + ++ if (WARN_ON(length > maxlen)) ++ length = maxlen; ++ + /* Read from the EmacLite device */ + xemaclite_aligned_read((u32 __force *) (addr + XEL_RXBUFF_OFFSET), + data, length); + + /* Acknowledge the frame */ +- reg_data = __raw_readl(addr + XEL_RSR_OFFSET); ++ reg_data = xemaclite_readl(addr + XEL_RSR_OFFSET); + reg_data &= ~XEL_RSR_RECV_DONE_MASK; +- __raw_writel(reg_data, addr + XEL_RSR_OFFSET); ++ xemaclite_writel(reg_data, addr + XEL_RSR_OFFSET); + + return length; + } +@@ -463,14 +475,14 @@ static void xemaclite_update_address(struct net_local *drvdata, + + xemaclite_aligned_write(address_ptr, (u32 __force *) addr, ETH_ALEN); + +- __raw_writel(ETH_ALEN, addr + XEL_TPLR_OFFSET); ++ xemaclite_writel(ETH_ALEN, addr + XEL_TPLR_OFFSET); + + /* Update the MAC address in the EmacLite */ +- reg_data = __raw_readl(addr + XEL_TSR_OFFSET); +- __raw_writel(reg_data | XEL_TSR_PROG_MAC_ADDR, addr + XEL_TSR_OFFSET); ++ reg_data = xemaclite_readl(addr + XEL_TSR_OFFSET); ++ xemaclite_writel(reg_data | XEL_TSR_PROG_MAC_ADDR, addr + XEL_TSR_OFFSET); + + /* Wait for EmacLite to finish with the MAC address update */ +- while ((__raw_readl(addr + XEL_TSR_OFFSET) & ++ while ((xemaclite_readl(addr + XEL_TSR_OFFSET) & + XEL_TSR_PROG_MAC_ADDR) != 0) + ; + } +@@ -603,7 +615,7 @@ static void xemaclite_rx_handler(struct net_device *dev) + + skb_reserve(skb, 2); + +- len = xemaclite_recv_data(lp, (u8 *) skb->data); ++ len = xemaclite_recv_data(lp, (u8 *) skb->data, len); + + if (!len) { + dev->stats.rx_errors++; +@@ -640,32 +652,32 @@ static irqreturn_t xemaclite_interrupt(int irq, void *dev_id) + u32 tx_status; + + /* Check if there is Rx Data available */ +- if ((__raw_readl(base_addr + XEL_RSR_OFFSET) & ++ if ((xemaclite_readl(base_addr + XEL_RSR_OFFSET) & + XEL_RSR_RECV_DONE_MASK) || +- (__raw_readl(base_addr + XEL_BUFFER_OFFSET + XEL_RSR_OFFSET) ++ (xemaclite_readl(base_addr + XEL_BUFFER_OFFSET + XEL_RSR_OFFSET) + & XEL_RSR_RECV_DONE_MASK)) + + xemaclite_rx_handler(dev); + + /* Check if the Transmission for the first buffer is completed */ +- tx_status = __raw_readl(base_addr + XEL_TSR_OFFSET); ++ tx_status = xemaclite_readl(base_addr + XEL_TSR_OFFSET); + if (((tx_status & XEL_TSR_XMIT_BUSY_MASK) == 0) && + (tx_status & XEL_TSR_XMIT_ACTIVE_MASK) != 0) { + + tx_status &= ~XEL_TSR_XMIT_ACTIVE_MASK; +- __raw_writel(tx_status, base_addr + XEL_TSR_OFFSET); ++ xemaclite_writel(tx_status, base_addr + XEL_TSR_OFFSET); + + tx_complete = true; + } + + /* Check if the Transmission for the second buffer is completed */ +- tx_status = __raw_readl(base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET); ++ tx_status = xemaclite_readl(base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET); + if (((tx_status & XEL_TSR_XMIT_BUSY_MASK) == 0) && + (tx_status & XEL_TSR_XMIT_ACTIVE_MASK) != 0) { + + tx_status &= ~XEL_TSR_XMIT_ACTIVE_MASK; +- __raw_writel(tx_status, base_addr + XEL_BUFFER_OFFSET + +- XEL_TSR_OFFSET); ++ xemaclite_writel(tx_status, base_addr + XEL_BUFFER_OFFSET + ++ XEL_TSR_OFFSET); + + tx_complete = true; + } +@@ -698,7 +710,7 @@ static int xemaclite_mdio_wait(struct net_local *lp) + /* wait for the MDIO interface to not be busy or timeout + after some time. + */ +- while (__raw_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET) & ++ while (xemaclite_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET) & + XEL_MDIOCTRL_MDIOSTS_MASK) { + if (time_before_eq(end, jiffies)) { + WARN_ON(1); +@@ -734,17 +746,17 @@ static int xemaclite_mdio_read(struct mii_bus *bus, int phy_id, int reg) + * MDIO Address register. Set the Status bit in the MDIO Control + * register to start a MDIO read transaction. + */ +- ctrl_reg = __raw_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET); +- __raw_writel(XEL_MDIOADDR_OP_MASK | +- ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg), +- lp->base_addr + XEL_MDIOADDR_OFFSET); +- __raw_writel(ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK, +- lp->base_addr + XEL_MDIOCTRL_OFFSET); ++ ctrl_reg = xemaclite_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET); ++ xemaclite_writel(XEL_MDIOADDR_OP_MASK | ++ ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg), ++ lp->base_addr + XEL_MDIOADDR_OFFSET); ++ xemaclite_writel(ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK, ++ lp->base_addr + XEL_MDIOCTRL_OFFSET); + + if (xemaclite_mdio_wait(lp)) + return -ETIMEDOUT; + +- rc = __raw_readl(lp->base_addr + XEL_MDIORD_OFFSET); ++ rc = xemaclite_readl(lp->base_addr + XEL_MDIORD_OFFSET); + + dev_dbg(&lp->ndev->dev, + "xemaclite_mdio_read(phy_id=%i, reg=%x) == %x\n", +@@ -781,13 +793,13 @@ static int xemaclite_mdio_write(struct mii_bus *bus, int phy_id, int reg, + * Data register. Finally, set the Status bit in the MDIO Control + * register to start a MDIO write transaction. + */ +- ctrl_reg = __raw_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET); +- __raw_writel(~XEL_MDIOADDR_OP_MASK & +- ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg), +- lp->base_addr + XEL_MDIOADDR_OFFSET); +- __raw_writel(val, lp->base_addr + XEL_MDIOWR_OFFSET); +- __raw_writel(ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK, +- lp->base_addr + XEL_MDIOCTRL_OFFSET); ++ ctrl_reg = xemaclite_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET); ++ xemaclite_writel(~XEL_MDIOADDR_OP_MASK & ++ ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg), ++ lp->base_addr + XEL_MDIOADDR_OFFSET); ++ xemaclite_writel(val, lp->base_addr + XEL_MDIOWR_OFFSET); ++ xemaclite_writel(ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK, ++ lp->base_addr + XEL_MDIOCTRL_OFFSET); + + return 0; + } +@@ -834,8 +846,8 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) + /* Enable the MDIO bus by asserting the enable bit in MDIO Control + * register. + */ +- __raw_writel(XEL_MDIOCTRL_MDIOEN_MASK, +- lp->base_addr + XEL_MDIOCTRL_OFFSET); ++ xemaclite_writel(XEL_MDIOCTRL_MDIOEN_MASK, ++ lp->base_addr + XEL_MDIOCTRL_OFFSET); + + bus = mdiobus_alloc(); + if (!bus) { +@@ -1140,8 +1152,8 @@ static int xemaclite_of_probe(struct platform_device *ofdev) + } + + /* Clear the Tx CSR's in case this is a restart */ +- __raw_writel(0, lp->base_addr + XEL_TSR_OFFSET); +- __raw_writel(0, lp->base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET); ++ xemaclite_writel(0, lp->base_addr + XEL_TSR_OFFSET); ++ xemaclite_writel(0, lp->base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET); + + /* Set the MAC address in the EmacLite device */ + xemaclite_update_address(lp, ndev->dev_addr); +diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c +index 97e0cbca0a08..cebde074d196 100644 +--- a/drivers/net/gtp.c ++++ b/drivers/net/gtp.c +@@ -1372,3 +1372,4 @@ MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Harald Welte <hwelte@sysmocom.de>"); + MODULE_DESCRIPTION("Interface driver for GTP encapsulated traffic"); + MODULE_ALIAS_RTNL_LINK("gtp"); ++MODULE_ALIAS_GENL_FAMILY("gtp"); +diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c +index 1dfe2304daa7..e0a6b1a0ca88 100644 +--- a/drivers/net/hamradio/mkiss.c ++++ b/drivers/net/hamradio/mkiss.c +@@ -648,8 +648,8 @@ static void ax_setup(struct net_device *dev) + { + /* Finish setting up the DEVICE info. */ + dev->mtu = AX_MTU; +- dev->hard_header_len = 0; +- dev->addr_len = 0; ++ dev->hard_header_len = AX25_MAX_HEADER_LEN; ++ dev->addr_len = AX25_ADDR_LEN; + dev->type = ARPHRD_AX25; + dev->tx_queue_len = 10; + dev->header_ops = &ax25_header_ops; +diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c +index ea92d524d5a8..fab56c9350cf 100644 +--- a/drivers/net/phy/micrel.c ++++ b/drivers/net/phy/micrel.c +@@ -1014,6 +1014,20 @@ static struct phy_driver ksphy_driver[] = { + .get_stats = kszphy_get_stats, + .suspend = genphy_suspend, + .resume = genphy_resume, ++}, { ++ .phy_id = PHY_ID_KSZ8795, ++ .phy_id_mask = MICREL_PHY_ID_MASK, ++ .name = "Micrel KSZ8795", ++ .features = (SUPPORTED_Pause | SUPPORTED_Asym_Pause), ++ .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, ++ .config_init = kszphy_config_init, ++ .config_aneg = ksz8873mll_config_aneg, ++ .read_status = ksz8873mll_read_status, ++ .get_sset_count = kszphy_get_sset_count, ++ .get_strings = kszphy_get_strings, ++ .get_stats = kszphy_get_stats, ++ .suspend = genphy_suspend, ++ .resume = genphy_resume, + } }; + + module_phy_driver(ksphy_driver); +diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c +index c4ceb082e970..14d57d0d1c04 100644 +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -860,6 +860,7 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, + struct module *ndev_owner = dev->dev.parent->driver->owner; + struct mii_bus *bus = phydev->mdio.bus; + struct device *d = &phydev->mdio.dev; ++ bool using_genphy = false; + int err; + + /* For Ethernet device drivers that register their own MDIO bus, we +@@ -885,12 +886,22 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, + d->driver = + &genphy_driver[GENPHY_DRV_1G].mdiodrv.driver; + ++ using_genphy = true; ++ } ++ ++ if (!try_module_get(d->driver->owner)) { ++ dev_err(&dev->dev, "failed to get the device driver module\n"); ++ err = -EIO; ++ goto error_put_device; ++ } ++ ++ if (using_genphy) { + err = d->driver->probe(d); + if (err >= 0) + err = device_bind_driver(d); + + if (err) +- goto error; ++ goto error_module_put; + } + + if (phydev->attached_dev) { +@@ -926,6 +937,13 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, + return err; + + error: ++ /* phy_detach() does all of the cleanup below */ ++ phy_detach(phydev); ++ return err; ++ ++error_module_put: ++ module_put(d->driver->owner); ++error_put_device: + put_device(d); + if (ndev_owner != bus->owner) + module_put(bus->owner); +@@ -987,6 +1005,8 @@ void phy_detach(struct phy_device *phydev) + phydev->attached_dev = NULL; + phy_suspend(phydev); + ++ module_put(phydev->mdio.dev.driver->owner); ++ + /* If the device had no specific driver before (i.e. - it + * was using the generic driver), we unbind the device + * from the generic driver so that there's a chance a +diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c +index 90b426c5ffce..afb953a258cd 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -32,7 +32,7 @@ + #define NETNEXT_VERSION "08" + + /* Information for net */ +-#define NET_VERSION "7" ++#define NET_VERSION "8" + + #define DRIVER_VERSION "v1." NETNEXT_VERSION "." NET_VERSION + #define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>" +@@ -1936,6 +1936,9 @@ static int r8152_poll(struct napi_struct *napi, int budget) + napi_complete(napi); + if (!list_empty(&tp->rx_done)) + napi_schedule(napi); ++ else if (!skb_queue_empty(&tp->tx_queue) && ++ !list_empty(&tp->tx_free)) ++ napi_schedule(napi); + } + + return work_done; +@@ -3155,10 +3158,13 @@ static void set_carrier(struct r8152 *tp) + if (!netif_carrier_ok(netdev)) { + tp->rtl_ops.enable(tp); + set_bit(RTL8152_SET_RX_MODE, &tp->flags); ++ netif_stop_queue(netdev); + napi_disable(&tp->napi); + netif_carrier_on(netdev); + rtl_start_rx(tp); + napi_enable(&tp->napi); ++ netif_wake_queue(netdev); ++ netif_info(tp, link, netdev, "carrier on\n"); + } + } else { + if (netif_carrier_ok(netdev)) { +@@ -3166,6 +3172,7 @@ static void set_carrier(struct r8152 *tp) + napi_disable(&tp->napi); + tp->rtl_ops.disable(tp); + napi_enable(&tp->napi); ++ netif_info(tp, link, netdev, "carrier off\n"); + } + } + } +@@ -3515,12 +3522,12 @@ static int rtl8152_pre_reset(struct usb_interface *intf) + if (!netif_running(netdev)) + return 0; + ++ netif_stop_queue(netdev); + napi_disable(&tp->napi); + clear_bit(WORK_ENABLE, &tp->flags); + usb_kill_urb(tp->intr_urb); + cancel_delayed_work_sync(&tp->schedule); + if (netif_carrier_ok(netdev)) { +- netif_stop_queue(netdev); + mutex_lock(&tp->control); + tp->rtl_ops.disable(tp); + mutex_unlock(&tp->control); +@@ -3545,12 +3552,17 @@ static int rtl8152_post_reset(struct usb_interface *intf) + if (netif_carrier_ok(netdev)) { + mutex_lock(&tp->control); + tp->rtl_ops.enable(tp); ++ rtl_start_rx(tp); + rtl8152_set_rx_mode(netdev); + mutex_unlock(&tp->control); +- netif_wake_queue(netdev); + } + + napi_enable(&tp->napi); ++ netif_wake_queue(netdev); ++ usb_submit_urb(tp->intr_urb, GFP_KERNEL); ++ ++ if (!list_empty(&tp->rx_done)) ++ napi_schedule(&tp->napi); + + return 0; + } +@@ -3583,10 +3595,15 @@ static int rtl8152_rumtime_suspend(struct r8152 *tp) + struct net_device *netdev = tp->netdev; + int ret = 0; + ++ set_bit(SELECTIVE_SUSPEND, &tp->flags); ++ smp_mb__after_atomic(); ++ + if (netif_running(netdev) && test_bit(WORK_ENABLE, &tp->flags)) { + u32 rcr = 0; + + if (delay_autosuspend(tp)) { ++ clear_bit(SELECTIVE_SUSPEND, &tp->flags); ++ smp_mb__after_atomic(); + ret = -EBUSY; + goto out1; + } +@@ -3603,6 +3620,8 @@ static int rtl8152_rumtime_suspend(struct r8152 *tp) + if (!(ocp_data & RXFIFO_EMPTY)) { + rxdy_gated_en(tp, false); + ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, rcr); ++ clear_bit(SELECTIVE_SUSPEND, &tp->flags); ++ smp_mb__after_atomic(); + ret = -EBUSY; + goto out1; + } +@@ -3622,8 +3641,6 @@ static int rtl8152_rumtime_suspend(struct r8152 *tp) + } + } + +- set_bit(SELECTIVE_SUSPEND, &tp->flags); +- + out1: + return ret; + } +@@ -3679,12 +3696,15 @@ static int rtl8152_resume(struct usb_interface *intf) + if (netif_running(tp->netdev) && tp->netdev->flags & IFF_UP) { + if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) { + tp->rtl_ops.autosuspend_en(tp, false); +- clear_bit(SELECTIVE_SUSPEND, &tp->flags); + napi_disable(&tp->napi); + set_bit(WORK_ENABLE, &tp->flags); + if (netif_carrier_ok(tp->netdev)) + rtl_start_rx(tp); + napi_enable(&tp->napi); ++ clear_bit(SELECTIVE_SUSPEND, &tp->flags); ++ smp_mb__after_atomic(); ++ if (!list_empty(&tp->rx_done)) ++ napi_schedule(&tp->napi); + } else { + tp->rtl_ops.up(tp); + netif_carrier_off(tp->netdev); +diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c +index a251588762ec..0b5a84c9022c 100644 +--- a/drivers/net/usb/sierra_net.c ++++ b/drivers/net/usb/sierra_net.c +@@ -73,8 +73,6 @@ static atomic_t iface_counter = ATOMIC_INIT(0); + /* Private data structure */ + struct sierra_net_data { + +- u8 ethr_hdr_tmpl[ETH_HLEN]; /* ethernet header template for rx'd pkts */ +- + u16 link_up; /* air link up or down */ + u8 tx_hdr_template[4]; /* part of HIP hdr for tx'd packets */ + +@@ -122,6 +120,7 @@ struct param { + + /* LSI Protocol types */ + #define SIERRA_NET_PROTOCOL_UMTS 0x01 ++#define SIERRA_NET_PROTOCOL_UMTS_DS 0x04 + /* LSI Coverage */ + #define SIERRA_NET_COVERAGE_NONE 0x00 + #define SIERRA_NET_COVERAGE_NOPACKET 0x01 +@@ -129,7 +128,8 @@ struct param { + /* LSI Session */ + #define SIERRA_NET_SESSION_IDLE 0x00 + /* LSI Link types */ +-#define SIERRA_NET_AS_LINK_TYPE_IPv4 0x00 ++#define SIERRA_NET_AS_LINK_TYPE_IPV4 0x00 ++#define SIERRA_NET_AS_LINK_TYPE_IPV6 0x02 + + struct lsi_umts { + u8 protocol; +@@ -137,9 +137,14 @@ struct lsi_umts { + __be16 length; + /* eventually use a union for the rest - assume umts for now */ + u8 coverage; +- u8 unused2[41]; ++ u8 network_len; /* network name len */ ++ u8 network[40]; /* network name (UCS2, bigendian) */ + u8 session_state; + u8 unused3[33]; ++} __packed; ++ ++struct lsi_umts_single { ++ struct lsi_umts lsi; + u8 link_type; + u8 pdp_addr_len; /* NW-supplied PDP address len */ + u8 pdp_addr[16]; /* NW-supplied PDP address (bigendian)) */ +@@ -158,10 +163,31 @@ struct lsi_umts { + u8 reserved[8]; + } __packed; + ++struct lsi_umts_dual { ++ struct lsi_umts lsi; ++ u8 pdp_addr4_len; /* NW-supplied PDP IPv4 address len */ ++ u8 pdp_addr4[4]; /* NW-supplied PDP IPv4 address (bigendian)) */ ++ u8 pdp_addr6_len; /* NW-supplied PDP IPv6 address len */ ++ u8 pdp_addr6[16]; /* NW-supplied PDP IPv6 address (bigendian)) */ ++ u8 unused4[23]; ++ u8 dns1_addr4_len; /* NW-supplied 1st DNS v4 address len (bigendian) */ ++ u8 dns1_addr4[4]; /* NW-supplied 1st DNS v4 address */ ++ u8 dns1_addr6_len; /* NW-supplied 1st DNS v6 address len */ ++ u8 dns1_addr6[16]; /* NW-supplied 1st DNS v6 address (bigendian)*/ ++ u8 dns2_addr4_len; /* NW-supplied 2nd DNS v4 address len (bigendian) */ ++ u8 dns2_addr4[4]; /* NW-supplied 2nd DNS v4 address */ ++ u8 dns2_addr6_len; /* NW-supplied 2nd DNS v6 address len */ ++ u8 dns2_addr6[16]; /* NW-supplied 2nd DNS v6 address (bigendian)*/ ++ u8 unused5[68]; ++} __packed; ++ + #define SIERRA_NET_LSI_COMMON_LEN 4 +-#define SIERRA_NET_LSI_UMTS_LEN (sizeof(struct lsi_umts)) ++#define SIERRA_NET_LSI_UMTS_LEN (sizeof(struct lsi_umts_single)) + #define SIERRA_NET_LSI_UMTS_STATUS_LEN \ + (SIERRA_NET_LSI_UMTS_LEN - SIERRA_NET_LSI_COMMON_LEN) ++#define SIERRA_NET_LSI_UMTS_DS_LEN (sizeof(struct lsi_umts_dual)) ++#define SIERRA_NET_LSI_UMTS_DS_STATUS_LEN \ ++ (SIERRA_NET_LSI_UMTS_DS_LEN - SIERRA_NET_LSI_COMMON_LEN) + + /* Forward definitions */ + static void sierra_sync_timer(unsigned long syncdata); +@@ -191,10 +217,11 @@ static inline void sierra_net_set_private(struct usbnet *dev, + dev->data[0] = (unsigned long)priv; + } + +-/* is packet IPv4 */ ++/* is packet IPv4/IPv6 */ + static inline int is_ip(struct sk_buff *skb) + { +- return skb->protocol == cpu_to_be16(ETH_P_IP); ++ return skb->protocol == cpu_to_be16(ETH_P_IP) || ++ skb->protocol == cpu_to_be16(ETH_P_IPV6); + } + + /* +@@ -350,49 +377,54 @@ static inline int sierra_net_is_valid_addrlen(u8 len) + static int sierra_net_parse_lsi(struct usbnet *dev, char *data, int datalen) + { + struct lsi_umts *lsi = (struct lsi_umts *)data; ++ u32 expected_length; + +- if (datalen < sizeof(struct lsi_umts)) { +- netdev_err(dev->net, "%s: Data length %d, exp %Zu\n", +- __func__, datalen, +- sizeof(struct lsi_umts)); ++ if (datalen < sizeof(struct lsi_umts_single)) { ++ netdev_err(dev->net, "%s: Data length %d, exp >= %Zu\n", ++ __func__, datalen, sizeof(struct lsi_umts_single)); + return -1; + } + +- if (lsi->length != cpu_to_be16(SIERRA_NET_LSI_UMTS_STATUS_LEN)) { +- netdev_err(dev->net, "%s: LSI_UMTS_STATUS_LEN %d, exp %u\n", +- __func__, be16_to_cpu(lsi->length), +- (u32)SIERRA_NET_LSI_UMTS_STATUS_LEN); +- return -1; ++ /* Validate the session state */ ++ if (lsi->session_state == SIERRA_NET_SESSION_IDLE) { ++ netdev_err(dev->net, "Session idle, 0x%02x\n", ++ lsi->session_state); ++ return 0; + } + + /* Validate the protocol - only support UMTS for now */ +- if (lsi->protocol != SIERRA_NET_PROTOCOL_UMTS) { ++ if (lsi->protocol == SIERRA_NET_PROTOCOL_UMTS) { ++ struct lsi_umts_single *single = (struct lsi_umts_single *)lsi; ++ ++ /* Validate the link type */ ++ if (single->link_type != SIERRA_NET_AS_LINK_TYPE_IPV4 && ++ single->link_type != SIERRA_NET_AS_LINK_TYPE_IPV6) { ++ netdev_err(dev->net, "Link type unsupported: 0x%02x\n", ++ single->link_type); ++ return -1; ++ } ++ expected_length = SIERRA_NET_LSI_UMTS_STATUS_LEN; ++ } else if (lsi->protocol == SIERRA_NET_PROTOCOL_UMTS_DS) { ++ expected_length = SIERRA_NET_LSI_UMTS_DS_STATUS_LEN; ++ } else { + netdev_err(dev->net, "Protocol unsupported, 0x%02x\n", +- lsi->protocol); ++ lsi->protocol); + return -1; + } + +- /* Validate the link type */ +- if (lsi->link_type != SIERRA_NET_AS_LINK_TYPE_IPv4) { +- netdev_err(dev->net, "Link type unsupported: 0x%02x\n", +- lsi->link_type); ++ if (be16_to_cpu(lsi->length) != expected_length) { ++ netdev_err(dev->net, "%s: LSI_UMTS_STATUS_LEN %d, exp %u\n", ++ __func__, be16_to_cpu(lsi->length), expected_length); + return -1; + } + + /* Validate the coverage */ +- if (lsi->coverage == SIERRA_NET_COVERAGE_NONE +- || lsi->coverage == SIERRA_NET_COVERAGE_NOPACKET) { ++ if (lsi->coverage == SIERRA_NET_COVERAGE_NONE || ++ lsi->coverage == SIERRA_NET_COVERAGE_NOPACKET) { + netdev_err(dev->net, "No coverage, 0x%02x\n", lsi->coverage); + return 0; + } + +- /* Validate the session state */ +- if (lsi->session_state == SIERRA_NET_SESSION_IDLE) { +- netdev_err(dev->net, "Session idle, 0x%02x\n", +- lsi->session_state); +- return 0; +- } +- + /* Set link_sense true */ + return 1; + } +@@ -662,7 +694,6 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf) + u8 numendpoints; + u16 fwattr = 0; + int status; +- struct ethhdr *eth; + struct sierra_net_data *priv; + static const u8 sync_tmplate[sizeof(priv->sync_msg)] = { + 0x00, 0x00, SIERRA_NET_HIP_MSYNC_ID, 0x00}; +@@ -700,11 +731,6 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf) + dev->net->dev_addr[ETH_ALEN-2] = atomic_inc_return(&iface_counter); + dev->net->dev_addr[ETH_ALEN-1] = ifacenum; + +- /* we will have to manufacture ethernet headers, prepare template */ +- eth = (struct ethhdr *)priv->ethr_hdr_tmpl; +- memcpy(ð->h_dest, dev->net->dev_addr, ETH_ALEN); +- eth->h_proto = cpu_to_be16(ETH_P_IP); +- + /* prepare shutdown message template */ + memcpy(priv->shdwn_msg, shdwn_tmplate, sizeof(priv->shdwn_msg)); + /* set context index initially to 0 - prepares tx hdr template */ +@@ -833,9 +859,14 @@ static int sierra_net_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + + skb_pull(skb, hh.hdrlen); + +- /* We are going to accept this packet, prepare it */ +- memcpy(skb->data, sierra_net_get_private(dev)->ethr_hdr_tmpl, +- ETH_HLEN); ++ /* We are going to accept this packet, prepare it. ++ * In case protocol is IPv6, keep it, otherwise force IPv4. ++ */ ++ skb_reset_mac_header(skb); ++ if (eth_hdr(skb)->h_proto != cpu_to_be16(ETH_P_IPV6)) ++ eth_hdr(skb)->h_proto = cpu_to_be16(ETH_P_IP); ++ eth_zero_addr(eth_hdr(skb)->h_source); ++ memcpy(eth_hdr(skb)->h_dest, dev->net->dev_addr, ETH_ALEN); + + /* Last packet in batch handled by usbnet */ + if (hh.payload_len.word == skb->len) +diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c +index 005ef5d17a19..ca8ddc3fb19e 100644 +--- a/drivers/nvme/target/rdma.c ++++ b/drivers/nvme/target/rdma.c +@@ -438,6 +438,10 @@ static int nvmet_rdma_post_recv(struct nvmet_rdma_device *ndev, + { + struct ib_recv_wr *bad_wr; + ++ ib_dma_sync_single_for_device(ndev->device, ++ cmd->sge[0].addr, cmd->sge[0].length, ++ DMA_FROM_DEVICE); ++ + if (ndev->srq) + return ib_post_srq_recv(ndev->srq, &cmd->wr, &bad_wr); + return ib_post_recv(cmd->queue->cm_id->qp, &cmd->wr, &bad_wr); +@@ -538,6 +542,11 @@ static void nvmet_rdma_queue_response(struct nvmet_req *req) + first_wr = &rsp->send_wr; + + nvmet_rdma_post_recv(rsp->queue->dev, rsp->cmd); ++ ++ ib_dma_sync_single_for_device(rsp->queue->dev->device, ++ rsp->send_sge.addr, rsp->send_sge.length, ++ DMA_TO_DEVICE); ++ + if (ib_post_send(cm_id->qp, first_wr, &bad_wr)) { + pr_err("sending cmd response failed\n"); + nvmet_rdma_release_rsp(rsp); +@@ -698,6 +707,14 @@ static void nvmet_rdma_handle_command(struct nvmet_rdma_queue *queue, + cmd->n_rdma = 0; + cmd->req.port = queue->port; + ++ ++ ib_dma_sync_single_for_cpu(queue->dev->device, ++ cmd->cmd->sge[0].addr, cmd->cmd->sge[0].length, ++ DMA_FROM_DEVICE); ++ ib_dma_sync_single_for_cpu(queue->dev->device, ++ cmd->send_sge.addr, cmd->send_sge.length, ++ DMA_TO_DEVICE); ++ + if (!nvmet_req_init(&cmd->req, &queue->nvme_cq, + &queue->nvme_sq, &nvmet_rdma_ops)) + return; +diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c +index 6e3a60c78873..50f3bb0dd1f1 100644 +--- a/drivers/parport/parport_gsc.c ++++ b/drivers/parport/parport_gsc.c +@@ -293,7 +293,7 @@ struct parport *parport_gsc_probe_port(unsigned long base, + p->irq = PARPORT_IRQ_NONE; + } + if (p->irq != PARPORT_IRQ_NONE) { +- printk(", irq %d", p->irq); ++ pr_cont(", irq %d", p->irq); + + if (p->dma == PARPORT_DMA_AUTO) { + p->dma = PARPORT_DMA_NONE; +@@ -303,8 +303,8 @@ struct parport *parport_gsc_probe_port(unsigned long base, + is mandatory (see above) */ + p->dma = PARPORT_DMA_NONE; + +- printk(" ["); +-#define printmode(x) {if(p->modes&PARPORT_MODE_##x){printk("%s%s",f?",":"",#x);f++;}} ++ pr_cont(" ["); ++#define printmode(x) {if(p->modes&PARPORT_MODE_##x){pr_cont("%s%s",f?",":"",#x);f++;}} + { + int f = 0; + printmode(PCSPP); +@@ -315,7 +315,7 @@ struct parport *parport_gsc_probe_port(unsigned long base, + // printmode(DMA); + } + #undef printmode +- printk("]\n"); ++ pr_cont("]\n"); + + if (p->irq != PARPORT_IRQ_NONE) { + if (request_irq (p->irq, parport_irq_handler, +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index 579c4946dc6e..e7d4048e81f2 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -2142,7 +2142,8 @@ bool pci_dev_keep_suspended(struct pci_dev *pci_dev) + + if (!pm_runtime_suspended(dev) + || pci_target_state(pci_dev) != pci_dev->current_state +- || platform_pci_need_resume(pci_dev)) ++ || platform_pci_need_resume(pci_dev) ++ || (pci_dev->dev_flags & PCI_DEV_FLAGS_NEEDS_RESUME)) + return false; + + /* +diff --git a/drivers/pinctrl/berlin/berlin-bg4ct.c b/drivers/pinctrl/berlin/berlin-bg4ct.c +index 09172043d589..c617ec49e9ed 100644 +--- a/drivers/pinctrl/berlin/berlin-bg4ct.c ++++ b/drivers/pinctrl/berlin/berlin-bg4ct.c +@@ -217,7 +217,7 @@ static const struct berlin_desc_group berlin4ct_soc_pinctrl_groups[] = { + BERLIN_PINCTRL_GROUP("SCRD0_CRD_PRES", 0xc, 0x3, 0x15, + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO20 */ + BERLIN_PINCTRL_FUNCTION(0x1, "scrd0"), /* crd pres */ +- BERLIN_PINCTRL_FUNCTION(0x1, "sd1a")), /* DAT3 */ ++ BERLIN_PINCTRL_FUNCTION(0x3, "sd1a")), /* DAT3 */ + BERLIN_PINCTRL_GROUP("SPI1_SS0n", 0xc, 0x3, 0x18, + BERLIN_PINCTRL_FUNCTION(0x0, "spi1"), /* SS0n */ + BERLIN_PINCTRL_FUNCTION(0x1, "gpio"), /* GPIO37 */ +diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c +index 583ae3f38fc0..5419de8e20b1 100644 +--- a/drivers/pinctrl/intel/pinctrl-baytrail.c ++++ b/drivers/pinctrl/intel/pinctrl-baytrail.c +@@ -1250,10 +1250,12 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, + debounce = readl(db_reg); + debounce &= ~BYT_DEBOUNCE_PULSE_MASK; + ++ if (arg) ++ conf |= BYT_DEBOUNCE_EN; ++ else ++ conf &= ~BYT_DEBOUNCE_EN; ++ + switch (arg) { +- case 0: +- conf &= BYT_DEBOUNCE_EN; +- break; + case 375: + debounce |= BYT_DEBOUNCE_PULSE_375US; + break; +@@ -1276,7 +1278,9 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, + debounce |= BYT_DEBOUNCE_PULSE_24MS; + break; + default: +- ret = -EINVAL; ++ if (arg) ++ ret = -EINVAL; ++ break; + } + + if (!ret) +diff --git a/drivers/staging/media/cec/cec-adap.c b/drivers/staging/media/cec/cec-adap.c +index 611e07b78bfe..057c9b5ab1e5 100644 +--- a/drivers/staging/media/cec/cec-adap.c ++++ b/drivers/staging/media/cec/cec-adap.c +@@ -1017,7 +1017,7 @@ static int cec_config_thread_func(void *arg) + las->log_addr[i] = CEC_LOG_ADDR_INVALID; + if (last_la == CEC_LOG_ADDR_INVALID || + last_la == CEC_LOG_ADDR_UNREGISTERED || +- !(last_la & type2mask[type])) ++ !((1 << last_la) & type2mask[type])) + last_la = la_list[0]; + + err = cec_config_log_addr(adap, i, last_la); +diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c +index 358feca54945..261ed2ca28f9 100644 +--- a/drivers/usb/musb/musb_core.c ++++ b/drivers/usb/musb/musb_core.c +@@ -1909,6 +1909,14 @@ static void musb_pm_runtime_check_session(struct musb *musb) + static void musb_irq_work(struct work_struct *data) + { + struct musb *musb = container_of(data, struct musb, irq_work.work); ++ int error; ++ ++ error = pm_runtime_get_sync(musb->controller); ++ if (error < 0) { ++ dev_err(musb->controller, "Could not enable: %i\n", error); ++ ++ return; ++ } + + musb_pm_runtime_check_session(musb); + +@@ -1916,6 +1924,9 @@ static void musb_irq_work(struct work_struct *data) + musb->xceiv_old_state = musb->xceiv->otg->state; + sysfs_notify(&musb->controller->kobj, NULL, "mode"); + } ++ ++ pm_runtime_mark_last_busy(musb->controller); ++ pm_runtime_put_autosuspend(musb->controller); + } + + static void musb_recover_from_babble(struct musb *musb) +diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c +index c8823578a1b2..79ddcb05d126 100644 +--- a/drivers/vfio/vfio_iommu_spapr_tce.c ++++ b/drivers/vfio/vfio_iommu_spapr_tce.c +@@ -1246,6 +1246,8 @@ static void tce_iommu_release_ownership_ddw(struct tce_container *container, + static long tce_iommu_take_ownership_ddw(struct tce_container *container, + struct iommu_table_group *table_group) + { ++ long i, ret = 0; ++ + if (!table_group->ops->create_table || !table_group->ops->set_window || + !table_group->ops->release_ownership) { + WARN_ON_ONCE(1); +@@ -1254,7 +1256,27 @@ static long tce_iommu_take_ownership_ddw(struct tce_container *container, + + table_group->ops->take_ownership(table_group); + ++ /* Set all windows to the new group */ ++ for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) { ++ struct iommu_table *tbl = container->tables[i]; ++ ++ if (!tbl) ++ continue; ++ ++ ret = table_group->ops->set_window(table_group, i, tbl); ++ if (ret) ++ goto release_exit; ++ } ++ + return 0; ++ ++release_exit: ++ for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) ++ table_group->ops->unset_window(table_group, i); ++ ++ table_group->ops->release_ownership(table_group); ++ ++ return ret; + } + + static int tce_iommu_attach_group(void *iommu_data, +diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c +index a504e2e003da..e3fad302b4fb 100644 +--- a/drivers/vhost/vsock.c ++++ b/drivers/vhost/vsock.c +@@ -368,6 +368,7 @@ static void vhost_vsock_handle_rx_kick(struct vhost_work *work) + + static int vhost_vsock_start(struct vhost_vsock *vsock) + { ++ struct vhost_virtqueue *vq; + size_t i; + int ret; + +@@ -378,19 +379,20 @@ static int vhost_vsock_start(struct vhost_vsock *vsock) + goto err; + + for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) { +- struct vhost_virtqueue *vq = &vsock->vqs[i]; ++ vq = &vsock->vqs[i]; + + mutex_lock(&vq->mutex); + + if (!vhost_vq_access_ok(vq)) { + ret = -EFAULT; +- mutex_unlock(&vq->mutex); + goto err_vq; + } + + if (!vq->private_data) { + vq->private_data = vsock; +- vhost_vq_init_access(vq); ++ ret = vhost_vq_init_access(vq); ++ if (ret) ++ goto err_vq; + } + + mutex_unlock(&vq->mutex); +@@ -400,8 +402,11 @@ static int vhost_vsock_start(struct vhost_vsock *vsock) + return 0; + + err_vq: ++ vq->private_data = NULL; ++ mutex_unlock(&vq->mutex); ++ + for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) { +- struct vhost_virtqueue *vq = &vsock->vqs[i]; ++ vq = &vsock->vqs[i]; + + mutex_lock(&vq->mutex); + vq->private_data = NULL; +diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c +index 4304072161aa..40d61077bead 100644 +--- a/fs/fscache/cookie.c ++++ b/fs/fscache/cookie.c +@@ -542,6 +542,7 @@ void __fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate) + hlist_for_each_entry(object, &cookie->backing_objects, cookie_link) { + if (invalidate) + set_bit(FSCACHE_OBJECT_RETIRED, &object->flags); ++ clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags); + fscache_raise_event(object, FSCACHE_OBJECT_EV_KILL); + } + } else { +@@ -560,6 +561,10 @@ void __fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate) + wait_on_atomic_t(&cookie->n_active, fscache_wait_atomic_t, + TASK_UNINTERRUPTIBLE); + ++ /* Make sure any pending writes are cancelled. */ ++ if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) ++ fscache_invalidate_writes(cookie); ++ + /* Reset the cookie state if it wasn't relinquished */ + if (!test_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags)) { + atomic_inc(&cookie->n_active); +diff --git a/fs/fscache/netfs.c b/fs/fscache/netfs.c +index 9b28649df3a1..a8aa00be4444 100644 +--- a/fs/fscache/netfs.c ++++ b/fs/fscache/netfs.c +@@ -48,6 +48,7 @@ int __fscache_register_netfs(struct fscache_netfs *netfs) + cookie->flags = 1 << FSCACHE_COOKIE_ENABLED; + + spin_lock_init(&cookie->lock); ++ spin_lock_init(&cookie->stores_lock); + INIT_HLIST_HEAD(&cookie->backing_objects); + + /* check the netfs type is not already present */ +diff --git a/fs/fscache/object.c b/fs/fscache/object.c +index 9e792e30f4db..7a182c87f378 100644 +--- a/fs/fscache/object.c ++++ b/fs/fscache/object.c +@@ -30,6 +30,7 @@ static const struct fscache_state *fscache_look_up_object(struct fscache_object + static const struct fscache_state *fscache_object_available(struct fscache_object *, int); + static const struct fscache_state *fscache_parent_ready(struct fscache_object *, int); + static const struct fscache_state *fscache_update_object(struct fscache_object *, int); ++static const struct fscache_state *fscache_object_dead(struct fscache_object *, int); + + #define __STATE_NAME(n) fscache_osm_##n + #define STATE(n) (&__STATE_NAME(n)) +@@ -91,7 +92,7 @@ static WORK_STATE(LOOKUP_FAILURE, "LCFL", fscache_lookup_failure); + static WORK_STATE(KILL_OBJECT, "KILL", fscache_kill_object); + static WORK_STATE(KILL_DEPENDENTS, "KDEP", fscache_kill_dependents); + static WORK_STATE(DROP_OBJECT, "DROP", fscache_drop_object); +-static WORK_STATE(OBJECT_DEAD, "DEAD", (void*)2UL); ++static WORK_STATE(OBJECT_DEAD, "DEAD", fscache_object_dead); + + static WAIT_STATE(WAIT_FOR_INIT, "?INI", + TRANSIT_TO(INIT_OBJECT, 1 << FSCACHE_OBJECT_EV_NEW_CHILD)); +@@ -229,6 +230,10 @@ static void fscache_object_sm_dispatcher(struct fscache_object *object) + event = -1; + if (new_state == NO_TRANSIT) { + _debug("{OBJ%x} %s notrans", object->debug_id, state->name); ++ if (unlikely(state == STATE(OBJECT_DEAD))) { ++ _leave(" [dead]"); ++ return; ++ } + fscache_enqueue_object(object); + event_mask = object->oob_event_mask; + goto unmask_events; +@@ -239,7 +244,7 @@ static void fscache_object_sm_dispatcher(struct fscache_object *object) + object->state = state = new_state; + + if (state->work) { +- if (unlikely(state->work == ((void *)2UL))) { ++ if (unlikely(state == STATE(OBJECT_DEAD))) { + _leave(" [dead]"); + return; + } +@@ -645,6 +650,12 @@ static const struct fscache_state *fscache_kill_object(struct fscache_object *ob + fscache_mark_object_dead(object); + object->oob_event_mask = 0; + ++ if (test_bit(FSCACHE_OBJECT_RETIRED, &object->flags)) { ++ /* Reject any new read/write ops and abort any that are pending. */ ++ clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags); ++ fscache_cancel_all_ops(object); ++ } ++ + if (list_empty(&object->dependents) && + object->n_ops == 0 && + object->n_children == 0) +@@ -1077,3 +1088,20 @@ void fscache_object_mark_killed(struct fscache_object *object, + } + } + EXPORT_SYMBOL(fscache_object_mark_killed); ++ ++/* ++ * The object is dead. We can get here if an object gets queued by an event ++ * that would lead to its death (such as EV_KILL) when the dispatcher is ++ * already running (and so can be requeued) but hasn't yet cleared the event ++ * mask. ++ */ ++static const struct fscache_state *fscache_object_dead(struct fscache_object *object, ++ int event) ++{ ++ if (!test_and_set_bit(FSCACHE_OBJECT_RUN_AFTER_DEAD, ++ &object->flags)) ++ return NO_TRANSIT; ++ ++ WARN(true, "FS-Cache object redispatched after death"); ++ return NO_TRANSIT; ++} +diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c +index 133f322573b5..6528724ad6e5 100644 +--- a/fs/gfs2/glock.c ++++ b/fs/gfs2/glock.c +@@ -1425,26 +1425,32 @@ static struct shrinker glock_shrinker = { + * @sdp: the filesystem + * @bucket: the bucket + * ++ * Note that the function can be called multiple times on the same ++ * object. So the user must ensure that the function can cope with ++ * that. + */ + + static void glock_hash_walk(glock_examiner examiner, const struct gfs2_sbd *sdp) + { + struct gfs2_glock *gl; +- struct rhash_head *pos; +- const struct bucket_table *tbl; +- int i; ++ struct rhashtable_iter iter; + +- rcu_read_lock(); +- tbl = rht_dereference_rcu(gl_hash_table.tbl, &gl_hash_table); +- for (i = 0; i < tbl->size; i++) { +- rht_for_each_entry_rcu(gl, pos, tbl, i, gl_node) { ++ rhashtable_walk_enter(&gl_hash_table, &iter); ++ ++ do { ++ gl = ERR_PTR(rhashtable_walk_start(&iter)); ++ if (gl) ++ continue; ++ ++ while ((gl = rhashtable_walk_next(&iter)) && !IS_ERR(gl)) + if ((gl->gl_name.ln_sbd == sdp) && + lockref_get_not_dead(&gl->gl_lockref)) + examiner(gl); +- } +- } +- rcu_read_unlock(); +- cond_resched(); ++ ++ rhashtable_walk_stop(&iter); ++ } while (cond_resched(), gl == ERR_PTR(-EAGAIN)); ++ ++ rhashtable_walk_exit(&iter); + } + + /** +diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c +index 0959c9661662..92671914067f 100644 +--- a/fs/nfs/nfs4state.c ++++ b/fs/nfs/nfs4state.c +@@ -1079,6 +1079,7 @@ static void nfs_increment_seqid(int status, struct nfs_seqid *seqid) + case -NFS4ERR_BADXDR: + case -NFS4ERR_RESOURCE: + case -NFS4ERR_NOFILEHANDLE: ++ case -NFS4ERR_MOVED: + /* Non-seqid mutating errors */ + return; + }; +diff --git a/fs/proc/base.c b/fs/proc/base.c +index ca651ac00660..e67fec3c9856 100644 +--- a/fs/proc/base.c ++++ b/fs/proc/base.c +@@ -3181,6 +3181,8 @@ int proc_pid_readdir(struct file *file, struct dir_context *ctx) + iter.tgid += 1, iter = next_tgid(ns, iter)) { + char name[PROC_NUMBUF]; + int len; ++ ++ cond_resched(); + if (!has_pid_permissions(ns, iter.task, 2)) + continue; + +diff --git a/fs/romfs/super.c b/fs/romfs/super.c +index d0f8a38dfafa..0186fe6d39f3 100644 +--- a/fs/romfs/super.c ++++ b/fs/romfs/super.c +@@ -74,6 +74,7 @@ + #include <linux/highmem.h> + #include <linux/pagemap.h> + #include <linux/uaccess.h> ++#include <linux/major.h> + #include "internal.h" + + static struct kmem_cache *romfs_inode_cachep; +@@ -416,7 +417,22 @@ static void romfs_destroy_inode(struct inode *inode) + static int romfs_statfs(struct dentry *dentry, struct kstatfs *buf) + { + struct super_block *sb = dentry->d_sb; +- u64 id = huge_encode_dev(sb->s_bdev->bd_dev); ++ u64 id = 0; ++ ++ /* When calling huge_encode_dev(), ++ * use sb->s_bdev->bd_dev when, ++ * - CONFIG_ROMFS_ON_BLOCK defined ++ * use sb->s_dev when, ++ * - CONFIG_ROMFS_ON_BLOCK undefined and ++ * - CONFIG_ROMFS_ON_MTD defined ++ * leave id as 0 when, ++ * - CONFIG_ROMFS_ON_BLOCK undefined and ++ * - CONFIG_ROMFS_ON_MTD undefined ++ */ ++ if (sb->s_bdev) ++ id = huge_encode_dev(sb->s_bdev->bd_dev); ++ else if (sb->s_dev) ++ id = huge_encode_dev(sb->s_dev); + + buf->f_type = ROMFS_MAGIC; + buf->f_namelen = ROMFS_MAXFN; +@@ -489,6 +505,11 @@ static int romfs_fill_super(struct super_block *sb, void *data, int silent) + sb->s_flags |= MS_RDONLY | MS_NOATIME; + sb->s_op = &romfs_super_ops; + ++#ifdef CONFIG_ROMFS_ON_MTD ++ /* Use same dev ID from the underlying mtdblock device */ ++ if (sb->s_mtd) ++ sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, sb->s_mtd->index); ++#endif + /* read the image superblock and check it */ + rsb = kmalloc(512, GFP_KERNEL); + if (!rsb) +diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c +index 85959d8324df..b86054cc41db 100644 +--- a/fs/userfaultfd.c ++++ b/fs/userfaultfd.c +@@ -63,6 +63,7 @@ struct userfaultfd_wait_queue { + struct uffd_msg msg; + wait_queue_t wq; + struct userfaultfd_ctx *ctx; ++ bool waken; + }; + + struct userfaultfd_wake_range { +@@ -86,6 +87,12 @@ static int userfaultfd_wake_function(wait_queue_t *wq, unsigned mode, + if (len && (start > uwq->msg.arg.pagefault.address || + start + len <= uwq->msg.arg.pagefault.address)) + goto out; ++ WRITE_ONCE(uwq->waken, true); ++ /* ++ * The implicit smp_mb__before_spinlock in try_to_wake_up() ++ * renders uwq->waken visible to other CPUs before the task is ++ * waken. ++ */ + ret = wake_up_state(wq->private, mode); + if (ret) + /* +@@ -264,6 +271,7 @@ int handle_userfault(struct fault_env *fe, unsigned long reason) + struct userfaultfd_wait_queue uwq; + int ret; + bool must_wait, return_to_userland; ++ long blocking_state; + + BUG_ON(!rwsem_is_locked(&mm->mmap_sem)); + +@@ -333,10 +341,13 @@ int handle_userfault(struct fault_env *fe, unsigned long reason) + uwq.wq.private = current; + uwq.msg = userfault_msg(fe->address, fe->flags, reason); + uwq.ctx = ctx; ++ uwq.waken = false; + + return_to_userland = + (fe->flags & (FAULT_FLAG_USER|FAULT_FLAG_KILLABLE)) == + (FAULT_FLAG_USER|FAULT_FLAG_KILLABLE); ++ blocking_state = return_to_userland ? TASK_INTERRUPTIBLE : ++ TASK_KILLABLE; + + spin_lock(&ctx->fault_pending_wqh.lock); + /* +@@ -349,8 +360,7 @@ int handle_userfault(struct fault_env *fe, unsigned long reason) + * following the spin_unlock to happen before the list_add in + * __add_wait_queue. + */ +- set_current_state(return_to_userland ? TASK_INTERRUPTIBLE : +- TASK_KILLABLE); ++ set_current_state(blocking_state); + spin_unlock(&ctx->fault_pending_wqh.lock); + + must_wait = userfaultfd_must_wait(ctx, fe->address, fe->flags, reason); +@@ -362,6 +372,29 @@ int handle_userfault(struct fault_env *fe, unsigned long reason) + wake_up_poll(&ctx->fd_wqh, POLLIN); + schedule(); + ret |= VM_FAULT_MAJOR; ++ ++ /* ++ * False wakeups can orginate even from rwsem before ++ * up_read() however userfaults will wait either for a ++ * targeted wakeup on the specific uwq waitqueue from ++ * wake_userfault() or for signals or for uffd ++ * release. ++ */ ++ while (!READ_ONCE(uwq.waken)) { ++ /* ++ * This needs the full smp_store_mb() ++ * guarantee as the state write must be ++ * visible to other CPUs before reading ++ * uwq.waken from other CPUs. ++ */ ++ set_current_state(blocking_state); ++ if (READ_ONCE(uwq.waken) || ++ READ_ONCE(ctx->released) || ++ (return_to_userland ? signal_pending(current) : ++ fatal_signal_pending(current))) ++ break; ++ schedule(); ++ } + } + + __set_current_state(TASK_RUNNING); +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index e9fb2e802feb..0c4f9c67c221 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -776,6 +776,7 @@ struct drm_device { + struct drm_minor *control; /**< Control node */ + struct drm_minor *primary; /**< Primary node */ + struct drm_minor *render; /**< Render node */ ++ bool registered; + + /* currently active master for this device. Protected by master_mutex */ + struct drm_master *master; +diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h +index ac9d7d8e0e43..d8bb8d151825 100644 +--- a/include/drm/drm_connector.h ++++ b/include/drm/drm_connector.h +@@ -345,6 +345,8 @@ struct drm_connector_funcs { + * core drm connector interfaces. Everything added from this callback + * should be unregistered in the early_unregister callback. + * ++ * This is called while holding drm_connector->mutex. ++ * + * Returns: + * + * 0 on success, or a negative error code on failure. +@@ -359,6 +361,8 @@ struct drm_connector_funcs { + * late_register(). It is called from drm_connector_unregister(), + * early in the driver unload sequence to disable userspace access + * before data structures are torndown. ++ * ++ * This is called while holding drm_connector->mutex. + */ + void (*early_unregister)(struct drm_connector *connector); + +@@ -511,7 +515,6 @@ struct drm_cmdline_mode { + * @interlace_allowed: can this connector handle interlaced modes? + * @doublescan_allowed: can this connector handle doublescan? + * @stereo_allowed: can this connector handle stereo modes? +- * @registered: is this connector exposed (registered) with userspace? + * @modes: modes available on this connector (from fill_modes() + user) + * @status: one of the drm_connector_status enums (connected, not, or unknown) + * @probed_modes: list of modes derived directly from the display +@@ -560,6 +563,13 @@ struct drm_connector { + char *name; + + /** ++ * @mutex: Lock for general connector state, but currently only protects ++ * @registered. Most of the connector state is still protected by the ++ * mutex in &drm_mode_config. ++ */ ++ struct mutex mutex; ++ ++ /** + * @index: Compacted connector index, which matches the position inside + * the mode_config.list for drivers not supporting hot-add/removing. Can + * be used as an array index. It is invariant over the lifetime of the +@@ -572,6 +582,10 @@ struct drm_connector { + bool interlace_allowed; + bool doublescan_allowed; + bool stereo_allowed; ++ /** ++ * @registered: Is this connector exposed (registered) with userspace? ++ * Protected by @mutex. ++ */ + bool registered; + struct list_head modes; /* list of modes on this connector */ + +diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h +index 13ba552e6c09..4c467ef50159 100644 +--- a/include/linux/fscache-cache.h ++++ b/include/linux/fscache-cache.h +@@ -360,6 +360,7 @@ struct fscache_object { + #define FSCACHE_OBJECT_IS_AVAILABLE 5 /* T if object has become active */ + #define FSCACHE_OBJECT_RETIRED 6 /* T if object was retired on relinquishment */ + #define FSCACHE_OBJECT_KILLED_BY_CACHE 7 /* T if object was killed by the cache */ ++#define FSCACHE_OBJECT_RUN_AFTER_DEAD 8 /* T if object has been dispatched after death */ + + struct list_head cache_link; /* link in cache->object_list */ + struct hlist_node cookie_link; /* link in cookie->backing_objects */ +diff --git a/include/linux/log2.h b/include/linux/log2.h +index f38fae23bdac..c373295f359f 100644 +--- a/include/linux/log2.h ++++ b/include/linux/log2.h +@@ -194,6 +194,17 @@ unsigned long __rounddown_pow_of_two(unsigned long n) + * ... and so on. + */ + +-#define order_base_2(n) ilog2(roundup_pow_of_two(n)) ++static inline __attribute_const__ ++int __order_base_2(unsigned long n) ++{ ++ return n > 1 ? ilog2(n - 1) + 1 : 0; ++} + ++#define order_base_2(n) \ ++( \ ++ __builtin_constant_p(n) ? ( \ ++ ((n) == 0 || (n) == 1) ? 0 : \ ++ ilog2((n) - 1) + 1) : \ ++ __order_base_2(n) \ ++) + #endif /* _LINUX_LOG2_H */ +diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h +index 257173e0095e..f541da68d1e7 100644 +--- a/include/linux/micrel_phy.h ++++ b/include/linux/micrel_phy.h +@@ -35,6 +35,8 @@ + #define PHY_ID_KSZ886X 0x00221430 + #define PHY_ID_KSZ8863 0x00221435 + ++#define PHY_ID_KSZ8795 0x00221550 ++ + /* struct phy_device dev_flags definitions */ + #define MICREL_PHY_50MHZ_CLK 0x00000001 + #define MICREL_PHY_FXEN 0x00000002 +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index bb9b102c15cd..780e7171f548 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -865,11 +865,15 @@ struct netdev_xdp { + * of useless work if you return NETDEV_TX_BUSY. + * Required; cannot be NULL. + * +- * netdev_features_t (*ndo_fix_features)(struct net_device *dev, +- * netdev_features_t features); +- * Adjusts the requested feature flags according to device-specific +- * constraints, and returns the resulting flags. Must not modify +- * the device state. ++ * netdev_features_t (*ndo_features_check)(struct sk_buff *skb, ++ * struct net_device *dev ++ * netdev_features_t features); ++ * Called by core transmit path to determine if device is capable of ++ * performing offload operations on a given packet. This is to give ++ * the device an opportunity to implement any restrictions that cannot ++ * be otherwise expressed by feature flags. The check is called with ++ * the set of features that the stack has calculated and it returns ++ * those the driver believes to be appropriate. + * + * u16 (*ndo_select_queue)(struct net_device *dev, struct sk_buff *skb, + * void *accel_priv, select_queue_fallback_t fallback); +@@ -1027,6 +1031,12 @@ struct netdev_xdp { + * Called to release previously enslaved netdev. + * + * Feature/offload setting functions. ++ * netdev_features_t (*ndo_fix_features)(struct net_device *dev, ++ * netdev_features_t features); ++ * Adjusts the requested feature flags according to device-specific ++ * constraints, and returns the resulting flags. Must not modify ++ * the device state. ++ * + * int (*ndo_set_features)(struct net_device *dev, netdev_features_t features); + * Called to update device configuration to new features. Passed + * feature set might be less than what was returned by ndo_fix_features()). +@@ -1099,15 +1109,6 @@ struct netdev_xdp { + * Callback to use for xmit over the accelerated station. This + * is used in place of ndo_start_xmit on accelerated net + * devices. +- * netdev_features_t (*ndo_features_check)(struct sk_buff *skb, +- * struct net_device *dev +- * netdev_features_t features); +- * Called by core transmit path to determine if device is capable of +- * performing offload operations on a given packet. This is to give +- * the device an opportunity to implement any restrictions that cannot +- * be otherwise expressed by feature flags. The check is called with +- * the set of features that the stack has calculated and it returns +- * those the driver believes to be appropriate. + * int (*ndo_set_tx_maxrate)(struct net_device *dev, + * int queue_index, u32 maxrate); + * Called when a user wants to set a max-rate limitation of specific +diff --git a/include/linux/nmi.h b/include/linux/nmi.h +index a78c35cff1ae..0a3fadc32693 100644 +--- a/include/linux/nmi.h ++++ b/include/linux/nmi.h +@@ -7,6 +7,23 @@ + #include <linux/sched.h> + #include <asm/irq.h> + ++/* ++ * The run state of the lockup detectors is controlled by the content of the ++ * 'watchdog_enabled' variable. Each lockup detector has its dedicated bit - ++ * bit 0 for the hard lockup detector and bit 1 for the soft lockup detector. ++ * ++ * 'watchdog_user_enabled', 'nmi_watchdog_enabled' and 'soft_watchdog_enabled' ++ * are variables that are only used as an 'interface' between the parameters ++ * in /proc/sys/kernel and the internal state bits in 'watchdog_enabled'. The ++ * 'watchdog_thresh' variable is handled differently because its value is not ++ * boolean, and the lockup detectors are 'suspended' while 'watchdog_thresh' ++ * is equal zero. ++ */ ++#define NMI_WATCHDOG_ENABLED_BIT 0 ++#define SOFT_WATCHDOG_ENABLED_BIT 1 ++#define NMI_WATCHDOG_ENABLED (1 << NMI_WATCHDOG_ENABLED_BIT) ++#define SOFT_WATCHDOG_ENABLED (1 << SOFT_WATCHDOG_ENABLED_BIT) ++ + /** + * touch_nmi_watchdog - restart NMI watchdog timeout. + * +@@ -91,9 +108,17 @@ extern int nmi_watchdog_enabled; + extern int soft_watchdog_enabled; + extern int watchdog_user_enabled; + extern int watchdog_thresh; ++extern unsigned long watchdog_enabled; + extern unsigned long *watchdog_cpumask_bits; ++extern atomic_t watchdog_park_in_progress; ++#ifdef CONFIG_SMP + extern int sysctl_softlockup_all_cpu_backtrace; + extern int sysctl_hardlockup_all_cpu_backtrace; ++#else ++#define sysctl_softlockup_all_cpu_backtrace 0 ++#define sysctl_hardlockup_all_cpu_backtrace 0 ++#endif ++extern bool is_hardlockup(void); + struct ctl_table; + extern int proc_watchdog(struct ctl_table *, int , + void __user *, size_t *, loff_t *); +diff --git a/include/linux/pci.h b/include/linux/pci.h +index a38772a85588..1b711796d989 100644 +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -178,6 +178,11 @@ enum pci_dev_flags { + PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1 << 7), + /* Get VPD from function 0 VPD */ + PCI_DEV_FLAGS_VPD_REF_F0 = (__force pci_dev_flags_t) (1 << 8), ++ /* ++ * Resume before calling the driver's system suspend hooks, disabling ++ * the direct_complete optimization. ++ */ ++ PCI_DEV_FLAGS_NEEDS_RESUME = (__force pci_dev_flags_t) (1 << 11), + }; + + enum pci_irq_reroute_variant { +diff --git a/include/net/ipv6.h b/include/net/ipv6.h +index 91afb4aadaa6..615ce0abba9c 100644 +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -776,6 +776,11 @@ static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb, + { + u32 hash; + ++ /* @flowlabel may include more than a flow label, eg, the traffic class. ++ * Here we want only the flow label value. ++ */ ++ flowlabel &= IPV6_FLOWLABEL_MASK; ++ + if (flowlabel || + net->ipv6.sysctl.auto_flowlabels == IP6_AUTO_FLOW_LABEL_OFF || + (!autolabel && +diff --git a/include/uapi/linux/netfilter/nf_log.h b/include/uapi/linux/netfilter/nf_log.h +index 8be21e02387d..d0b5fa91ff54 100644 +--- a/include/uapi/linux/netfilter/nf_log.h ++++ b/include/uapi/linux/netfilter/nf_log.h +@@ -9,4 +9,6 @@ + #define NF_LOG_MACDECODE 0x20 /* Decode MAC header */ + #define NF_LOG_MASK 0x2f + ++#define NF_LOG_PREFIXLEN 128 ++ + #endif /* _NETFILTER_NF_LOG_H */ +diff --git a/kernel/Makefile b/kernel/Makefile +index eb26e12c6c2a..314e7d62f5f0 100644 +--- a/kernel/Makefile ++++ b/kernel/Makefile +@@ -84,6 +84,7 @@ obj-$(CONFIG_KPROBES) += kprobes.o + obj-$(CONFIG_KGDB) += debug/ + obj-$(CONFIG_DETECT_HUNG_TASK) += hung_task.o + obj-$(CONFIG_LOCKUP_DETECTOR) += watchdog.o ++obj-$(CONFIG_HARDLOCKUP_DETECTOR) += watchdog_hld.o + obj-$(CONFIG_SECCOMP) += seccomp.o + obj-$(CONFIG_RELAY) += relay.o + obj-$(CONFIG_SYSCTL) += utsname_sysctl.o +diff --git a/kernel/ucount.c b/kernel/ucount.c +index f4ac18509ecf..c761cdba2a2d 100644 +--- a/kernel/ucount.c ++++ b/kernel/ucount.c +@@ -231,11 +231,10 @@ static __init int user_namespace_sysctl_init(void) + * properly. + */ + user_header = register_sysctl("user", empty); ++ kmemleak_ignore(user_header); + BUG_ON(!user_header); + BUG_ON(!setup_userns_sysctls(&init_user_ns)); + #endif + return 0; + } + subsys_initcall(user_namespace_sysctl_init); +- +- +diff --git a/kernel/watchdog.c b/kernel/watchdog.c +index 6d1020c03d41..63177be0159e 100644 +--- a/kernel/watchdog.c ++++ b/kernel/watchdog.c +@@ -24,32 +24,14 @@ + + #include <asm/irq_regs.h> + #include <linux/kvm_para.h> +-#include <linux/perf_event.h> + #include <linux/kthread.h> + +-/* +- * The run state of the lockup detectors is controlled by the content of the +- * 'watchdog_enabled' variable. Each lockup detector has its dedicated bit - +- * bit 0 for the hard lockup detector and bit 1 for the soft lockup detector. +- * +- * 'watchdog_user_enabled', 'nmi_watchdog_enabled' and 'soft_watchdog_enabled' +- * are variables that are only used as an 'interface' between the parameters +- * in /proc/sys/kernel and the internal state bits in 'watchdog_enabled'. The +- * 'watchdog_thresh' variable is handled differently because its value is not +- * boolean, and the lockup detectors are 'suspended' while 'watchdog_thresh' +- * is equal zero. +- */ +-#define NMI_WATCHDOG_ENABLED_BIT 0 +-#define SOFT_WATCHDOG_ENABLED_BIT 1 +-#define NMI_WATCHDOG_ENABLED (1 << NMI_WATCHDOG_ENABLED_BIT) +-#define SOFT_WATCHDOG_ENABLED (1 << SOFT_WATCHDOG_ENABLED_BIT) +- + static DEFINE_MUTEX(watchdog_proc_mutex); + +-#ifdef CONFIG_HARDLOCKUP_DETECTOR +-static unsigned long __read_mostly watchdog_enabled = SOFT_WATCHDOG_ENABLED|NMI_WATCHDOG_ENABLED; ++#if defined(CONFIG_HAVE_NMI_WATCHDOG) || defined(CONFIG_HARDLOCKUP_DETECTOR) ++unsigned long __read_mostly watchdog_enabled = SOFT_WATCHDOG_ENABLED|NMI_WATCHDOG_ENABLED; + #else +-static unsigned long __read_mostly watchdog_enabled = SOFT_WATCHDOG_ENABLED; ++unsigned long __read_mostly watchdog_enabled = SOFT_WATCHDOG_ENABLED; + #endif + int __read_mostly nmi_watchdog_enabled; + int __read_mostly soft_watchdog_enabled; +@@ -59,9 +41,6 @@ int __read_mostly watchdog_thresh = 10; + #ifdef CONFIG_SMP + int __read_mostly sysctl_softlockup_all_cpu_backtrace; + int __read_mostly sysctl_hardlockup_all_cpu_backtrace; +-#else +-#define sysctl_softlockup_all_cpu_backtrace 0 +-#define sysctl_hardlockup_all_cpu_backtrace 0 + #endif + static struct cpumask watchdog_cpumask __read_mostly; + unsigned long *watchdog_cpumask_bits = cpumask_bits(&watchdog_cpumask); +@@ -70,6 +49,8 @@ unsigned long *watchdog_cpumask_bits = cpumask_bits(&watchdog_cpumask); + #define for_each_watchdog_cpu(cpu) \ + for_each_cpu_and((cpu), cpu_online_mask, &watchdog_cpumask) + ++atomic_t watchdog_park_in_progress = ATOMIC_INIT(0); ++ + /* + * The 'watchdog_running' variable is set to 1 when the watchdog threads + * are registered/started and is set to 0 when the watchdog threads are +@@ -100,50 +81,9 @@ static DEFINE_PER_CPU(bool, soft_watchdog_warn); + static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts); + static DEFINE_PER_CPU(unsigned long, soft_lockup_hrtimer_cnt); + static DEFINE_PER_CPU(struct task_struct *, softlockup_task_ptr_saved); +-#ifdef CONFIG_HARDLOCKUP_DETECTOR +-static DEFINE_PER_CPU(bool, hard_watchdog_warn); +-static DEFINE_PER_CPU(bool, watchdog_nmi_touch); + static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts_saved); +-static DEFINE_PER_CPU(struct perf_event *, watchdog_ev); +-#endif + static unsigned long soft_lockup_nmi_warn; + +-/* boot commands */ +-/* +- * Should we panic when a soft-lockup or hard-lockup occurs: +- */ +-#ifdef CONFIG_HARDLOCKUP_DETECTOR +-unsigned int __read_mostly hardlockup_panic = +- CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE; +-static unsigned long hardlockup_allcpu_dumped; +-/* +- * We may not want to enable hard lockup detection by default in all cases, +- * for example when running the kernel as a guest on a hypervisor. In these +- * cases this function can be called to disable hard lockup detection. This +- * function should only be executed once by the boot processor before the +- * kernel command line parameters are parsed, because otherwise it is not +- * possible to override this in hardlockup_panic_setup(). +- */ +-void hardlockup_detector_disable(void) +-{ +- watchdog_enabled &= ~NMI_WATCHDOG_ENABLED; +-} +- +-static int __init hardlockup_panic_setup(char *str) +-{ +- if (!strncmp(str, "panic", 5)) +- hardlockup_panic = 1; +- else if (!strncmp(str, "nopanic", 7)) +- hardlockup_panic = 0; +- else if (!strncmp(str, "0", 1)) +- watchdog_enabled &= ~NMI_WATCHDOG_ENABLED; +- else if (!strncmp(str, "1", 1)) +- watchdog_enabled |= NMI_WATCHDOG_ENABLED; +- return 1; +-} +-__setup("nmi_watchdog=", hardlockup_panic_setup); +-#endif +- + unsigned int __read_mostly softlockup_panic = + CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE; + +@@ -264,32 +204,14 @@ void touch_all_softlockup_watchdogs(void) + wq_watchdog_touch(-1); + } + +-#ifdef CONFIG_HARDLOCKUP_DETECTOR +-void touch_nmi_watchdog(void) +-{ +- /* +- * Using __raw here because some code paths have +- * preemption enabled. If preemption is enabled +- * then interrupts should be enabled too, in which +- * case we shouldn't have to worry about the watchdog +- * going off. +- */ +- raw_cpu_write(watchdog_nmi_touch, true); +- touch_softlockup_watchdog(); +-} +-EXPORT_SYMBOL(touch_nmi_watchdog); +- +-#endif +- + void touch_softlockup_watchdog_sync(void) + { + __this_cpu_write(softlockup_touch_sync, true); + __this_cpu_write(watchdog_touch_ts, 0); + } + +-#ifdef CONFIG_HARDLOCKUP_DETECTOR + /* watchdog detector functions */ +-static bool is_hardlockup(void) ++bool is_hardlockup(void) + { + unsigned long hrint = __this_cpu_read(hrtimer_interrupts); + +@@ -299,7 +221,6 @@ static bool is_hardlockup(void) + __this_cpu_write(hrtimer_interrupts_saved, hrint); + return false; + } +-#endif + + static int is_softlockup(unsigned long touch_ts) + { +@@ -313,77 +234,22 @@ static int is_softlockup(unsigned long touch_ts) + return 0; + } + +-#ifdef CONFIG_HARDLOCKUP_DETECTOR +- +-static struct perf_event_attr wd_hw_attr = { +- .type = PERF_TYPE_HARDWARE, +- .config = PERF_COUNT_HW_CPU_CYCLES, +- .size = sizeof(struct perf_event_attr), +- .pinned = 1, +- .disabled = 1, +-}; +- +-/* Callback function for perf event subsystem */ +-static void watchdog_overflow_callback(struct perf_event *event, +- struct perf_sample_data *data, +- struct pt_regs *regs) +-{ +- /* Ensure the watchdog never gets throttled */ +- event->hw.interrupts = 0; +- +- if (__this_cpu_read(watchdog_nmi_touch) == true) { +- __this_cpu_write(watchdog_nmi_touch, false); +- return; +- } +- +- /* check for a hardlockup +- * This is done by making sure our timer interrupt +- * is incrementing. The timer interrupt should have +- * fired multiple times before we overflow'd. If it hasn't +- * then this is a good indication the cpu is stuck +- */ +- if (is_hardlockup()) { +- int this_cpu = smp_processor_id(); +- +- /* only print hardlockups once */ +- if (__this_cpu_read(hard_watchdog_warn) == true) +- return; +- +- pr_emerg("Watchdog detected hard LOCKUP on cpu %d", this_cpu); +- print_modules(); +- print_irqtrace_events(current); +- if (regs) +- show_regs(regs); +- else +- dump_stack(); +- +- /* +- * Perform all-CPU dump only once to avoid multiple hardlockups +- * generating interleaving traces +- */ +- if (sysctl_hardlockup_all_cpu_backtrace && +- !test_and_set_bit(0, &hardlockup_allcpu_dumped)) +- trigger_allbutself_cpu_backtrace(); +- +- if (hardlockup_panic) +- nmi_panic(regs, "Hard LOCKUP"); +- +- __this_cpu_write(hard_watchdog_warn, true); +- return; +- } +- +- __this_cpu_write(hard_watchdog_warn, false); +- return; +-} +-#endif /* CONFIG_HARDLOCKUP_DETECTOR */ +- + static void watchdog_interrupt_count(void) + { + __this_cpu_inc(hrtimer_interrupts); + } + +-static int watchdog_nmi_enable(unsigned int cpu); +-static void watchdog_nmi_disable(unsigned int cpu); ++/* ++ * These two functions are mostly architecture specific ++ * defining them as weak here. ++ */ ++int __weak watchdog_nmi_enable(unsigned int cpu) ++{ ++ return 0; ++} ++void __weak watchdog_nmi_disable(unsigned int cpu) ++{ ++} + + static int watchdog_enable_all_cpus(void); + static void watchdog_disable_all_cpus(void); +@@ -396,6 +262,9 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer) + int duration; + int softlockup_all_cpu_backtrace = sysctl_softlockup_all_cpu_backtrace; + ++ if (atomic_read(&watchdog_park_in_progress) != 0) ++ return HRTIMER_NORESTART; ++ + /* kick the hardlockup detector */ + watchdog_interrupt_count(); + +@@ -576,109 +445,6 @@ static void watchdog(unsigned int cpu) + watchdog_nmi_disable(cpu); + } + +-#ifdef CONFIG_HARDLOCKUP_DETECTOR +-/* +- * People like the simple clean cpu node info on boot. +- * Reduce the watchdog noise by only printing messages +- * that are different from what cpu0 displayed. +- */ +-static unsigned long cpu0_err; +- +-static int watchdog_nmi_enable(unsigned int cpu) +-{ +- struct perf_event_attr *wd_attr; +- struct perf_event *event = per_cpu(watchdog_ev, cpu); +- +- /* nothing to do if the hard lockup detector is disabled */ +- if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED)) +- goto out; +- +- /* is it already setup and enabled? */ +- if (event && event->state > PERF_EVENT_STATE_OFF) +- goto out; +- +- /* it is setup but not enabled */ +- if (event != NULL) +- goto out_enable; +- +- wd_attr = &wd_hw_attr; +- wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh); +- +- /* Try to register using hardware perf events */ +- event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback, NULL); +- +- /* save cpu0 error for future comparision */ +- if (cpu == 0 && IS_ERR(event)) +- cpu0_err = PTR_ERR(event); +- +- if (!IS_ERR(event)) { +- /* only print for cpu0 or different than cpu0 */ +- if (cpu == 0 || cpu0_err) +- pr_info("enabled on all CPUs, permanently consumes one hw-PMU counter.\n"); +- goto out_save; +- } +- +- /* +- * Disable the hard lockup detector if _any_ CPU fails to set up +- * set up the hardware perf event. The watchdog() function checks +- * the NMI_WATCHDOG_ENABLED bit periodically. +- * +- * The barriers are for syncing up watchdog_enabled across all the +- * cpus, as clear_bit() does not use barriers. +- */ +- smp_mb__before_atomic(); +- clear_bit(NMI_WATCHDOG_ENABLED_BIT, &watchdog_enabled); +- smp_mb__after_atomic(); +- +- /* skip displaying the same error again */ +- if (cpu > 0 && (PTR_ERR(event) == cpu0_err)) +- return PTR_ERR(event); +- +- /* vary the KERN level based on the returned errno */ +- if (PTR_ERR(event) == -EOPNOTSUPP) +- pr_info("disabled (cpu%i): not supported (no LAPIC?)\n", cpu); +- else if (PTR_ERR(event) == -ENOENT) +- pr_warn("disabled (cpu%i): hardware events not enabled\n", +- cpu); +- else +- pr_err("disabled (cpu%i): unable to create perf event: %ld\n", +- cpu, PTR_ERR(event)); +- +- pr_info("Shutting down hard lockup detector on all cpus\n"); +- +- return PTR_ERR(event); +- +- /* success path */ +-out_save: +- per_cpu(watchdog_ev, cpu) = event; +-out_enable: +- perf_event_enable(per_cpu(watchdog_ev, cpu)); +-out: +- return 0; +-} +- +-static void watchdog_nmi_disable(unsigned int cpu) +-{ +- struct perf_event *event = per_cpu(watchdog_ev, cpu); +- +- if (event) { +- perf_event_disable(event); +- per_cpu(watchdog_ev, cpu) = NULL; +- +- /* should be in cleanup, but blocks oprofile */ +- perf_event_release_kernel(event); +- } +- if (cpu == 0) { +- /* watchdog_nmi_enable() expects this to be zero initially. */ +- cpu0_err = 0; +- } +-} +- +-#else +-static int watchdog_nmi_enable(unsigned int cpu) { return 0; } +-static void watchdog_nmi_disable(unsigned int cpu) { return; } +-#endif /* CONFIG_HARDLOCKUP_DETECTOR */ +- + static struct smp_hotplug_thread watchdog_threads = { + .store = &softlockup_watchdog, + .thread_should_run = watchdog_should_run, +@@ -706,12 +472,16 @@ static int watchdog_park_threads(void) + { + int cpu, ret = 0; + ++ atomic_set(&watchdog_park_in_progress, 1); ++ + for_each_watchdog_cpu(cpu) { + ret = kthread_park(per_cpu(softlockup_watchdog, cpu)); + if (ret) + break; + } + ++ atomic_set(&watchdog_park_in_progress, 0); ++ + return ret; + } + +diff --git a/kernel/watchdog_hld.c b/kernel/watchdog_hld.c +new file mode 100644 +index 000000000000..12b8dd640786 +--- /dev/null ++++ b/kernel/watchdog_hld.c +@@ -0,0 +1,230 @@ ++/* ++ * Detect hard lockups on a system ++ * ++ * started by Don Zickus, Copyright (C) 2010 Red Hat, Inc. ++ * ++ * Note: Most of this code is borrowed heavily from the original softlockup ++ * detector, so thanks to Ingo for the initial implementation. ++ * Some chunks also taken from the old x86-specific nmi watchdog code, thanks ++ * to those contributors as well. ++ */ ++ ++#define pr_fmt(fmt) "NMI watchdog: " fmt ++ ++#include <linux/nmi.h> ++#include <linux/module.h> ++#include <asm/irq_regs.h> ++#include <linux/perf_event.h> ++ ++static DEFINE_PER_CPU(bool, hard_watchdog_warn); ++static DEFINE_PER_CPU(bool, watchdog_nmi_touch); ++static DEFINE_PER_CPU(struct perf_event *, watchdog_ev); ++ ++/* boot commands */ ++/* ++ * Should we panic when a soft-lockup or hard-lockup occurs: ++ */ ++unsigned int __read_mostly hardlockup_panic = ++ CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE; ++static unsigned long hardlockup_allcpu_dumped; ++/* ++ * We may not want to enable hard lockup detection by default in all cases, ++ * for example when running the kernel as a guest on a hypervisor. In these ++ * cases this function can be called to disable hard lockup detection. This ++ * function should only be executed once by the boot processor before the ++ * kernel command line parameters are parsed, because otherwise it is not ++ * possible to override this in hardlockup_panic_setup(). ++ */ ++void hardlockup_detector_disable(void) ++{ ++ watchdog_enabled &= ~NMI_WATCHDOG_ENABLED; ++} ++ ++static int __init hardlockup_panic_setup(char *str) ++{ ++ if (!strncmp(str, "panic", 5)) ++ hardlockup_panic = 1; ++ else if (!strncmp(str, "nopanic", 7)) ++ hardlockup_panic = 0; ++ else if (!strncmp(str, "0", 1)) ++ watchdog_enabled &= ~NMI_WATCHDOG_ENABLED; ++ else if (!strncmp(str, "1", 1)) ++ watchdog_enabled |= NMI_WATCHDOG_ENABLED; ++ return 1; ++} ++__setup("nmi_watchdog=", hardlockup_panic_setup); ++ ++void touch_nmi_watchdog(void) ++{ ++ /* ++ * Using __raw here because some code paths have ++ * preemption enabled. If preemption is enabled ++ * then interrupts should be enabled too, in which ++ * case we shouldn't have to worry about the watchdog ++ * going off. ++ */ ++ raw_cpu_write(watchdog_nmi_touch, true); ++ touch_softlockup_watchdog(); ++} ++EXPORT_SYMBOL(touch_nmi_watchdog); ++ ++static struct perf_event_attr wd_hw_attr = { ++ .type = PERF_TYPE_HARDWARE, ++ .config = PERF_COUNT_HW_CPU_CYCLES, ++ .size = sizeof(struct perf_event_attr), ++ .pinned = 1, ++ .disabled = 1, ++}; ++ ++/* Callback function for perf event subsystem */ ++static void watchdog_overflow_callback(struct perf_event *event, ++ struct perf_sample_data *data, ++ struct pt_regs *regs) ++{ ++ /* Ensure the watchdog never gets throttled */ ++ event->hw.interrupts = 0; ++ ++ if (atomic_read(&watchdog_park_in_progress) != 0) ++ return; ++ ++ if (__this_cpu_read(watchdog_nmi_touch) == true) { ++ __this_cpu_write(watchdog_nmi_touch, false); ++ return; ++ } ++ ++ /* check for a hardlockup ++ * This is done by making sure our timer interrupt ++ * is incrementing. The timer interrupt should have ++ * fired multiple times before we overflow'd. If it hasn't ++ * then this is a good indication the cpu is stuck ++ */ ++ if (is_hardlockup()) { ++ int this_cpu = smp_processor_id(); ++ ++ /* only print hardlockups once */ ++ if (__this_cpu_read(hard_watchdog_warn) == true) ++ return; ++ ++ pr_emerg("Watchdog detected hard LOCKUP on cpu %d", this_cpu); ++ print_modules(); ++ print_irqtrace_events(current); ++ if (regs) ++ show_regs(regs); ++ else ++ dump_stack(); ++ ++ /* ++ * Perform all-CPU dump only once to avoid multiple hardlockups ++ * generating interleaving traces ++ */ ++ if (sysctl_hardlockup_all_cpu_backtrace && ++ !test_and_set_bit(0, &hardlockup_allcpu_dumped)) ++ trigger_allbutself_cpu_backtrace(); ++ ++ if (hardlockup_panic) ++ nmi_panic(regs, "Hard LOCKUP"); ++ ++ __this_cpu_write(hard_watchdog_warn, true); ++ return; ++ } ++ ++ __this_cpu_write(hard_watchdog_warn, false); ++ return; ++} ++ ++/* ++ * People like the simple clean cpu node info on boot. ++ * Reduce the watchdog noise by only printing messages ++ * that are different from what cpu0 displayed. ++ */ ++static unsigned long cpu0_err; ++ ++int watchdog_nmi_enable(unsigned int cpu) ++{ ++ struct perf_event_attr *wd_attr; ++ struct perf_event *event = per_cpu(watchdog_ev, cpu); ++ ++ /* nothing to do if the hard lockup detector is disabled */ ++ if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED)) ++ goto out; ++ ++ /* is it already setup and enabled? */ ++ if (event && event->state > PERF_EVENT_STATE_OFF) ++ goto out; ++ ++ /* it is setup but not enabled */ ++ if (event != NULL) ++ goto out_enable; ++ ++ wd_attr = &wd_hw_attr; ++ wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh); ++ ++ /* Try to register using hardware perf events */ ++ event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback, NULL); ++ ++ /* save cpu0 error for future comparision */ ++ if (cpu == 0 && IS_ERR(event)) ++ cpu0_err = PTR_ERR(event); ++ ++ if (!IS_ERR(event)) { ++ /* only print for cpu0 or different than cpu0 */ ++ if (cpu == 0 || cpu0_err) ++ pr_info("enabled on all CPUs, permanently consumes one hw-PMU counter.\n"); ++ goto out_save; ++ } ++ ++ /* ++ * Disable the hard lockup detector if _any_ CPU fails to set up ++ * set up the hardware perf event. The watchdog() function checks ++ * the NMI_WATCHDOG_ENABLED bit periodically. ++ * ++ * The barriers are for syncing up watchdog_enabled across all the ++ * cpus, as clear_bit() does not use barriers. ++ */ ++ smp_mb__before_atomic(); ++ clear_bit(NMI_WATCHDOG_ENABLED_BIT, &watchdog_enabled); ++ smp_mb__after_atomic(); ++ ++ /* skip displaying the same error again */ ++ if (cpu > 0 && (PTR_ERR(event) == cpu0_err)) ++ return PTR_ERR(event); ++ ++ /* vary the KERN level based on the returned errno */ ++ if (PTR_ERR(event) == -EOPNOTSUPP) ++ pr_info("disabled (cpu%i): not supported (no LAPIC?)\n", cpu); ++ else if (PTR_ERR(event) == -ENOENT) ++ pr_warn("disabled (cpu%i): hardware events not enabled\n", ++ cpu); ++ else ++ pr_err("disabled (cpu%i): unable to create perf event: %ld\n", ++ cpu, PTR_ERR(event)); ++ ++ pr_info("Shutting down hard lockup detector on all cpus\n"); ++ ++ return PTR_ERR(event); ++ ++ /* success path */ ++out_save: ++ per_cpu(watchdog_ev, cpu) = event; ++out_enable: ++ perf_event_enable(per_cpu(watchdog_ev, cpu)); ++out: ++ return 0; ++} ++ ++void watchdog_nmi_disable(unsigned int cpu) ++{ ++ struct perf_event *event = per_cpu(watchdog_ev, cpu); ++ ++ if (event) { ++ perf_event_disable(event); ++ per_cpu(watchdog_ev, cpu) = NULL; ++ ++ /* should be in cleanup, but blocks oprofile */ ++ perf_event_release_kernel(event); ++ } ++ if (cpu == 0) { ++ /* watchdog_nmi_enable() expects this to be zero initially. */ ++ cpu0_err = 0; ++ } ++} +diff --git a/mm/kasan/report.c b/mm/kasan/report.c +index 073325aedc68..8ca412aebcf1 100644 +--- a/mm/kasan/report.c ++++ b/mm/kasan/report.c +@@ -13,6 +13,7 @@ + * + */ + ++#include <linux/ftrace.h> + #include <linux/kernel.h> + #include <linux/mm.h> + #include <linux/printk.h> +@@ -298,6 +299,8 @@ void kasan_report(unsigned long addr, size_t size, + if (likely(!kasan_report_enabled())) + return; + ++ disable_trace_on_warning(); ++ + info.access_addr = (void *)addr; + info.access_size = size; + info.is_write = is_write; +diff --git a/mm/shmem.c b/mm/shmem.c +index 9d32e1cb9f38..d99cfb6eb03a 100644 +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -412,6 +412,7 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo, + struct shrink_control *sc, unsigned long nr_to_split) + { + LIST_HEAD(list), *pos, *next; ++ LIST_HEAD(to_remove); + struct inode *inode; + struct shmem_inode_info *info; + struct page *page; +@@ -438,9 +439,8 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo, + /* Check if there's anything to gain */ + if (round_up(inode->i_size, PAGE_SIZE) == + round_up(inode->i_size, HPAGE_PMD_SIZE)) { +- list_del_init(&info->shrinklist); ++ list_move(&info->shrinklist, &to_remove); + removed++; +- iput(inode); + goto next; + } + +@@ -451,6 +451,13 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo, + } + spin_unlock(&sbinfo->shrinklist_lock); + ++ list_for_each_safe(pos, next, &to_remove) { ++ info = list_entry(pos, struct shmem_inode_info, shrinklist); ++ inode = &info->vfs_inode; ++ list_del_init(&info->shrinklist); ++ iput(inode); ++ } ++ + list_for_each_safe(pos, next, &list) { + int ret; + +diff --git a/net/core/ethtool.c b/net/core/ethtool.c +index 047a1752ece1..072c1f4998c9 100644 +--- a/net/core/ethtool.c ++++ b/net/core/ethtool.c +@@ -1394,9 +1394,12 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) + if (regs.len > reglen) + regs.len = reglen; + +- regbuf = vzalloc(reglen); +- if (reglen && !regbuf) +- return -ENOMEM; ++ regbuf = NULL; ++ if (reglen) { ++ regbuf = vzalloc(reglen); ++ if (!regbuf) ++ return -ENOMEM; ++ } + + ops->get_regs(dev, ®s, regbuf); + +diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c +index 89a8cac4726a..51b27ae09fbd 100644 +--- a/net/ipv4/arp.c ++++ b/net/ipv4/arp.c +@@ -1263,7 +1263,7 @@ void __init arp_init(void) + /* + * ax25 -> ASCII conversion + */ +-static char *ax2asc2(ax25_address *a, char *buf) ++static void ax2asc2(ax25_address *a, char *buf) + { + char c, *s; + int n; +@@ -1285,10 +1285,10 @@ static char *ax2asc2(ax25_address *a, char *buf) + *s++ = n + '0'; + *s++ = '\0'; + +- if (*buf == '\0' || *buf == '-') +- return "*"; +- +- return buf; ++ if (*buf == '\0' || *buf == '-') { ++ buf[0] = '*'; ++ buf[1] = '\0'; ++ } + } + #endif /* CONFIG_AX25 */ + +@@ -1322,7 +1322,7 @@ static void arp_format_neigh_entry(struct seq_file *seq, + } + #endif + sprintf(tbuf, "%pI4", n->primary_key); +- seq_printf(seq, "%-16s 0x%-10x0x%-10x%s * %s\n", ++ seq_printf(seq, "%-16s 0x%-10x0x%-10x%-17s * %s\n", + tbuf, hatype, arp_state_to_flags(n), hbuffer, dev->name); + read_unlock(&n->lock); + } +diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c +index f6c50af24a64..3d063eb37848 100644 +--- a/net/ipv4/tcp_probe.c ++++ b/net/ipv4/tcp_probe.c +@@ -117,7 +117,7 @@ static void jtcp_rcv_established(struct sock *sk, struct sk_buff *skb, + (fwmark > 0 && skb->mark == fwmark)) && + (full || tp->snd_cwnd != tcp_probe.lastcwnd)) { + +- spin_lock(&tcp_probe.lock); ++ spin_lock_bh(&tcp_probe.lock); + /* If log fills, just silently drop */ + if (tcp_probe_avail() > 1) { + struct tcp_log *p = tcp_probe.log + tcp_probe.head; +@@ -157,7 +157,7 @@ static void jtcp_rcv_established(struct sock *sk, struct sk_buff *skb, + tcp_probe.head = (tcp_probe.head + 1) & (bufsize - 1); + } + tcp_probe.lastcwnd = tp->snd_cwnd; +- spin_unlock(&tcp_probe.lock); ++ spin_unlock_bh(&tcp_probe.lock); + + wake_up(&tcp_probe.wait); + } +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index f088a1d9a618..045738319e8b 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -3387,9 +3387,15 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, + } + + if (idev) { +- if (idev->if_flags & IF_READY) +- /* device is already configured. */ ++ if (idev->if_flags & IF_READY) { ++ /* device is already configured - ++ * but resend MLD reports, we might ++ * have roamed and need to update ++ * multicast snooping switches ++ */ ++ ipv6_mc_up(idev); + break; ++ } + idev->if_flags |= IF_READY; + } + +@@ -4004,6 +4010,12 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp, bool bump_id) + + if (bump_id) + rt_genid_bump_ipv6(dev_net(dev)); ++ ++ /* Make sure that a new temporary address will be created ++ * before this temporary address becomes deprecated. ++ */ ++ if (ifp->flags & IFA_F_TEMPORARY) ++ addrconf_verify_rtnl(); + } + + static void addrconf_dad_run(struct inet6_dev *idev) +diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c +index 442ec1f39ed1..38062f403ceb 100644 +--- a/net/ipv6/datagram.c ++++ b/net/ipv6/datagram.c +@@ -166,18 +166,22 @@ int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, + if (np->sndflow) + fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK; + +- addr_type = ipv6_addr_type(&usin->sin6_addr); +- +- if (addr_type == IPV6_ADDR_ANY) { ++ if (ipv6_addr_any(&usin->sin6_addr)) { + /* + * connect to self + */ +- usin->sin6_addr.s6_addr[15] = 0x01; ++ if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr)) ++ ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK), ++ &usin->sin6_addr); ++ else ++ usin->sin6_addr = in6addr_loopback; + } + ++ addr_type = ipv6_addr_type(&usin->sin6_addr); ++ + daddr = &usin->sin6_addr; + +- if (addr_type == IPV6_ADDR_MAPPED) { ++ if (addr_type & IPV6_ADDR_MAPPED) { + struct sockaddr_in sin; + + if (__ipv6_only_sock(sk)) { +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index 1ac3cea49171..3ab32ac57ccd 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1019,6 +1019,9 @@ static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk, + } + } + #endif ++ if (ipv6_addr_v4mapped(&fl6->saddr) && ++ !(ipv6_addr_v4mapped(&fl6->daddr) || ipv6_addr_any(&fl6->daddr))) ++ return -EAFNOSUPPORT; + + return 0; + +diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c +index aef9b28067f4..7ac2365aa6fb 100644 +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -148,8 +148,13 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, + * connect() to INADDR_ANY means loopback (BSD'ism). + */ + +- if (ipv6_addr_any(&usin->sin6_addr)) +- usin->sin6_addr.s6_addr[15] = 0x1; ++ if (ipv6_addr_any(&usin->sin6_addr)) { ++ if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr)) ++ ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK), ++ &usin->sin6_addr); ++ else ++ usin->sin6_addr = in6addr_loopback; ++ } + + addr_type = ipv6_addr_type(&usin->sin6_addr); + +@@ -188,7 +193,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, + * TCP over IPv4 + */ + +- if (addr_type == IPV6_ADDR_MAPPED) { ++ if (addr_type & IPV6_ADDR_MAPPED) { + u32 exthdrlen = icsk->icsk_ext_hdr_len; + struct sockaddr_in sin; + +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index 40a289f78d77..2497f62fa4c2 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -1049,6 +1049,10 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + if (addr_len < SIN6_LEN_RFC2133) + return -EINVAL; + daddr = &sin6->sin6_addr; ++ if (ipv6_addr_any(daddr) && ++ ipv6_addr_v4mapped(&np->saddr)) ++ ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK), ++ daddr); + break; + case AF_INET: + goto do_udp_sendmsg; +diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c +index c3fc14e021ec..3a8dc39a9116 100644 +--- a/net/netfilter/nf_conntrack_sip.c ++++ b/net/netfilter/nf_conntrack_sip.c +@@ -1630,8 +1630,6 @@ static int __init nf_conntrack_sip_init(void) + ports[ports_c++] = SIP_PORT; + + for (i = 0; i < ports_c; i++) { +- memset(&sip[i], 0, sizeof(sip[i])); +- + nf_ct_helper_init(&sip[4 * i], AF_INET, IPPROTO_UDP, "sip", + SIP_PORT, ports[i], i, sip_exp_policy, + SIP_EXPECT_MAX, +diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c +index 3dca90dc24ad..ffb9e8ada899 100644 +--- a/net/netfilter/nf_log.c ++++ b/net/netfilter/nf_log.c +@@ -13,7 +13,6 @@ + /* Internal logging interface, which relies on the real + LOG target modules */ + +-#define NF_LOG_PREFIXLEN 128 + #define NFLOGGER_NAME_LEN 64 + + static struct nf_logger __rcu *loggers[NFPROTO_NUMPROTO][NF_LOG_TYPE_MAX] __read_mostly; +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index e5194f6f906c..778fcdb83225 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -3637,10 +3637,18 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, + goto err5; + } + ++ if (set->size && ++ !atomic_add_unless(&set->nelems, 1, set->size + set->ndeact)) { ++ err = -ENFILE; ++ goto err6; ++ } ++ + nft_trans_elem(trans) = elem; + list_add_tail(&trans->list, &ctx->net->nft.commit_list); + return 0; + ++err6: ++ set->ops->remove(set, &elem); + err5: + kfree(trans); + err4: +@@ -3687,15 +3695,9 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk, + return -EBUSY; + + nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) { +- if (set->size && +- !atomic_add_unless(&set->nelems, 1, set->size + set->ndeact)) +- return -ENFILE; +- + err = nft_add_set_elem(&ctx, set, attr, nlh->nlmsg_flags); +- if (err < 0) { +- atomic_dec(&set->nelems); ++ if (err < 0) + break; +- } + } + return err; + } +diff --git a/net/netfilter/nft_log.c b/net/netfilter/nft_log.c +index 1b01404bb33f..c7704e9123ef 100644 +--- a/net/netfilter/nft_log.c ++++ b/net/netfilter/nft_log.c +@@ -38,7 +38,8 @@ static void nft_log_eval(const struct nft_expr *expr, + + static const struct nla_policy nft_log_policy[NFTA_LOG_MAX + 1] = { + [NFTA_LOG_GROUP] = { .type = NLA_U16 }, +- [NFTA_LOG_PREFIX] = { .type = NLA_STRING }, ++ [NFTA_LOG_PREFIX] = { .type = NLA_STRING, ++ .len = NF_LOG_PREFIXLEN - 1 }, + [NFTA_LOG_SNAPLEN] = { .type = NLA_U32 }, + [NFTA_LOG_QTHRESHOLD] = { .type = NLA_U16 }, + [NFTA_LOG_LEVEL] = { .type = NLA_U32 }, +diff --git a/net/sctp/offload.c b/net/sctp/offload.c +index 7e869d0cca69..4f5a2b580aa5 100644 +--- a/net/sctp/offload.c ++++ b/net/sctp/offload.c +@@ -68,7 +68,7 @@ static struct sk_buff *sctp_gso_segment(struct sk_buff *skb, + goto out; + } + +- segs = skb_segment(skb, features | NETIF_F_HW_CSUM); ++ segs = skb_segment(skb, features | NETIF_F_HW_CSUM | NETIF_F_SG); + if (IS_ERR(segs)) + goto out; + +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index 14346dccc4fe..e1719c695174 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -235,8 +235,12 @@ static struct sctp_transport *sctp_addr_id2transport(struct sock *sk, + sctp_assoc_t id) + { + struct sctp_association *addr_asoc = NULL, *id_asoc = NULL; +- struct sctp_transport *transport; ++ struct sctp_af *af = sctp_get_af_specific(addr->ss_family); + union sctp_addr *laddr = (union sctp_addr *)addr; ++ struct sctp_transport *transport; ++ ++ if (sctp_verify_addr(sk, laddr, af->sockaddr_len)) ++ return NULL; + + addr_asoc = sctp_endpoint_lookup_assoc(sctp_sk(sk)->ep, + laddr, +diff --git a/net/tipc/net.c b/net/tipc/net.c +index 28bf4feeb81c..ab8a2d5d1e32 100644 +--- a/net/tipc/net.c ++++ b/net/tipc/net.c +@@ -110,6 +110,10 @@ int tipc_net_start(struct net *net, u32 addr) + char addr_string[16]; + + tn->own_addr = addr; ++ ++ /* Ensure that the new address is visible before we reinit. */ ++ smp_mb(); ++ + tipc_named_reinit(net); + tipc_sk_reinit(net); + +diff --git a/net/tipc/node.c b/net/tipc/node.c +index 9d2f4c2b08ab..27753325e06e 100644 +--- a/net/tipc/node.c ++++ b/net/tipc/node.c +@@ -263,6 +263,11 @@ static void tipc_node_write_lock(struct tipc_node *n) + write_lock_bh(&n->lock); + } + ++static void tipc_node_write_unlock_fast(struct tipc_node *n) ++{ ++ write_unlock_bh(&n->lock); ++} ++ + static void tipc_node_write_unlock(struct tipc_node *n) + { + struct net *net = n->net; +@@ -417,7 +422,7 @@ void tipc_node_subscribe(struct net *net, struct list_head *subscr, u32 addr) + } + tipc_node_write_lock(n); + list_add_tail(subscr, &n->publ_list); +- tipc_node_write_unlock(n); ++ tipc_node_write_unlock_fast(n); + tipc_node_put(n); + } + +@@ -435,7 +440,7 @@ void tipc_node_unsubscribe(struct net *net, struct list_head *subscr, u32 addr) + } + tipc_node_write_lock(n); + list_del_init(subscr); +- tipc_node_write_unlock(n); ++ tipc_node_write_unlock_fast(n); + tipc_node_put(n); + } + +diff --git a/net/tipc/server.c b/net/tipc/server.c +index 215849ce453d..f89c0c2e8c16 100644 +--- a/net/tipc/server.c ++++ b/net/tipc/server.c +@@ -91,7 +91,8 @@ static void tipc_sock_release(struct tipc_conn *con); + static void tipc_conn_kref_release(struct kref *kref) + { + struct tipc_conn *con = container_of(kref, struct tipc_conn, kref); +- struct sockaddr_tipc *saddr = con->server->saddr; ++ struct tipc_server *s = con->server; ++ struct sockaddr_tipc *saddr = s->saddr; + struct socket *sock = con->sock; + struct sock *sk; + +@@ -106,6 +107,11 @@ static void tipc_conn_kref_release(struct kref *kref) + tipc_sock_release(con); + sock_release(sock); + con->sock = NULL; ++ ++ spin_lock_bh(&s->idr_lock); ++ idr_remove(&s->conn_idr, con->conid); ++ s->idr_in_use--; ++ spin_unlock_bh(&s->idr_lock); + } + + tipc_clean_outqueues(con); +@@ -128,8 +134,10 @@ static struct tipc_conn *tipc_conn_lookup(struct tipc_server *s, int conid) + + spin_lock_bh(&s->idr_lock); + con = idr_find(&s->conn_idr, conid); +- if (con) ++ if (con && test_bit(CF_CONNECTED, &con->flags)) + conn_get(con); ++ else ++ con = NULL; + spin_unlock_bh(&s->idr_lock); + return con; + } +@@ -198,15 +206,8 @@ static void tipc_sock_release(struct tipc_conn *con) + + static void tipc_close_conn(struct tipc_conn *con) + { +- struct tipc_server *s = con->server; +- + if (test_and_clear_bit(CF_CONNECTED, &con->flags)) { + +- spin_lock_bh(&s->idr_lock); +- idr_remove(&s->conn_idr, con->conid); +- s->idr_in_use--; +- spin_unlock_bh(&s->idr_lock); +- + /* We shouldn't flush pending works as we may be in the + * thread. In fact the races with pending rx/tx work structs + * are harmless for us here as we have already deleted this +@@ -458,6 +459,11 @@ int tipc_conn_sendmsg(struct tipc_server *s, int conid, + if (!con) + return -EINVAL; + ++ if (!test_bit(CF_CONNECTED, &con->flags)) { ++ conn_put(con); ++ return 0; ++ } ++ + e = tipc_alloc_entry(data, len); + if (!e) { + conn_put(con); +@@ -471,12 +477,8 @@ int tipc_conn_sendmsg(struct tipc_server *s, int conid, + list_add_tail(&e->list, &con->outqueue); + spin_unlock_bh(&con->outqueue_lock); + +- if (test_bit(CF_CONNECTED, &con->flags)) { +- if (!queue_work(s->send_wq, &con->swork)) +- conn_put(con); +- } else { ++ if (!queue_work(s->send_wq, &con->swork)) + conn_put(con); +- } + return 0; + } + +@@ -500,7 +502,7 @@ static void tipc_send_to_sock(struct tipc_conn *con) + int ret; + + spin_lock_bh(&con->outqueue_lock); +- while (1) { ++ while (test_bit(CF_CONNECTED, &con->flags)) { + e = list_entry(con->outqueue.next, struct outqueue_entry, + list); + if ((struct list_head *) e == &con->outqueue) +diff --git a/net/tipc/socket.c b/net/tipc/socket.c +index 41f013888f07..25bc5c30d7fb 100644 +--- a/net/tipc/socket.c ++++ b/net/tipc/socket.c +@@ -335,8 +335,6 @@ static int tipc_sk_create(struct net *net, struct socket *sock, + INIT_LIST_HEAD(&tsk->publications); + msg = &tsk->phdr; + tn = net_generic(sock_net(sk), tipc_net_id); +- tipc_msg_init(tn->own_addr, msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG, +- NAMED_H_SIZE, 0); + + /* Finish initializing socket data structures */ + sock->ops = ops; +@@ -346,6 +344,13 @@ static int tipc_sk_create(struct net *net, struct socket *sock, + pr_warn("Socket create failed; port number exhausted\n"); + return -EINVAL; + } ++ ++ /* Ensure tsk is visible before we read own_addr. */ ++ smp_mb(); ++ ++ tipc_msg_init(tn->own_addr, msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG, ++ NAMED_H_SIZE, 0); ++ + msg_set_origport(msg, tsk->portid); + setup_timer(&sk->sk_timer, tipc_sk_timeout, (unsigned long)tsk); + sk->sk_backlog_rcv = tipc_backlog_rcv; +@@ -2264,24 +2269,27 @@ static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope, + void tipc_sk_reinit(struct net *net) + { + struct tipc_net *tn = net_generic(net, tipc_net_id); +- const struct bucket_table *tbl; +- struct rhash_head *pos; ++ struct rhashtable_iter iter; + struct tipc_sock *tsk; + struct tipc_msg *msg; +- int i; + +- rcu_read_lock(); +- tbl = rht_dereference_rcu((&tn->sk_rht)->tbl, &tn->sk_rht); +- for (i = 0; i < tbl->size; i++) { +- rht_for_each_entry_rcu(tsk, pos, tbl, i, node) { ++ rhashtable_walk_enter(&tn->sk_rht, &iter); ++ ++ do { ++ tsk = ERR_PTR(rhashtable_walk_start(&iter)); ++ if (tsk) ++ continue; ++ ++ while ((tsk = rhashtable_walk_next(&iter)) && !IS_ERR(tsk)) { + spin_lock_bh(&tsk->sk.sk_lock.slock); + msg = &tsk->phdr; + msg_set_prevnode(msg, tn->own_addr); + msg_set_orignode(msg, tn->own_addr); + spin_unlock_bh(&tsk->sk.sk_lock.slock); + } +- } +- rcu_read_unlock(); ++ ++ rhashtable_walk_stop(&iter); ++ } while (tsk == ERR_PTR(-EAGAIN)); + } + + static struct tipc_sock *tipc_sk_lookup(struct net *net, u32 portid) +diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c +index 0dd02244e21d..9d94e65d0894 100644 +--- a/net/tipc/subscr.c ++++ b/net/tipc/subscr.c +@@ -54,6 +54,8 @@ struct tipc_subscriber { + + static void tipc_subscrp_delete(struct tipc_subscription *sub); + static void tipc_subscrb_put(struct tipc_subscriber *subscriber); ++static void tipc_subscrp_put(struct tipc_subscription *subscription); ++static void tipc_subscrp_get(struct tipc_subscription *subscription); + + /** + * htohl - convert value to endianness used by destination +@@ -123,6 +125,7 @@ void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower, + { + struct tipc_name_seq seq; + ++ tipc_subscrp_get(sub); + tipc_subscrp_convert_seq(&sub->evt.s.seq, sub->swap, &seq); + if (!tipc_subscrp_check_overlap(&seq, found_lower, found_upper)) + return; +@@ -132,30 +135,23 @@ void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower, + + tipc_subscrp_send_event(sub, found_lower, found_upper, event, port_ref, + node); ++ tipc_subscrp_put(sub); + } + + static void tipc_subscrp_timeout(unsigned long data) + { + struct tipc_subscription *sub = (struct tipc_subscription *)data; +- struct tipc_subscriber *subscriber = sub->subscriber; + + /* Notify subscriber of timeout */ + tipc_subscrp_send_event(sub, sub->evt.s.seq.lower, sub->evt.s.seq.upper, + TIPC_SUBSCR_TIMEOUT, 0, 0); + +- spin_lock_bh(&subscriber->lock); +- tipc_subscrp_delete(sub); +- spin_unlock_bh(&subscriber->lock); +- +- tipc_subscrb_put(subscriber); ++ tipc_subscrp_put(sub); + } + + static void tipc_subscrb_kref_release(struct kref *kref) + { +- struct tipc_subscriber *subcriber = container_of(kref, +- struct tipc_subscriber, kref); +- +- kfree(subcriber); ++ kfree(container_of(kref,struct tipc_subscriber, kref)); + } + + static void tipc_subscrb_put(struct tipc_subscriber *subscriber) +@@ -168,6 +164,59 @@ static void tipc_subscrb_get(struct tipc_subscriber *subscriber) + kref_get(&subscriber->kref); + } + ++static void tipc_subscrp_kref_release(struct kref *kref) ++{ ++ struct tipc_subscription *sub = container_of(kref, ++ struct tipc_subscription, ++ kref); ++ struct tipc_net *tn = net_generic(sub->net, tipc_net_id); ++ struct tipc_subscriber *subscriber = sub->subscriber; ++ ++ spin_lock_bh(&subscriber->lock); ++ tipc_nametbl_unsubscribe(sub); ++ list_del(&sub->subscrp_list); ++ atomic_dec(&tn->subscription_count); ++ spin_unlock_bh(&subscriber->lock); ++ kfree(sub); ++ tipc_subscrb_put(subscriber); ++} ++ ++static void tipc_subscrp_put(struct tipc_subscription *subscription) ++{ ++ kref_put(&subscription->kref, tipc_subscrp_kref_release); ++} ++ ++static void tipc_subscrp_get(struct tipc_subscription *subscription) ++{ ++ kref_get(&subscription->kref); ++} ++ ++/* tipc_subscrb_subscrp_delete - delete a specific subscription or all ++ * subscriptions for a given subscriber. ++ */ ++static void tipc_subscrb_subscrp_delete(struct tipc_subscriber *subscriber, ++ struct tipc_subscr *s) ++{ ++ struct list_head *subscription_list = &subscriber->subscrp_list; ++ struct tipc_subscription *sub, *temp; ++ ++ spin_lock_bh(&subscriber->lock); ++ list_for_each_entry_safe(sub, temp, subscription_list, subscrp_list) { ++ if (s && memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) ++ continue; ++ ++ tipc_subscrp_get(sub); ++ spin_unlock_bh(&subscriber->lock); ++ tipc_subscrp_delete(sub); ++ tipc_subscrp_put(sub); ++ spin_lock_bh(&subscriber->lock); ++ ++ if (s) ++ break; ++ } ++ spin_unlock_bh(&subscriber->lock); ++} ++ + static struct tipc_subscriber *tipc_subscrb_create(int conid) + { + struct tipc_subscriber *subscriber; +@@ -177,8 +226,8 @@ static struct tipc_subscriber *tipc_subscrb_create(int conid) + pr_warn("Subscriber rejected, no memory\n"); + return NULL; + } +- kref_init(&subscriber->kref); + INIT_LIST_HEAD(&subscriber->subscrp_list); ++ kref_init(&subscriber->kref); + subscriber->conid = conid; + spin_lock_init(&subscriber->lock); + +@@ -187,55 +236,22 @@ static struct tipc_subscriber *tipc_subscrb_create(int conid) + + static void tipc_subscrb_delete(struct tipc_subscriber *subscriber) + { +- struct tipc_subscription *sub, *temp; +- u32 timeout; +- +- spin_lock_bh(&subscriber->lock); +- /* Destroy any existing subscriptions for subscriber */ +- list_for_each_entry_safe(sub, temp, &subscriber->subscrp_list, +- subscrp_list) { +- timeout = htohl(sub->evt.s.timeout, sub->swap); +- if ((timeout == TIPC_WAIT_FOREVER) || del_timer(&sub->timer)) { +- tipc_subscrp_delete(sub); +- tipc_subscrb_put(subscriber); +- } +- } +- spin_unlock_bh(&subscriber->lock); +- ++ tipc_subscrb_subscrp_delete(subscriber, NULL); + tipc_subscrb_put(subscriber); + } + + static void tipc_subscrp_delete(struct tipc_subscription *sub) + { +- struct tipc_net *tn = net_generic(sub->net, tipc_net_id); ++ u32 timeout = htohl(sub->evt.s.timeout, sub->swap); + +- tipc_nametbl_unsubscribe(sub); +- list_del(&sub->subscrp_list); +- kfree(sub); +- atomic_dec(&tn->subscription_count); ++ if (timeout == TIPC_WAIT_FOREVER || del_timer(&sub->timer)) ++ tipc_subscrp_put(sub); + } + + static void tipc_subscrp_cancel(struct tipc_subscr *s, + struct tipc_subscriber *subscriber) + { +- struct tipc_subscription *sub, *temp; +- u32 timeout; +- +- spin_lock_bh(&subscriber->lock); +- /* Find first matching subscription, exit if not found */ +- list_for_each_entry_safe(sub, temp, &subscriber->subscrp_list, +- subscrp_list) { +- if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) { +- timeout = htohl(sub->evt.s.timeout, sub->swap); +- if ((timeout == TIPC_WAIT_FOREVER) || +- del_timer(&sub->timer)) { +- tipc_subscrp_delete(sub); +- tipc_subscrb_put(subscriber); +- } +- break; +- } +- } +- spin_unlock_bh(&subscriber->lock); ++ tipc_subscrb_subscrp_delete(subscriber, s); + } + + static struct tipc_subscription *tipc_subscrp_create(struct net *net, +@@ -272,6 +288,7 @@ static struct tipc_subscription *tipc_subscrp_create(struct net *net, + sub->swap = swap; + memcpy(&sub->evt.s, s, sizeof(*s)); + atomic_inc(&tn->subscription_count); ++ kref_init(&sub->kref); + return sub; + } + +@@ -288,17 +305,16 @@ static void tipc_subscrp_subscribe(struct net *net, struct tipc_subscr *s, + + spin_lock_bh(&subscriber->lock); + list_add(&sub->subscrp_list, &subscriber->subscrp_list); +- tipc_subscrb_get(subscriber); + sub->subscriber = subscriber; + tipc_nametbl_subscribe(sub); ++ tipc_subscrb_get(subscriber); + spin_unlock_bh(&subscriber->lock); + ++ setup_timer(&sub->timer, tipc_subscrp_timeout, (unsigned long)sub); + timeout = htohl(sub->evt.s.timeout, swap); +- if (timeout == TIPC_WAIT_FOREVER) +- return; + +- setup_timer(&sub->timer, tipc_subscrp_timeout, (unsigned long)sub); +- mod_timer(&sub->timer, jiffies + msecs_to_jiffies(timeout)); ++ if (timeout != TIPC_WAIT_FOREVER) ++ mod_timer(&sub->timer, jiffies + msecs_to_jiffies(timeout)); + } + + /* Handle one termination request for the subscriber */ +diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h +index be60103082c9..ffdc214c117a 100644 +--- a/net/tipc/subscr.h ++++ b/net/tipc/subscr.h +@@ -57,6 +57,7 @@ struct tipc_subscriber; + * @evt: template for events generated by subscription + */ + struct tipc_subscription { ++ struct kref kref; + struct tipc_subscriber *subscriber; + struct net *net; + struct timer_list timer; |