diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 9975dcab99c3..5c2594d7c9ac 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -4409,6 +4409,9 @@
rootflags= [KNL] Set root filesystem mount option string
+ initramfs_options= [KNL] + Specify mount options for for the initramfs mount. + rootfstype= [KNL] Set root filesystem type
rootwait [KNL] Wait (indefinitely) for root device to show up. diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst index 17da97209976..951657baeaa8 100644 --- a/Documentation/arm64/silicon-errata.rst +++ b/Documentation/arm64/silicon-errata.rst @@ -134,6 +134,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-V3AE | #3312417 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-500 | #841119,826419 | N/A | +----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ diff --git a/Makefile b/Makefile index e56e5031852c..2c591495ed37 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 4 -SUBLEVEL = 300 +SUBLEVEL = 301 EXTRAVERSION = NAME = Kleptomaniac Octopus
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 82eba7ffa1d5..a242c4632137 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -617,6 +617,7 @@ config ARM64_ERRATUM_3194386 * ARM Neoverse-V1 erratum 3324341 * ARM Neoverse V2 erratum 3324336 * ARM Neoverse-V3 erratum 3312417 + * ARM Neoverse-V3AE erratum 3312417
On affected cores "MSR SSBS, #0" instructions may not affect subsequent speculative instructions, which may permit unexepected diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index e1097ba6c948..f01e2f0895a0 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -1599,6 +1599,8 @@ hexagon_smp2p_in: slave-kernel { qcom,entry-name = "slave-kernel";
+ resets = <&gcc GCC_MDSS_BCR>; + interrupt-controller; #interrupt-cells = <2>; }; diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index ca86e9c14fa6..6a8bd0ce74ae 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -87,6 +87,7 @@ #define ARM_CPU_PART_NEOVERSE_V2 0xD4F #define ARM_CPU_PART_CORTEX_A720 0xD81 #define ARM_CPU_PART_CORTEX_X4 0xD82 +#define ARM_CPU_PART_NEOVERSE_V3AE 0xD83 #define ARM_CPU_PART_NEOVERSE_V3 0xD84 #define ARM_CPU_PART_CORTEX_X925 0xD85 #define ARM_CPU_PART_CORTEX_A725 0xD87 @@ -139,6 +140,7 @@ #define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2) #define MIDR_CORTEX_A720 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A720) #define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4) +#define MIDR_NEOVERSE_V3AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3AE) #define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3) #define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925) #define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725) diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 709badd4475f..a05d782dcf5e 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -145,7 +145,8 @@ static inline pte_t set_pte_bit(pte_t pte, pgprot_t prot) static inline pte_t pte_mkwrite(pte_t pte) { pte = set_pte_bit(pte, __pgprot(PTE_WRITE)); - pte = clear_pte_bit(pte, __pgprot(PTE_RDONLY)); + if (pte_sw_dirty(pte)) + pte = clear_pte_bit(pte, __pgprot(PTE_RDONLY)); return pte; }
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 1e1dfe59a469..ebf39755eaf5 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -863,6 +863,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = { MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3AE), {} }; #endif diff --git a/arch/m68k/include/asm/bitops.h b/arch/m68k/include/asm/bitops.h index 10133a968c8e..d2a9aa048517 100644 --- a/arch/m68k/include/asm/bitops.h +++ b/arch/m68k/include/asm/bitops.h @@ -314,12 +314,12 @@ static inline int bfchg_mem_test_and_change_bit(int nr, #include <asm-generic/bitops/ffz.h> #else
-static inline int find_first_zero_bit(const unsigned long *vaddr, - unsigned size) +static inline unsigned long find_first_zero_bit(const unsigned long *vaddr, + unsigned long size) { const unsigned long *p = vaddr; - int res = 32; - unsigned int words; + unsigned long res = 32; + unsigned long words; unsigned long num;
if (!size) @@ -340,8 +340,9 @@ static inline int find_first_zero_bit(const unsigned long *vaddr, } #define find_first_zero_bit find_first_zero_bit
-static inline int find_next_zero_bit(const unsigned long *vaddr, int size, - int offset) +static inline unsigned long find_next_zero_bit(const unsigned long *vaddr, + unsigned long size, + unsigned long offset) { const unsigned long *p = vaddr + (offset >> 5); int bit = offset & 31UL, res; @@ -370,11 +371,12 @@ static inline int find_next_zero_bit(const unsigned long *vaddr, int size, } #define find_next_zero_bit find_next_zero_bit
-static inline int find_first_bit(const unsigned long *vaddr, unsigned size) +static inline unsigned long find_first_bit(const unsigned long *vaddr, + unsigned long size) { const unsigned long *p = vaddr; - int res = 32; - unsigned int words; + unsigned long res = 32; + unsigned long words; unsigned long num;
if (!size) @@ -395,8 +397,9 @@ static inline int find_first_bit(const unsigned long *vaddr, unsigned size) } #define find_first_bit find_first_bit
-static inline int find_next_bit(const unsigned long *vaddr, int size, - int offset) +static inline unsigned long find_next_bit(const unsigned long *vaddr, + unsigned long size, + unsigned long offset) { const unsigned long *p = vaddr + (offset >> 5); int bit = offset & 31UL, res; diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c index c4ad5a9b4bc1..ba6a3d4c1050 100644 --- a/arch/mips/mti-malta/malta-setup.c +++ b/arch/mips/mti-malta/malta-setup.c @@ -48,7 +48,7 @@ static struct resource standard_io_resources[] = { .name = "keyboard", .start = 0x60, .end = 0x6f, - .flags = IORESOURCE_IO | IORESOURCE_BUSY + .flags = IORESOURCE_IO }, { .name = "dma page reg", diff --git a/arch/parisc/include/uapi/asm/ioctls.h b/arch/parisc/include/uapi/asm/ioctls.h index 82d1148c6379..74b4027a4e80 100644 --- a/arch/parisc/include/uapi/asm/ioctls.h +++ b/arch/parisc/include/uapi/asm/ioctls.h @@ -10,10 +10,10 @@ #define TCSETS _IOW('T', 17, struct termios) /* TCSETATTR */ #define TCSETSW _IOW('T', 18, struct termios) /* TCSETATTRD */ #define TCSETSF _IOW('T', 19, struct termios) /* TCSETATTRF */ -#define TCGETA _IOR('T', 1, struct termio) -#define TCSETA _IOW('T', 2, struct termio) -#define TCSETAW _IOW('T', 3, struct termio) -#define TCSETAF _IOW('T', 4, struct termio) +#define TCGETA 0x40125401 +#define TCSETA 0x80125402 +#define TCSETAW 0x80125403 +#define TCSETAF 0x80125404 #define TCSBRK _IO('T', 5) #define TCXONC _IO('T', 6) #define TCFLSH _IO('T', 7) diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 4ebf51e6e78e..b06b92c9a375 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -387,6 +387,7 @@ static struct platform_device * __init scan_one_device(struct device_node *dp,
if (of_device_register(op)) { printk("%pOF: Could not register of device.\n", dp); + put_device(&op->dev); kfree(op); op = NULL; } diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index 5a9f86b1d4e7..6e616bd5cc46 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -680,6 +680,7 @@ static struct platform_device * __init scan_one_device(struct device_node *dp,
if (of_device_register(op)) { printk("%pOF: Could not register of device.\n", dp); + put_device(&op->dev); kfree(op); op = NULL; } diff --git a/arch/sparc/lib/M7memcpy.S b/arch/sparc/lib/M7memcpy.S index cbd42ea7c3f7..99357bfa8e82 100644 --- a/arch/sparc/lib/M7memcpy.S +++ b/arch/sparc/lib/M7memcpy.S @@ -696,16 +696,16 @@ FUNC_NAME: EX_LD_FP(LOAD(ldd, %o4+40, %f26), memcpy_retl_o2_plus_o5_plus_40) faligndata %f24, %f26, %f10 EX_ST_FP(STORE(std, %f6, %o0+24), memcpy_retl_o2_plus_o5_plus_40) - EX_LD_FP(LOAD(ldd, %o4+48, %f28), memcpy_retl_o2_plus_o5_plus_40) + EX_LD_FP(LOAD(ldd, %o4+48, %f28), memcpy_retl_o2_plus_o5_plus_32) faligndata %f26, %f28, %f12 - EX_ST_FP(STORE(std, %f8, %o0+32), memcpy_retl_o2_plus_o5_plus_40) + EX_ST_FP(STORE(std, %f8, %o0+32), memcpy_retl_o2_plus_o5_plus_32) add %o4, 64, %o4 - EX_LD_FP(LOAD(ldd, %o4-8, %f30), memcpy_retl_o2_plus_o5_plus_40) + EX_LD_FP(LOAD(ldd, %o4-8, %f30), memcpy_retl_o2_plus_o5_plus_24) faligndata %f28, %f30, %f14 - EX_ST_FP(STORE(std, %f10, %o0+40), memcpy_retl_o2_plus_o5_plus_40) - EX_ST_FP(STORE(std, %f12, %o0+48), memcpy_retl_o2_plus_o5_plus_40) + EX_ST_FP(STORE(std, %f10, %o0+40), memcpy_retl_o2_plus_o5_plus_24) + EX_ST_FP(STORE(std, %f12, %o0+48), memcpy_retl_o2_plus_o5_plus_16) add %o0, 64, %o0 - EX_ST_FP(STORE(std, %f14, %o0-8), memcpy_retl_o2_plus_o5_plus_40) + EX_ST_FP(STORE(std, %f14, %o0-8), memcpy_retl_o2_plus_o5_plus_8) fsrc2 %f30, %f14 bgu,pt %xcc, .Lunalign_sloop prefetch [%o4 + (8 * BLOCK_SIZE)], 20 @@ -728,7 +728,7 @@ FUNC_NAME: add %o4, 8, %o4 faligndata %f0, %f2, %f16 subcc %o5, 8, %o5 - EX_ST_FP(STORE(std, %f16, %o0), memcpy_retl_o2_plus_o5) + EX_ST_FP(STORE(std, %f16, %o0), memcpy_retl_o2_plus_o5_plus_8) fsrc2 %f2, %f0 bgu,pt %xcc, .Lunalign_by8 add %o0, 8, %o0 @@ -772,7 +772,7 @@ FUNC_NAME: subcc %o5, 0x20, %o5 EX_ST(STORE(stx, %o3, %o0 + 0x00), memcpy_retl_o2_plus_o5_plus_32) EX_ST(STORE(stx, %g2, %o0 + 0x08), memcpy_retl_o2_plus_o5_plus_24) - EX_ST(STORE(stx, %g7, %o0 + 0x10), memcpy_retl_o2_plus_o5_plus_24) + EX_ST(STORE(stx, %g7, %o0 + 0x10), memcpy_retl_o2_plus_o5_plus_16) EX_ST(STORE(stx, %o4, %o0 + 0x18), memcpy_retl_o2_plus_o5_plus_8) bne,pt %xcc, 1b add %o0, 0x20, %o0 @@ -804,12 +804,12 @@ FUNC_NAME: brz,pt %o3, 2f sub %o2, %o3, %o2
-1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2), memcpy_retl_o2_plus_g1) +1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2), memcpy_retl_o2_plus_o3) add %o1, 1, %o1 subcc %o3, 1, %o3 add %o0, 1, %o0 bne,pt %xcc, 1b - EX_ST(STORE(stb, %g2, %o0 - 0x01), memcpy_retl_o2_plus_g1_plus_1) + EX_ST(STORE(stb, %g2, %o0 - 0x01), memcpy_retl_o2_plus_o3_plus_1) 2: and %o1, 0x7, %o3 brz,pn %o3, .Lmedium_noprefetch_cp diff --git a/arch/sparc/lib/Memcpy_utils.S b/arch/sparc/lib/Memcpy_utils.S index 64fbac28b3db..207343367bb2 100644 --- a/arch/sparc/lib/Memcpy_utils.S +++ b/arch/sparc/lib/Memcpy_utils.S @@ -137,6 +137,15 @@ ENTRY(memcpy_retl_o2_plus_63_8) ba,pt %xcc, __restore_asi add %o2, 8, %o0 ENDPROC(memcpy_retl_o2_plus_63_8) +ENTRY(memcpy_retl_o2_plus_o3) + ba,pt %xcc, __restore_asi + add %o2, %o3, %o0 +ENDPROC(memcpy_retl_o2_plus_o3) +ENTRY(memcpy_retl_o2_plus_o3_plus_1) + add %o3, 1, %o3 + ba,pt %xcc, __restore_asi + add %o2, %o3, %o0 +ENDPROC(memcpy_retl_o2_plus_o3_plus_1) ENTRY(memcpy_retl_o2_plus_o5) ba,pt %xcc, __restore_asi add %o2, %o5, %o0 diff --git a/arch/sparc/lib/NG4memcpy.S b/arch/sparc/lib/NG4memcpy.S index 7ad58ebe0d00..df0ec1bd1948 100644 --- a/arch/sparc/lib/NG4memcpy.S +++ b/arch/sparc/lib/NG4memcpy.S @@ -281,7 +281,7 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ subcc %o5, 0x20, %o5 EX_ST(STORE(stx, %g1, %o0 + 0x00), memcpy_retl_o2_plus_o5_plus_32) EX_ST(STORE(stx, %g2, %o0 + 0x08), memcpy_retl_o2_plus_o5_plus_24) - EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x10), memcpy_retl_o2_plus_o5_plus_24) + EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x10), memcpy_retl_o2_plus_o5_plus_16) EX_ST(STORE(stx, %o4, %o0 + 0x18), memcpy_retl_o2_plus_o5_plus_8) bne,pt %icc, 1b add %o0, 0x20, %o0 diff --git a/arch/sparc/lib/NGmemcpy.S b/arch/sparc/lib/NGmemcpy.S index 8e4d22a6ba0b..846a8c4ea394 100644 --- a/arch/sparc/lib/NGmemcpy.S +++ b/arch/sparc/lib/NGmemcpy.S @@ -80,8 +80,8 @@ #ifndef EX_RETVAL #define EX_RETVAL(x) x __restore_asi: - ret wr %g0, ASI_AIUS, %asi + ret restore ENTRY(NG_ret_i2_plus_i4_plus_1) ba,pt %xcc, __restore_asi @@ -126,15 +126,16 @@ ENTRY(NG_ret_i2_plus_g1_minus_56) ba,pt %xcc, __restore_asi add %i2, %g1, %i0 ENDPROC(NG_ret_i2_plus_g1_minus_56) -ENTRY(NG_ret_i2_plus_i4) +ENTRY(NG_ret_i2_plus_i4_plus_16) + add %i4, 16, %i4 ba,pt %xcc, __restore_asi add %i2, %i4, %i0 -ENDPROC(NG_ret_i2_plus_i4) -ENTRY(NG_ret_i2_plus_i4_minus_8) - sub %i4, 8, %i4 +ENDPROC(NG_ret_i2_plus_i4_plus_16) +ENTRY(NG_ret_i2_plus_i4_plus_8) + add %i4, 8, %i4 ba,pt %xcc, __restore_asi add %i2, %i4, %i0 -ENDPROC(NG_ret_i2_plus_i4_minus_8) +ENDPROC(NG_ret_i2_plus_i4_plus_8) ENTRY(NG_ret_i2_plus_8) ba,pt %xcc, __restore_asi add %i2, 8, %i0 @@ -161,6 +162,12 @@ ENTRY(NG_ret_i2_and_7_plus_i4) ba,pt %xcc, __restore_asi add %i2, %i4, %i0 ENDPROC(NG_ret_i2_and_7_plus_i4) +ENTRY(NG_ret_i2_and_7_plus_i4_plus_8) + and %i2, 7, %i2 + add %i4, 8, %i4 + ba,pt %xcc, __restore_asi + add %i2, %i4, %i0 +ENDPROC(NG_ret_i2_and_7_plus_i4) #endif
.align 64 @@ -406,13 +413,13 @@ FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */ andn %i2, 0xf, %i4 and %i2, 0xf, %i2 1: subcc %i4, 0x10, %i4 - EX_LD(LOAD(ldx, %i1, %o4), NG_ret_i2_plus_i4) + EX_LD(LOAD(ldx, %i1, %o4), NG_ret_i2_plus_i4_plus_16) add %i1, 0x08, %i1 - EX_LD(LOAD(ldx, %i1, %g1), NG_ret_i2_plus_i4) + EX_LD(LOAD(ldx, %i1, %g1), NG_ret_i2_plus_i4_plus_16) sub %i1, 0x08, %i1 - EX_ST(STORE(stx, %o4, %i1 + %i3), NG_ret_i2_plus_i4) + EX_ST(STORE(stx, %o4, %i1 + %i3), NG_ret_i2_plus_i4_plus_16) add %i1, 0x8, %i1 - EX_ST(STORE(stx, %g1, %i1 + %i3), NG_ret_i2_plus_i4_minus_8) + EX_ST(STORE(stx, %g1, %i1 + %i3), NG_ret_i2_plus_i4_plus_8) bgu,pt %XCC, 1b add %i1, 0x8, %i1 73: andcc %i2, 0x8, %g0 @@ -469,7 +476,7 @@ FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */ subcc %i4, 0x8, %i4 srlx %g3, %i3, %i5 or %i5, %g2, %i5 - EX_ST(STORE(stx, %i5, %o0), NG_ret_i2_and_7_plus_i4) + EX_ST(STORE(stx, %i5, %o0), NG_ret_i2_and_7_plus_i4_plus_8) add %o0, 0x8, %o0 bgu,pt %icc, 1b sllx %g3, %g1, %g2 diff --git a/arch/sparc/lib/U1memcpy.S b/arch/sparc/lib/U1memcpy.S index a6f4ee391897..021b94a383d1 100644 --- a/arch/sparc/lib/U1memcpy.S +++ b/arch/sparc/lib/U1memcpy.S @@ -164,17 +164,18 @@ ENTRY(U1_gs_40_fp) retl add %o0, %o2, %o0 ENDPROC(U1_gs_40_fp) -ENTRY(U1_g3_0_fp) - VISExitHalf - retl - add %g3, %o2, %o0 -ENDPROC(U1_g3_0_fp) ENTRY(U1_g3_8_fp) VISExitHalf add %g3, 8, %g3 retl add %g3, %o2, %o0 ENDPROC(U1_g3_8_fp) +ENTRY(U1_g3_16_fp) + VISExitHalf + add %g3, 16, %g3 + retl + add %g3, %o2, %o0 +ENDPROC(U1_g3_16_fp) ENTRY(U1_o2_0_fp) VISExitHalf retl @@ -547,18 +548,18 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ 62: FINISH_VISCHUNK(o0, f44, f46) 63: UNEVEN_VISCHUNK_LAST(o0, f46, f0)
-93: EX_LD_FP(LOAD(ldd, %o1, %f2), U1_g3_0_fp) +93: EX_LD_FP(LOAD(ldd, %o1, %f2), U1_g3_8_fp) add %o1, 8, %o1 subcc %g3, 8, %g3 faligndata %f0, %f2, %f8 - EX_ST_FP(STORE(std, %f8, %o0), U1_g3_8_fp) + EX_ST_FP(STORE(std, %f8, %o0), U1_g3_16_fp) bl,pn %xcc, 95f add %o0, 8, %o0 - EX_LD_FP(LOAD(ldd, %o1, %f0), U1_g3_0_fp) + EX_LD_FP(LOAD(ldd, %o1, %f0), U1_g3_8_fp) add %o1, 8, %o1 subcc %g3, 8, %g3 faligndata %f2, %f0, %f8 - EX_ST_FP(STORE(std, %f8, %o0), U1_g3_8_fp) + EX_ST_FP(STORE(std, %f8, %o0), U1_g3_16_fp) bge,pt %xcc, 93b add %o0, 8, %o0
diff --git a/arch/sparc/lib/U3memcpy.S b/arch/sparc/lib/U3memcpy.S index 9248d59c734c..bace3a18f836 100644 --- a/arch/sparc/lib/U3memcpy.S +++ b/arch/sparc/lib/U3memcpy.S @@ -267,6 +267,7 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ faligndata %f10, %f12, %f26 EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0), U3_retl_o2)
+ and %o2, 0x3f, %o2 subcc GLOBAL_SPARE, 0x80, GLOBAL_SPARE add %o1, 0x40, %o1 bgu,pt %XCC, 1f @@ -336,7 +337,6 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ * Also notice how this code is careful not to perform a * load past the end of the src buffer. */ - and %o2, 0x3f, %o2 andcc %o2, 0x38, %g2 be,pn %XCC, 2f subcc %g2, 0x8, %g2 diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c index f78793a06bbd..d0b134902e6e 100644 --- a/arch/sparc/mm/hugetlbpage.c +++ b/arch/sparc/mm/hugetlbpage.c @@ -134,6 +134,26 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
static pte_t sun4u_hugepage_shift_to_tte(pte_t entry, unsigned int shift) { + unsigned long hugepage_size = _PAGE_SZ4MB_4U; + + pte_val(entry) = pte_val(entry) & ~_PAGE_SZALL_4U; + + switch (shift) { + case HPAGE_256MB_SHIFT: + hugepage_size = _PAGE_SZ256MB_4U; + pte_val(entry) |= _PAGE_PMD_HUGE; + break; + case HPAGE_SHIFT: + pte_val(entry) |= _PAGE_PMD_HUGE; + break; + case HPAGE_64K_SHIFT: + hugepage_size = _PAGE_SZ64K_4U; + break; + default: + WARN_ONCE(1, "unsupported hugepage shift=%u\n", shift); + } + + pte_val(entry) = pte_val(entry) | hugepage_size; return entry; }
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 77cf6c11f66b..f8e8799a8757 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -448,7 +448,7 @@ bool x86_page_table_writing_insn(struct x86_emulate_ctxt *ctxt); #define EMULATION_RESTART 1 #define EMULATION_INTERCEPTED 2 void init_decode_cache(struct x86_emulate_ctxt *ctxt); -int x86_emulate_insn(struct x86_emulate_ctxt *ctxt); +int x86_emulate_insn(struct x86_emulate_ctxt *ctxt, bool check_intercepts); int emulator_task_switch(struct x86_emulate_ctxt *ctxt, u16 tss_selector, int idt_index, int reason, bool has_error_code, u32 error_code); diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h index 6669164abadc..531a0cb93b47 100644 --- a/arch/x86/include/asm/segment.h +++ b/arch/x86/include/asm/segment.h @@ -253,7 +253,7 @@ static inline unsigned long vdso_encode_cpunode(int cpu, unsigned long node)
static inline void vdso_read_cpunode(unsigned *cpu, unsigned *node) { - unsigned int p; + unsigned long p;
/* * Load CPU and node number from the GDT. LSL is faster than RDTSCP @@ -263,10 +263,10 @@ static inline void vdso_read_cpunode(unsigned *cpu, unsigned *node) * * If RDPID is available, use it. */ - alternative_io ("lsl %[seg],%[p]", - ".byte 0xf3,0x0f,0xc7,0xf8", /* RDPID %eax/rax */ + alternative_io ("lsl %[seg],%k[p]", + "rdpid %[p]", X86_FEATURE_RDPID, - [p] "=a" (p), [seg] "r" (__CPUNODE_SEG)); + [p] "=r" (p), [seg] "r" (__CPUNODE_SEG));
if (cpu) *cpu = (p & VDSO_CPUNODE_MASK); diff --git a/arch/x86/kernel/umip.c b/arch/x86/kernel/umip.c index 548fefed71ee..b97323edb4f4 100644 --- a/arch/x86/kernel/umip.c +++ b/arch/x86/kernel/umip.c @@ -155,15 +155,26 @@ static int identify_insn(struct insn *insn) if (!insn->modrm.nbytes) return -EINVAL;
- /* All the instructions of interest start with 0x0f. */ - if (insn->opcode.bytes[0] != 0xf) + /* The instructions of interest have 2-byte opcodes: 0F 00 or 0F 01. */ + if (insn->opcode.nbytes < 2 || insn->opcode.bytes[0] != 0xf) return -EINVAL;
if (insn->opcode.bytes[1] == 0x1) { switch (X86_MODRM_REG(insn->modrm.value)) { case 0: + /* The reg form of 0F 01 /0 encodes VMX instructions. */ + if (X86_MODRM_MOD(insn->modrm.value) == 3) + return -EINVAL; + return UMIP_INST_SGDT; case 1: + /* + * The reg form of 0F 01 /1 encodes MONITOR/MWAIT, + * STAC/CLAC, and ENCLS. + */ + if (X86_MODRM_MOD(insn->modrm.value) == 3) + return -EINVAL; + return UMIP_INST_SIDT; case 4: return UMIP_INST_SMSW; diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 1a9fa2903852..90c495b87070 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -5605,12 +5605,11 @@ void init_decode_cache(struct x86_emulate_ctxt *ctxt) ctxt->mem_read.end = 0; }
-int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) +int x86_emulate_insn(struct x86_emulate_ctxt *ctxt, bool check_intercepts) { const struct x86_emulate_ops *ops = ctxt->ops; int rc = X86EMUL_CONTINUE; int saved_dst_type = ctxt->dst.type; - unsigned emul_flags;
ctxt->mem_read.pos = 0;
@@ -5625,7 +5624,6 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) goto done; }
- emul_flags = ctxt->ops->get_hflags(ctxt); if (unlikely(ctxt->d & (No64|Undefined|Sse|Mmx|Intercept|CheckPerm|Priv|Prot|String))) { if ((ctxt->mode == X86EMUL_MODE_PROT64 && (ctxt->d & No64)) || @@ -5659,7 +5657,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) fetch_possible_mmx_operand(ctxt, &ctxt->dst); }
- if (unlikely(emul_flags & X86EMUL_GUEST_MASK) && ctxt->intercept) { + if (unlikely(check_intercepts) && ctxt->intercept) { rc = emulator_check_intercept(ctxt, ctxt->intercept, X86_ICPT_PRE_EXCEPT); if (rc != X86EMUL_CONTINUE) @@ -5688,7 +5686,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) goto done; }
- if (unlikely(emul_flags & X86EMUL_GUEST_MASK) && (ctxt->d & Intercept)) { + if (unlikely(check_intercepts) && (ctxt->d & Intercept)) { rc = emulator_check_intercept(ctxt, ctxt->intercept, X86_ICPT_POST_EXCEPT); if (rc != X86EMUL_CONTINUE) @@ -5742,7 +5740,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
special_insn:
- if (unlikely(emul_flags & X86EMUL_GUEST_MASK) && (ctxt->d & Intercept)) { + if (unlikely(check_intercepts) && (ctxt->d & Intercept)) { rc = emulator_check_intercept(ctxt, ctxt->intercept, X86_ICPT_POST_MEMACCESS); if (rc != X86EMUL_CONTINUE) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 8eb62dbb3a18..9c53bc25aa36 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -6855,7 +6855,14 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, /* Save the faulting GPA (cr2) in the address field */ ctxt->exception.address = cr2_or_gpa;
- r = x86_emulate_insn(ctxt); + /* + * Check L1's instruction intercepts when emulating instructions for + * L2, unless KVM is re-emulating a previously decoded instruction, + * e.g. to complete userspace I/O, in which case KVM has already + * checked the intercepts. + */ + r = x86_emulate_insn(ctxt, is_guest_mode(vcpu) && + !(emulation_type & EMULTYPE_NO_DECODE));
if (r == EMULATION_INTERCEPTED) return 1; diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c index 7abd66d1228a..532afcb67241 100644 --- a/block/blk-mq-sysfs.c +++ b/block/blk-mq-sysfs.c @@ -241,9 +241,11 @@ static void blk_mq_unregister_hctx(struct blk_mq_hw_ctx *hctx) return;
hctx_for_each_ctx(hctx, ctx, i) - kobject_del(&ctx->kobj); + if (ctx->kobj.state_in_sysfs) + kobject_del(&ctx->kobj);
- kobject_del(&hctx->kobj); + if (hctx->kobj.state_in_sysfs) + kobject_del(&hctx->kobj); }
static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx) diff --git a/block/blk-settings.c b/block/blk-settings.c index 13be635300a8..d4870441a38a 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -505,7 +505,8 @@ static unsigned int blk_round_down_sectors(unsigned int sectors, unsigned int lb int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, sector_t start) { - unsigned int top, bottom, alignment, ret = 0; + unsigned int top, bottom, alignment; + int ret = 0;
t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors); t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors); diff --git a/crypto/essiv.c b/crypto/essiv.c index aa6b89e91ac8..8a74cc34ac50 100644 --- a/crypto/essiv.c +++ b/crypto/essiv.c @@ -203,9 +203,14 @@ static int essiv_aead_crypt(struct aead_request *req, bool enc) const struct essiv_tfm_ctx *tctx = crypto_aead_ctx(tfm); struct essiv_aead_request_ctx *rctx = aead_request_ctx(req); struct aead_request *subreq = &rctx->aead_req; + int ivsize = crypto_aead_ivsize(tfm); + int ssize = req->assoclen - ivsize; struct scatterlist *src = req->src; int err;
+ if (ssize < 0) + return -EINVAL; + crypto_cipher_encrypt_one(tctx->essiv_cipher, req->iv, req->iv);
/* @@ -215,19 +220,12 @@ static int essiv_aead_crypt(struct aead_request *req, bool enc) */ rctx->assoc = NULL; if (req->src == req->dst || !enc) { - scatterwalk_map_and_copy(req->iv, req->dst, - req->assoclen - crypto_aead_ivsize(tfm), - crypto_aead_ivsize(tfm), 1); + scatterwalk_map_and_copy(req->iv, req->dst, ssize, ivsize, 1); } else { u8 *iv = (u8 *)aead_request_ctx(req) + tctx->ivoffset; - int ivsize = crypto_aead_ivsize(tfm); - int ssize = req->assoclen - ivsize; struct scatterlist *sg; int nents;
- if (ssize < 0) - return -EINVAL; - nents = sg_nents_for_len(req->src, ssize); if (nents < 0) return -EINVAL; diff --git a/drivers/acpi/acpi_dbg.c b/drivers/acpi/acpi_dbg.c index cc4b509bad94..ec6868c64fdb 100644 --- a/drivers/acpi/acpi_dbg.c +++ b/drivers/acpi/acpi_dbg.c @@ -576,11 +576,11 @@ static int acpi_aml_release(struct inode *inode, struct file *file) return 0; }
-static int acpi_aml_read_user(char __user *buf, int len) +static ssize_t acpi_aml_read_user(char __user *buf, size_t len) { - int ret; struct circ_buf *crc = &acpi_aml_io.out_crc; - int n; + ssize_t ret; + size_t n; char *p;
ret = acpi_aml_lock_read(crc, ACPI_AML_OUT_USER); @@ -589,7 +589,7 @@ static int acpi_aml_read_user(char __user *buf, int len) /* sync head before removing logs */ smp_rmb(); p = &crc->buf[crc->tail]; - n = min(len, circ_count_to_end(crc)); + n = min_t(size_t, len, circ_count_to_end(crc)); if (copy_to_user(buf, p, n)) { ret = -EFAULT; goto out; @@ -606,8 +606,8 @@ static int acpi_aml_read_user(char __user *buf, int len) static ssize_t acpi_aml_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - int ret = 0; - int size = 0; + ssize_t ret = 0; + ssize_t size = 0;
if (!count) return 0; @@ -646,11 +646,11 @@ static ssize_t acpi_aml_read(struct file *file, char __user *buf, return size > 0 ? size : ret; }
-static int acpi_aml_write_user(const char __user *buf, int len) +static ssize_t acpi_aml_write_user(const char __user *buf, size_t len) { - int ret; struct circ_buf *crc = &acpi_aml_io.in_crc; - int n; + ssize_t ret; + size_t n; char *p;
ret = acpi_aml_lock_write(crc, ACPI_AML_IN_USER); @@ -659,7 +659,7 @@ static int acpi_aml_write_user(const char __user *buf, int len) /* sync tail before inserting cmds */ smp_mb(); p = &crc->buf[crc->head]; - n = min(len, circ_space_to_end(crc)); + n = min_t(size_t, len, circ_space_to_end(crc)); if (copy_from_user(p, buf, n)) { ret = -EFAULT; goto out; @@ -670,14 +670,14 @@ static int acpi_aml_write_user(const char __user *buf, int len) ret = n; out: acpi_aml_unlock_fifo(ACPI_AML_IN_USER, ret >= 0); - return n; + return ret; }
static ssize_t acpi_aml_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - int ret = 0; - int size = 0; + ssize_t ret = 0; + ssize_t size = 0;
if (!count) return 0; diff --git a/drivers/acpi/acpi_tad.c b/drivers/acpi/acpi_tad.c index bab8583443a6..3db173e30779 100644 --- a/drivers/acpi/acpi_tad.c +++ b/drivers/acpi/acpi_tad.c @@ -563,6 +563,9 @@ static int acpi_tad_remove(struct platform_device *pdev)
pm_runtime_get_sync(dev);
+ if (dd->capabilities & ACPI_TAD_RT) + sysfs_remove_group(&dev->kobj, &acpi_tad_time_attr_group); + if (dd->capabilities & ACPI_TAD_DC_WAKE) sysfs_remove_group(&dev->kobj, &acpi_tad_dc_attr_group);
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index e6bba26caf3c..86655d65f321 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -1506,6 +1506,9 @@ int acpi_processor_power_init(struct acpi_processor *pr) if (retval) { if (acpi_processor_registered == 0) cpuidle_unregister_driver(&acpi_idle_driver); + + per_cpu(acpi_cpuidle_device, pr->id) = NULL; + kfree(dev); return retval; } acpi_processor_registered++; diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 30d71b928f0d..9e943e3123fa 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -1208,17 +1208,8 @@ static int binder_inc_node_nilocked(struct binder_node *node, int strong, } else { if (!internal) node->local_weak_refs++; - if (!node->has_weak_ref && list_empty(&node->work.entry)) { - if (target_list == NULL) { - pr_err("invalid inc weak node for %d\n", - node->debug_id); - return -EINVAL; - } - /* - * See comment above - */ + if (!node->has_weak_ref && target_list && list_empty(&node->work.entry)) binder_enqueue_work_ilocked(&node->work, target_list); - } } return 0; } diff --git a/drivers/base/node.c b/drivers/base/node.c index 666eb55c0774..83b13a295bbe 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -938,6 +938,10 @@ int __register_one_node(int nid) return -ENOMEM;
error = register_node(node_devices[nid], nid); + if (error) { + node_devices[nid] = NULL; + return error; + }
/* link cpu under this node */ for_each_present_cpu(cpu) { diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index c453c24afeb8..5824cfd28812 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -824,7 +824,7 @@ struct regmap *__regmap_init(struct device *dev, map->read_flag_mask = bus->read_flag_mask; }
- if (config && config->read && config->write) { + if (config->read && config->write) { map->reg_read = _regmap_bus_read;
/* Bulk read/write */ diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index a084f732c180..b538db3052b7 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -633,16 +633,10 @@ static void tpm_tis_gen_interrupt(struct tpm_chip *chip) cap_t cap; int ret;
- ret = request_locality(chip, 0); - if (ret < 0) - return; - if (chip->flags & TPM_CHIP_FLAG_TPM2) ret = tpm2_get_tpm_pt(chip, 0x100, &cap2, desc); else ret = tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc, 0); - - release_locality(chip, 0); }
/* Register the IRQ and issue a command that will cause an interrupt. If an @@ -665,10 +659,16 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask, } priv->irq = irq;
+ rc = request_locality(chip, 0); + if (rc < 0) + return rc; + rc = tpm_tis_read8(priv, TPM_INT_VECTOR(priv->locality), &original_int_vec); - if (rc < 0) + if (rc < 0) { + release_locality(chip, priv->locality); return rc; + }
rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), irq); if (rc < 0) @@ -700,12 +700,14 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask, * will call disable_irq which undoes all of the above. */ if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) { - tpm_tis_write8(priv, original_int_vec, - TPM_INT_VECTOR(priv->locality)); - return -1; + tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), + original_int_vec); + rc = -1; }
- return 0; + release_locality(chip, priv->locality); + + return rc; }
/* Try to find the IRQ the TPM is using. This is for legacy x86 systems that diff --git a/drivers/clk/nxp/clk-lpc18xx-cgu.c b/drivers/clk/nxp/clk-lpc18xx-cgu.c index 8b686da5577b..ab8741fe57c9 100644 --- a/drivers/clk/nxp/clk-lpc18xx-cgu.c +++ b/drivers/clk/nxp/clk-lpc18xx-cgu.c @@ -374,23 +374,25 @@ static unsigned long lpc18xx_pll0_recalc_rate(struct clk_hw *hw, return 0; }
-static long lpc18xx_pll0_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int lpc18xx_pll0_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { unsigned long m;
- if (*prate < rate) { + if (req->best_parent_rate < req->rate) { pr_warn("%s: pll dividers not supported\n", __func__); return -EINVAL; }
- m = DIV_ROUND_UP_ULL(*prate, rate * 2); - if (m <= 0 && m > LPC18XX_PLL0_MSEL_MAX) { - pr_warn("%s: unable to support rate %lu\n", __func__, rate); + m = DIV_ROUND_UP_ULL(req->best_parent_rate, req->rate * 2); + if (m == 0 || m > LPC18XX_PLL0_MSEL_MAX) { + pr_warn("%s: unable to support rate %lu\n", __func__, req->rate); return -EINVAL; }
- return 2 * *prate * m; + req->rate = 2 * req->best_parent_rate * m; + + return 0; }
static int lpc18xx_pll0_set_rate(struct clk_hw *hw, unsigned long rate, @@ -406,7 +408,7 @@ static int lpc18xx_pll0_set_rate(struct clk_hw *hw, unsigned long rate, }
m = DIV_ROUND_UP_ULL(parent_rate, rate * 2); - if (m <= 0 && m > LPC18XX_PLL0_MSEL_MAX) { + if (m == 0 || m > LPC18XX_PLL0_MSEL_MAX) { pr_warn("%s: unable to support rate %lu\n", __func__, rate); return -EINVAL; } @@ -447,7 +449,7 @@ static int lpc18xx_pll0_set_rate(struct clk_hw *hw, unsigned long rate,
static const struct clk_ops lpc18xx_pll0_ops = { .recalc_rate = lpc18xx_pll0_recalc_rate, - .round_rate = lpc18xx_pll0_round_rate, + .determine_rate = lpc18xx_pll0_determine_rate, .set_rate = lpc18xx_pll0_set_rate, };
diff --git a/drivers/clocksource/clps711x-timer.c b/drivers/clocksource/clps711x-timer.c index e95fdc49c226..bbceb0289d45 100644 --- a/drivers/clocksource/clps711x-timer.c +++ b/drivers/clocksource/clps711x-timer.c @@ -78,24 +78,33 @@ static int __init clps711x_timer_init(struct device_node *np) unsigned int irq = irq_of_parse_and_map(np, 0); struct clk *clock = of_clk_get(np, 0); void __iomem *base = of_iomap(np, 0); + int ret = 0;
if (!base) return -ENOMEM; - if (!irq) - return -EINVAL; - if (IS_ERR(clock)) - return PTR_ERR(clock); + if (!irq) { + ret = -EINVAL; + goto unmap_io; + } + if (IS_ERR(clock)) { + ret = PTR_ERR(clock); + goto unmap_io; + }
switch (of_alias_get_id(np, "timer")) { case CLPS711X_CLKSRC_CLOCKSOURCE: clps711x_clksrc_init(clock, base); break; case CLPS711X_CLKSRC_CLOCKEVENT: - return _clps711x_clkevt_init(clock, base, irq); + ret = _clps711x_clkevt_init(clock, base, irq); + break; default: - return -EINVAL; + ret = -EINVAL; + break; }
- return 0; +unmap_io: + iounmap(base); + return ret; } TIMER_OF_DECLARE(clps711x, "cirrus,ep7209-timer", clps711x_timer_init); diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 06302eaa3e94..ab6f3bef978b 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -1092,10 +1092,10 @@ static void update_qos_request(enum freq_qos_req_type type) continue;
req = policy->driver_data; - cpufreq_cpu_put(policy); - - if (!req) + if (!req) { + cpufreq_cpu_put(policy); continue; + }
if (hwp_active) intel_pstate_get_hwp_max(i, &turbo_max, &max_state); @@ -1114,6 +1114,8 @@ static void update_qos_request(enum freq_qos_req_type type)
if (freq_qos_update_request(req, freq) < 0) pr_warn("Failed to update freq constraint: CPU%d\n", i); + + cpufreq_cpu_put(policy); } }
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index bb7288f6adbf..fcf03952d48a 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -258,20 +258,17 @@ static unsigned int get_typical_interval(struct menu_device *data, * * This can deal with workloads that have long pauses interspersed * with sporadic activity with a bunch of short pauses. + * + * However, if the number of remaining samples is too small to exclude + * any more outliers, allow the deepest available idle state to be + * selected because there are systems where the time spent by CPUs in + * deep idle states is correlated to the maximum frequency the CPUs + * can get to. On those systems, shallow idle states should be avoided + * unless there is a clear indication that the given CPU is most likley + * going to be woken up shortly. */ - if (divisor * 4 <= INTERVALS * 3) { - /* - * If there are sufficiently many data points still under - * consideration after the outliers have been eliminated, - * returning without a prediction would be a mistake because it - * is likely that the next interval will not exceed the current - * maximum, so return the latter in that case. - */ - if (divisor >= INTERVALS / 2) - return max; - + if (divisor * 4 <= INTERVALS * 3) return UINT_MAX; - }
thresh = max - 1; goto again; diff --git a/drivers/crypto/atmel-tdes.c b/drivers/crypto/atmel-tdes.c index 1a6c86ae6148..674e1ca8383a 100644 --- a/drivers/crypto/atmel-tdes.c +++ b/drivers/crypto/atmel-tdes.c @@ -565,7 +565,7 @@ static int atmel_tdes_crypt_start(struct atmel_tdes_dev *dd)
if (err && (dd->flags & TDES_FLAGS_FAST)) { dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); - dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_TO_DEVICE); + dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE); }
return err; diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c index a63ce2815d7d..f4a101016444 100644 --- a/drivers/firmware/meson/meson_sm.c +++ b/drivers/firmware/meson/meson_sm.c @@ -223,11 +223,16 @@ EXPORT_SYMBOL(meson_sm_call_write); struct meson_sm_firmware *meson_sm_get(struct device_node *sm_node) { struct platform_device *pdev = of_find_device_by_node(sm_node); + struct meson_sm_firmware *fw;
if (!pdev) return NULL;
- return platform_get_drvdata(pdev); + fw = platform_get_drvdata(pdev); + + put_device(&pdev->dev); + + return fw; } EXPORT_SYMBOL_GPL(meson_sm_get);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index 06c88dbc5a4a..753408bb4a2c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -1572,10 +1572,9 @@ int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct kgd_dev *kgd, struct amdgpu_device *adev;
adev = (struct amdgpu_device *)kgd; - if (atomic_read(&adev->gmc.vm_fault_info_updated) == 1) { + if (atomic_read_acquire(&adev->gmc.vm_fault_info_updated) == 1) { *mem = *adev->gmc.vm_fault_info; - mb(); - atomic_set(&adev->gmc.vm_fault_info_updated, 0); + atomic_set_release(&adev->gmc.vm_fault_info_updated, 0); } return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index 0c3d9bc3a641..f517cfa25309 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -1042,7 +1042,7 @@ static int gmc_v7_0_sw_init(void *handle) GFP_KERNEL); if (!adev->gmc.vm_fault_info) return -ENOMEM; - atomic_set(&adev->gmc.vm_fault_info_updated, 0); + atomic_set_release(&adev->gmc.vm_fault_info_updated, 0);
return 0; } @@ -1272,7 +1272,7 @@ static int gmc_v7_0_process_interrupt(struct amdgpu_device *adev, vmid = REG_GET_FIELD(status, VM_CONTEXT1_PROTECTION_FAULT_STATUS, VMID); if (amdgpu_amdkfd_is_kfd_vmid(adev, vmid) - && !atomic_read(&adev->gmc.vm_fault_info_updated)) { + && !atomic_read_acquire(&adev->gmc.vm_fault_info_updated)) { struct kfd_vm_fault_info *info = adev->gmc.vm_fault_info; u32 protections = REG_GET_FIELD(status, VM_CONTEXT1_PROTECTION_FAULT_STATUS, @@ -1288,8 +1288,7 @@ static int gmc_v7_0_process_interrupt(struct amdgpu_device *adev, info->prot_read = protections & 0x8 ? true : false; info->prot_write = protections & 0x10 ? true : false; info->prot_exec = protections & 0x20 ? true : false; - mb(); - atomic_set(&adev->gmc.vm_fault_info_updated, 1); + atomic_set_release(&adev->gmc.vm_fault_info_updated, 1); }
return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 2975331a7b86..d38171931a3e 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -1175,7 +1175,7 @@ static int gmc_v8_0_sw_init(void *handle) GFP_KERNEL); if (!adev->gmc.vm_fault_info) return -ENOMEM; - atomic_set(&adev->gmc.vm_fault_info_updated, 0); + atomic_set_release(&adev->gmc.vm_fault_info_updated, 0);
return 0; } @@ -1464,7 +1464,7 @@ static int gmc_v8_0_process_interrupt(struct amdgpu_device *adev, vmid = REG_GET_FIELD(status, VM_CONTEXT1_PROTECTION_FAULT_STATUS, VMID); if (amdgpu_amdkfd_is_kfd_vmid(adev, vmid) - && !atomic_read(&adev->gmc.vm_fault_info_updated)) { + && !atomic_read_acquire(&adev->gmc.vm_fault_info_updated)) { struct kfd_vm_fault_info *info = adev->gmc.vm_fault_info; u32 protections = REG_GET_FIELD(status, VM_CONTEXT1_PROTECTION_FAULT_STATUS, @@ -1480,8 +1480,7 @@ static int gmc_v8_0_process_interrupt(struct amdgpu_device *adev, info->prot_read = protections & 0x8 ? true : false; info->prot_write = protections & 0x10 ? true : false; info->prot_exec = protections & 0x20 ? true : false; - mb(); - atomic_set(&adev->gmc.vm_fault_info_updated, 1); + atomic_set_release(&adev->gmc.vm_fault_info_updated, 1); }
return 0; diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index a0049ee129ed..344375293ace 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -51,7 +51,6 @@ struct decon_context { void __iomem *regs; unsigned long irq_flags; bool i80_if; - bool suspended; wait_queue_head_t wait_vsync_queue; atomic_t wait_vsync_event;
@@ -85,9 +84,6 @@ static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc) { struct decon_context *ctx = crtc->ctx;
- if (ctx->suspended) - return; - atomic_set(&ctx->wait_vsync_event, 1);
/* @@ -155,9 +151,6 @@ static void decon_commit(struct exynos_drm_crtc *crtc) struct drm_display_mode *mode = &crtc->base.state->adjusted_mode; u32 val, clkdiv;
- if (ctx->suspended) - return; - /* nothing to do if we haven't set the mode yet */ if (mode->htotal == 0 || mode->vtotal == 0) return; @@ -219,9 +212,6 @@ static int decon_enable_vblank(struct exynos_drm_crtc *crtc) struct decon_context *ctx = crtc->ctx; u32 val;
- if (ctx->suspended) - return -EPERM; - if (!test_and_set_bit(0, &ctx->irq_flags)) { val = readl(ctx->regs + VIDINTCON0);
@@ -244,9 +234,6 @@ static void decon_disable_vblank(struct exynos_drm_crtc *crtc) struct decon_context *ctx = crtc->ctx; u32 val;
- if (ctx->suspended) - return; - if (test_and_clear_bit(0, &ctx->irq_flags)) { val = readl(ctx->regs + VIDINTCON0);
@@ -369,9 +356,6 @@ static void decon_atomic_begin(struct exynos_drm_crtc *crtc) struct decon_context *ctx = crtc->ctx; int i;
- if (ctx->suspended) - return; - for (i = 0; i < WINDOWS_NR; i++) decon_shadow_protect_win(ctx, i, true); } @@ -391,9 +375,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, unsigned int cpp = fb->format->cpp[0]; unsigned int pitch = fb->pitches[0];
- if (ctx->suspended) - return; - /* * SHADOWCON/PRTCON register is used for enabling timing. * @@ -481,9 +462,6 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, unsigned int win = plane->index; u32 val;
- if (ctx->suspended) - return; - /* protect windows */ decon_shadow_protect_win(ctx, win, true);
@@ -502,9 +480,6 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc) struct decon_context *ctx = crtc->ctx; int i;
- if (ctx->suspended) - return; - for (i = 0; i < WINDOWS_NR; i++) decon_shadow_protect_win(ctx, i, false); exynos_crtc_handle_event(crtc); @@ -531,9 +506,6 @@ static void decon_enable(struct exynos_drm_crtc *crtc) { struct decon_context *ctx = crtc->ctx;
- if (!ctx->suspended) - return; - pm_runtime_get_sync(ctx->dev);
decon_init(ctx); @@ -543,8 +515,6 @@ static void decon_enable(struct exynos_drm_crtc *crtc) decon_enable_vblank(ctx->crtc);
decon_commit(ctx->crtc); - - ctx->suspended = false; }
static void decon_disable(struct exynos_drm_crtc *crtc) @@ -552,9 +522,6 @@ static void decon_disable(struct exynos_drm_crtc *crtc) struct decon_context *ctx = crtc->ctx; int i;
- if (ctx->suspended) - return; - /* * We need to make sure that all windows are disabled before we * suspend that connector. Otherwise we might try to scan from @@ -564,8 +531,6 @@ static void decon_disable(struct exynos_drm_crtc *crtc) decon_disable_plane(crtc, &ctx->planes[i]);
pm_runtime_put_sync(ctx->dev); - - ctx->suspended = true; }
static const struct exynos_drm_crtc_ops decon_crtc_ops = { @@ -687,7 +652,6 @@ static int decon_probe(struct platform_device *pdev) return -ENOMEM;
ctx->dev = dev; - ctx->suspended = true;
i80_if_timings = of_get_child_by_name(dev->of_node, "i80-if-timings"); if (i80_if_timings) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index e67ead37d63e..b046da2a5cb2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1122,7 +1122,7 @@ nouveau_bo_move_prep(struct nouveau_drm *drm, struct ttm_buffer_object *bo, nvif_vmm_put(vmm, &old_mem->vma[1]); nvif_vmm_put(vmm, &old_mem->vma[0]); } - return 0; + return ret; }
static int diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index a85470213b27..637a4f2a30af 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -1411,7 +1411,7 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, unsigned block_align, unsigned height_align, unsigned base_align, unsigned *l0_size, unsigned *mipmap_size) { - unsigned offset, i, level; + unsigned offset, i; unsigned width, height, depth, size; unsigned blocksize; unsigned nbx, nby; @@ -1423,7 +1423,7 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, w0 = r600_mip_minify(w0, 0); h0 = r600_mip_minify(h0, 0); d0 = r600_mip_minify(d0, 0); - for(i = 0, offset = 0, level = blevel; i < nlevels; i++, level++) { + for (i = 0, offset = 0; i < nlevels; i++) { width = r600_mip_minify(w0, i); nbx = r600_fmt_get_nblocksx(format, width);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c index f611b2290a1b..a18b9bb0631c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c @@ -339,8 +339,10 @@ int vmw_validation_add_resource(struct vmw_validation_context *ctx, } } node->res = vmw_resource_reference_unless_doomed(res); - if (!node->res) + if (!node->res) { + hash_del_rcu(&node->hash.head); return -ESRCH; + }
node->first_usage = 1; if (!res->dev_priv->has_mob) { diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 75313c80f132..fd5ffe13c703 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -414,6 +414,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
exit_probe: dw_i2c_plat_pm_cleanup(dev); + i2c_dw_prepare_clk(dev, false); exit_reset: reset_control_assert(dev->rst); return ret; diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 5587e7c549c4..2b56ad08efed 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -782,6 +782,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, { int ret; int left_num = num; + bool write_then_read_en = false; struct mtk_i2c *i2c = i2c_get_adapdata(adap);
ret = mtk_i2c_clock_enable(i2c); @@ -795,6 +796,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, if (!(msgs[0].flags & I2C_M_RD) && (msgs[1].flags & I2C_M_RD) && msgs[0].addr == msgs[1].addr) { i2c->auto_restart = 0; + write_then_read_en = true; } }
@@ -818,12 +820,10 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, else i2c->op = I2C_MASTER_WR;
- if (!i2c->auto_restart) { - if (num > 1) { - /* combined two messages into one transaction */ - i2c->op = I2C_MASTER_WRRD; - left_num--; - } + if (write_then_read_en) { + /* combined two messages into one transaction */ + i2c->op = I2C_MASTER_WRRD; + left_num--; }
/* always use DMA mode. */ @@ -831,7 +831,10 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, if (ret < 0) goto err_exit;
- msgs++; + if (i2c->op == I2C_MASTER_WRRD) + msgs += 2; + else + msgs++; } /* the return value is number of executed messages */ ret = num; diff --git a/drivers/iio/dac/ad5360.c b/drivers/iio/dac/ad5360.c index 2ac428b957e3..5a3ae91726f9 100644 --- a/drivers/iio/dac/ad5360.c +++ b/drivers/iio/dac/ad5360.c @@ -259,7 +259,7 @@ static int ad5360_update_ctrl(struct iio_dev *indio_dev, unsigned int set, unsigned int clr) { struct ad5360_state *st = iio_priv(indio_dev); - unsigned int ret; + int ret;
mutex_lock(&indio_dev->mlock);
diff --git a/drivers/iio/dac/ad5421.c b/drivers/iio/dac/ad5421.c index 63063e85cd0a..8cae84586abb 100644 --- a/drivers/iio/dac/ad5421.c +++ b/drivers/iio/dac/ad5421.c @@ -183,7 +183,7 @@ static int ad5421_update_ctrl(struct iio_dev *indio_dev, unsigned int set, unsigned int clr) { struct ad5421_state *st = iio_priv(indio_dev); - unsigned int ret; + int ret;
mutex_lock(&indio_dev->mlock);
diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c index ae0ca09ae062..00207d924e88 100644 --- a/drivers/iio/frequency/adf4350.c +++ b/drivers/iio/frequency/adf4350.c @@ -137,6 +137,19 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq) if (freq > ADF4350_MAX_OUT_FREQ || freq < st->min_out_freq) return -EINVAL;
+ st->r4_rf_div_sel = 0; + + /* + * !\TODO: The below computation is making sure we get a power of 2 + * shift (st->r4_rf_div_sel) so that freq becomes higher or equal to + * ADF4350_MIN_VCO_FREQ. This might be simplified with fls()/fls_long() + * and friends. + */ + while (freq < ADF4350_MIN_VCO_FREQ) { + freq <<= 1; + st->r4_rf_div_sel++; + } + if (freq > ADF4350_MAX_FREQ_45_PRESC) { prescaler = ADF4350_REG1_PRESCALER; mdiv = 75; @@ -145,13 +158,6 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq) mdiv = 23; }
- st->r4_rf_div_sel = 0; - - while (freq < ADF4350_MIN_VCO_FREQ) { - freq <<= 1; - st->r4_rf_div_sel++; - } - /* * Allow a predefined reference division factor * if not set, compute our own diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 6374d5091555..6bdd175df021 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -627,7 +627,7 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan, * If no channel scaling is available apply consumer scale to * raw value and return. */ - *processed = raw * scale; + *processed = raw64 * scale; return 0; }
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index c9e63c692b6e..48de2285922f 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -459,14 +459,10 @@ static int addr_resolve_neigh(const struct dst_entry *dst, { int ret = 0;
- if (ndev_flags & IFF_LOOPBACK) { + if (ndev_flags & IFF_LOOPBACK) memcpy(addr->dst_dev_addr, addr->src_dev_addr, MAX_ADDR_LEN); - } else { - if (!(ndev_flags & IFF_NOARP)) { - /* If the device doesn't do ARP internally */ - ret = fetch_ha(dst, addr, dst_in, seq); - } - } + else + ret = fetch_ha(dst, addr, dst_in, seq); return ret; }
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 11ab6390eda4..b05df8694a4a 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -1036,6 +1036,8 @@ int ib_nl_handle_set_timeout(struct sk_buff *skb, if (timeout > IB_SA_LOCAL_SVC_TIMEOUT_MAX) timeout = IB_SA_LOCAL_SVC_TIMEOUT_MAX;
+ spin_lock_irqsave(&ib_nl_request_lock, flags); + delta = timeout - sa_local_svc_timeout_ms; if (delta < 0) abs_delta = -delta; @@ -1043,7 +1045,6 @@ int ib_nl_handle_set_timeout(struct sk_buff *skb, abs_delta = delta;
if (delta != 0) { - spin_lock_irqsave(&ib_nl_request_lock, flags); sa_local_svc_timeout_ms = timeout; list_for_each_entry(query, &ib_nl_request_list, list) { if (delta < 0 && abs_delta > query->timeout) @@ -1061,9 +1062,10 @@ int ib_nl_handle_set_timeout(struct sk_buff *skb, if (delay) mod_delayed_work(ib_nl_wq, &ib_nl_timed_work, (unsigned long)delay); - spin_unlock_irqrestore(&ib_nl_request_lock, flags); }
+ spin_unlock_irqrestore(&ib_nl_request_lock, flags); + settimeout_out: return 0; } diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c index 236f9efaa75c..b5a845985ba4 100644 --- a/drivers/infiniband/sw/siw/siw_verbs.c +++ b/drivers/infiniband/sw/siw/siw_verbs.c @@ -779,7 +779,7 @@ int siw_post_send(struct ib_qp *base_qp, const struct ib_send_wr *wr, struct siw_wqe *wqe = tx_wqe(qp);
unsigned long flags; - int rv = 0; + int rv = 0, imm_err = 0;
if (wr && !qp->kernel_verbs) { siw_dbg_qp(qp, "wr must be empty for user mapped sq\n"); @@ -965,9 +965,17 @@ int siw_post_send(struct ib_qp *base_qp, const struct ib_send_wr *wr, * Send directly if SQ processing is not in progress. * Eventual immediate errors (rv < 0) do not affect the involved * RI resources (Verbs, 8.3.1) and thus do not prevent from SQ - * processing, if new work is already pending. But rv must be passed - * to caller. + * processing, if new work is already pending. But rv and pointer + * to failed work request must be passed to caller. */ + if (unlikely(rv < 0)) { + /* + * Immediate error + */ + siw_dbg_qp(qp, "Immediate error %d\n", rv); + imm_err = rv; + *bad_wr = wr; + } if (wqe->wr_status != SIW_WR_IDLE) { spin_unlock_irqrestore(&qp->sq_lock, flags); goto skip_direct_sending; @@ -992,15 +1000,10 @@ int siw_post_send(struct ib_qp *base_qp, const struct ib_send_wr *wr,
up_read(&qp->state_lock);
- if (rv >= 0) - return 0; - /* - * Immediate error - */ - siw_dbg_qp(qp, "error %d\n", rv); + if (unlikely(imm_err)) + return imm_err;
- *bad_wr = wr; - return rv; + return (rv >= 0) ? 0 : rv; }
/* diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index e707da0b1fe2..8c9644e04ff3 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -740,6 +740,7 @@ static int uinput_ff_upload_to_user(char __user *buffer, if (in_compat_syscall()) { struct uinput_ff_upload_compat ff_up_compat;
+ memset(&ff_up_compat, 0, sizeof(ff_up_compat)); ff_up_compat.request_id = ff_up->request_id; ff_up_compat.retval = ff_up->retval; /* diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c index bb7bb1738647..dcabf38859ec 100644 --- a/drivers/mailbox/zynqmp-ipi-mailbox.c +++ b/drivers/mailbox/zynqmp-ipi-mailbox.c @@ -618,11 +618,8 @@ static void zynqmp_ipi_free_mboxes(struct zynqmp_ipi_pdata *pdata) i = pdata->num_mboxes; for (; i >= 0; i--) { ipi_mbox = &pdata->ipi_mboxes[i]; - if (ipi_mbox->dev.parent) { - mbox_controller_unregister(&ipi_mbox->mbox); - if (device_is_registered(&ipi_mbox->dev)) - device_unregister(&ipi_mbox->dev); - } + if (device_is_registered(&ipi_mbox->dev)) + device_unregister(&ipi_mbox->dev); } }
diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index 15580ba773e7..38791b7e59ba 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -116,7 +116,7 @@ struct journal_sector { commit_id_t commit_id; };
-#define MAX_TAG_SIZE (JOURNAL_SECTOR_DATA - JOURNAL_MAC_PER_SECTOR - offsetof(struct journal_entry, last_bytes[MAX_SECTORS_PER_BLOCK])) +#define MAX_TAG_SIZE 255
#define METADATA_PADDING_SECTORS 8
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 3d00bb98d702..be7182adcdd5 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -2595,7 +2595,7 @@ static int __dm_suspend(struct mapped_device *md, struct dm_table *map, { bool do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG; bool noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG; - int r; + int r = 0;
lockdep_assert_held(&md->suspend_lock);
@@ -2648,7 +2648,7 @@ static int __dm_suspend(struct mapped_device *md, struct dm_table *map, * Stop md->queue before flushing md->wq in case request-based * dm defers requests to md->wq from md->queue. */ - if (dm_request_based(md)) + if (map && dm_request_based(md)) dm_stop_queue(md->queue);
flush_workqueue(md->wq); @@ -2658,7 +2658,8 @@ static int __dm_suspend(struct mapped_device *md, struct dm_table *map, * We call dm_wait_for_completion to wait for all existing requests * to finish. */ - r = dm_wait_for_completion(md, task_state); + if (map) + r = dm_wait_for_completion(md, task_state); if (!r) set_bit(dmf_suspended_flag, &md->flags);
diff --git a/drivers/media/i2c/mt9v111.c b/drivers/media/i2c/mt9v111.c index bb41bea950ac..4dc56a9fd0b3 100644 --- a/drivers/media/i2c/mt9v111.c +++ b/drivers/media/i2c/mt9v111.c @@ -534,8 +534,8 @@ static int mt9v111_calc_frame_rate(struct mt9v111_dev *mt9v111, static int mt9v111_hw_config(struct mt9v111_dev *mt9v111) { struct i2c_client *c = mt9v111->client; - unsigned int ret; u16 outfmtctrl2; + int ret;
/* Force device reset. */ ret = __mt9v111_hw_reset(mt9v111); diff --git a/drivers/media/i2c/rj54n1cb0c.c b/drivers/media/i2c/rj54n1cb0c.c index 4cc51e001874..b35b3e428686 100644 --- a/drivers/media/i2c/rj54n1cb0c.c +++ b/drivers/media/i2c/rj54n1cb0c.c @@ -1332,10 +1332,13 @@ static int rj54n1_probe(struct i2c_client *client, V4L2_CID_GAIN, 0, 127, 1, 66); v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops, V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1); - rj54n1->subdev.ctrl_handler = &rj54n1->hdl; - if (rj54n1->hdl.error) - return rj54n1->hdl.error;
+ if (rj54n1->hdl.error) { + ret = rj54n1->hdl.error; + goto err_free_ctrl; + } + + rj54n1->subdev.ctrl_handler = &rj54n1->hdl; rj54n1->clk_div = clk_div; rj54n1->rect.left = RJ54N1_COLUMN_SKIP; rj54n1->rect.top = RJ54N1_ROW_SKIP; diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 2dad35568586..4ac84c0b7f8d 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -2200,10 +2200,10 @@ static int tc358743_probe(struct i2c_client *client) err_work_queues: cec_unregister_adapter(state->cec_adap); if (!state->i2c_client->irq) { - del_timer(&state->timer); + timer_delete_sync(&state->timer); flush_work(&state->work_i2c_poll); } - cancel_delayed_work(&state->delayed_work_enable_hotplug); + cancel_delayed_work_sync(&state->delayed_work_enable_hotplug); mutex_destroy(&state->confctl_mutex); err_hdl: media_entity_cleanup(&sd->entity); diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index f249199dc616..f8257aa5fc58 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -50,11 +50,6 @@ static void media_devnode_release(struct device *cd) { struct media_devnode *devnode = to_media_devnode(cd);
- mutex_lock(&media_devnode_lock); - /* Mark device node number as free */ - clear_bit(devnode->minor, media_devnode_nums); - mutex_unlock(&media_devnode_lock); - /* Release media_devnode and perform other cleanups as needed. */ if (devnode->release) devnode->release(devnode); @@ -283,6 +278,7 @@ void media_devnode_unregister(struct media_devnode *devnode) /* Delete the cdev on this minor as well */ cdev_device_del(&devnode->cdev, &devnode->dev); devnode->media_dev = NULL; + clear_bit(devnode->minor, media_devnode_nums); mutex_unlock(&media_devnode_lock);
put_device(&devnode->dev); diff --git a/drivers/media/pci/b2c2/flexcop-pci.c b/drivers/media/pci/b2c2/flexcop-pci.c index c9e6c7d66376..976e5dead34f 100644 --- a/drivers/media/pci/b2c2/flexcop-pci.c +++ b/drivers/media/pci/b2c2/flexcop-pci.c @@ -411,7 +411,7 @@ static void flexcop_pci_remove(struct pci_dev *pdev) struct flexcop_pci *fc_pci = pci_get_drvdata(pdev);
if (irq_chk_intv > 0) - cancel_delayed_work(&fc_pci->irq_check_work); + cancel_delayed_work_sync(&fc_pci->irq_check_work);
flexcop_pci_dma_exit(fc_pci); flexcop_device_exit(fc_pci->fc_dev); diff --git a/drivers/media/pci/cx18/cx18-queue.c b/drivers/media/pci/cx18/cx18-queue.c index 2f5df471dada..9b247ecf48d5 100644 --- a/drivers/media/pci/cx18/cx18-queue.c +++ b/drivers/media/pci/cx18/cx18-queue.c @@ -379,14 +379,22 @@ int cx18_stream_alloc(struct cx18_stream *s) break; }
+ buf->dma_handle = dma_map_single(&s->cx->pci_dev->dev, + buf->buf, s->buf_size, + s->dma); + if (dma_mapping_error(&s->cx->pci_dev->dev, buf->dma_handle)) { + kfree(buf->buf); + kfree(mdl); + kfree(buf); + break; + } + INIT_LIST_HEAD(&mdl->list); INIT_LIST_HEAD(&mdl->buf_list); mdl->id = s->mdl_base_idx; /* a somewhat safe value */ cx18_enqueue(s, mdl, &s->q_idle);
INIT_LIST_HEAD(&buf->list); - buf->dma_handle = pci_map_single(s->cx->pci_dev, - buf->buf, s->buf_size, s->dma); cx18_buf_sync_for_cpu(s, buf); list_add_tail(&buf->list, &s->buf_pool); } diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c index 3f3f40ea890b..e0d9b8f8c986 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.c +++ b/drivers/media/pci/ivtv/ivtv-driver.c @@ -843,7 +843,7 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev, IVTV_ERR("Can't enable device!\n"); return -EIO; } - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { + if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) { IVTV_ERR("No suitable DMA available.\n"); return -EIO; } diff --git a/drivers/media/pci/ivtv/ivtv-irq.c b/drivers/media/pci/ivtv/ivtv-irq.c index b7aaa8b4a784..e39bf64c5c71 100644 --- a/drivers/media/pci/ivtv/ivtv-irq.c +++ b/drivers/media/pci/ivtv/ivtv-irq.c @@ -351,7 +351,7 @@ void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock)
/* Insert buffer block for YUV if needed */ if (s->type == IVTV_DEC_STREAM_TYPE_YUV && f->offset_y) { - if (yi->blanking_dmaptr) { + if (yi->blanking_ptr) { s->sg_pending[idx].src = yi->blanking_dmaptr; s->sg_pending[idx].dst = offset; s->sg_pending[idx].size = 720 * 16; diff --git a/drivers/media/pci/ivtv/ivtv-queue.c b/drivers/media/pci/ivtv/ivtv-queue.c index 7ac4615e92ea..f9b192ab7e7c 100644 --- a/drivers/media/pci/ivtv/ivtv-queue.c +++ b/drivers/media/pci/ivtv/ivtv-queue.c @@ -188,7 +188,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s) return 0;
IVTV_DEBUG_INFO("Allocate %s%s stream: %d x %d buffers (%dkB total)\n", - s->dma != PCI_DMA_NONE ? "DMA " : "", + s->dma != DMA_NONE ? "DMA " : "", s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024);
s->sg_pending = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN); @@ -218,8 +218,9 @@ int ivtv_stream_alloc(struct ivtv_stream *s) return -ENOMEM; } if (ivtv_might_use_dma(s)) { - s->sg_handle = pci_map_single(itv->pdev, s->sg_dma, - sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE); + s->sg_handle = dma_map_single(&itv->pdev->dev, s->sg_dma, + sizeof(struct ivtv_sg_element), + DMA_TO_DEVICE); ivtv_stream_sync_for_cpu(s); }
@@ -237,7 +238,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s) } INIT_LIST_HEAD(&buf->list); if (ivtv_might_use_dma(s)) { - buf->dma_handle = pci_map_single(s->itv->pdev, + buf->dma_handle = dma_map_single(&s->itv->pdev->dev, buf->buf, s->buf_size + 256, s->dma); ivtv_buf_sync_for_cpu(s, buf); } @@ -260,8 +261,8 @@ void ivtv_stream_free(struct ivtv_stream *s) /* empty q_free */ while ((buf = ivtv_dequeue(s, &s->q_free))) { if (ivtv_might_use_dma(s)) - pci_unmap_single(s->itv->pdev, buf->dma_handle, - s->buf_size + 256, s->dma); + dma_unmap_single(&s->itv->pdev->dev, buf->dma_handle, + s->buf_size + 256, s->dma); kfree(buf->buf); kfree(buf); } @@ -269,8 +270,9 @@ void ivtv_stream_free(struct ivtv_stream *s) /* Free SG Array/Lists */ if (s->sg_dma != NULL) { if (s->sg_handle != IVTV_DMA_UNMAPPED) { - pci_unmap_single(s->itv->pdev, s->sg_handle, - sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE); + dma_unmap_single(&s->itv->pdev->dev, s->sg_handle, + sizeof(struct ivtv_sg_element), + DMA_TO_DEVICE); s->sg_handle = IVTV_DMA_UNMAPPED; } kfree(s->sg_pending); diff --git a/drivers/media/pci/ivtv/ivtv-streams.c b/drivers/media/pci/ivtv/ivtv-streams.c index f9de5d1605fe..13d7d55e6594 100644 --- a/drivers/media/pci/ivtv/ivtv-streams.c +++ b/drivers/media/pci/ivtv/ivtv-streams.c @@ -100,7 +100,7 @@ static struct { { /* IVTV_ENC_STREAM_TYPE_MPG */ "encoder MPG", VFL_TYPE_VIDEO, 0, - PCI_DMA_FROMDEVICE, 0, + DMA_FROM_DEVICE, 0, V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_enc_fops @@ -108,7 +108,7 @@ static struct { { /* IVTV_ENC_STREAM_TYPE_YUV */ "encoder YUV", VFL_TYPE_VIDEO, IVTV_V4L2_ENC_YUV_OFFSET, - PCI_DMA_FROMDEVICE, 0, + DMA_FROM_DEVICE, 0, V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_enc_fops @@ -116,7 +116,7 @@ static struct { { /* IVTV_ENC_STREAM_TYPE_VBI */ "encoder VBI", VFL_TYPE_VBI, 0, - PCI_DMA_FROMDEVICE, 0, + DMA_FROM_DEVICE, 0, V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_enc_fops @@ -124,42 +124,42 @@ static struct { { /* IVTV_ENC_STREAM_TYPE_PCM */ "encoder PCM", VFL_TYPE_VIDEO, IVTV_V4L2_ENC_PCM_OFFSET, - PCI_DMA_FROMDEVICE, 0, + DMA_FROM_DEVICE, 0, V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_enc_fops }, { /* IVTV_ENC_STREAM_TYPE_RAD */ "encoder radio", VFL_TYPE_RADIO, 0, - PCI_DMA_NONE, 1, + DMA_NONE, 1, V4L2_CAP_RADIO | V4L2_CAP_TUNER, &ivtv_v4l2_radio_fops }, { /* IVTV_DEC_STREAM_TYPE_MPG */ "decoder MPG", VFL_TYPE_VIDEO, IVTV_V4L2_DEC_MPG_OFFSET, - PCI_DMA_TODEVICE, 0, + DMA_TO_DEVICE, 0, V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_dec_fops }, { /* IVTV_DEC_STREAM_TYPE_VBI */ "decoder VBI", VFL_TYPE_VBI, IVTV_V4L2_DEC_VBI_OFFSET, - PCI_DMA_NONE, 1, + DMA_NONE, 1, V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_READWRITE, &ivtv_v4l2_enc_fops }, { /* IVTV_DEC_STREAM_TYPE_VOUT */ "decoder VOUT", VFL_TYPE_VBI, IVTV_V4L2_DEC_VOUT_OFFSET, - PCI_DMA_NONE, 1, + DMA_NONE, 1, V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_dec_fops }, { /* IVTV_DEC_STREAM_TYPE_YUV */ "decoder YUV", VFL_TYPE_VIDEO, IVTV_V4L2_DEC_YUV_OFFSET, - PCI_DMA_TODEVICE, 0, + DMA_TO_DEVICE, 0, V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_dec_fops } @@ -179,7 +179,7 @@ static void ivtv_stream_init(struct ivtv *itv, int type) s->vdev.device_caps = ivtv_stream_info[type].v4l2_caps;
if (ivtv_stream_info[type].pio) - s->dma = PCI_DMA_NONE; + s->dma = DMA_NONE; else s->dma = ivtv_stream_info[type].dma; s->buf_size = itv->stream_buf_size[type]; @@ -217,7 +217,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
/* User explicitly selected 0 buffers for these streams, so don't create them. */ - if (ivtv_stream_info[type].dma != PCI_DMA_NONE && + if (ivtv_stream_info[type].dma != DMA_NONE && itv->options.kilobytes[type] == 0) { IVTV_INFO("Disabled %s device\n", ivtv_stream_info[type].name); return 0; diff --git a/drivers/media/pci/ivtv/ivtv-udma.c b/drivers/media/pci/ivtv/ivtv-udma.c index 5f8883031c9c..7dff08696304 100644 --- a/drivers/media/pci/ivtv/ivtv-udma.c +++ b/drivers/media/pci/ivtv/ivtv-udma.c @@ -81,8 +81,10 @@ void ivtv_udma_alloc(struct ivtv *itv) { if (itv->udma.SG_handle == 0) { /* Map DMA Page Array Buffer */ - itv->udma.SG_handle = pci_map_single(itv->pdev, itv->udma.SGarray, - sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE); + itv->udma.SG_handle = dma_map_single(&itv->pdev->dev, + itv->udma.SGarray, + sizeof(itv->udma.SGarray), + DMA_TO_DEVICE); ivtv_udma_sync_for_cpu(itv); } } @@ -138,7 +140,8 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr, }
/* Map SG List */ - dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); + dma->SG_length = dma_map_sg(&itv->pdev->dev, dma->SGlist, + dma->page_count, DMA_TO_DEVICE);
/* Fill SG Array with new values */ ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1); @@ -163,7 +166,8 @@ void ivtv_udma_unmap(struct ivtv *itv)
/* Unmap Scatterlist */ if (dma->SG_length) { - pci_unmap_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); + dma_unmap_sg(&itv->pdev->dev, dma->SGlist, dma->page_count, + DMA_TO_DEVICE); dma->SG_length = 0; } /* sync DMA */ @@ -182,13 +186,14 @@ void ivtv_udma_free(struct ivtv *itv)
/* Unmap SG Array */ if (itv->udma.SG_handle) { - pci_unmap_single(itv->pdev, itv->udma.SG_handle, - sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE); + dma_unmap_single(&itv->pdev->dev, itv->udma.SG_handle, + sizeof(itv->udma.SGarray), DMA_TO_DEVICE); }
/* Unmap Scatterlist */ if (itv->udma.SG_length) { - pci_unmap_sg(itv->pdev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE); + dma_unmap_sg(&itv->pdev->dev, itv->udma.SGlist, + itv->udma.page_count, DMA_TO_DEVICE); }
for (i = 0; i < IVTV_DMA_SG_OSD_ENT; i++) { diff --git a/drivers/media/pci/ivtv/ivtv-yuv.c b/drivers/media/pci/ivtv/ivtv-yuv.c index cd2fe2d444c0..1b101b032a35 100644 --- a/drivers/media/pci/ivtv/ivtv-yuv.c +++ b/drivers/media/pci/ivtv/ivtv-yuv.c @@ -118,13 +118,14 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma, dma->page_count = 0; return -ENOMEM; } - dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); + dma->SG_length = dma_map_sg(&itv->pdev->dev, dma->SGlist, + dma->page_count, DMA_TO_DEVICE);
/* Fill SG Array with new values */ ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size);
/* If we've offset the y plane, ensure top area is blanked */ - if (f->offset_y && yi->blanking_dmaptr) { + if (f->offset_y && yi->blanking_ptr) { dma->SGarray[dma->SG_length].size = cpu_to_le32(720*16); dma->SGarray[dma->SG_length].src = cpu_to_le32(yi->blanking_dmaptr); dma->SGarray[dma->SG_length].dst = cpu_to_le32(IVTV_DECODER_OFFSET + yuv_offset[frame]); @@ -925,7 +926,15 @@ static void ivtv_yuv_init(struct ivtv *itv) /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */ yi->blanking_ptr = kzalloc(720 * 16, GFP_ATOMIC|__GFP_NOWARN); if (yi->blanking_ptr) { - yi->blanking_dmaptr = pci_map_single(itv->pdev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE); + yi->blanking_dmaptr = dma_map_single(&itv->pdev->dev, + yi->blanking_ptr, + 720 * 16, DMA_TO_DEVICE); + if (dma_mapping_error(&itv->pdev->dev, yi->blanking_dmaptr)) { + kfree(yi->blanking_ptr); + yi->blanking_ptr = NULL; + yi->blanking_dmaptr = 0; + IVTV_DEBUG_WARN("Failed to dma_map yuv blanking buffer\n"); + } } else { yi->blanking_dmaptr = 0; IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n"); @@ -1269,7 +1278,8 @@ void ivtv_yuv_close(struct ivtv *itv) if (yi->blanking_ptr) { kfree(yi->blanking_ptr); yi->blanking_ptr = NULL; - pci_unmap_single(itv->pdev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE); + dma_unmap_single(&itv->pdev->dev, yi->blanking_dmaptr, + 720 * 16, DMA_TO_DEVICE); }
/* Invalidate the old dimension information */ diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c index 1f42130cc865..23c47d92c071 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c @@ -14,8 +14,7 @@ #include "s5p_mfc_opr.h" #include "s5p_mfc_cmd_v6.h"
-static int s5p_mfc_cmd_host2risc_v6(struct s5p_mfc_dev *dev, int cmd, - struct s5p_mfc_cmd_args *args) +static int s5p_mfc_cmd_host2risc_v6(struct s5p_mfc_dev *dev, int cmd) { mfc_debug(2, "Issue the command: %d\n", cmd);
@@ -31,7 +30,6 @@ static int s5p_mfc_cmd_host2risc_v6(struct s5p_mfc_dev *dev, int cmd,
static int s5p_mfc_sys_init_cmd_v6(struct s5p_mfc_dev *dev) { - struct s5p_mfc_cmd_args h2r_args; struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv; int ret;
@@ -41,33 +39,23 @@ static int s5p_mfc_sys_init_cmd_v6(struct s5p_mfc_dev *dev)
mfc_write(dev, dev->ctx_buf.dma, S5P_FIMV_CONTEXT_MEM_ADDR_V6); mfc_write(dev, buf_size->dev_ctx, S5P_FIMV_CONTEXT_MEM_SIZE_V6); - return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_SYS_INIT_V6, - &h2r_args); + return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_SYS_INIT_V6); }
static int s5p_mfc_sleep_cmd_v6(struct s5p_mfc_dev *dev) { - struct s5p_mfc_cmd_args h2r_args; - - memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args)); - return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_SLEEP_V6, - &h2r_args); + return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_SLEEP_V6); }
static int s5p_mfc_wakeup_cmd_v6(struct s5p_mfc_dev *dev) { - struct s5p_mfc_cmd_args h2r_args; - - memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args)); - return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_WAKEUP_V6, - &h2r_args); + return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_WAKEUP_V6); }
/* Open a new instance and get its number */ static int s5p_mfc_open_inst_cmd_v6(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; - struct s5p_mfc_cmd_args h2r_args; int codec_type;
mfc_debug(2, "Requested codec mode: %d\n", ctx->codec_mode); @@ -129,23 +117,20 @@ static int s5p_mfc_open_inst_cmd_v6(struct s5p_mfc_ctx *ctx) mfc_write(dev, ctx->ctx.size, S5P_FIMV_CONTEXT_MEM_SIZE_V6); mfc_write(dev, 0, S5P_FIMV_D_CRC_CTRL_V6); /* no crc */
- return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE_V6, - &h2r_args); + return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE_V6); }
/* Close instance */ static int s5p_mfc_close_inst_cmd_v6(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; - struct s5p_mfc_cmd_args h2r_args; int ret = 0;
dev->curr_ctx = ctx->num; if (ctx->state != MFCINST_FREE) { mfc_write(dev, ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6); ret = s5p_mfc_cmd_host2risc_v6(dev, - S5P_FIMV_H2R_CMD_CLOSE_INSTANCE_V6, - &h2r_args); + S5P_FIMV_H2R_CMD_CLOSE_INSTANCE_V6); } else { ret = -EINVAL; } @@ -153,9 +138,15 @@ static int s5p_mfc_close_inst_cmd_v6(struct s5p_mfc_ctx *ctx) return ret; }
+static int s5p_mfc_cmd_host2risc_v6_args(struct s5p_mfc_dev *dev, int cmd, + struct s5p_mfc_cmd_args *ignored) +{ + return s5p_mfc_cmd_host2risc_v6(dev, cmd); +} + /* Initialize cmd function pointers for MFC v6 */ static struct s5p_mfc_hw_cmds s5p_mfc_cmds_v6 = { - .cmd_host2risc = s5p_mfc_cmd_host2risc_v6, + .cmd_host2risc = s5p_mfc_cmd_host2risc_v6_args, .sys_init_cmd = s5p_mfc_sys_init_cmd_v6, .sleep_cmd = s5p_mfc_sleep_cmd_v6, .wakeup_cmd = s5p_mfc_wakeup_cmd_v6, diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 38f6dd12d870..8cab6e1500b7 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -83,6 +83,7 @@ struct imon_usb_dev_descr { __u16 flags; #define IMON_NO_FLAGS 0 #define IMON_NEED_20MS_PKT_DELAY 1 +#define IMON_SUPPRESS_REPEATED_KEYS 2 struct imon_panel_key_table key_table[]; };
@@ -149,8 +150,27 @@ struct imon_context { struct timer_list ttimer; /* touch screen timer */ int touch_x; /* x coordinate on touchscreen */ int touch_y; /* y coordinate on touchscreen */ - struct imon_usb_dev_descr *dev_descr; /* device description with key - table for front panels */ + const struct imon_usb_dev_descr *dev_descr; + /* device description with key */ + /* table for front panels */ + /* + * Fields for deferring free_imon_context(). + * + * Since reference to "struct imon_context" is stored into + * "struct file"->private_data, we need to remember + * how many file descriptors might access this "struct imon_context". + */ + refcount_t users; + /* + * Use a flag for telling display_open()/vfd_write()/lcd_write() that + * imon_disconnect() was already called. + */ + bool disconnected; + /* + * We need to wait for RCU grace period in order to allow + * display_open() to safely check ->disconnected and increment ->users. + */ + struct rcu_head rcu; };
#define TOUCH_TIMEOUT (HZ/30) @@ -158,18 +178,18 @@ struct imon_context { /* vfd character device file operations */ static const struct file_operations vfd_fops = { .owner = THIS_MODULE, - .open = &display_open, - .write = &vfd_write, - .release = &display_close, + .open = display_open, + .write = vfd_write, + .release = display_close, .llseek = noop_llseek, };
/* lcd character device file operations */ static const struct file_operations lcd_fops = { .owner = THIS_MODULE, - .open = &display_open, - .write = &lcd_write, - .release = &display_close, + .open = display_open, + .write = lcd_write, + .release = display_close, .llseek = noop_llseek, };
@@ -315,6 +335,32 @@ static const struct imon_usb_dev_descr imon_DH102 = { } };
+/* imon ultrabay front panel key table */ +static const struct imon_usb_dev_descr ultrabay_table = { + .flags = IMON_SUPPRESS_REPEATED_KEYS, + .key_table = { + { 0x0000000f0000ffeell, KEY_MEDIA }, /* Go */ + { 0x000000000100ffeell, KEY_UP }, + { 0x000000000001ffeell, KEY_DOWN }, + { 0x000000160000ffeell, KEY_ENTER }, + { 0x0000001f0000ffeell, KEY_AUDIO }, /* Music */ + { 0x000000200000ffeell, KEY_VIDEO }, /* Movie */ + { 0x000000210000ffeell, KEY_CAMERA }, /* Photo */ + { 0x000000270000ffeell, KEY_DVD }, /* DVD */ + { 0x000000230000ffeell, KEY_TV }, /* TV */ + { 0x000000050000ffeell, KEY_PREVIOUS }, /* Previous */ + { 0x000000070000ffeell, KEY_REWIND }, + { 0x000000040000ffeell, KEY_STOP }, + { 0x000000020000ffeell, KEY_PLAYPAUSE }, + { 0x000000080000ffeell, KEY_FASTFORWARD }, + { 0x000000060000ffeell, KEY_NEXT }, /* Next */ + { 0x000100000000ffeell, KEY_VOLUMEUP }, + { 0x010000000000ffeell, KEY_VOLUMEDOWN }, + { 0x000000010000ffeell, KEY_MUTE }, + { 0, KEY_RESERVED }, + } +}; + /* * USB Device ID for iMON USB Control Boards * @@ -411,9 +457,6 @@ static struct usb_driver imon_driver = { .id_table = imon_usb_id_table, };
-/* to prevent races between open() and disconnect(), probing, etc */ -static DEFINE_MUTEX(driver_lock); - /* Module bookkeeping bits */ MODULE_AUTHOR(MOD_AUTHOR); MODULE_DESCRIPTION(MOD_DESC); @@ -453,9 +496,11 @@ static void free_imon_context(struct imon_context *ictx) struct device *dev = ictx->dev;
usb_free_urb(ictx->tx_urb); + WARN_ON(ictx->dev_present_intf0); usb_free_urb(ictx->rx_urb_intf0); + WARN_ON(ictx->dev_present_intf1); usb_free_urb(ictx->rx_urb_intf1); - kfree(ictx); + kfree_rcu(ictx, rcu);
dev_dbg(dev, "%s: iMON context freed\n", __func__); } @@ -471,9 +516,6 @@ static int display_open(struct inode *inode, struct file *file) int subminor; int retval = 0;
- /* prevent races with disconnect */ - mutex_lock(&driver_lock); - subminor = iminor(inode); interface = usb_find_interface(&imon_driver, subminor); if (!interface) { @@ -481,17 +523,22 @@ static int display_open(struct inode *inode, struct file *file) retval = -ENODEV; goto exit; } - ictx = usb_get_intfdata(interface);
- if (!ictx) { + rcu_read_lock(); + ictx = usb_get_intfdata(interface); + if (!ictx || ictx->disconnected || !refcount_inc_not_zero(&ictx->users)) { + rcu_read_unlock(); pr_err("no context found for minor %d\n", subminor); retval = -ENODEV; goto exit; } + rcu_read_unlock();
mutex_lock(&ictx->lock);
- if (!ictx->display_supported) { + if (ictx->disconnected) { + retval = -ENODEV; + } else if (!ictx->display_supported) { pr_err("display not supported by device\n"); retval = -ENODEV; } else if (ictx->display_isopen) { @@ -505,8 +552,10 @@ static int display_open(struct inode *inode, struct file *file)
mutex_unlock(&ictx->lock);
+ if (retval && refcount_dec_and_test(&ictx->users)) + free_imon_context(ictx); + exit: - mutex_unlock(&driver_lock); return retval; }
@@ -516,16 +565,9 @@ static int display_open(struct inode *inode, struct file *file) */ static int display_close(struct inode *inode, struct file *file) { - struct imon_context *ictx = NULL; + struct imon_context *ictx = file->private_data; int retval = 0;
- ictx = file->private_data; - - if (!ictx) { - pr_err("no context for device\n"); - return -ENODEV; - } - mutex_lock(&ictx->lock);
if (!ictx->display_supported) { @@ -540,6 +582,8 @@ static int display_close(struct inode *inode, struct file *file) }
mutex_unlock(&ictx->lock); + if (refcount_dec_and_test(&ictx->users)) + free_imon_context(ictx); return retval; }
@@ -556,6 +600,11 @@ static int send_packet(struct imon_context *ictx) int retval = 0; struct usb_ctrlrequest *control_req = NULL;
+ lockdep_assert_held(&ictx->lock); + + if (ictx->disconnected) + return -ENODEV; + /* Check if we need to use control or interrupt urb */ if (!ictx->tx_control) { pipe = usb_sndintpipe(ictx->usbdev_intf0, @@ -908,19 +957,18 @@ static ssize_t vfd_write(struct file *file, const char __user *buf, int offset; int seq; int retval = 0; - struct imon_context *ictx; + struct imon_context *ictx = file->private_data; static const unsigned char vfd_packet6[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
- ictx = file->private_data; - if (!ictx) { - pr_err_ratelimited("no context for device\n"); - return -ENODEV; - } - if (mutex_lock_interruptible(&ictx->lock)) return -ERESTARTSYS;
+ if (ictx->disconnected) { + retval = -ENODEV; + goto exit; + } + if (!ictx->dev_present_intf0) { pr_err_ratelimited("no iMON device present\n"); retval = -ENODEV; @@ -993,16 +1041,15 @@ static ssize_t lcd_write(struct file *file, const char __user *buf, size_t n_bytes, loff_t *pos) { int retval = 0; - struct imon_context *ictx; - - ictx = file->private_data; - if (!ictx) { - pr_err_ratelimited("no context for device\n"); - return -ENODEV; - } + struct imon_context *ictx = file->private_data;
mutex_lock(&ictx->lock);
+ if (ictx->disconnected) { + retval = -ENODEV; + goto exit; + } + if (!ictx->display_supported) { pr_err_ratelimited("no iMON display present\n"); retval = -ENODEV; @@ -1090,7 +1137,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto) int retval; struct imon_context *ictx = rc->priv; struct device *dev = ictx->dev; - bool unlock = false; + const bool unlock = mutex_trylock(&ictx->lock); unsigned char ir_proto_packet[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
@@ -1117,8 +1164,6 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto)
memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet));
- unlock = mutex_trylock(&ictx->lock); - retval = send_packet(ictx); if (retval) goto out; @@ -1261,9 +1306,11 @@ static u32 imon_mce_key_lookup(struct imon_context *ictx, u32 scancode)
static u32 imon_panel_key_lookup(struct imon_context *ictx, u64 code) { - int i; + const struct imon_panel_key_table *key_table; u32 keycode = KEY_RESERVED; - struct imon_panel_key_table *key_table = ictx->dev_descr->key_table; + int i; + + key_table = ictx->dev_descr->key_table;
for (i = 0; key_table[i].hw_code != 0; i++) { if (key_table[i].hw_code == (code | 0xffee)) { @@ -1547,7 +1594,6 @@ static void imon_incoming_packet(struct imon_context *ictx, u32 kc; u64 scancode; int press_type = 0; - long msec; ktime_t t; static ktime_t prev_time; u8 ktype; @@ -1649,14 +1695,16 @@ static void imon_incoming_packet(struct imon_context *ictx, spin_lock_irqsave(&ictx->kc_lock, flags);
t = ktime_get(); - /* KEY_MUTE repeats from knob need to be suppressed */ - if (ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) { - msec = ktime_ms_delta(t, prev_time); - if (msec < ictx->idev->rep[REP_DELAY]) { + /* KEY repeats from knob and panel that need to be suppressed */ + if (ictx->kc == KEY_MUTE || + ictx->dev_descr->flags & IMON_SUPPRESS_REPEATED_KEYS) { + if (ictx->kc == ictx->last_keycode && + ktime_ms_delta(t, prev_time) < ictx->idev->rep[REP_DELAY]) { spin_unlock_irqrestore(&ictx->kc_lock, flags); return; } } + prev_time = t; kc = ictx->kc;
@@ -1844,6 +1892,14 @@ static void imon_get_ffdc_type(struct imon_context *ictx) dev_info(ictx->dev, "0xffdc iMON Inside, iMON IR"); ictx->display_supported = false; break; + /* Soundgraph iMON UltraBay */ + case 0x98: + dev_info(ictx->dev, "0xffdc iMON UltraBay, LCD + IR"); + detected_display_type = IMON_DISPLAY_TYPE_LCD; + allowed_protos = RC_PROTO_BIT_IMON | RC_PROTO_BIT_RC6_MCE; + ictx->dev_descr = &ultrabay_table; + break; + default: dev_info(ictx->dev, "Unknown 0xffdc device, defaulting to VFD and iMON IR"); detected_display_type = IMON_DISPLAY_TYPE_VFD; @@ -1975,10 +2031,12 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
static struct input_dev *imon_init_idev(struct imon_context *ictx) { - struct imon_panel_key_table *key_table = ictx->dev_descr->key_table; + const struct imon_panel_key_table *key_table; struct input_dev *idev; int ret, i;
+ key_table = ictx->dev_descr->key_table; + idev = input_allocate_device(); if (!idev) goto out; @@ -2361,7 +2419,6 @@ static int imon_probe(struct usb_interface *interface, int ifnum, sysfs_err; int ret = 0; struct imon_context *ictx = NULL; - struct imon_context *first_if_ctx = NULL; u16 vendor, product;
usbdev = usb_get_dev(interface_to_usbdev(interface)); @@ -2373,17 +2430,12 @@ static int imon_probe(struct usb_interface *interface, dev_dbg(dev, "%s: found iMON device (%04x:%04x, intf%d)\n", __func__, vendor, product, ifnum);
- /* prevent races probing devices w/multiple interfaces */ - mutex_lock(&driver_lock); - first_if = usb_ifnum_to_if(usbdev, 0); if (!first_if) { ret = -ENODEV; goto fail; }
- first_if_ctx = usb_get_intfdata(first_if); - if (ifnum == 0) { ictx = imon_init_intf0(interface, id); if (!ictx) { @@ -2391,9 +2443,11 @@ static int imon_probe(struct usb_interface *interface, ret = -ENODEV; goto fail; } + refcount_set(&ictx->users, 1);
} else { /* this is the secondary interface on the device */ + struct imon_context *first_if_ctx = usb_get_intfdata(first_if);
/* fail early if first intf failed to register */ if (!first_if_ctx) { @@ -2407,14 +2461,13 @@ static int imon_probe(struct usb_interface *interface, ret = -ENODEV; goto fail; } + refcount_inc(&ictx->users);
}
usb_set_intfdata(interface, ictx);
if (ifnum == 0) { - mutex_lock(&ictx->lock); - if (product == 0xffdc && ictx->rf_device) { sysfs_err = sysfs_create_group(&interface->dev.kobj, &imon_rf_attr_group); @@ -2425,21 +2478,17 @@ static int imon_probe(struct usb_interface *interface,
if (ictx->display_supported) imon_init_display(ictx, interface); - - mutex_unlock(&ictx->lock); }
dev_info(dev, "iMON device (%04x:%04x, intf%d) on usb<%d:%d> initialized\n", vendor, product, ifnum, usbdev->bus->busnum, usbdev->devnum);
- mutex_unlock(&driver_lock); usb_put_dev(usbdev);
return 0;
fail: - mutex_unlock(&driver_lock); usb_put_dev(usbdev); dev_err(dev, "unable to register, err %d\n", ret);
@@ -2455,10 +2504,12 @@ static void imon_disconnect(struct usb_interface *interface) struct device *dev; int ifnum;
- /* prevent races with multi-interface device probing and display_open */ - mutex_lock(&driver_lock); - ictx = usb_get_intfdata(interface); + + mutex_lock(&ictx->lock); + ictx->disconnected = true; + mutex_unlock(&ictx->lock); + dev = ictx->dev; ifnum = interface->cur_altsetting->desc.bInterfaceNumber;
@@ -2499,11 +2550,9 @@ static void imon_disconnect(struct usb_interface *interface) } }
- if (!ictx->dev_present_intf0 && !ictx->dev_present_intf1) + if (refcount_dec_and_test(&ictx->users)) free_imon_context(ictx);
- mutex_unlock(&driver_lock); - dev_dbg(dev, "%s: iMON device (intf%d) disconnected\n", __func__, ifnum); } diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 7de97c26b622..aeff7d7155fd 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -746,7 +746,7 @@ int ir_lirc_register(struct rc_dev *dev) const char *rx_type, *tx_type; int err, minor;
- minor = ida_simple_get(&lirc_ida, 0, RC_DEV_MAX, GFP_KERNEL); + minor = ida_alloc_max(&lirc_ida, RC_DEV_MAX - 1, GFP_KERNEL); if (minor < 0) return minor;
@@ -762,11 +762,11 @@ int ir_lirc_register(struct rc_dev *dev)
cdev_init(&dev->lirc_cdev, &lirc_fops);
+ get_device(&dev->dev); + err = cdev_device_add(&dev->lirc_cdev, &dev->lirc_dev); if (err) - goto out_ida; - - get_device(&dev->dev); + goto out_put_device;
switch (dev->driver_type) { case RC_DRIVER_SCANCODE: @@ -790,8 +790,9 @@ int ir_lirc_register(struct rc_dev *dev)
return 0;
-out_ida: - ida_simple_remove(&lirc_ida, minor); +out_put_device: + put_device(&dev->lirc_dev); + ida_free(&lirc_ida, minor); return err; }
@@ -809,7 +810,7 @@ void ir_lirc_unregister(struct rc_dev *dev) spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
cdev_device_del(&dev->lirc_cdev, &dev->lirc_dev); - ida_simple_remove(&lirc_ida, MINOR(dev->lirc_dev.devt)); + ida_free(&lirc_ida, MINOR(dev->lirc_dev.devt)); }
int __init lirc_dev_init(void) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index ee80f38970bc..e5cbe8c50ce1 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1861,7 +1861,7 @@ int rc_register_device(struct rc_dev *dev) if (!dev) return -EINVAL;
- minor = ida_simple_get(&rc_ida, 0, RC_DEV_MAX, GFP_KERNEL); + minor = ida_alloc_max(&rc_ida, RC_DEV_MAX - 1, GFP_KERNEL); if (minor < 0) return minor;
@@ -1944,7 +1944,7 @@ int rc_register_device(struct rc_dev *dev) out_raw: ir_raw_event_free(dev); out_minor: - ida_simple_remove(&rc_ida, minor); + ida_free(&rc_ida, minor); return rc; } EXPORT_SYMBOL_GPL(rc_register_device); @@ -2004,7 +2004,7 @@ void rc_unregister_device(struct rc_dev *dev)
device_del(&dev->dev);
- ida_simple_remove(&rc_ida, dev->minor); + ida_free(&rc_ida, dev->minor);
if (!dev->managed_alloc) rc_free_device(dev); diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c index 65b886338557..ea4f1ae4d686 100644 --- a/drivers/media/tuners/xc5000.c +++ b/drivers/media/tuners/xc5000.c @@ -58,7 +58,7 @@ struct xc5000_priv { struct dvb_frontend *fe; struct delayed_work timer_sleep;
- const struct firmware *firmware; + bool inited; };
/* Misc Defines */ @@ -1110,23 +1110,19 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force) if (!force && xc5000_is_firmware_loaded(fe) == 0) return 0;
- if (!priv->firmware) { - ret = request_firmware(&fw, desired_fw->name, - priv->i2c_props.adap->dev.parent); - if (ret) { - pr_err("xc5000: Upload failed. rc %d\n", ret); - return ret; - } - dprintk(1, "firmware read %zu bytes.\n", fw->size); + ret = request_firmware(&fw, desired_fw->name, + priv->i2c_props.adap->dev.parent); + if (ret) { + pr_err("xc5000: Upload failed. rc %d\n", ret); + return ret; + } + dprintk(1, "firmware read %zu bytes.\n", fw->size);
- if (fw->size != desired_fw->size) { - pr_err("xc5000: Firmware file with incorrect size\n"); - release_firmware(fw); - return -EINVAL; - } - priv->firmware = fw; - } else - fw = priv->firmware; + if (fw->size != desired_fw->size) { + pr_err("xc5000: Firmware file with incorrect size\n"); + release_firmware(fw); + return -EINVAL; + }
/* Try up to 5 times to load firmware */ for (i = 0; i < 5; i++) { @@ -1204,6 +1200,7 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force) }
err: + release_firmware(fw); if (!ret) printk(KERN_INFO "xc5000: Firmware %s loaded and running.\n", desired_fw->name); @@ -1274,7 +1271,7 @@ static int xc5000_resume(struct dvb_frontend *fe)
/* suspended before firmware is loaded. Avoid firmware load in resume path. */ - if (!priv->firmware) + if (!priv->inited) return 0;
return xc5000_set_params(fe); @@ -1293,6 +1290,8 @@ static int xc5000_init(struct dvb_frontend *fe) if (debug) xc_debug_dump(priv);
+ priv->inited = true; + return 0; }
@@ -1305,11 +1304,7 @@ static void xc5000_release(struct dvb_frontend *fe) mutex_lock(&xc5000_list_mutex);
if (priv) { - cancel_delayed_work(&priv->timer_sleep); - if (priv->firmware) { - release_firmware(priv->firmware); - priv->firmware = NULL; - } + cancel_delayed_work_sync(&priv->timer_sleep); hybrid_tuner_release_state(priv); }
diff --git a/drivers/memory/samsung/exynos-srom.c b/drivers/memory/samsung/exynos-srom.c index c27c6105c66d..0f182698ccc6 100644 --- a/drivers/memory/samsung/exynos-srom.c +++ b/drivers/memory/samsung/exynos-srom.c @@ -47,9 +47,9 @@ struct exynos_srom { struct exynos_srom_reg_dump *reg_offset; };
-static struct exynos_srom_reg_dump *exynos_srom_alloc_reg_dump( - const unsigned long *rdump, - unsigned long nr_rdump) +static struct exynos_srom_reg_dump * +exynos_srom_alloc_reg_dump(const unsigned long *rdump, + unsigned long nr_rdump) { struct exynos_srom_reg_dump *rd; unsigned int i; @@ -116,25 +116,23 @@ static int exynos_srom_probe(struct platform_device *pdev) }
srom = devm_kzalloc(&pdev->dev, - sizeof(struct exynos_srom), GFP_KERNEL); + sizeof(struct exynos_srom), GFP_KERNEL); if (!srom) return -ENOMEM;
srom->dev = dev; - srom->reg_base = of_iomap(np, 0); - if (!srom->reg_base) { + srom->reg_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(srom->reg_base)) { dev_err(&pdev->dev, "iomap of exynos srom controller failed\n"); - return -ENOMEM; + return PTR_ERR(srom->reg_base); }
platform_set_drvdata(pdev, srom);
srom->reg_offset = exynos_srom_alloc_reg_dump(exynos_srom_offsets, - ARRAY_SIZE(exynos_srom_offsets)); - if (!srom->reg_offset) { - iounmap(srom->reg_base); + ARRAY_SIZE(exynos_srom_offsets)); + if (!srom->reg_offset) return -ENOMEM; - }
for_each_child_of_node(np, child) { if (exynos_srom_configure_bank(srom, child)) { @@ -157,16 +155,16 @@ static int exynos_srom_probe(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP static void exynos_srom_save(void __iomem *base, - struct exynos_srom_reg_dump *rd, - unsigned int num_regs) + struct exynos_srom_reg_dump *rd, + unsigned int num_regs) { for (; num_regs > 0; --num_regs, ++rd) rd->value = readl(base + rd->offset); }
static void exynos_srom_restore(void __iomem *base, - const struct exynos_srom_reg_dump *rd, - unsigned int num_regs) + const struct exynos_srom_reg_dump *rd, + unsigned int num_regs) { for (; num_regs > 0; --num_regs, ++rd) writel(rd->value, base + rd->offset); @@ -177,7 +175,7 @@ static int exynos_srom_suspend(struct device *dev) struct exynos_srom *srom = dev_get_drvdata(dev);
exynos_srom_save(srom->reg_base, srom->reg_offset, - ARRAY_SIZE(exynos_srom_offsets)); + ARRAY_SIZE(exynos_srom_offsets)); return 0; }
@@ -186,7 +184,7 @@ static int exynos_srom_resume(struct device *dev) struct exynos_srom *srom = dev_get_drvdata(dev);
exynos_srom_restore(srom->reg_base, srom->reg_offset, - ARRAY_SIZE(exynos_srom_offsets)); + ARRAY_SIZE(exynos_srom_offsets)); return 0; } #endif diff --git a/drivers/mfd/intel_soc_pmic_chtdc_ti.c b/drivers/mfd/intel_soc_pmic_chtdc_ti.c index 64b5c3cc30e7..c629624fd4a5 100644 --- a/drivers/mfd/intel_soc_pmic_chtdc_ti.c +++ b/drivers/mfd/intel_soc_pmic_chtdc_ti.c @@ -81,8 +81,9 @@ static struct mfd_cell chtdc_ti_dev[] = { static const struct regmap_config chtdc_ti_regmap_config = { .reg_bits = 8, .val_bits = 8, - .max_register = 128, - .cache_type = REGCACHE_NONE, + .max_register = 0xff, + /* The hardware does not support reading multiple registers at once */ + .use_single_read = true, };
static const struct regmap_irq chtdc_ti_irqs[] = { diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c index c68ff56dbdb1..1463cf43687d 100644 --- a/drivers/mfd/vexpress-sysreg.c +++ b/drivers/mfd/vexpress-sysreg.c @@ -160,6 +160,7 @@ static int vexpress_sysreg_probe(struct platform_device *pdev) struct gpio_chip *mmc_gpio_chip; int master; u32 dt_hbi; + int ret;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) @@ -195,7 +196,10 @@ static int vexpress_sysreg_probe(struct platform_device *pdev) bgpio_init(mmc_gpio_chip, &pdev->dev, 0x4, base + SYS_MCI, NULL, NULL, NULL, NULL, 0); mmc_gpio_chip->ngpio = 2; - gpiochip_add_data(mmc_gpio_chip, NULL); + + ret = gpiochip_add_data(mmc_gpio_chip, NULL); + if (ret) + return ret;
return mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, vexpress_sysreg_cells, diff --git a/drivers/misc/genwqe/card_ddcb.c b/drivers/misc/genwqe/card_ddcb.c index 026c6ca24540..e53bdd5f04ea 100644 --- a/drivers/misc/genwqe/card_ddcb.c +++ b/drivers/misc/genwqe/card_ddcb.c @@ -918,7 +918,7 @@ int __genwqe_execute_raw_ddcb(struct genwqe_dev *cd, } if (cmd->asv_length > DDCB_ASV_LENGTH) { dev_err(&pci_dev->dev, "[%s] err: wrong asv_length of %d\n", - __func__, cmd->asiv_length); + __func__, cmd->asv_length); return -EINVAL; } rc = __genwqe_enqueue_ddcb(cd, req, f_flags); diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 2362a70460f1..2908037a1526 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -868,7 +868,11 @@ static void mmc_sdio_remove(struct mmc_host *host) */ static int mmc_sdio_alive(struct mmc_host *host) { - return mmc_select_card(host->card); + if (!mmc_host_is_spi(host)) + return mmc_select_card(host->card); + else + return mmc_io_rw_direct(host->card, 0, 0, SDIO_CCCR_CCCR, 0, + NULL); }
/* diff --git a/drivers/mtd/nand/raw/fsmc_nand.c b/drivers/mtd/nand/raw/fsmc_nand.c index c44b64542818..f093587e330d 100644 --- a/drivers/mtd/nand/raw/fsmc_nand.c +++ b/drivers/mtd/nand/raw/fsmc_nand.c @@ -861,10 +861,14 @@ static int fsmc_nand_probe_config_dt(struct platform_device *pdev, if (!of_property_read_u32(np, "bank-width", &val)) { if (val == 2) { nand->options |= NAND_BUSWIDTH_16; - } else if (val != 1) { + } else if (val == 1) { + nand->options |= NAND_BUSWIDTH_AUTO; + } else { dev_err(&pdev->dev, "invalid bank-width %u\n", val); return -EINVAL; } + } else { + nand->options |= NAND_BUSWIDTH_AUTO; }
if (of_get_property(np, "nand-skip-bbtscan", NULL)) diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c index 7bdc558d8560..e10ff219aa5e 100644 --- a/drivers/mtd/spi-nor/cadence-quadspi.c +++ b/drivers/mtd/spi-nor/cadence-quadspi.c @@ -496,6 +496,7 @@ static int cqspi_read_setup(struct spi_nor *nor) reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK; reg |= (nor->addr_width - 1); writel(reg, reg_base + CQSPI_REG_SIZE); + readl(reg_base + CQSPI_REG_SIZE); /* Flush posted write. */ return 0; }
@@ -523,6 +524,7 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf, reinit_completion(&cqspi->transfer_complete); writel(CQSPI_REG_INDIRECTRD_START_MASK, reg_base + CQSPI_REG_INDIRECTRD); + readl(reg_base + CQSPI_REG_INDIRECTRD); /* Flush posted write. */
while (remaining > 0) { if (!wait_for_completion_timeout(&cqspi->transfer_complete, @@ -608,6 +610,7 @@ static int cqspi_write_setup(struct spi_nor *nor) reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK; reg |= (nor->addr_width - 1); writel(reg, reg_base + CQSPI_REG_SIZE); + readl(reg_base + CQSPI_REG_SIZE); /* Flush posted write. */ return 0; }
@@ -633,6 +636,8 @@ static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t to_addr, reinit_completion(&cqspi->transfer_complete); writel(CQSPI_REG_INDIRECTWR_START_MASK, reg_base + CQSPI_REG_INDIRECTWR); + readl(reg_base + CQSPI_REG_INDIRECTWR); /* Flush posted write. */ + /* * As per 66AK2G02 TRM SPRUHY8F section 11.15.5.3 Indirect Access * Controller programming sequence, couple of cycles of diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 3b235a269c1b..99c7231bda73 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2331,7 +2331,7 @@ static void bond_mii_monitor(struct work_struct *work) { struct bonding *bond = container_of(work, struct bonding, mii_work.work); - bool should_notify_peers = false; + bool should_notify_peers; bool commit; unsigned long delay; struct slave *slave; @@ -2343,30 +2343,33 @@ static void bond_mii_monitor(struct work_struct *work) goto re_arm;
rcu_read_lock(); + should_notify_peers = bond_should_notify_peers(bond); commit = !!bond_miimon_inspect(bond); - if (bond->send_peer_notif) { - rcu_read_unlock(); - if (rtnl_trylock()) { - bond->send_peer_notif--; - rtnl_unlock(); - } - } else { - rcu_read_unlock(); - }
- if (commit) { + rcu_read_unlock(); + + if (commit || bond->send_peer_notif) { /* Race avoidance with bond_close cancel of workqueue */ if (!rtnl_trylock()) { delay = 1; - should_notify_peers = false; goto re_arm; }
- bond_for_each_slave(bond, slave, iter) { - bond_commit_link_state(slave, BOND_SLAVE_NOTIFY_LATER); + if (commit) { + bond_for_each_slave(bond, slave, iter) { + bond_commit_link_state(slave, + BOND_SLAVE_NOTIFY_LATER); + } + bond_miimon_commit(bond); + } + + if (bond->send_peer_notif) { + bond->send_peer_notif--; + if (should_notify_peers) + call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, + bond->dev); } - bond_miimon_commit(bond);
rtnl_unlock(); /* might sleep, hold no other locks */ } @@ -2374,13 +2377,6 @@ static void bond_mii_monitor(struct work_struct *work) re_arm: if (bond->params.miimon) queue_delayed_work(bond->wq, &bond->mii_work, delay); - - if (should_notify_peers) { - if (!rtnl_trylock()) - return; - call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, bond->dev); - rtnl_unlock(); - } }
static int bond_upper_dev_walk(struct net_device *upper, void *data) diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c b/drivers/net/ethernet/amazon/ena/ena_ethtool.c index ae631b8770fc..5f037e9db023 100644 --- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c +++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c @@ -633,7 +633,10 @@ static u32 ena_get_rxfh_indir_size(struct net_device *netdev)
static u32 ena_get_rxfh_key_size(struct net_device *netdev) { - return ENA_HASH_KEY_SIZE; + struct ena_adapter *adapter = netdev_priv(netdev); + struct ena_rss *rss = &adapter->ena_dev->rss; + + return rss->hash_key ? ENA_HASH_KEY_SIZE : 0; }
static int ena_indirection_table_get(struct ena_adapter *adapter, u32 *indir) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index de10e7e3a68d..1fa7eb75d1a3 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c @@ -1247,7 +1247,6 @@ static void xgbe_free_rx_data(struct xgbe_prv_data *pdata)
static int xgbe_phy_reset(struct xgbe_prv_data *pdata) { - pdata->phy_link = -1; pdata->phy_speed = SPEED_UNKNOWN;
return pdata->phy_if.phy_reset(pdata); diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c index 3819b23c927d..6dd95e7d81e4 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c @@ -1637,6 +1637,7 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata) pdata->phy.duplex = DUPLEX_FULL; }
+ pdata->phy_link = 0; pdata->phy.link = 0;
pdata->phy.pause_autoneg = pdata->pause_autoneg; diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 55aa87771333..3ea966d85ea3 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -5827,7 +5827,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, bool force_reset) u32 current_speed = SPEED_UNKNOWN; u8 current_duplex = DUPLEX_UNKNOWN; bool current_link_up = false; - u32 local_adv, remote_adv, sgsr; + u32 local_adv = 0, remote_adv = 0, sgsr;
if ((tg3_asic_rev(tp) == ASIC_REV_5719 || tg3_asic_rev(tp) == ASIC_REV_5720) && @@ -5968,9 +5968,6 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, bool force_reset) else current_duplex = DUPLEX_HALF;
- local_adv = 0; - remote_adv = 0; - if (bmcr & BMCR_ANENABLE) { u32 common;
diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c index b4a8d4f12087..855328ae6ea5 100644 --- a/drivers/net/ethernet/dlink/dl2k.c +++ b/drivers/net/ethernet/dlink/dl2k.c @@ -233,13 +233,15 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_drvdata (pdev, dev);
- ring_space = pci_alloc_consistent (pdev, TX_TOTAL_SIZE, &ring_dma); + ring_space = dma_alloc_coherent(&pdev->dev, TX_TOTAL_SIZE, &ring_dma, + GFP_KERNEL); if (!ring_space) goto err_out_iounmap; np->tx_ring = ring_space; np->tx_ring_dma = ring_dma;
- ring_space = pci_alloc_consistent (pdev, RX_TOTAL_SIZE, &ring_dma); + ring_space = dma_alloc_coherent(&pdev->dev, RX_TOTAL_SIZE, &ring_dma, + GFP_KERNEL); if (!ring_space) goto err_out_unmap_tx; np->rx_ring = ring_space; @@ -290,9 +292,11 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) return 0;
err_out_unmap_rx: - pci_free_consistent (pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma); + dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE, np->rx_ring, + np->rx_ring_dma); err_out_unmap_tx: - pci_free_consistent (pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma); + dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE, np->tx_ring, + np->tx_ring_dma); err_out_iounmap: #ifdef MEM_MAPPING pci_iounmap(pdev, np->ioaddr); @@ -446,8 +450,9 @@ static void free_list(struct net_device *dev) for (i = 0; i < RX_RING_SIZE; i++) { skb = np->rx_skbuff[i]; if (skb) { - pci_unmap_single(np->pdev, desc_to_dma(&np->rx_ring[i]), - skb->len, PCI_DMA_FROMDEVICE); + dma_unmap_single(&np->pdev->dev, + desc_to_dma(&np->rx_ring[i]), + skb->len, DMA_FROM_DEVICE); dev_kfree_skb(skb); np->rx_skbuff[i] = NULL; } @@ -457,8 +462,9 @@ static void free_list(struct net_device *dev) for (i = 0; i < TX_RING_SIZE; i++) { skb = np->tx_skbuff[i]; if (skb) { - pci_unmap_single(np->pdev, desc_to_dma(&np->tx_ring[i]), - skb->len, PCI_DMA_TODEVICE); + dma_unmap_single(&np->pdev->dev, + desc_to_dma(&np->tx_ring[i]), + skb->len, DMA_TO_DEVICE); dev_kfree_skb(skb); np->tx_skbuff[i] = NULL; } @@ -502,26 +508,34 @@ static int alloc_list(struct net_device *dev) for (i = 0; i < RX_RING_SIZE; i++) { /* Allocated fixed size of skbuff */ struct sk_buff *skb; + dma_addr_t addr;
skb = netdev_alloc_skb_ip_align(dev, np->rx_buf_sz); np->rx_skbuff[i] = skb; - if (!skb) { - free_list(dev); - return -ENOMEM; - } + if (!skb) + goto err_free_list; + + addr = dma_map_single(&np->pdev->dev, skb->data, + np->rx_buf_sz, DMA_FROM_DEVICE); + if (dma_mapping_error(&np->pdev->dev, addr)) + goto err_kfree_skb;
np->rx_ring[i].next_desc = cpu_to_le64(np->rx_ring_dma + ((i + 1) % RX_RING_SIZE) * sizeof(struct netdev_desc)); /* Rubicon now supports 40 bits of addressing space. */ - np->rx_ring[i].fraginfo = - cpu_to_le64(pci_map_single( - np->pdev, skb->data, np->rx_buf_sz, - PCI_DMA_FROMDEVICE)); + np->rx_ring[i].fraginfo = cpu_to_le64(addr); np->rx_ring[i].fraginfo |= cpu_to_le64((u64)np->rx_buf_sz << 48); }
return 0; + +err_kfree_skb: + dev_kfree_skb(np->rx_skbuff[i]); + np->rx_skbuff[i] = NULL; +err_free_list: + free_list(dev); + return -ENOMEM; }
static void rio_hw_init(struct net_device *dev) @@ -683,9 +697,8 @@ rio_timer (struct timer_list *t) } np->rx_skbuff[entry] = skb; np->rx_ring[entry].fraginfo = - cpu_to_le64 (pci_map_single - (np->pdev, skb->data, np->rx_buf_sz, - PCI_DMA_FROMDEVICE)); + cpu_to_le64 (dma_map_single(&np->pdev->dev, skb->data, + np->rx_buf_sz, DMA_FROM_DEVICE)); } np->rx_ring[entry].fraginfo |= cpu_to_le64((u64)np->rx_buf_sz << 48); @@ -739,9 +752,8 @@ start_xmit (struct sk_buff *skb, struct net_device *dev) ((u64)np->vlan << 32) | ((u64)skb->priority << 45); } - txdesc->fraginfo = cpu_to_le64 (pci_map_single (np->pdev, skb->data, - skb->len, - PCI_DMA_TODEVICE)); + txdesc->fraginfo = cpu_to_le64 (dma_map_single(&np->pdev->dev, skb->data, + skb->len, DMA_TO_DEVICE)); txdesc->fraginfo |= cpu_to_le64((u64)skb->len << 48);
/* DL2K bug: DMA fails to get next descriptor ptr in 10Mbps mode @@ -838,9 +850,9 @@ rio_free_tx (struct net_device *dev, int irq) if (!(np->tx_ring[entry].status & cpu_to_le64(TFDDone))) break; skb = np->tx_skbuff[entry]; - pci_unmap_single (np->pdev, - desc_to_dma(&np->tx_ring[entry]), - skb->len, PCI_DMA_TODEVICE); + dma_unmap_single(&np->pdev->dev, + desc_to_dma(&np->tx_ring[entry]), skb->len, + DMA_TO_DEVICE); if (irq) dev_consume_skb_irq(skb); else @@ -965,25 +977,25 @@ receive_packet (struct net_device *dev)
/* Small skbuffs for short packets */ if (pkt_len > copy_thresh) { - pci_unmap_single (np->pdev, - desc_to_dma(desc), - np->rx_buf_sz, - PCI_DMA_FROMDEVICE); + dma_unmap_single(&np->pdev->dev, + desc_to_dma(desc), + np->rx_buf_sz, + DMA_FROM_DEVICE); skb_put (skb = np->rx_skbuff[entry], pkt_len); np->rx_skbuff[entry] = NULL; } else if ((skb = netdev_alloc_skb_ip_align(dev, pkt_len))) { - pci_dma_sync_single_for_cpu(np->pdev, - desc_to_dma(desc), - np->rx_buf_sz, - PCI_DMA_FROMDEVICE); + dma_sync_single_for_cpu(&np->pdev->dev, + desc_to_dma(desc), + np->rx_buf_sz, + DMA_FROM_DEVICE); skb_copy_to_linear_data (skb, np->rx_skbuff[entry]->data, pkt_len); skb_put (skb, pkt_len); - pci_dma_sync_single_for_device(np->pdev, - desc_to_dma(desc), - np->rx_buf_sz, - PCI_DMA_FROMDEVICE); + dma_sync_single_for_device(&np->pdev->dev, + desc_to_dma(desc), + np->rx_buf_sz, + DMA_FROM_DEVICE); } skb->protocol = eth_type_trans (skb, dev); #if 0 @@ -1016,9 +1028,8 @@ receive_packet (struct net_device *dev) } np->rx_skbuff[entry] = skb; np->rx_ring[entry].fraginfo = - cpu_to_le64 (pci_map_single - (np->pdev, skb->data, np->rx_buf_sz, - PCI_DMA_FROMDEVICE)); + cpu_to_le64(dma_map_single(&np->pdev->dev, skb->data, + np->rx_buf_sz, DMA_FROM_DEVICE)); } np->rx_ring[entry].fraginfo |= cpu_to_le64((u64)np->rx_buf_sz << 48); @@ -1818,10 +1829,10 @@ rio_remove1 (struct pci_dev *pdev) struct netdev_private *np = netdev_priv(dev);
unregister_netdev (dev); - pci_free_consistent (pdev, RX_TOTAL_SIZE, np->rx_ring, - np->rx_ring_dma); - pci_free_consistent (pdev, TX_TOTAL_SIZE, np->tx_ring, - np->tx_ring_dma); + dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE, np->rx_ring, + np->rx_ring_dma); + dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE, np->tx_ring, + np->tx_ring_dma); #ifdef MEM_MAPPING pci_iounmap(pdev, np->ioaddr); #endif diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h index b8801a2b6a02..6203d117d0d2 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc.h +++ b/drivers/net/ethernet/freescale/enetc/enetc.h @@ -27,7 +27,7 @@ struct enetc_tx_swbd { };
#define ENETC_RX_MAXFRM_SIZE ENETC_MAC_MAXFRM_SIZE -#define ENETC_RXB_TRUESIZE 2048 /* PAGE_SIZE >> 1 */ +#define ENETC_RXB_TRUESIZE (PAGE_SIZE >> 1) #define ENETC_RXB_PAD NET_SKB_PAD /* add extra space if needed */ #define ENETC_RXB_DMA_SIZE \ (SKB_WITH_OVERHEAD(ENETC_RXB_TRUESIZE) - ENETC_RXB_PAD) diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c index c6481bd61239..565a8bfe5692 100644 --- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c +++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c @@ -482,10 +482,12 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev) "missing 'reg' property in node %pOF\n", tbi); err = -EBUSY; + of_node_put(tbi); goto error; } set_tbipa(*prop, pdev, data->get_tbipa, priv->map, &res); + of_node_put(tbi); } }
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 91334229c120..545658afb4f5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -1175,9 +1175,9 @@ static void mlx4_en_do_uc_filter(struct mlx4_en_priv *priv, mlx4_unregister_mac(mdev->dev, priv->port, mac);
hlist_del_rcu(&entry->hlist); - kfree_rcu(entry, rcu); en_dbg(DRV, priv, "Removed MAC %pM on port:%d\n", entry->mac, priv->port); + kfree_rcu(entry, rcu); ++removed; } } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h index 7b852b87a609..34f55b81a0de 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h @@ -64,23 +64,11 @@ struct mlx5e_port_buffer { struct mlx5e_bufferx_reg buffer[MLX5E_MAX_BUFFER]; };
-#ifdef CONFIG_MLX5_CORE_EN_DCB int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, u32 change, unsigned int mtu, struct ieee_pfc *pfc, u32 *buffer_size, u8 *prio2buffer); -#else -static inline int -mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, - u32 change, unsigned int mtu, - void *pfc, - u32 *buffer_size, - u8 *prio2buffer) -{ - return 0; -} -#endif
int mlx5e_port_query_buffer(struct mlx5e_priv *priv, struct mlx5e_port_buffer *port_buffer); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 41bd16cc9d0f..b3ba996004f1 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -42,7 +42,6 @@ #include "eswitch.h" #include "en.h" #include "en/txrx.h" -#include "en/port_buffer.h" #include "en_tc.h" #include "en_rep.h" #include "en_accel/ipsec.h" @@ -2895,11 +2894,9 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv) struct mlx5e_params *params = &priv->channels.params; struct net_device *netdev = priv->netdev; struct mlx5_core_dev *mdev = priv->mdev; - u16 mtu, prev_mtu; + u16 mtu; int err;
- mlx5e_query_mtu(mdev, params, &prev_mtu); - err = mlx5e_set_mtu(mdev, params, params->sw_mtu); if (err) return err; @@ -2909,18 +2906,6 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv) netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n", __func__, mtu, params->sw_mtu);
- if (mtu != prev_mtu && MLX5_BUFFER_SUPPORTED(mdev)) { - err = mlx5e_port_manual_buffer_config(priv, 0, mtu, - NULL, NULL, NULL); - if (err) { - netdev_warn(netdev, "%s: Failed to set Xon/Xoff values with MTU %d (err %d), setting back to previous MTU %d\n", - __func__, mtu, err, prev_mtu); - - mlx5e_set_mtu(mdev, params, prev_mtu); - return err; - } - } - params->sw_mtu = mtu; return 0; } diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c index ff8810357181..6e1707ef391d 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c @@ -914,7 +914,7 @@ static u32 nfp_net_get_rxfh_key_size(struct net_device *netdev) struct nfp_net *nn = netdev_priv(netdev);
if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY)) - return -EOPNOTSUPP; + return 0;
return nfp_net_rss_key_sz(nn); } diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index 3cc312a526d9..c3b9281885e3 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c @@ -1602,6 +1602,14 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev) } else { desc->die_dt = DT_FSINGLE; } + + /* Before ringing the doorbell we need to make sure that the latest + * writes have been committed to memory, otherwise it could delay + * things until the doorbell is rang again. + * This is in replacement of the read operation mentioned in the HW + * manuals. + */ + dma_wmb(); ravb_modify(ndev, TCCR, TCCR_TSRQ0 << q, TCCR_TSRQ0 << q);
priv->cur_tx[q] += num_tx_desc; diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index 3829b7eb3fc9..e4cca92aa4a8 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -684,7 +684,6 @@ static void rtl8150_set_multicast(struct net_device *netdev) rtl8150_t *dev = netdev_priv(netdev); u16 rx_creg = 0x9e;
- netif_stop_queue(netdev); if (netdev->flags & IFF_PROMISC) { rx_creg |= 0x0001; dev_info(&netdev->dev, "%s: promiscuous mode\n", netdev->name); @@ -698,7 +697,6 @@ static void rtl8150_set_multicast(struct net_device *netdev) rx_creg &= 0x00fc; } async_set_registers(dev, RCR, sizeof(rx_creg), rx_creg); - netif_wake_queue(netdev); }
static netdev_tx_t rtl8150_start_xmit(struct sk_buff *skb, @@ -707,9 +705,16 @@ static netdev_tx_t rtl8150_start_xmit(struct sk_buff *skb, rtl8150_t *dev = netdev_priv(netdev); int count, res;
+ /* pad the frame and ensure terminating USB packet, datasheet 9.2.3 */ + count = max(skb->len, ETH_ZLEN); + if (count % 64 == 0) + count++; + if (skb_padto(skb, count)) { + netdev->stats.tx_dropped++; + return NETDEV_TX_OK; + } + netif_stop_queue(netdev); - count = (skb->len < 60) ? 60 : skb->len; - count = (count & 0x3f) ? count : count + 1; dev->tx_skb = skb; usb_fill_bulk_urb(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), skb->data, count, write_bulk_callback, dev); diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c index 40e10f6e3dbf..9f9826b94ad4 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -667,10 +667,9 @@ static void mwifiex_reg_notifier(struct wiphy *wiphy, return; }
- /* Don't send world or same regdom info to firmware */ - if (strncmp(request->alpha2, "00", 2) && - strncmp(request->alpha2, adapter->country_code, - sizeof(request->alpha2))) { + /* Don't send same regdom info to firmware */ + if (strncmp(request->alpha2, adapter->country_code, + sizeof(request->alpha2)) != 0) { memcpy(adapter->country_code, request->alpha2, sizeof(request->alpha2)); mwifiex_send_domain_info_cmd_fw(wiphy); diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/soc.c b/drivers/net/wireless/mediatek/mt76/mt7603/soc.c index 68efb300c0d8..8c3603f11389 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/soc.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/soc.c @@ -48,7 +48,7 @@ mt76_wmac_probe(struct platform_device *pdev)
return 0; error: - ieee80211_free_hw(mt76_hw(dev)); + mt76_free_device(mdev); return ret; }
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c index ab3e4aebad39..300f90a11879 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c @@ -297,7 +297,6 @@ static const struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/ {RTL_USB_DEVICE(0x050d, 0x11f2, rtl92cu_hal_cfg)}, /*Belkin - ISY*/ {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ - {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ {RTL_USB_DEVICE(0x0846, 0x9043, rtl92cu_hal_cfg)}, /*NG WNA1000Mv2*/ diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c index b28d3c4205fe..0a12fbcd29df 100644 --- a/drivers/pci/controller/dwc/pci-keystone.c +++ b/drivers/pci/controller/dwc/pci-keystone.c @@ -1294,8 +1294,8 @@ static int ks_pcie_probe(struct platform_device *pdev) return irq; }
- ret = request_irq(irq, ks_pcie_err_irq_handler, IRQF_SHARED, - "ks-pcie-error-irq", ks_pcie); + ret = devm_request_irq(dev, irq, ks_pcie_err_irq_handler, IRQF_SHARED, + "ks-pcie-error-irq", ks_pcie); if (ret < 0) { dev_err(dev, "failed to request error IRQ %d\n", irq); diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c index 74c0ddd43381..9e3588d568ce 100644 --- a/drivers/pci/controller/pci-tegra.c +++ b/drivers/pci/controller/pci-tegra.c @@ -1394,7 +1394,7 @@ static int tegra_pcie_port_get_phys(struct tegra_pcie_port *port) unsigned int i; int err;
- port->phys = devm_kcalloc(dev, sizeof(phy), port->lanes, GFP_KERNEL); + port->phys = devm_kcalloc(dev, port->lanes, sizeof(phy), GFP_KERNEL); if (!port->phys) return -ENOMEM;
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index e15220385666..1f46dc70eb56 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -431,15 +431,18 @@ static int sriov_add_vfs(struct pci_dev *dev, u16 num_vfs) if (dev->no_vf_scan) return 0;
+ pci_lock_rescan_remove(); for (i = 0; i < num_vfs; i++) { rc = pci_iov_add_virtfn(dev, i); if (rc) goto failed; } + pci_unlock_rescan_remove(); return 0; failed: while (i--) pci_iov_remove_virtfn(dev, i); + pci_unlock_rescan_remove();
return rc; } @@ -562,8 +565,10 @@ static void sriov_del_vfs(struct pci_dev *dev) if (dev->no_vf_scan) return;
+ pci_lock_rescan_remove(); for (i = 0; i < iov->num_VFs; i++) pci_iov_remove_virtfn(dev, i); + pci_unlock_rescan_remove(); }
static void sriov_disable(struct pci_dev *dev) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 617b13c94b39..ff197ee055a9 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -1603,6 +1603,7 @@ void pci_uevent_ers(struct pci_dev *pdev, enum pci_ers_result err_type) switch (err_type) { case PCI_ERS_RESULT_NONE: case PCI_ERS_RESULT_CAN_RECOVER: + case PCI_ERS_RESULT_NEED_RESET: envp[idx++] = "ERROR_EVENT=BEGIN_RECOVERY"; envp[idx++] = "DEVICE_ONLINE=0"; break; diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c index 079701e8de18..91a6631af556 100644 --- a/drivers/perf/arm_spe_pmu.c +++ b/drivers/perf/arm_spe_pmu.c @@ -75,7 +75,8 @@ struct arm_spe_pmu { #define to_spe_pmu(p) (container_of(p, struct arm_spe_pmu, pmu))
/* Convert a free-running index from perf into an SPE buffer offset */ -#define PERF_IDX2OFF(idx, buf) ((idx) % ((buf)->nr_pages << PAGE_SHIFT)) +#define PERF_IDX2OFF(idx, buf) \ + ((idx) % ((unsigned long)(buf)->nr_pages << PAGE_SHIFT))
/* Keep track of our dynamic hotplug state */ static enum cpuhp_state arm_spe_pmu_online; diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c index e8d1f3050487..2da0f2ab4038 100644 --- a/drivers/pinctrl/meson/pinctrl-meson-gxl.c +++ b/drivers/pinctrl/meson/pinctrl-meson-gxl.c @@ -187,6 +187,9 @@ static const unsigned int i2c_sda_c_pins[] = { GPIODV_28 }; static const unsigned int i2c_sck_c_dv19_pins[] = { GPIODV_19 }; static const unsigned int i2c_sda_c_dv18_pins[] = { GPIODV_18 };
+static const unsigned int i2c_sck_d_pins[] = { GPIOX_11 }; +static const unsigned int i2c_sda_d_pins[] = { GPIOX_10 }; + static const unsigned int eth_mdio_pins[] = { GPIOZ_0 }; static const unsigned int eth_mdc_pins[] = { GPIOZ_1 }; static const unsigned int eth_clk_rx_clk_pins[] = { GPIOZ_2 }; @@ -400,6 +403,8 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = { GPIO_GROUP(GPIO_TEST_N),
/* Bank X */ + GROUP(i2c_sda_d, 5, 5), + GROUP(i2c_sck_d, 5, 4), GROUP(sdio_d0, 5, 31), GROUP(sdio_d1, 5, 30), GROUP(sdio_d2, 5, 29), @@ -631,6 +636,10 @@ static const char * const i2c_c_groups[] = { "i2c_sck_c", "i2c_sda_c", "i2c_sda_c_dv18", "i2c_sck_c_dv19", };
+static const char * const i2c_d_groups[] = { + "i2c_sck_d", "i2c_sda_d", +}; + static const char * const eth_groups[] = { "eth_mdio", "eth_mdc", "eth_clk_rx_clk", "eth_rx_dv", "eth_rxd0", "eth_rxd1", "eth_rxd2", "eth_rxd3", @@ -751,6 +760,7 @@ static struct meson_pmx_func meson_gxl_periphs_functions[] = { FUNCTION(i2c_a), FUNCTION(i2c_b), FUNCTION(i2c_c), + FUNCTION(i2c_d), FUNCTION(eth), FUNCTION(pwm_a), FUNCTION(pwm_b), diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 9503ddf2edc7..b76c3f682287 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -324,7 +324,7 @@ static int pinmux_func_name_to_selector(struct pinctrl_dev *pctldev, while (selector < nfuncs) { const char *fname = ops->get_function_name(pctldev, selector);
- if (!strcmp(function, fname)) + if (fname && !strcmp(function, fname)) return selector;
selector++; diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c index 92d1b62ea239..e9389876229e 100644 --- a/drivers/pps/kapi.c +++ b/drivers/pps/kapi.c @@ -109,16 +109,13 @@ struct pps_device *pps_register_source(struct pps_source_info *info, if (err < 0) { pr_err("%s: unable to create char device\n", info->name); - goto kfree_pps; + goto pps_register_source_exit; }
dev_dbg(&pps->dev, "new PPS source %s\n", info->name);
return pps;
-kfree_pps: - kfree(pps); - pps_register_source_exit: pr_err("%s: unable to register source\n", info->name);
diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c index ea966fc67d28..dbeb67ffebf3 100644 --- a/drivers/pps/pps.c +++ b/drivers/pps/pps.c @@ -375,6 +375,7 @@ int pps_register_cdev(struct pps_device *pps) pps->info.name); err = -EBUSY; } + kfree(pps); goto out_unlock; } pps->id = err; @@ -384,13 +385,11 @@ int pps_register_cdev(struct pps_device *pps) pps->dev.devt = MKDEV(pps_major, pps->id); dev_set_drvdata(&pps->dev, pps); dev_set_name(&pps->dev, "pps%d", pps->id); + pps->dev.release = pps_device_destruct; err = device_register(&pps->dev); if (err) goto free_idr;
- /* Override the release function with our own */ - pps->dev.release = pps_device_destruct; - pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, pps_major, pps->id);
diff --git a/drivers/pwm/pwm-berlin.c b/drivers/pwm/pwm-berlin.c index b91c477cc84b..c9d11486f2c1 100644 --- a/drivers/pwm/pwm-berlin.c +++ b/drivers/pwm/pwm-berlin.c @@ -249,7 +249,7 @@ static int berlin_pwm_suspend(struct device *dev) if (!channel) continue;
- channel->enable = berlin_pwm_readl(pwm, i, BERLIN_PWM_ENABLE); + channel->enable = berlin_pwm_readl(pwm, i, BERLIN_PWM_EN); channel->ctrl = berlin_pwm_readl(pwm, i, BERLIN_PWM_CONTROL); channel->duty = berlin_pwm_readl(pwm, i, BERLIN_PWM_DUTY); channel->tcnt = berlin_pwm_readl(pwm, i, BERLIN_PWM_TCNT); @@ -280,7 +280,7 @@ static int berlin_pwm_resume(struct device *dev) berlin_pwm_writel(pwm, i, channel->ctrl, BERLIN_PWM_CONTROL); berlin_pwm_writel(pwm, i, channel->duty, BERLIN_PWM_DUTY); berlin_pwm_writel(pwm, i, channel->tcnt, BERLIN_PWM_TCNT); - berlin_pwm_writel(pwm, i, channel->enable, BERLIN_PWM_ENABLE); + berlin_pwm_writel(pwm, i, channel->enable, BERLIN_PWM_EN); }
return 0; diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index 7b4c770ce9d6..7414daef81a3 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c @@ -167,7 +167,7 @@ static int set_prescale_div(unsigned long rqst_prescaler, u16 *prescale_div,
*prescale_div = (1 << clkdiv) * (hspclkdiv ? (hspclkdiv * 2) : 1); - if (*prescale_div > rqst_prescaler) { + if (*prescale_div >= rqst_prescaler) { *tb_clk_div = (clkdiv << TBCTL_CLKDIV_SHIFT) | (hspclkdiv << TBCTL_HSPCLKDIV_SHIFT); return 0; @@ -266,7 +266,7 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, pc->period_cycles[pwm->hwpwm] = period_cycles;
/* Configure clock prescaler to support Low frequency PWM wave */ - if (set_prescale_div(period_cycles/PERIOD_MAX, &ps_divval, + if (set_prescale_div(DIV_ROUND_UP(period_cycles, PERIOD_MAX), &ps_divval, &tb_divval)) { dev_err(chip->dev, "Unsupported values\n"); return -EINVAL; diff --git a/drivers/remoteproc/qcom_q6v5.c b/drivers/remoteproc/qcom_q6v5.c index eaeb6aee6da5..9c9beeb3bcd7 100644 --- a/drivers/remoteproc/qcom_q6v5.c +++ b/drivers/remoteproc/qcom_q6v5.c @@ -113,9 +113,6 @@ int qcom_q6v5_wait_for_start(struct qcom_q6v5 *q6v5, int timeout) int ret;
ret = wait_for_completion_timeout(&q6v5->start_done, timeout); - if (!ret) - disable_irq(q6v5->handover_irq); - return !ret ? -ETIMEDOUT : 0; } EXPORT_SYMBOL_GPL(qcom_q6v5_wait_for_start); diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 1536d53a7af7..68ff63c33d43 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -442,6 +442,29 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) else err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
+ /* + * Check for potential race described above. If the waiting for next + * second, and the second just ticked since the check above, either + * + * 1) It ticked after the alarm was set, and an alarm irq should be + * generated. + * + * 2) It ticked before the alarm was set, and alarm irq most likely will + * not be generated. + * + * While we cannot easily check for which of these two scenarios we + * are in, we can return -ETIME to signal that the timer has already + * expired, which is true in both cases. + */ + if ((scheduled - now) <= 1) { + err = __rtc_read_time(rtc, &tm); + if (err) + return err; + now = rtc_tm_to_time64(&tm); + if (scheduled <= now) + return -ETIME; + } + trace_rtc_set_alarm(rtc_tm_to_time64(&alarm->time), err); return err; } @@ -577,6 +600,10 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) rtc->uie_rtctimer.node.expires = ktime_add(now, onesec); rtc->uie_rtctimer.period = ktime_set(1, 0); err = rtc_timer_enqueue(rtc, &rtc->uie_rtctimer); + if (!err && rtc->ops && rtc->ops->alarm_irq_enable) + err = rtc->ops->alarm_irq_enable(rtc->dev.parent, 1); + if (err) + goto out; } else { rtc_timer_remove(rtc, &rtc->uie_rtctimer); } diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index d1d5a44d9122..3b3aaa7d8283 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c @@ -671,7 +671,7 @@ static const struct i2c_device_id x1205_id[] = { MODULE_DEVICE_TABLE(i2c, x1205_id);
static const struct of_device_id x1205_dt_ids[] = { - { .compatible = "xircom,x1205", }, + { .compatible = "xicor,x1205", }, {}, }; MODULE_DEVICE_TABLE(of, x1205_dt_ids); diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index b760477b5742..359e1f61d598 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -6508,18 +6508,21 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp) while (left) { sz = (left > ioc->malloc_size) ? ioc->malloc_size : left; buff_size[sg_used] = sz; - buff[sg_used] = kmalloc(sz, GFP_KERNEL); - if (buff[sg_used] == NULL) { - status = -ENOMEM; - goto cleanup1; - } + if (ioc->Request.Type.Direction & XFER_WRITE) { - if (copy_from_user(buff[sg_used], data_ptr, sz)) { - status = -EFAULT; + buff[sg_used] = memdup_user(data_ptr, sz); + if (IS_ERR(buff[sg_used])) { + status = PTR_ERR(buff[sg_used]); goto cleanup1; } - } else - memset(buff[sg_used], 0, sz); + } else { + buff[sg_used] = kzalloc(sz, GFP_KERNEL); + if (!buff[sg_used]) { + status = -ENOMEM; + goto cleanup1; + } + } + left -= sz; data_ptr += sz; sg_used++; diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c index ebe78ec42da8..a355471cf079 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_transport.c +++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c @@ -812,11 +812,9 @@ mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, list_for_each_entry_safe(mpt3sas_phy, next_phy, &mpt3sas_port->phy_list, port_siblings) { if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) - dev_printk(KERN_INFO, &mpt3sas_port->port->dev, - "remove: sas_addr(0x%016llx), phy(%d)\n", - (unsigned long long) - mpt3sas_port->remote_identify.sas_address, - mpt3sas_phy->phy_id); + ioc_info(ioc, "remove: sas_addr(0x%016llx), phy(%d)\n", + (unsigned long long) mpt3sas_port->remote_identify.sas_address, + mpt3sas_phy->phy_id); mpt3sas_phy->phy_belongs_to_port = 0; if (!ioc->remove_host) sas_port_delete_phy(mpt3sas_port->port, diff --git a/drivers/scsi/mvsas/mv_defs.h b/drivers/scsi/mvsas/mv_defs.h index 199ab49aa047..3ec1c7546cdb 100644 --- a/drivers/scsi/mvsas/mv_defs.h +++ b/drivers/scsi/mvsas/mv_defs.h @@ -40,6 +40,7 @@ enum driver_configuration { MVS_ATA_CMD_SZ = 96, /* SATA command table buffer size */ MVS_OAF_SZ = 64, /* Open address frame buffer size */ MVS_QUEUE_SIZE = 64, /* Support Queue depth */ + MVS_RSVD_SLOTS = 4, MVS_SOC_CAN_QUEUE = MVS_SOC_SLOTS - 2, };
diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index 0c5e2c610586..d0a6639c3542 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -138,8 +138,8 @@ static void mvs_free(struct mvs_info *mvi) if (mvi->shost) scsi_host_put(mvi->shost); list_for_each_entry(mwq, &mvi->wq_list, entry) - cancel_delayed_work(&mwq->work_q); - kfree(mvi->tags); + cancel_delayed_work_sync(&mwq->work_q); + kfree(mvi->rsvd_tags); kfree(mvi); }
@@ -284,10 +284,7 @@ static int mvs_alloc(struct mvs_info *mvi, struct Scsi_Host *shost) printk(KERN_DEBUG "failed to create dma pool %s.\n", pool_name); goto err_out; } - mvi->tags_num = slot_nr;
- /* Initialize tags */ - mvs_tag_init(mvi); return 0; err_out: return 1; @@ -370,8 +367,8 @@ static struct mvs_info *mvs_pci_alloc(struct pci_dev *pdev, mvi->sas = sha; mvi->shost = shost;
- mvi->tags = kzalloc(MVS_CHIP_SLOT_SZ>>3, GFP_KERNEL); - if (!mvi->tags) + mvi->rsvd_tags = bitmap_zalloc(MVS_RSVD_SLOTS, GFP_KERNEL); + if (!mvi->rsvd_tags) goto err_out;
if (MVS_CHIP_DISP->chip_ioremap(mvi)) @@ -472,6 +469,8 @@ static void mvs_post_sas_ha_init(struct Scsi_Host *shost, else can_queue = MVS_CHIP_SLOT_SZ;
+ can_queue -= MVS_RSVD_SLOTS; + shost->sg_tablesize = min_t(u16, SG_ALL, MVS_MAX_SG); shost->can_queue = can_queue; mvi->shost->cmd_per_lun = MVS_QUEUE_SIZE; diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index 68caeaf9e636..393a8ee551e4 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c @@ -20,44 +20,40 @@ static int mvs_find_tag(struct mvs_info *mvi, struct sas_task *task, u32 *tag) return 0; }
-void mvs_tag_clear(struct mvs_info *mvi, u32 tag) +static void mvs_tag_clear(struct mvs_info *mvi, u32 tag) { - void *bitmap = mvi->tags; + void *bitmap = mvi->rsvd_tags; clear_bit(tag, bitmap); }
-void mvs_tag_free(struct mvs_info *mvi, u32 tag) +static void mvs_tag_free(struct mvs_info *mvi, u32 tag) { + if (tag >= MVS_RSVD_SLOTS) + return; + mvs_tag_clear(mvi, tag); }
-void mvs_tag_set(struct mvs_info *mvi, unsigned int tag) +static void mvs_tag_set(struct mvs_info *mvi, unsigned int tag) { - void *bitmap = mvi->tags; + void *bitmap = mvi->rsvd_tags; set_bit(tag, bitmap); }
-inline int mvs_tag_alloc(struct mvs_info *mvi, u32 *tag_out) +static int mvs_tag_alloc(struct mvs_info *mvi, u32 *tag_out) { unsigned int index, tag; - void *bitmap = mvi->tags; + void *bitmap = mvi->rsvd_tags;
- index = find_first_zero_bit(bitmap, mvi->tags_num); + index = find_first_zero_bit(bitmap, MVS_RSVD_SLOTS); tag = index; - if (tag >= mvi->tags_num) + if (tag >= MVS_RSVD_SLOTS) return -SAS_QUEUE_FULL; mvs_tag_set(mvi, tag); *tag_out = tag; return 0; }
-void mvs_tag_init(struct mvs_info *mvi) -{ - int i; - for (i = 0; i < mvi->tags_num; ++i) - mvs_tag_clear(mvi, i); -} - static struct mvs_info *mvs_find_dev_mvi(struct domain_device *dev) { unsigned long i = 0, j = 0, hi = 0; @@ -700,6 +696,7 @@ static int mvs_task_prep(struct sas_task *task, struct mvs_info *mvi, int is_tmf struct mvs_task_exec_info tei; struct mvs_slot_info *slot; u32 tag = 0xdeadbeef, n_elem = 0; + struct request *rq; int rc = 0;
if (!dev->port) { @@ -764,9 +761,14 @@ static int mvs_task_prep(struct sas_task *task, struct mvs_info *mvi, int is_tmf n_elem = task->num_scatter; }
- rc = mvs_tag_alloc(mvi, &tag); - if (rc) - goto err_out; + rq = sas_task_find_rq(task); + if (rq) { + tag = rq->tag + MVS_RSVD_SLOTS; + } else { + rc = mvs_tag_alloc(mvi, &tag); + if (rc) + goto err_out; + }
slot = &mvi->slot_info[tag];
@@ -869,7 +871,7 @@ int mvs_queue_command(struct sas_task *task, gfp_t gfp_flags) static void mvs_slot_free(struct mvs_info *mvi, u32 rx_desc) { u32 slot_idx = rx_desc & RXQ_SLOT_MASK; - mvs_tag_clear(mvi, slot_idx); + mvs_tag_free(mvi, slot_idx); }
static void mvs_slot_task_free(struct mvs_info *mvi, struct sas_task *task, diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h index 519edc796691..42caca5bb874 100644 --- a/drivers/scsi/mvsas/mv_sas.h +++ b/drivers/scsi/mvsas/mv_sas.h @@ -370,8 +370,7 @@ struct mvs_info { u32 chip_id; const struct mvs_chip_info *chip;
- int tags_num; - unsigned long *tags; + unsigned long *rsvd_tags; /* further per-slot information */ struct mvs_phy phy[MVS_MAX_PHYS]; struct mvs_port port[MVS_MAX_PHYS]; @@ -424,11 +423,6 @@ struct mvs_task_exec_info {
/******************** function prototype *********************/ void mvs_get_sas_addr(void *buf, u32 buflen); -void mvs_tag_clear(struct mvs_info *mvi, u32 tag); -void mvs_tag_free(struct mvs_info *mvi, u32 tag); -void mvs_tag_set(struct mvs_info *mvi, unsigned int tag); -int mvs_tag_alloc(struct mvs_info *mvi, u32 *tag_out); -void mvs_tag_init(struct mvs_info *mvi); void mvs_iounmap(void __iomem *regs); int mvs_ioremap(struct mvs_info *mvi, int bar, int bar_ex); void mvs_phys_reset(struct mvs_info *mvi, u32 phy_mask, int hard); diff --git a/drivers/scsi/myrs.c b/drivers/scsi/myrs.c index bf0546fc555f..04740f623a12 100644 --- a/drivers/scsi/myrs.c +++ b/drivers/scsi/myrs.c @@ -499,14 +499,14 @@ static bool myrs_enable_mmio_mbox(struct myrs_hba *cs, /* Temporary dma mapping, used only in the scope of this function */ mbox = dma_alloc_coherent(&pdev->dev, sizeof(union myrs_cmd_mbox), &mbox_addr, GFP_KERNEL); - if (dma_mapping_error(&pdev->dev, mbox_addr)) + if (!mbox) return false;
/* These are the base addresses for the command memory mailbox array */ cs->cmd_mbox_size = MYRS_MAX_CMD_MBOX * sizeof(union myrs_cmd_mbox); cmd_mbox = dma_alloc_coherent(&pdev->dev, cs->cmd_mbox_size, &cs->cmd_mbox_addr, GFP_KERNEL); - if (dma_mapping_error(&pdev->dev, cs->cmd_mbox_addr)) { + if (!cmd_mbox) { dev_err(&pdev->dev, "Failed to map command mailbox\n"); goto out_free; } @@ -521,7 +521,7 @@ static bool myrs_enable_mmio_mbox(struct myrs_hba *cs, cs->stat_mbox_size = MYRS_MAX_STAT_MBOX * sizeof(struct myrs_stat_mbox); stat_mbox = dma_alloc_coherent(&pdev->dev, cs->stat_mbox_size, &cs->stat_mbox_addr, GFP_KERNEL); - if (dma_mapping_error(&pdev->dev, cs->stat_mbox_addr)) { + if (!stat_mbox) { dev_err(&pdev->dev, "Failed to map status mailbox\n"); goto out_free; } @@ -534,7 +534,7 @@ static bool myrs_enable_mmio_mbox(struct myrs_hba *cs, cs->fwstat_buf = dma_alloc_coherent(&pdev->dev, sizeof(struct myrs_fwstat), &cs->fwstat_addr, GFP_KERNEL); - if (dma_mapping_error(&pdev->dev, cs->fwstat_addr)) { + if (!cs->fwstat_buf) { dev_err(&pdev->dev, "Failed to map firmware health buffer\n"); cs->fwstat_buf = NULL; goto out_free; diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 1215fc36862d..45b1af5a8d74 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -875,6 +875,7 @@ static void pm8001_dev_gone_notify(struct domain_device *dev) unsigned long flags = 0; struct pm8001_hba_info *pm8001_ha; struct pm8001_device *pm8001_dev = dev->lldd_dev; + struct domain_device *parent_dev = dev->parent;
pm8001_ha = pm8001_find_ha_by_dev(dev); spin_lock_irqsave(&pm8001_ha->lock, flags); @@ -893,7 +894,13 @@ static void pm8001_dev_gone_notify(struct domain_device *dev) spin_lock_irqsave(&pm8001_ha->lock, flags); } PM8001_CHIP_DISP->dereg_dev_req(pm8001_ha, device_id); - pm8001_ha->phy[pm8001_dev->attached_phy].phy_attached = 0; + + /* + * The phy array only contains local phys. Thus, we cannot clear + * phy_attached for a device behind an expander. + */ + if (!(parent_dev && dev_is_expander(parent_dev->dev_type))) + pm8001_ha->phy[pm8001_dev->attached_phy].phy_attached = 0; pm8001_free_dev(pm8001_dev); } else { PM8001_DISC_DBG(pm8001_ha, diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index 8924fcd9f5f5..a89d78afc897 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -265,13 +265,10 @@ static irqreturn_t tcs_tx_done(int irq, void *p)
trace_rpmh_tx_done(drv, i, req, err);
- /* - * If wake tcs was re-purposed for sending active - * votes, clear AMC trigger & enable modes and + /* Clear AMC trigger & enable modes and * disable interrupt for this TCS */ - if (!drv->tcs[ACTIVE_TCS].num_tcs) - __tcs_set_trigger(drv, i, false); + __tcs_set_trigger(drv, i, false); skip: /* Reclaim the TCS */ write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, i, 0); diff --git a/drivers/staging/axis-fifo/axis-fifo.c b/drivers/staging/axis-fifo/axis-fifo.c index 4dd2c8e9b787..8abcfe2725ba 100644 --- a/drivers/staging/axis-fifo/axis-fifo.c +++ b/drivers/staging/axis-fifo/axis-fifo.c @@ -400,6 +400,7 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf, }
bytes_available = ioread32(fifo->base_addr + XLLF_RLR_OFFSET); + words_available = bytes_available / sizeof(u32); if (!bytes_available) { dev_err(fifo->dt_device, "received a packet of length 0\n"); ret = -EIO; @@ -410,7 +411,7 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf, dev_err(fifo->dt_device, "user read buffer too small (available bytes=%zu user buffer bytes=%zu)\n", bytes_available, len); ret = -EINVAL; - goto end_unlock; + goto err_flush_rx; }
if (bytes_available % sizeof(u32)) { @@ -419,11 +420,9 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf, */ dev_err(fifo->dt_device, "received a packet that isn't word-aligned\n"); ret = -EIO; - goto end_unlock; + goto err_flush_rx; }
- words_available = bytes_available / sizeof(u32); - /* read data into an intermediate buffer, copying the contents * to userspace when the buffer is full */ @@ -435,18 +434,23 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf, tmp_buf[i] = ioread32(fifo->base_addr + XLLF_RDFD_OFFSET); } + words_available -= copy;
if (copy_to_user(buf + copied * sizeof(u32), tmp_buf, copy * sizeof(u32))) { ret = -EFAULT; - goto end_unlock; + goto err_flush_rx; }
copied += copy; - words_available -= copy; } + mutex_unlock(&fifo->read_lock);
- ret = bytes_available; + return bytes_available; + +err_flush_rx: + while (words_available--) + ioread32(fifo->base_addr + XLLF_RDFD_OFFSET);
end_unlock: mutex_unlock(&fifo->read_lock); @@ -494,11 +498,17 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf, return -EINVAL; }
- if (words_to_write > fifo->tx_fifo_depth) { - dev_err(fifo->dt_device, "tried to write more words [%u] than slots in the fifo buffer [%u]\n", - words_to_write, fifo->tx_fifo_depth); + /* + * In 'Store-and-Forward' mode, the maximum packet that can be + * transmitted is limited by the size of the FIFO, which is + * (C_TX_FIFO_DEPTH–4)*(data interface width/8) bytes. + * + * Do not attempt to send a packet larger than 'tx_fifo_depth - 4', + * otherwise a 'Transmit Packet Overrun Error' interrupt will be + * raised, which requires a reset of the TX circuit to recover. + */ + if (words_to_write > (fifo->tx_fifo_depth - 4)) return -EINVAL; - }
if (fifo->write_flags & O_NONBLOCK) { /* diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index 3ef3ddabf139..3df045b25cb3 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -369,7 +369,7 @@ static unsigned int comedi_buf_munge(struct comedi_subdevice *s, unsigned int count = 0; const unsigned int num_sample_bytes = comedi_bytes_per_sample(s);
- if (!s->munge || (async->cmd.flags & CMDF_RAWDATA)) { + if (!s->munge || (async->cmd.flags & CMDF_RAWDATA) || async->cmd.chanlist_len == 0) { async->munge_count += num_bytes; count = num_bytes; } else { diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 4edabab65b87..ce7fda75b9cc 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -2563,7 +2563,7 @@ static ssize_t target_lu_gp_members_show(struct config_item *item, char *page) config_item_name(&dev->dev_group.cg_item)); cur_len++; /* Extra byte for NULL terminator */
- if ((cur_len + len) > PAGE_SIZE) { + if ((cur_len + len) > PAGE_SIZE || cur_len > LU_GROUP_NAME_BUF) { pr_warn("Ran out of lu_gp_show_attr" "_members buffer\n"); break; diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 363b68555fe6..4ef2762347f6 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -1660,6 +1660,8 @@ static int max310x_i2c_probe(struct i2c_client *client) port_client = devm_i2c_new_dummy_device(&client->dev, client->adapter, port_addr); + if (IS_ERR(port_client)) + return PTR_ERR(port_client);
regmaps[i] = devm_regmap_init_i2c(port_client, ®cfg_i2c); } diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c index c707c3627cc2..10d24f47c564 100644 --- a/drivers/uio/uio_hv_generic.c +++ b/drivers/uio/uio_hv_generic.c @@ -96,7 +96,6 @@ static void hv_uio_channel_cb(void *context) struct hv_device *hv_dev = chan->device_obj; struct hv_uio_private_data *pdata = hv_get_drvdata(hv_dev);
- chan->inbound.ring_buffer->interrupt_mask = 1; virt_mb();
uio_event_notify(&pdata->info); @@ -173,8 +172,6 @@ hv_uio_new_channel(struct vmbus_channel *new_sc) return; }
- /* Disable interrupts on sub channel */ - new_sc->inbound.ring_buffer->interrupt_mask = 1; set_channel_read_mode(new_sc, HV_CALL_ISR);
ret = sysfs_create_bin_file(&new_sc->kobj, &ring_buffer_bin_attr); @@ -218,9 +215,7 @@ hv_uio_open(struct uio_info *info, struct inode *inode)
ret = vmbus_connect_ring(dev->channel, hv_uio_channel_cb, dev->channel); - if (ret == 0) - dev->channel->inbound.ring_buffer->interrupt_mask = 1; - else + if (ret) atomic_dec(&pdata->refcnt);
return ret; diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 716bcf9f4d34..aa6c9a6810b9 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -462,6 +462,8 @@ static const struct usb_device_id usb_quirk_list[] = { /* Huawei 4G LTE module */ { USB_DEVICE(0x12d1, 0x15bb), .driver_info = USB_QUIRK_DISCONNECT_SUSPEND }, + { USB_DEVICE(0x12d1, 0x15c1), .driver_info = + USB_QUIRK_DISCONNECT_SUSPEND }, { USB_DEVICE(0x12d1, 0x15c3), .driver_info = USB_QUIRK_DISCONNECT_SUSPEND },
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 476a22728e8d..d2be874af7d3 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1327,6 +1327,8 @@ static int configfs_composite_bind(struct usb_gadget *gadget, cdev->use_os_string = true; cdev->b_vendor_code = gi->b_vendor_code; memcpy(cdev->qw_sign, gi->qw_sign, OS_STRING_QW_SIGN_LEN); + } else { + cdev->use_os_string = false; }
if (gadget_is_otg(gadget) && !otg_desc[0]) { diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c index 5a21777197e9..cfdbe90f867e 100644 --- a/drivers/usb/host/max3421-hcd.c +++ b/drivers/usb/host/max3421-hcd.c @@ -1925,7 +1925,7 @@ max3421_probe(struct spi_device *spi) if (hcd) { kfree(max3421_hcd->tx); kfree(max3421_hcd->rx); - if (max3421_hcd->spi_thread) + if (!IS_ERR_OR_NULL(max3421_hcd->spi_thread)) kthread_stop(max3421_hcd->spi_thread); usb_put_hcd(hcd); } diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c index 93e2cca5262d..4e65ebbaa09b 100644 --- a/drivers/usb/host/xhci-dbgcap.c +++ b/drivers/usb/host/xhci-dbgcap.c @@ -975,8 +975,15 @@ int xhci_dbc_suspend(struct xhci_hcd *xhci) if (!dbc) return 0;
- if (dbc->state == DS_CONFIGURED) + switch (dbc->state) { + case DS_ENABLED: + case DS_CONNECTED: + case DS_CONFIGURED: dbc->resume_required = 1; + break; + default: + break; + }
xhci_dbc_stop(xhci);
diff --git a/drivers/usb/phy/phy-twl6030-usb.c b/drivers/usb/phy/phy-twl6030-usb.c index 9337c30f0743..607c3f18356a 100644 --- a/drivers/usb/phy/phy-twl6030-usb.c +++ b/drivers/usb/phy/phy-twl6030-usb.c @@ -328,9 +328,8 @@ static int twl6030_set_vbus(struct phy_companion *comparator, bool enabled)
static int twl6030_usb_probe(struct platform_device *pdev) { - u32 ret; struct twl6030_usb *twl; - int status, err; + int status, err, ret; struct device_node *np = pdev->dev.of_node; struct device *dev = &pdev->dev;
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index a417d32bfc96..4a93bfbe4c6c 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -273,6 +273,7 @@ static void option_instat_callback(struct urb *urb); #define QUECTEL_PRODUCT_EM05CN 0x0312 #define QUECTEL_PRODUCT_EM05G_GR 0x0313 #define QUECTEL_PRODUCT_EM05G_RS 0x0314 +#define QUECTEL_PRODUCT_RG255C 0x0316 #define QUECTEL_PRODUCT_EM12 0x0512 #define QUECTEL_PRODUCT_RM500Q 0x0800 #define QUECTEL_PRODUCT_RM520N 0x0801 @@ -617,6 +618,7 @@ static void option_instat_callback(struct urb *urb); #define UNISOC_VENDOR_ID 0x1782 /* TOZED LT70-C based on UNISOC SL8563 uses UNISOC's vendor ID */ #define TOZED_PRODUCT_LT70C 0x4055 +#define UNISOC_PRODUCT_UIS7720 0x4064 /* Luat Air72*U series based on UNISOC UIS8910 uses UNISOC's vendor ID */ #define LUAT_PRODUCT_AIR720U 0x4e00
@@ -1270,6 +1272,9 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG650V, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG650V, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG255C, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG255C, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG255C, 0xff, 0xff, 0x40) },
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, @@ -1398,10 +1403,14 @@ static const struct usb_device_id option_ids[] = { .driver_info = RSVD(0) | NCTRL(3) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a2, 0xff), /* Telit FN920C04 (MBIM) */ .driver_info = NCTRL(4) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a3, 0xff), /* Telit FN920C04 (ECM) */ + .driver_info = NCTRL(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a4, 0xff), /* Telit FN20C04 (rmnet) */ .driver_info = RSVD(0) | NCTRL(3) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a7, 0xff), /* Telit FN920C04 (MBIM) */ .driver_info = NCTRL(4) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a8, 0xff), /* Telit FN920C04 (ECM) */ + .driver_info = NCTRL(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a9, 0xff), /* Telit FN20C04 (rmnet) */ .driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10aa, 0xff), /* Telit FN920C04 (MBIM) */ @@ -2114,6 +2123,12 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9003, 0xff) }, /* Simcom SIM7500/SIM7600 MBIM mode */ { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9011, 0xff), /* Simcom SIM7500/SIM7600 RNDIS mode */ .driver_info = RSVD(7) }, + { USB_DEVICE(0x1e0e, 0x9071), /* Simcom SIM8230 RMNET mode */ + .driver_info = RSVD(3) | RSVD(4) }, + { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9078, 0xff), /* Simcom SIM8230 ECM mode */ + .driver_info = RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x907b, 0xff), /* Simcom SIM8230 RNDIS mode */ + .driver_info = RSVD(5) }, { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9205, 0xff) }, /* Simcom SIM7070/SIM7080/SIM7090 AT+ECM mode */ { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9206, 0xff) }, /* Simcom SIM7070/SIM7080/SIM7090 AT-only mode */ { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), @@ -2460,6 +2475,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9291, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9291, 0xff, 0xff, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, UNISOC_PRODUCT_UIS7720, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) }, { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */ .driver_info = NCTRL(1) }, diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index ee8fa558e3ed..d31b7e5895ce 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -765,6 +765,17 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag ctrlreq->wValue, vdev->rhport);
vdev->udev = usb_get_dev(urb->dev); + /* + * NOTE: A similar operation has been done via + * USB_REQ_GET_DESCRIPTOR handler below, which is + * supposed to always precede USB_REQ_SET_ADDRESS. + * + * It's not entirely clear if operating on a different + * usb_device instance here is a real possibility, + * otherwise this call and vdev->udev assignment above + * should be dropped. + */ + dev_pm_syscore_device(&vdev->udev->dev, true); usb_put_dev(old);
spin_lock(&vdev->ud.lock); @@ -785,6 +796,17 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag "Not yet?:Get_Descriptor to device 0 (get max pipe size)\n");
vdev->udev = usb_get_dev(urb->dev); + /* + * Set syscore PM flag for the virtually attached + * devices to ensure they will not enter suspend on + * the client side. + * + * Note this doesn't have any impact on the physical + * devices attached to the host system on the server + * side, hence there is no need to undo the operation + * on disconnect. + */ + dev_pm_syscore_device(&vdev->udev->dev, true); usb_put_dev(old); goto out;
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c index 3fc457bc16db..18349ec0c101 100644 --- a/drivers/watchdog/mpc8xxx_wdt.c +++ b/drivers/watchdog/mpc8xxx_wdt.c @@ -100,6 +100,8 @@ static int mpc8xxx_wdt_start(struct watchdog_device *w) ddata->swtc = tmp >> 16; set_bit(WDOG_HW_RUNNING, &ddata->wdd.status);
+ mpc8xxx_wdt_keepalive(ddata); + return 0; }
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c index f8554d9a9f28..5baa185c323c 100644 --- a/drivers/xen/events/events_base.c +++ b/drivers/xen/events/events_base.c @@ -1210,10 +1210,12 @@ EXPORT_SYMBOL_GPL(bind_interdomain_evtchn_to_irq_lateeoi); static int find_virq(unsigned int virq, unsigned int cpu) { struct evtchn_status status; - int port, rc = -ENOENT; + int port;
memset(&status, 0, sizeof(status)); for (port = 0; port < xen_evtchn_max_channels(); port++) { + int rc; + status.dom = DOMID_SELF; status.port = port; rc = HYPERVISOR_event_channel_op(EVTCHNOP_status, &status); @@ -1221,12 +1223,10 @@ static int find_virq(unsigned int virq, unsigned int cpu) continue; if (status.status != EVTCHNSTAT_virq) continue; - if (status.u.virq == virq && status.vcpu == xen_vcpu_nr(cpu)) { - rc = port; - break; - } + if (status.u.virq == virq && status.vcpu == xen_vcpu_nr(cpu)) + return port; } - return rc; + return -ENOENT; }
/** @@ -1717,9 +1717,20 @@ static int xen_rebind_evtchn_to_cpu(struct irq_info *info, unsigned int tcpu) * virq or IPI channel, which don't actually need to be rebound. Ignore * it, but don't do the xenlinux-level rebind in that case. */ - if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0) + if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0) { + int old_cpu = info->cpu; + bind_evtchn_to_cpu(evtchn, tcpu);
+ if (info->type == IRQT_VIRQ) { + int virq = info->u.virq; + int irq = per_cpu(virq_to_irq, old_cpu)[virq]; + + per_cpu(virq_to_irq, old_cpu)[virq] = -1; + per_cpu(virq_to_irq, tcpu)[virq] = irq; + } + } + do_unmask(info, EVT_MASK_REASON_TEMPORARY);
return 0; diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index cd046684e0d1..86341bd5f6e4 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -116,7 +116,7 @@ static void do_suspend(void) err = dpm_suspend_start(PMSG_FREEZE); if (err) { pr_err("%s: dpm_suspend_start %d\n", __func__, err); - goto out_thaw; + goto out_resume_end; }
printk(KERN_DEBUG "suspending xenstore...\n"); @@ -156,6 +156,7 @@ static void do_suspend(void) else xs_suspend_cancel();
+out_resume_end: dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
out_thaw: diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index 08d1d456e2f0..c244b4cc8ba1 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c @@ -22,7 +22,11 @@ static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len, int type;
if (parent && (len < BTRFS_FID_SIZE_CONNECTABLE)) { - *max_len = BTRFS_FID_SIZE_CONNECTABLE; + if (BTRFS_I(inode)->root->root_key.objectid != + BTRFS_I(parent)->root->root_key.objectid) + *max_len = BTRFS_FID_SIZE_CONNECTABLE_ROOT; + else + *max_len = BTRFS_FID_SIZE_CONNECTABLE; return FILEID_INVALID; } else if (len < BTRFS_FID_SIZE_NON_CONNECTABLE) { *max_len = BTRFS_FID_SIZE_NON_CONNECTABLE; @@ -44,6 +48,8 @@ static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len, parent_root_id = BTRFS_I(parent)->root->root_key.objectid;
if (parent_root_id != fid->root_objectid) { + if (*max_len < BTRFS_FID_SIZE_CONNECTABLE_ROOT) + return FILEID_INVALID; fid->parent_root_objectid = parent_root_id; len = BTRFS_FID_SIZE_CONNECTABLE_ROOT; type = FILEID_BTRFS_WITH_PARENT_ROOT; diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 2f04024c3588..82c45ca45321 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -117,9 +117,18 @@ static struct inode *get_cramfs_inode(struct super_block *sb, inode_nohighmem(inode); inode->i_data.a_ops = &cramfs_aops; break; - default: + case S_IFCHR: + case S_IFBLK: + case S_IFIFO: + case S_IFSOCK: init_special_inode(inode, cramfs_inode->mode, old_decode_dev(cramfs_inode->size)); + break; + default: + printk(KERN_DEBUG "CRAMFS: Invalid file type 0%04o for inode %lu.\n", + inode->i_mode, inode->i_ino); + iget_failed(inode); + return ERR_PTR(-EIO); }
inode->i_mode = cramfs_inode->mode; diff --git a/fs/dcache.c b/fs/dcache.c index 78081bdc4931..1c905958c011 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1782,6 +1782,8 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name) __dget_dlock(parent); dentry->d_parent = parent; list_add(&dentry->d_child, &parent->d_subdirs); + if (parent->d_flags & DCACHE_DISCONNECTED) + dentry->d_flags |= DCACHE_DISCONNECTED; spin_unlock(&parent->d_lock);
return dentry; diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index c689359ca532..9030e0e5927c 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -793,7 +793,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)
dlm_device_deregister(ls);
- if (force < 3 && dlm_user_daemon_available()) + if (force != 3 && dlm_user_daemon_available()) do_uevent(ls, 0);
dlm_recoverd_stop(ls); diff --git a/fs/exec.c b/fs/exec.c index 5dffc67745c8..5aa0d9ec7f21 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -701,7 +701,7 @@ int setup_arg_pages(struct linux_binprm *bprm, unsigned long stack_top, int executable_stack) { - unsigned long ret; + int ret; unsigned long stack_shift; struct mm_struct *mm = current->mm; struct vm_area_struct *vma = bprm->vma; diff --git a/fs/ext4/fsmap.c b/fs/ext4/fsmap.c index bdc194b8f4de..00b929ab0b68 100644 --- a/fs/ext4/fsmap.c +++ b/fs/ext4/fsmap.c @@ -74,7 +74,8 @@ static int ext4_getfsmap_dev_compare(const void *p1, const void *p2) static bool ext4_getfsmap_rec_before_low_key(struct ext4_getfsmap_info *info, struct ext4_fsmap *rec) { - return rec->fmr_physical < info->gfi_low.fmr_physical; + return rec->fmr_physical + rec->fmr_length <= + info->gfi_low.fmr_physical; }
/* @@ -200,15 +201,18 @@ static int ext4_getfsmap_meta_helper(struct super_block *sb, ext4_group_first_block_no(sb, agno)); fs_end = fs_start + EXT4_C2B(sbi, len);
- /* Return relevant extents from the meta_list */ + /* + * Return relevant extents from the meta_list. We emit all extents that + * partially/fully overlap with the query range + */ list_for_each_entry_safe(p, tmp, &info->gfi_meta_list, fmr_list) { - if (p->fmr_physical < info->gfi_next_fsblk) { + if (p->fmr_physical + p->fmr_length <= info->gfi_next_fsblk) { list_del(&p->fmr_list); kfree(p); continue; } - if (p->fmr_physical <= fs_start || - p->fmr_physical + p->fmr_length <= fs_end) { + if (p->fmr_physical <= fs_end && + p->fmr_physical + p->fmr_length > fs_start) { /* Emit the retained free extent record if present */ if (info->gfi_lastfree.fmr_owner) { error = ext4_getfsmap_helper(sb, info, diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index fe54c84a1df0..98f09beca90b 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4247,7 +4247,11 @@ int ext4_can_truncate(struct inode *inode) * We have to make sure i_disksize gets properly updated before we truncate * page cache due to hole punching or zero range. Otherwise i_disksize update * can get lost as it may have been postponed to submission of writeback but - * that will never happen after we truncate page cache. + * that will never happen if we remove the folio containing i_size from the + * page cache. Also if we punch hole within i_size but above i_disksize, + * following ext4_page_mkwrite() may mistakenly allocate written blocks over + * the hole and thus introduce allocated blocks beyond i_disksize which is + * not allowed (e2fsck would complain in case of crash). */ int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset, loff_t len) @@ -4256,9 +4260,11 @@ int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset, loff_t size = i_size_read(inode);
WARN_ON(!inode_is_locked(inode)); - if (offset > size || offset + len < size) + if (offset > size) return 0;
+ if (offset + len < size) + size = offset + len; if (EXT4_I(inode)->i_disksize >= size) return 0;
@@ -5071,6 +5077,14 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, } ei->i_flags = le32_to_cpu(raw_inode->i_flags); ext4_set_inode_flags(inode); + /* Detect invalid flag combination - can't have both inline data and extents */ + if (ext4_test_inode_flag(inode, EXT4_INODE_INLINE_DATA) && + ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) { + ext4_error_inode(inode, function, line, 0, + "inode has both inline data and extents flags"); + ret = -EFSCORRUPTED; + goto bad_inode; + } inode->i_blocks = ext4_inode_blocks(raw_inode, ei); ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo); if (ext4_has_feature_64bit(sb)) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index ff681888a123..0c7aedcb39ea 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3882,18 +3882,16 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) }
if (sbi->s_es->s_mount_opts[0]) { - char *s_mount_opts = kstrndup(sbi->s_es->s_mount_opts, - sizeof(sbi->s_es->s_mount_opts), - GFP_KERNEL); - if (!s_mount_opts) - goto failed_mount; + char s_mount_opts[65]; + + strscpy_pad(s_mount_opts, sbi->s_es->s_mount_opts, + sizeof(s_mount_opts)); if (!parse_options(s_mount_opts, sb, &journal_devnum, &journal_ioprio, 0)) { ext4_msg(sb, KERN_WARNING, "failed to parse options in superblock: %s", s_mount_opts); } - kfree(s_mount_opts); } sbi->s_def_mount_opt = sbi->s_mount_opt; if (!parse_options((char *) data, sb, &journal_devnum, diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index f32e720e9e20..e08ba064cb82 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -1030,7 +1030,7 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode, int ref_change) { struct ext4_iloc iloc; - s64 ref_count; + u64 ref_count; int ret;
inode_lock_nested(ea_inode, I_MUTEX_XATTR); @@ -1040,13 +1040,17 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode, goto out;
ref_count = ext4_xattr_inode_get_ref(ea_inode); + if ((ref_count == 0 && ref_change < 0) || (ref_count == U64_MAX && ref_change > 0)) { + ext4_error_inode(ea_inode, __func__, __LINE__, 0, + "EA inode %lu ref wraparound: ref_count=%lld ref_change=%d", + ea_inode->i_ino, ref_count, ref_change); + ret = -EFSCORRUPTED; + goto out; + } ref_count += ref_change; ext4_xattr_inode_set_ref(ea_inode, ref_count);
if (ref_change > 0) { - WARN_ONCE(ref_count <= 0, "EA inode %lu ref_count=%lld", - ea_inode->i_ino, ref_count); - if (ref_count == 1) { WARN_ONCE(ea_inode->i_nlink, "EA inode %lu i_nlink=%u", ea_inode->i_ino, ea_inode->i_nlink); @@ -1055,9 +1059,6 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode, ext4_orphan_del(handle, ea_inode); } } else { - WARN_ONCE(ref_count < 0, "EA inode %lu ref_count=%lld", - ea_inode->i_ino, ref_count); - if (ref_count == 0) { WARN_ONCE(ea_inode->i_nlink != 1, "EA inode %lu i_nlink=%u", diff --git a/fs/hfs/bfind.c b/fs/hfs/bfind.c index ef9498a6e88a..6d37b4c75903 100644 --- a/fs/hfs/bfind.c +++ b/fs/hfs/bfind.c @@ -18,7 +18,7 @@ int hfs_find_init(struct hfs_btree *tree, struct hfs_find_data *fd)
fd->tree = tree; fd->bnode = NULL; - ptr = kmalloc(tree->max_key_len * 2 + 4, GFP_KERNEL); + ptr = kzalloc(tree->max_key_len * 2 + 4, GFP_KERNEL); if (!ptr) return -ENOMEM; fd->search_key = ptr; @@ -112,6 +112,12 @@ int hfs_brec_find(struct hfs_find_data *fd) __be32 data; int height, res;
+ fd->record = -1; + fd->keyoffset = -1; + fd->keylength = -1; + fd->entryoffset = -1; + fd->entrylength = -1; + tree = fd->tree; if (fd->bnode) hfs_bnode_put(fd->bnode); diff --git a/fs/hfs/brec.c b/fs/hfs/brec.c index 896396554bcc..b01db1fae147 100644 --- a/fs/hfs/brec.c +++ b/fs/hfs/brec.c @@ -179,6 +179,7 @@ int hfs_brec_remove(struct hfs_find_data *fd) struct hfs_btree *tree; struct hfs_bnode *node, *parent; int end_off, rec_off, data_off, size; + int src, dst, len;
tree = fd->tree; node = fd->bnode; @@ -208,10 +209,14 @@ int hfs_brec_remove(struct hfs_find_data *fd) } hfs_bnode_write_u16(node, offsetof(struct hfs_bnode_desc, num_recs), node->num_recs);
- if (rec_off == end_off) - goto skip; size = fd->keylength + fd->entrylength;
+ if (rec_off == end_off) { + src = fd->keyoffset; + hfs_bnode_clear(node, src, size); + goto skip; + } + do { data_off = hfs_bnode_read_u16(node, rec_off); hfs_bnode_write_u16(node, rec_off + 2, data_off - size); @@ -219,9 +224,23 @@ int hfs_brec_remove(struct hfs_find_data *fd) } while (rec_off >= end_off);
/* fill hole */ - hfs_bnode_move(node, fd->keyoffset, fd->keyoffset + size, - data_off - fd->keyoffset - size); + dst = fd->keyoffset; + src = fd->keyoffset + size; + len = data_off - src; + + hfs_bnode_move(node, dst, src, len); + + src = dst + len; + len = data_off - src; + + hfs_bnode_clear(node, src, len); + skip: + /* + * Remove the obsolete offset to free space. + */ + hfs_bnode_write_u16(node, end_off, 0); + hfs_bnode_dump(node); if (!fd->record) hfs_brec_update_parent(fd); diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c index 460281b1299e..8036445672c5 100644 --- a/fs/hfs/mdb.c +++ b/fs/hfs/mdb.c @@ -166,7 +166,7 @@ int hfs_mdb_get(struct super_block *sb) pr_warn("continuing without an alternate MDB\n"); }
- HFS_SB(sb)->bitmap = kmalloc(8192, GFP_KERNEL); + HFS_SB(sb)->bitmap = kzalloc(8192, GFP_KERNEL); if (!HFS_SB(sb)->bitmap) goto out;
diff --git a/fs/hfsplus/bfind.c b/fs/hfsplus/bfind.c index 901e83d65d20..26ebac4c6042 100644 --- a/fs/hfsplus/bfind.c +++ b/fs/hfsplus/bfind.c @@ -18,7 +18,7 @@ int hfs_find_init(struct hfs_btree *tree, struct hfs_find_data *fd)
fd->tree = tree; fd->bnode = NULL; - ptr = kmalloc(tree->max_key_len * 2 + 4, GFP_KERNEL); + ptr = kzalloc(tree->max_key_len * 2 + 4, GFP_KERNEL); if (!ptr) return -ENOMEM; fd->search_key = ptr; @@ -158,6 +158,12 @@ int hfs_brec_find(struct hfs_find_data *fd, search_strategy_t do_key_compare) __be32 data; int height, res;
+ fd->record = -1; + fd->keyoffset = -1; + fd->keylength = -1; + fd->entryoffset = -1; + fd->entrylength = -1; + tree = fd->tree; if (fd->bnode) hfs_bnode_put(fd->bnode); diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index c9c38fddf505..e566cea23827 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -18,47 +18,6 @@ #include "hfsplus_fs.h" #include "hfsplus_raw.h"
-static inline -bool is_bnode_offset_valid(struct hfs_bnode *node, int off) -{ - bool is_valid = off < node->tree->node_size; - - if (!is_valid) { - pr_err("requested invalid offset: " - "NODE: id %u, type %#x, height %u, " - "node_size %u, offset %d\n", - node->this, node->type, node->height, - node->tree->node_size, off); - } - - return is_valid; -} - -static inline -int check_and_correct_requested_length(struct hfs_bnode *node, int off, int len) -{ - unsigned int node_size; - - if (!is_bnode_offset_valid(node, off)) - return 0; - - node_size = node->tree->node_size; - - if ((off + len) > node_size) { - int new_len = (int)node_size - off; - - pr_err("requested length has been corrected: " - "NODE: id %u, type %#x, height %u, " - "node_size %u, offset %d, " - "requested_len %d, corrected_len %d\n", - node->this, node->type, node->height, - node->tree->node_size, off, len, new_len); - - return new_len; - } - - return len; -}
/* Copy a specified range of bytes from the raw data of a node */ void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len) diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c index 66774f4cb4fd..2211907537fe 100644 --- a/fs/hfsplus/btree.c +++ b/fs/hfsplus/btree.c @@ -392,6 +392,12 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree) len = hfs_brec_lenoff(node, 2, &off16); off = off16;
+ if (!is_bnode_offset_valid(node, off)) { + hfs_bnode_put(node); + return ERR_PTR(-EIO); + } + len = check_and_correct_requested_length(node, off, len); + off += node->page_offset; pagep = node->page + (off >> PAGE_SHIFT); data = kmap(*pagep); diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 86cfc147bf3d..5355d1ff7a9b 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -561,6 +561,48 @@ hfsplus_btree_lock_class(struct hfs_btree *tree) return class; }
+static inline +bool is_bnode_offset_valid(struct hfs_bnode *node, int off) +{ + bool is_valid = off < node->tree->node_size; + + if (!is_valid) { + pr_err("requested invalid offset: " + "NODE: id %u, type %#x, height %u, " + "node_size %u, offset %d\n", + node->this, node->type, node->height, + node->tree->node_size, off); + } + + return is_valid; +} + +static inline +int check_and_correct_requested_length(struct hfs_bnode *node, int off, int len) +{ + unsigned int node_size; + + if (!is_bnode_offset_valid(node, off)) + return 0; + + node_size = node->tree->node_size; + + if ((off + len) > node_size) { + int new_len = (int)node_size - off; + + pr_err("requested length has been corrected: " + "NODE: id %u, type %#x, height %u, " + "node_size %u, offset %d, " + "requested_len %d, corrected_len %d\n", + node->this, node->type, node->height, + node->tree->node_size, off, len, new_len); + + return new_len; + } + + return len; +} + /* compatibility */ #define hfsp_mt2ut(t) (struct timespec){ .tv_sec = __hfsp_mt2ut(t) } #define hfsp_ut2mt(t) __hfsp_ut2mt((t).tv_sec) diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 29a39afe2653..db68ed59b4b2 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -67,13 +67,26 @@ struct inode *hfsplus_iget(struct super_block *sb, unsigned long ino) if (!(inode->i_state & I_NEW)) return inode;
- INIT_LIST_HEAD(&HFSPLUS_I(inode)->open_dir_list); - spin_lock_init(&HFSPLUS_I(inode)->open_dir_lock); - mutex_init(&HFSPLUS_I(inode)->extents_lock); - HFSPLUS_I(inode)->flags = 0; + atomic_set(&HFSPLUS_I(inode)->opencnt, 0); + HFSPLUS_I(inode)->first_blocks = 0; + HFSPLUS_I(inode)->clump_blocks = 0; + HFSPLUS_I(inode)->alloc_blocks = 0; + HFSPLUS_I(inode)->cached_start = U32_MAX; + HFSPLUS_I(inode)->cached_blocks = 0; + memset(HFSPLUS_I(inode)->first_extents, 0, sizeof(hfsplus_extent_rec)); + memset(HFSPLUS_I(inode)->cached_extents, 0, sizeof(hfsplus_extent_rec)); HFSPLUS_I(inode)->extent_state = 0; + mutex_init(&HFSPLUS_I(inode)->extents_lock); HFSPLUS_I(inode)->rsrc_inode = NULL; - atomic_set(&HFSPLUS_I(inode)->opencnt, 0); + HFSPLUS_I(inode)->create_date = 0; + HFSPLUS_I(inode)->linkid = 0; + HFSPLUS_I(inode)->flags = 0; + HFSPLUS_I(inode)->fs_blocks = 0; + HFSPLUS_I(inode)->userflags = 0; + HFSPLUS_I(inode)->subfolders = 0; + INIT_LIST_HEAD(&HFSPLUS_I(inode)->open_dir_list); + spin_lock_init(&HFSPLUS_I(inode)->open_dir_lock); + HFSPLUS_I(inode)->phys_size = 0;
if (inode->i_ino >= HFSPLUS_FIRSTUSER_CNID || inode->i_ino == HFSPLUS_ROOT_CNID) { @@ -526,7 +539,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) if (!hfs_brec_read(&fd, &entry, sizeof(entry))) { hfs_find_exit(&fd); if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) { - err = -EINVAL; + err = -EIO; goto out_put_root; } inode = hfsplus_iget(sb, be32_to_cpu(entry.folder.id)); diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c index 36b6cf2a3abb..ebd326799f35 100644 --- a/fs/hfsplus/unicode.c +++ b/fs/hfsplus/unicode.c @@ -40,6 +40,18 @@ int hfsplus_strcasecmp(const struct hfsplus_unistr *s1, p1 = s1->unicode; p2 = s2->unicode;
+ if (len1 > HFSPLUS_MAX_STRLEN) { + len1 = HFSPLUS_MAX_STRLEN; + pr_err("invalid length %u has been corrected to %d\n", + be16_to_cpu(s1->length), len1); + } + + if (len2 > HFSPLUS_MAX_STRLEN) { + len2 = HFSPLUS_MAX_STRLEN; + pr_err("invalid length %u has been corrected to %d\n", + be16_to_cpu(s2->length), len2); + } + while (1) { c1 = c2 = 0;
@@ -74,6 +86,18 @@ int hfsplus_strcmp(const struct hfsplus_unistr *s1, p1 = s1->unicode; p2 = s2->unicode;
+ if (len1 > HFSPLUS_MAX_STRLEN) { + len1 = HFSPLUS_MAX_STRLEN; + pr_err("invalid length %u has been corrected to %d\n", + be16_to_cpu(s1->length), len1); + } + + if (len2 > HFSPLUS_MAX_STRLEN) { + len2 = HFSPLUS_MAX_STRLEN; + pr_err("invalid length %u has been corrected to %d\n", + be16_to_cpu(s2->length), len2); + } + for (len = min(len1, len2); len > 0; len--) { c1 = be16_to_cpu(*p1); c2 = be16_to_cpu(*p2); diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 72e9297d6adc..97ff68f90d57 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -1550,6 +1550,7 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh) int drop_reserve = 0; int err = 0; int was_modified = 0; + int wait_for_writeback = 0;
if (is_handle_aborted(handle)) return -EROFS; @@ -1675,18 +1676,22 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh) }
/* - * The buffer is still not written to disk, we should - * attach this buffer to current transaction so that the - * buffer can be checkpointed only after the current - * transaction commits. + * The buffer has not yet been written to disk. We should + * either clear the buffer or ensure that the ongoing I/O + * is completed, and attach this buffer to current + * transaction so that the buffer can be checkpointed only + * after the current transaction commits. */ clear_buffer_dirty(bh); + wait_for_writeback = 1; __jbd2_journal_file_buffer(jh, transaction, BJ_Forget); spin_unlock(&journal->j_list_lock); }
jbd_unlock_bh_state(bh); __brelse(bh); + if (wait_for_writeback) + wait_on_buffer(bh); drop: if (drop_reserve) { /* no need to reserve log space for this block -bzzz */ diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 3fffc709afd4..c026706aec0c 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -470,8 +470,14 @@ void minix_set_inode(struct inode *inode, dev_t rdev) inode->i_op = &minix_symlink_inode_operations; inode_nohighmem(inode); inode->i_mapping->a_ops = &minix_aops; - } else + } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || + S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { init_special_inode(inode, inode->i_mode, rdev); + } else { + printk(KERN_DEBUG "MINIX-fs: Invalid file type 0%04o for inode %lu.\n", + inode->i_mode, inode->i_ino); + make_bad_inode(inode); + } }
/* diff --git a/fs/namespace.c b/fs/namespace.c index c87f847c959d..3c6f0586ae21 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -62,6 +62,15 @@ static int __init set_mphash_entries(char *str) } __setup("mphash_entries=", set_mphash_entries);
+static char * __initdata initramfs_options; +static int __init initramfs_options_setup(char *str) +{ + initramfs_options = str; + return 1; +} + +__setup("initramfs_options=", initramfs_options_setup); + static u64 event; static DEFINE_IDA(mnt_id_ida); static DEFINE_IDA(mnt_group_ida); @@ -3829,7 +3838,7 @@ static void __init init_mount_tree(void) struct mnt_namespace *ns; struct path root;
- mnt = vfs_kern_mount(&rootfs_fs_type, 0, "rootfs", NULL); + mnt = vfs_kern_mount(&rootfs_fs_type, 0, "rootfs", initramfs_options); if (IS_ERR(mnt)) panic("Can't create rootfs");
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index f511087d5e1c..44770bb9017d 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -8686,7 +8686,7 @@ static int nfs4_verify_back_channel_attrs(struct nfs41_create_session_args *args goto out; if (rcvd->max_rqst_sz > sent->max_rqst_sz) return -EINVAL; - if (rcvd->max_resp_sz < sent->max_resp_sz) + if (rcvd->max_resp_sz > sent->max_resp_sz) return -EINVAL; if (rcvd->max_resp_sz_cached > sent->max_resp_sz_cached) return -EINVAL; diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c index 9bbaa671c079..e620c1662e7b 100644 --- a/fs/nfsd/blocklayout.c +++ b/fs/nfsd/blocklayout.c @@ -120,7 +120,6 @@ static __be32 nfsd4_block_commit_blocks(struct inode *inode, struct nfsd4_layoutcommit *lcp, struct iomap *iomaps, int nr_iomaps) { - loff_t new_size = lcp->lc_last_wr + 1; struct iattr iattr = { .ia_valid = 0 }; int error;
@@ -130,9 +129,9 @@ nfsd4_block_commit_blocks(struct inode *inode, struct nfsd4_layoutcommit *lcp, iattr.ia_valid |= ATTR_ATIME | ATTR_CTIME | ATTR_MTIME; iattr.ia_atime = iattr.ia_ctime = iattr.ia_mtime = lcp->lc_mtime;
- if (new_size > i_size_read(inode)) { + if (lcp->lc_size_chg) { iattr.ia_valid |= ATTR_SIZE; - iattr.ia_size = new_size; + iattr.ia_size = lcp->lc_newsize; }
error = inode->i_sb->s_export_op->commit_blocks(inode, iomaps, diff --git a/fs/nfsd/flexfilelayout.c b/fs/nfsd/flexfilelayout.c index db7ef07ae50c..c2e1a985412c 100644 --- a/fs/nfsd/flexfilelayout.c +++ b/fs/nfsd/flexfilelayout.c @@ -124,6 +124,13 @@ nfsd4_ff_proc_getdeviceinfo(struct super_block *sb, struct svc_rqst *rqstp, return 0; }
+static __be32 +nfsd4_ff_proc_layoutcommit(struct inode *inode, + struct nfsd4_layoutcommit *lcp) +{ + return nfs_ok; +} + const struct nfsd4_layout_ops ff_layout_ops = { .notify_types = NOTIFY_DEVICEID4_DELETE | NOTIFY_DEVICEID4_CHANGE, @@ -132,4 +139,5 @@ const struct nfsd4_layout_ops ff_layout_ops = { .encode_getdeviceinfo = nfsd4_ff_encode_getdeviceinfo, .proc_layoutget = nfsd4_ff_proc_layoutget, .encode_layoutget = nfsd4_ff_encode_layoutget, + .proc_layoutcommit = nfsd4_ff_proc_layoutcommit, }; diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c index 3f5b3d7b62b7..64797df7aee4 100644 --- a/fs/nfsd/lockd.c +++ b/fs/nfsd/lockd.c @@ -44,6 +44,21 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp) switch (nfserr) { case nfs_ok: return 0; + case nfserr_jukebox: + /* this error can indicate a presence of a conflicting + * delegation to an NLM lock request. Options are: + * (1) For now, drop this request and make the client + * retry. When delegation is returned, client's lock retry + * will complete. + * (2) NLM4_DENIED as per "spec" signals to the client + * that the lock is unavailable now but client can retry. + * Linux client implementation does not. It treats + * NLM4_DENIED same as NLM4_FAILED and errors the request. + * (3) For the future, treat this as blocked lock and try + * to callback when the delegation is returned but might + * not have a proper lock request to block on. + */ + fallthrough; case nfserr_dropit: return nlm_drop_reply; case nfserr_stale: diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 527d6b29dffb..df1a86dff571 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1701,7 +1701,6 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp, const struct nfsd4_layout_seg *seg = &lcp->lc_seg; struct svc_fh *current_fh = &cstate->current_fh; const struct nfsd4_layout_ops *ops; - loff_t new_size = lcp->lc_last_wr + 1; struct inode *inode; struct nfs4_layout_stateid *ls; __be32 nfserr; @@ -1716,18 +1715,20 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp, goto out; inode = d_inode(current_fh->fh_dentry);
- nfserr = nfserr_inval; - if (new_size <= seg->offset) { - dprintk("pnfsd: last write before layout segment\n"); - goto out; - } - if (new_size > seg->offset + seg->length) { - dprintk("pnfsd: last write beyond layout segment\n"); - goto out; - } - if (!lcp->lc_newoffset && new_size > i_size_read(inode)) { - dprintk("pnfsd: layoutcommit beyond EOF\n"); - goto out; + lcp->lc_size_chg = false; + if (lcp->lc_newoffset) { + loff_t new_size = lcp->lc_last_wr + 1; + + nfserr = nfserr_inval; + if (new_size <= seg->offset) + goto out; + if (new_size > seg->offset + seg->length) + goto out; + + if (new_size > i_size_read(inode)) { + lcp->lc_size_chg = true; + lcp->lc_newsize = new_size; + } }
nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lcp->lc_sid, @@ -1744,13 +1745,6 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp, /* LAYOUTCOMMIT does not require any serialization */ mutex_unlock(&ls->ls_mutex);
- if (new_size > i_size_read(inode)) { - lcp->lc_size_chg = 1; - lcp->lc_newsize = new_size; - } else { - lcp->lc_size_chg = 0; - } - nfserr = ops->proc_layoutcommit(inode, lcp); nfs4_put_stid(&ls->ls_stid); out: diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c index 98e77ea957ff..3cc28afe9815 100644 --- a/fs/ocfs2/move_extents.c +++ b/fs/ocfs2/move_extents.c @@ -870,6 +870,11 @@ static int __ocfs2_move_extents_range(struct buffer_head *di_bh, mlog_errno(ret); goto out; } + /* + * Invalidate extent cache after moving/defragging to prevent + * stale cached data with outdated extent flags. + */ + ocfs2_extent_map_trunc(inode, cpos);
context->clusters_moved += alloc_size; next: diff --git a/fs/ocfs2/stack_user.c b/fs/ocfs2/stack_user.c index 7397064c3f35..c7a0625954c6 100644 --- a/fs/ocfs2/stack_user.c +++ b/fs/ocfs2/stack_user.c @@ -1032,6 +1032,7 @@ static int user_cluster_connect(struct ocfs2_cluster_connection *conn) printk(KERN_ERR "ocfs2: Could not determine" " locking version\n"); user_cluster_disconnect(conn); + lc = NULL; goto out; } wait_event(lc->oc_wait, (atomic_read(&lc->oc_this_node) > 0)); diff --git a/fs/squashfs/inode.c b/fs/squashfs/inode.c index 95a9ff9e2399..42c97c68db63 100644 --- a/fs/squashfs/inode.c +++ b/fs/squashfs/inode.c @@ -140,8 +140,17 @@ int squashfs_read_inode(struct inode *inode, long long ino) if (err < 0) goto failed_read;
+ inode->i_size = le32_to_cpu(sqsh_ino->file_size); frag = le32_to_cpu(sqsh_ino->fragment); if (frag != SQUASHFS_INVALID_FRAG) { + /* + * the file cannot have a fragment (tailend) and have a + * file size a multiple of the block size + */ + if ((inode->i_size & (msblk->block_size - 1)) == 0) { + err = -EINVAL; + goto failed_read; + } frag_offset = le32_to_cpu(sqsh_ino->offset); frag_size = squashfs_frag_lookup(sb, frag, &frag_blk); if (frag_size < 0) { @@ -155,7 +164,6 @@ int squashfs_read_inode(struct inode *inode, long long ino) }
set_nlink(inode, 1); - inode->i_size = le32_to_cpu(sqsh_ino->file_size); inode->i_fop = &generic_ro_fops; inode->i_mode |= S_IFREG; inode->i_blocks = ((inode->i_size - 1) >> 9) + 1; @@ -165,6 +173,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) squashfs_i(inode)->start = le32_to_cpu(sqsh_ino->start_block); squashfs_i(inode)->block_list_start = block; squashfs_i(inode)->offset = offset; + squashfs_i(inode)->parent = 0; inode->i_data.a_ops = &squashfs_aops;
TRACE("File inode %x:%x, start_block %llx, block_list_start " @@ -183,8 +192,21 @@ int squashfs_read_inode(struct inode *inode, long long ino) if (err < 0) goto failed_read;
+ inode->i_size = le64_to_cpu(sqsh_ino->file_size); + if (inode->i_size < 0) { + err = -EINVAL; + goto failed_read; + } frag = le32_to_cpu(sqsh_ino->fragment); if (frag != SQUASHFS_INVALID_FRAG) { + /* + * the file cannot have a fragment (tailend) and have a + * file size a multiple of the block size + */ + if ((inode->i_size & (msblk->block_size - 1)) == 0) { + err = -EINVAL; + goto failed_read; + } frag_offset = le32_to_cpu(sqsh_ino->offset); frag_size = squashfs_frag_lookup(sb, frag, &frag_blk); if (frag_size < 0) { @@ -199,7 +221,6 @@ int squashfs_read_inode(struct inode *inode, long long ino)
xattr_id = le32_to_cpu(sqsh_ino->xattr); set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); - inode->i_size = le64_to_cpu(sqsh_ino->file_size); inode->i_op = &squashfs_inode_ops; inode->i_fop = &generic_ro_fops; inode->i_mode |= S_IFREG; @@ -212,6 +233,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) squashfs_i(inode)->start = le64_to_cpu(sqsh_ino->start_block); squashfs_i(inode)->block_list_start = block; squashfs_i(inode)->offset = offset; + squashfs_i(inode)->parent = 0; inode->i_data.a_ops = &squashfs_aops;
TRACE("File inode %x:%x, start_block %llx, block_list_start " @@ -292,6 +314,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) inode->i_mode |= S_IFLNK; squashfs_i(inode)->start = block; squashfs_i(inode)->offset = offset; + squashfs_i(inode)->parent = 0;
if (type == SQUASHFS_LSYMLINK_TYPE) { __le32 xattr; @@ -329,6 +352,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); rdev = le32_to_cpu(sqsh_ino->rdev); init_special_inode(inode, inode->i_mode, new_decode_dev(rdev)); + squashfs_i(inode)->parent = 0;
TRACE("Device inode %x:%x, rdev %x\n", SQUASHFS_INODE_BLK(ino), offset, rdev); @@ -353,6 +377,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); rdev = le32_to_cpu(sqsh_ino->rdev); init_special_inode(inode, inode->i_mode, new_decode_dev(rdev)); + squashfs_i(inode)->parent = 0;
TRACE("Device inode %x:%x, rdev %x\n", SQUASHFS_INODE_BLK(ino), offset, rdev); @@ -373,6 +398,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) inode->i_mode |= S_IFSOCK; set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); init_special_inode(inode, inode->i_mode, 0); + squashfs_i(inode)->parent = 0; break; } case SQUASHFS_LFIFO_TYPE: @@ -392,6 +418,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) inode->i_op = &squashfs_inode_ops; set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); init_special_inode(inode, inode->i_mode, 0); + squashfs_i(inode)->parent = 0; break; } default: diff --git a/fs/squashfs/squashfs_fs_i.h b/fs/squashfs/squashfs_fs_i.h index 2c82d6f2a456..8e497ac07b9a 100644 --- a/fs/squashfs/squashfs_fs_i.h +++ b/fs/squashfs/squashfs_fs_i.h @@ -16,6 +16,7 @@ struct squashfs_inode_info { u64 xattr; unsigned int xattr_size; int xattr_count; + int parent; union { struct { u64 fragment_block; @@ -27,7 +28,6 @@ struct squashfs_inode_info { u64 dir_idx_start; int dir_idx_offset; int dir_idx_cnt; - int parent; }; }; struct inode vfs_inode; diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 7d878e36759b..e3fa86bb8021 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -2202,6 +2202,9 @@ int8_t udf_current_aext(struct inode *inode, struct extent_position *epos, if (check_add_overflow(sizeof(struct allocExtDesc), le32_to_cpu(header->lengthAllocDescs), &alen)) return -1; + + if (alen > epos->bh->b_size) + return -1; }
switch (iinfo->i_alloc_type) { diff --git a/include/linux/device.h b/include/linux/device.h index af4ecbf88910..844960850acb 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1441,6 +1441,9 @@ static inline bool device_pm_not_required(struct device *dev) static inline void device_set_pm_not_required(struct device *dev) { dev->power.no_pm = true; +#ifdef CONFIG_PM + dev->power.no_callbacks = true; +#endif }
static inline void dev_pm_syscore_device(struct device *dev, bool val) diff --git a/include/linux/iio/frequency/adf4350.h b/include/linux/iio/frequency/adf4350.h index ce9490bfeb89..531d9903446c 100644 --- a/include/linux/iio/frequency/adf4350.h +++ b/include/linux/iio/frequency/adf4350.h @@ -51,7 +51,7 @@
/* REG3 Bit Definitions */ #define ADF4350_REG3_12BIT_CLKDIV(x) ((x) << 3) -#define ADF4350_REG3_12BIT_CLKDIV_MODE(x) ((x) << 16) +#define ADF4350_REG3_12BIT_CLKDIV_MODE(x) ((x) << 15) #define ADF4350_REG3_12BIT_CSR_EN (1 << 18) #define ADF4351_REG3_CHARGE_CANCELLATION_EN (1 << 21) #define ADF4351_REG3_ANTI_BACKLASH_3ns_EN (1 << 22) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index f5c1058f565c..037a48bc5690 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1158,6 +1158,10 @@ struct tlsdev_ops; * struct net_device *dev, * const unsigned char *addr, u16 vid) * Deletes the FDB entry from dev coresponding to addr. + * int (*ndo_fdb_del_bulk)(struct ndmsg *ndm, struct nlattr *tb[], + * struct net_device *dev, + * u16 vid, + * struct netlink_ext_ack *extack); * int (*ndo_fdb_dump)(struct sk_buff *skb, struct netlink_callback *cb, * struct net_device *dev, struct net_device *filter_dev, * int *idx) @@ -1396,6 +1400,11 @@ struct net_device_ops { struct net_device *dev, const unsigned char *addr, u16 vid); + int (*ndo_fdb_del_bulk)(struct ndmsg *ndm, + struct nlattr *tb[], + struct net_device *dev, + u16 vid, + struct netlink_ext_ack *extack); int (*ndo_fdb_dump)(struct sk_buff *skb, struct netlink_callback *cb, struct net_device *dev, diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index 3a04e2ccfb39..d2945ec5aba2 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -454,6 +454,21 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, struct metadata_dst *iptunnel_metadata_reply(struct metadata_dst *md, gfp_t flags);
+static inline void ip_tunnel_adj_headroom(struct net_device *dev, + unsigned int headroom) +{ + /* we must cap headroom to some upperlimit, else pskb_expand_head + * will overflow header offsets in skb_headers_offset_update(). + */ + const unsigned int max_allowed = 512; + + if (headroom > max_allowed) + headroom = max_allowed; + + if (headroom > READ_ONCE(dev->needed_headroom)) + WRITE_ONCE(dev->needed_headroom, headroom); +} + int iptunnel_handle_offloads(struct sk_buff *skb, int gso_type_mask);
static inline int iptunnel_pull_offloads(struct sk_buff *skb) diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h index 5c2a73bbfabe..e893b1f21913 100644 --- a/include/net/rtnetlink.h +++ b/include/net/rtnetlink.h @@ -10,9 +10,23 @@ typedef int (*rtnl_doit_func)(struct sk_buff *, struct nlmsghdr *, typedef int (*rtnl_dumpit_func)(struct sk_buff *, struct netlink_callback *);
enum rtnl_link_flags { - RTNL_FLAG_DOIT_UNLOCKED = 1, + RTNL_FLAG_DOIT_UNLOCKED = BIT(0), + RTNL_FLAG_BULK_DEL_SUPPORTED = BIT(1), };
+enum rtnl_kinds { + RTNL_KIND_NEW, + RTNL_KIND_DEL, + RTNL_KIND_GET, + RTNL_KIND_SET +}; +#define RTNL_KIND_MASK 0x3 + +static inline enum rtnl_kinds rtnl_msgtype_kind(int msgtype) +{ + return msgtype & RTNL_KIND_MASK; +} + void rtnl_register(int protocol, int msgtype, rtnl_doit_func, rtnl_dumpit_func, unsigned int flags); int rtnl_register_module(struct module *owner, int protocol, int msgtype, diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 4e2d61e8fb1e..8461fad88a11 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -620,6 +620,24 @@ extern struct sas_task *sas_alloc_task(gfp_t flags); extern struct sas_task *sas_alloc_slow_task(gfp_t flags); extern void sas_free_task(struct sas_task *task);
+static inline struct request *sas_task_find_rq(struct sas_task *task) +{ + struct scsi_cmnd *scmd; + + if (task->task_proto & SAS_PROTOCOL_STP_ALL) { + struct ata_queued_cmd *qc = task->uldd_task; + + scmd = qc ? qc->scsicmd : NULL; + } else { + scmd = task->uldd_task; + } + + if (!scmd) + return NULL; + + return scsi_cmd_to_rq(scmd); +} + struct sas_domain_function_template { /* The class calls these to notify the LLDD of an event. */ void (*lldd_port_formed)(struct asd_sas_phy *); diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h index cf4e4836338f..9ad4c47dea84 100644 --- a/include/uapi/linux/netlink.h +++ b/include/uapi/linux/netlink.h @@ -72,6 +72,7 @@ struct nlmsghdr {
/* Modifiers to DELETE request */ #define NLM_F_NONREC 0x100 /* Do not delete recursively */ +#define NLM_F_BULK 0x200 /* Delete multiple objects */
/* Flags for ACK message */ #define NLM_F_CAPPED 0x100 /* request was capped */ diff --git a/kernel/padata.c b/kernel/padata.c index 47aebcda65d5..409d24228439 100644 --- a/kernel/padata.c +++ b/kernel/padata.c @@ -204,7 +204,11 @@ static struct padata_priv *padata_find_next(struct parallel_data *pd, list_del_init(&padata->list); atomic_dec(&pd->reorder_objects); ++pd->processed; - pd->cpu = cpumask_next_wrap(cpu, pd->cpumask.pcpu, -1, false); + /* When sequence wraps around, reset to the first CPU. */ + if (unlikely(pd->processed == 0)) + pd->cpu = cpumask_first(pd->cpumask.pcpu); + else + pd->cpu = cpumask_next_wrap(cpu, pd->cpumask.pcpu, -1, false); }
spin_unlock(&reorder->lock); diff --git a/kernel/pid.c b/kernel/pid.c index 0a9f2e437217..3a7b71258047 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -407,7 +407,7 @@ pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns) struct upid *upid; pid_t nr = 0;
- if (pid && ns->level <= pid->level) { + if (pid && ns && ns->level <= pid->level) { upid = &pid->numbers[ns->level]; if (upid->ns == ns) nr = upid->nr; diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 2680216234ff..5e8f2167d8ca 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -3690,6 +3690,8 @@ static inline unsigned long cfs_rq_load_avg(struct cfs_rq *cfs_rq) return cfs_rq->avg.load_avg; }
+static int sched_balance_newidle(struct rq *this_rq, struct rq_flags *rf); + static inline unsigned long task_util(struct task_struct *p) { return READ_ONCE(p->se.avg.util_avg); @@ -3849,7 +3851,7 @@ attach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags static inline void detach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) {}
-static inline int idle_balance(struct rq *rq, struct rq_flags *rf) +static inline int sched_balance_newidle(struct rq *rq, struct rq_flags *rf) { return 0; } @@ -6688,7 +6690,7 @@ balance_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf) if (rq->nr_running) return 1;
- return newidle_balance(rq, rf) != 0; + return sched_balance_newidle(rq, rf) != 0; } #endif /* CONFIG_SMP */
@@ -6976,21 +6978,21 @@ done: __maybe_unused; return p;
idle: - if (!rf) - return NULL; + if (rf) { + new_tasks = sched_balance_newidle(rq, rf);
- new_tasks = newidle_balance(rq, rf); - - /* - * Because newidle_balance() releases (and re-acquires) rq->lock, it is - * possible for any higher priority task to appear. In that case we - * must re-start the pick_next_entity() loop. - */ - if (new_tasks < 0) - return RETRY_TASK; + /* + * Because sched_balance_newidle() releases (and re-acquires) + * rq->lock, it is possible for any higher priority task to + * appear. In that case we must re-start the pick_next_entity() + * loop. + */ + if (new_tasks < 0) + return RETRY_TASK;
- if (new_tasks > 0) - goto again; + if (new_tasks > 0) + goto again; + }
/* * rq is about to be idle, check if we need to update the @@ -9180,7 +9182,7 @@ static int load_balance(int this_cpu, struct rq *this_rq, ld_moved = 0;
/* - * newidle_balance() disregards balance intervals, so we could + * sched_balance_newidle() disregards balance intervals, so we could * repeatedly reach this code, which would lead to balance_interval * skyrocketting in a short amount of time. Skip the balance_interval * increase logic to avoid that. @@ -9895,10 +9897,10 @@ static inline void nohz_newidle_balance(struct rq *this_rq) { } #endif /* CONFIG_NO_HZ_COMMON */
/* - * idle_balance is called by schedule() if this_cpu is about to become + * sched_balance_newidle is called by schedule() if this_cpu is about to become * idle. Attempts to pull tasks from other CPUs. */ -int newidle_balance(struct rq *this_rq, struct rq_flags *rf) +static int sched_balance_newidle(struct rq *this_rq, struct rq_flags *rf) { unsigned long next_balance = jiffies + HZ; int this_cpu = this_rq->cpu; diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index b8a3db59e326..46e6f4e905dd 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1464,14 +1464,10 @@ static inline void unregister_sched_domain_sysctl(void) } #endif
-extern int newidle_balance(struct rq *this_rq, struct rq_flags *rf); - #else
static inline void sched_ttwu_pending(void) { }
-static inline int newidle_balance(struct rq *this_rq, struct rq_flags *rf) { return 0; } - #endif /* CONFIG_SMP */
#include "stats.h" diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 56d22752a52e..01a9fc7279c6 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -1585,14 +1585,15 @@ static int kprobe_register(struct trace_event_call *event, static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs) { struct trace_kprobe *tk = container_of(kp, struct trace_kprobe, rp.kp); + unsigned int flags = trace_probe_load_flag(&tk->tp); int ret = 0;
raw_cpu_inc(*tk->nhit);
- if (trace_probe_test_flag(&tk->tp, TP_FLAG_TRACE)) + if (flags & TP_FLAG_TRACE) kprobe_trace_func(tk, regs); #ifdef CONFIG_PERF_EVENTS - if (trace_probe_test_flag(&tk->tp, TP_FLAG_PROFILE)) + if (flags & TP_FLAG_PROFILE) ret = kprobe_perf_func(tk, regs); #endif return ret; @@ -1603,13 +1604,15 @@ static int kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs) { struct trace_kprobe *tk = container_of(ri->rp, struct trace_kprobe, rp); + unsigned int flags;
raw_cpu_inc(*tk->nhit);
- if (trace_probe_test_flag(&tk->tp, TP_FLAG_TRACE)) + flags = trace_probe_load_flag(&tk->tp); + if (flags & TP_FLAG_TRACE) kretprobe_trace_func(tk, ri, regs); #ifdef CONFIG_PERF_EVENTS - if (trace_probe_test_flag(&tk->tp, TP_FLAG_PROFILE)) + if (flags & TP_FLAG_PROFILE) kretprobe_perf_func(tk, ri, regs); #endif return 0; /* We don't tweek kernel, so just return 0 */ diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index edbb1624061e..15c9ef34a611 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -252,16 +252,21 @@ struct event_file_link { struct list_head list; };
+static inline unsigned int trace_probe_load_flag(struct trace_probe *tp) +{ + return smp_load_acquire(&tp->event->flags); +} + static inline bool trace_probe_test_flag(struct trace_probe *tp, unsigned int flag) { - return !!(tp->event->flags & flag); + return !!(trace_probe_load_flag(tp) & flag); }
static inline void trace_probe_set_flag(struct trace_probe *tp, unsigned int flag) { - tp->event->flags |= flag; + smp_store_release(&tp->event->flags, tp->event->flags | flag); }
static inline void trace_probe_clear_flag(struct trace_probe *tp, diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index e924c04af627..4f844df6ee00 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -1465,6 +1465,7 @@ static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs) struct uprobe_dispatch_data udd; struct uprobe_cpu_buffer *ucb; int dsize, esize; + unsigned int flags; int ret = 0;
@@ -1485,11 +1486,12 @@ static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs) ucb = uprobe_buffer_get(); store_trace_args(ucb->buf, &tu->tp, regs, esize, dsize);
- if (trace_probe_test_flag(&tu->tp, TP_FLAG_TRACE)) + flags = trace_probe_load_flag(&tu->tp); + if (flags & TP_FLAG_TRACE) ret |= uprobe_trace_func(tu, regs, ucb, dsize);
#ifdef CONFIG_PERF_EVENTS - if (trace_probe_test_flag(&tu->tp, TP_FLAG_PROFILE)) + if (flags & TP_FLAG_PROFILE) ret |= uprobe_perf_func(tu, regs, ucb, dsize); #endif uprobe_buffer_put(ucb); @@ -1503,6 +1505,7 @@ static int uretprobe_dispatcher(struct uprobe_consumer *con, struct uprobe_dispatch_data udd; struct uprobe_cpu_buffer *ucb; int dsize, esize; + unsigned int flags;
tu = container_of(con, struct trace_uprobe, consumer);
@@ -1520,11 +1523,12 @@ static int uretprobe_dispatcher(struct uprobe_consumer *con, ucb = uprobe_buffer_get(); store_trace_args(ucb->buf, &tu->tp, regs, esize, dsize);
- if (trace_probe_test_flag(&tu->tp, TP_FLAG_TRACE)) + flags = trace_probe_load_flag(&tu->tp); + if (flags & TP_FLAG_TRACE) uretprobe_trace_func(tu, func, regs, ucb, dsize);
#ifdef CONFIG_PERF_EVENTS - if (trace_probe_test_flag(&tu->tp, TP_FLAG_PROFILE)) + if (flags & TP_FLAG_PROFILE) uretprobe_perf_func(tu, func, regs, ucb, dsize); #endif uprobe_buffer_put(ucb); diff --git a/lib/genalloc.c b/lib/genalloc.c index 80d10d02cf38..6a88836c1dce 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -892,8 +892,11 @@ struct gen_pool *of_gen_pool_get(struct device_node *np, if (!name) name = np_pool->name; } - if (pdev) + if (pdev) { pool = gen_pool_get(&pdev->dev, name); + put_device(&pdev->dev); + } + of_node_put(np_pool);
return pool; diff --git a/mm/hugetlb.c b/mm/hugetlb.c index e4478b62d0f7..e83563b9ab32 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -4703,6 +4703,8 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, pages++; } spin_unlock(ptl); + + cond_resched(); } /* * Must flush TLB before releasing i_mmap_rwsem: x86's huge_pmd_unshare diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 872568cca926..3a56a888f939 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -711,10 +711,10 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req) p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req);
spin_lock(&client->lock); - /* Ignore cancelled request if message has been received - * before lock. - */ - if (req->status == REQ_STATUS_RCVD) { + /* Ignore cancelled request if status changed since the request was + * processed in p9_client_flush() + */ + if (req->status != REQ_STATUS_SENT) { spin_unlock(&client->lock); return 0; } diff --git a/net/core/filter.c b/net/core/filter.c index fd18497977bd..2c56c910a0c1 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -7132,13 +7132,17 @@ static bool sock_addr_is_valid_access(int off, int size, return false; info->reg_type = PTR_TO_SOCKET; break; - default: - if (type == BPF_READ) { - if (size != size_default) - return false; - } else { + case bpf_ctx_range(struct bpf_sock_addr, user_family): + case bpf_ctx_range(struct bpf_sock_addr, family): + case bpf_ctx_range(struct bpf_sock_addr, type): + case bpf_ctx_range(struct bpf_sock_addr, protocol): + if (type != BPF_READ) return false; - } + if (size != size_default) + return false; + break; + default: + return false; }
return true; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 2b7ad5cf8fbf..76ff9a35ccf6 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -214,6 +214,8 @@ static int rtnl_register_internal(struct module *owner, if (dumpit) link->dumpit = dumpit;
+ WARN_ON(rtnl_msgtype_kind(msgtype) != RTNL_KIND_DEL && + (flags & RTNL_FLAG_BULK_DEL_SUPPORTED)); link->flags |= flags;
/* publish protocol:msgtype */ @@ -3816,22 +3818,31 @@ int ndo_dflt_fdb_del(struct ndmsg *ndm, } EXPORT_SYMBOL(ndo_dflt_fdb_del);
+static const struct nla_policy fdb_del_bulk_policy[NDA_MAX + 1] = { + [NDA_VLAN] = { .type = NLA_U16 }, + [NDA_IFINDEX] = NLA_POLICY_MIN(NLA_S32, 1), +}; + static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, struct netlink_ext_ack *extack) { + bool del_bulk = !!(nlh->nlmsg_flags & NLM_F_BULK); struct net *net = sock_net(skb->sk); + const struct net_device_ops *ops; struct ndmsg *ndm; struct nlattr *tb[NDA_MAX+1]; struct net_device *dev; - int err = -EINVAL; - __u8 *addr; + __u8 *addr = NULL; + int err; u16 vid;
- if (!netlink_capable(skb, CAP_NET_ADMIN)) - return -EPERM; - - err = nlmsg_parse_deprecated(nlh, sizeof(*ndm), tb, NDA_MAX, NULL, - extack); + if (!del_bulk) { + err = nlmsg_parse_deprecated(nlh, sizeof(*ndm), tb, NDA_MAX, + NULL, extack); + } else { + err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, + fdb_del_bulk_policy, extack); + } if (err < 0) return err;
@@ -3847,9 +3858,12 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, return -ENODEV; }
- if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) { - NL_SET_ERR_MSG(extack, "invalid address"); - return -EINVAL; + if (!del_bulk) { + if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) { + NL_SET_ERR_MSG(extack, "invalid address"); + return -EINVAL; + } + addr = nla_data(tb[NDA_LLADDR]); }
if (dev->type != ARPHRD_ETHER) { @@ -3857,8 +3871,6 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, return -EINVAL; }
- addr = nla_data(tb[NDA_LLADDR]); - err = fdb_vid_parse(tb[NDA_VLAN], &vid, extack); if (err) return err; @@ -3869,10 +3881,16 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, if ((!ndm->ndm_flags || ndm->ndm_flags & NTF_MASTER) && netif_is_bridge_port(dev)) { struct net_device *br_dev = netdev_master_upper_dev_get(dev); - const struct net_device_ops *ops = br_dev->netdev_ops;
- if (ops->ndo_fdb_del) - err = ops->ndo_fdb_del(ndm, tb, dev, addr, vid); + ops = br_dev->netdev_ops; + if (!del_bulk) { + if (ops->ndo_fdb_del) + err = ops->ndo_fdb_del(ndm, tb, dev, addr, vid); + } else { + if (ops->ndo_fdb_del_bulk) + err = ops->ndo_fdb_del_bulk(ndm, tb, dev, vid, + extack); + }
if (err) goto out; @@ -3882,15 +3900,24 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh,
/* Embedded bridge, macvlan, and any other device support */ if (ndm->ndm_flags & NTF_SELF) { - if (dev->netdev_ops->ndo_fdb_del) - err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr, - vid); - else - err = ndo_dflt_fdb_del(ndm, tb, dev, addr, vid); + ops = dev->netdev_ops; + if (!del_bulk) { + if (ops->ndo_fdb_del) + err = ops->ndo_fdb_del(ndm, tb, dev, addr, vid); + else + err = ndo_dflt_fdb_del(ndm, tb, dev, addr, vid); + } else { + /* in case err was cleared by NTF_MASTER call */ + err = -EOPNOTSUPP; + if (ops->ndo_fdb_del_bulk) + err = ops->ndo_fdb_del_bulk(ndm, tb, dev, vid, + extack); + }
if (!err) { - rtnl_fdb_notify(dev, addr, vid, RTM_DELNEIGH, - ndm->ndm_state); + if (!del_bulk) + rtnl_fdb_notify(dev, addr, vid, RTM_DELNEIGH, + ndm->ndm_state); ndm->ndm_flags &= ~NTF_SELF; } } @@ -5193,11 +5220,11 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, { struct net *net = sock_net(skb->sk); struct rtnl_link *link; + enum rtnl_kinds kind; struct module *owner; int err = -EOPNOTSUPP; rtnl_doit_func doit; unsigned int flags; - int kind; int family; int type;
@@ -5212,13 +5239,13 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, return 0;
family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family; - kind = type&3; + kind = rtnl_msgtype_kind(type);
- if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN)) + if (kind != RTNL_KIND_GET && !netlink_net_capable(skb, CAP_NET_ADMIN)) return -EPERM;
rcu_read_lock(); - if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { + if (kind == RTNL_KIND_GET && (nlh->nlmsg_flags & NLM_F_DUMP)) { struct sock *rtnl; rtnl_dumpit_func dumpit; u16 min_dump_alloc = 0; @@ -5274,6 +5301,13 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, }
flags = link->flags; + if (kind == RTNL_KIND_DEL && (nlh->nlmsg_flags & NLM_F_BULK) && + !(flags & RTNL_FLAG_BULK_DEL_SUPPORTED)) { + NL_SET_ERR_MSG(extack, "Bulk delete is not supported"); + module_put(owner); + goto err_unlock; + } + if (flags & RTNL_FLAG_DOIT_UNLOCKED) { doit = link->doit; rcu_read_unlock(); @@ -5399,7 +5433,8 @@ void __init rtnetlink_init(void) rtnl_register(PF_UNSPEC, RTM_GETNETCONF, NULL, rtnl_dump_all, 0);
rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, 0); - rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, 0); + rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, + RTNL_FLAG_BULK_DEL_SUPPORTED); rtnl_register(PF_BRIDGE, RTM_GETNEIGH, rtnl_fdb_get, rtnl_fdb_dump, 0);
rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, 0); diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 906c37c7f80d..38cace81bfa2 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -560,20 +560,6 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb, return 0; }
-static void ip_tunnel_adj_headroom(struct net_device *dev, unsigned int headroom) -{ - /* we must cap headroom to some upperlimit, else pskb_expand_head - * will overflow header offsets in skb_headers_offset_update(). - */ - static const unsigned int max_allowed = 512; - - if (headroom > max_allowed) - headroom = max_allowed; - - if (headroom > READ_ONCE(dev->needed_headroom)) - WRITE_ONCE(dev->needed_headroom, headroom); -} - void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, u8 proto, int tunnel_hlen) { diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index cc0efcb4a553..a0a5590573b0 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2359,8 +2359,8 @@ bool tcp_check_oom(struct sock *sk, int shift)
void __tcp_close(struct sock *sk, long timeout) { + bool data_was_unread = false; struct sk_buff *skb; - int data_was_unread = 0; int state;
WRITE_ONCE(sk->sk_shutdown, SHUTDOWN_MASK); @@ -2379,11 +2379,12 @@ void __tcp_close(struct sock *sk, long timeout) * reader process may not have drained the data yet! */ while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) { - u32 len = TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq; + u32 end_seq = TCP_SKB_CB(skb)->end_seq;
if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) - len--; - data_was_unread += len; + end_seq--; + if (after(end_seq, tcp_sk(sk)->copied_seq)) + data_was_unread = true; __kfree_skb(skb); }
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 9d65e684e626..541f9a89b490 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -6800,7 +6800,6 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, &foc, TCP_SYNACK_FASTOPEN); /* Add the child socket directly into the accept queue */ if (!inet_csk_reqsk_queue_add(sk, req, fastopen_sk)) { - reqsk_fastopen_remove(fastopen_sk, req, false); bh_unlock_sock(fastopen_sk); sock_put(fastopen_sk); goto drop_and_free; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 4f203cbbc99b..6492110e0c9b 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1952,7 +1952,8 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb, u32 max_segs) { const struct inet_connection_sock *icsk = inet_csk(sk); - u32 send_win, cong_win, limit, in_flight; + u32 send_win, cong_win, limit, in_flight, threshold; + u64 srtt_in_ns, expected_ack, how_far_is_the_ack; struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *head; int win_divisor; @@ -2014,9 +2015,19 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb, head = tcp_rtx_queue_head(sk); if (!head) goto send_now; - delta = tp->tcp_clock_cache - head->tstamp; - /* If next ACK is likely to come too late (half srtt), do not defer */ - if ((s64)(delta - (u64)NSEC_PER_USEC * (tp->srtt_us >> 4)) < 0) + + srtt_in_ns = (u64)(NSEC_PER_USEC >> 3) * tp->srtt_us; + /* When is the ACK expected ? */ + expected_ack = head->tstamp + srtt_in_ns; + /* How far from now is the ACK expected ? */ + how_far_is_the_ack = expected_ack - tp->tcp_clock_cache; + + /* If next ACK is likely to come too late, + * ie in more than min(1ms, half srtt), do not defer. + */ + threshold = min(srtt_in_ns >> 1, NSEC_PER_MSEC); + + if ((s64)(how_far_is_the_ack - threshold) > 0) goto send_now;
/* Ok, it looks like it is advisable to defer. diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 013260256875..08eaefb88774 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1371,12 +1371,12 @@ static bool udp_skb_has_head_state(struct sk_buff *skb) }
/* fully reclaim rmem/fwd memory allocated for skb */ -static void udp_rmem_release(struct sock *sk, int size, int partial, - bool rx_queue_lock_held) +static void udp_rmem_release(struct sock *sk, unsigned int size, + int partial, bool rx_queue_lock_held) { struct udp_sock *up = udp_sk(sk); struct sk_buff_head *sk_queue; - int amt; + unsigned int amt;
if (likely(partial)) { up->forward_deficit += size; @@ -1396,10 +1396,8 @@ static void udp_rmem_release(struct sock *sk, int size, int partial, if (!rx_queue_lock_held) spin_lock(&sk_queue->lock);
- - sk->sk_forward_alloc += size; - amt = (sk->sk_forward_alloc - partial) & ~(SK_MEM_QUANTUM - 1); - sk->sk_forward_alloc -= amt; + amt = (size + sk->sk_forward_alloc - partial) & ~(PAGE_SIZE - 1); + sk->sk_forward_alloc += size - amt;
if (amt) __sk_mem_reduce_allocated(sk, amt >> SK_MEM_QUANTUM_SHIFT); @@ -1583,7 +1581,7 @@ EXPORT_SYMBOL_GPL(skb_consume_udp);
static struct sk_buff *__first_packet_length(struct sock *sk, struct sk_buff_head *rcvq, - int *total) + unsigned int *total) { struct sk_buff *skb;
@@ -1616,8 +1614,8 @@ static int first_packet_length(struct sock *sk) { struct sk_buff_head *rcvq = &udp_sk(sk)->reader_queue; struct sk_buff_head *sk_queue = &sk->sk_receive_queue; + unsigned int total = 0; struct sk_buff *skb; - int total = 0; int res;
spin_lock_bh(&rcvq->lock); diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 5319093d9aa6..c79e6c032b30 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1201,8 +1201,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, */ max_headroom = LL_RESERVED_SPACE(dst->dev) + sizeof(struct ipv6hdr) + dst->header_len + t->hlen; - if (max_headroom > READ_ONCE(dev->needed_headroom)) - WRITE_ONCE(dev->needed_headroom, max_headroom); + ip_tunnel_adj_headroom(dev, max_headroom);
err = ip6_tnl_encap(skb, t, &proto, fl6); if (err) diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h index 297631f9717b..0dcba0a87283 100644 --- a/net/netfilter/ipset/ip_set_hash_gen.h +++ b/net/netfilter/ipset/ip_set_hash_gen.h @@ -87,7 +87,7 @@ struct hbucket { : jhash_size((htable_bits) - HTABLE_REGION_BITS)) #define ahash_sizeof_regions(htable_bits) \ (ahash_numof_locks(htable_bits) * sizeof(struct ip_set_region)) -#define ahash_region(n, htable_bits) \ +#define ahash_region(n) \ ((n) / jhash_size(HTABLE_REGION_BITS)) #define ahash_bucket_start(h, htable_bits) \ ((htable_bits) < HTABLE_REGION_BITS ? 0 \ @@ -716,7 +716,7 @@ mtype_resize(struct ip_set *set, bool retried) #endif key = HKEY(data, h->initval, htable_bits); m = __ipset_dereference(hbucket(t, key)); - nr = ahash_region(key, htable_bits); + nr = ahash_region(key); if (!m) { m = kzalloc(sizeof(*m) + AHASH_INIT_SIZE * dsize, @@ -866,7 +866,7 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, rcu_read_lock_bh(); t = rcu_dereference_bh(h->table); key = HKEY(value, h->initval, t->htable_bits); - r = ahash_region(key, t->htable_bits); + r = ahash_region(key); atomic_inc(&t->uref); elements = t->hregion[r].elements; maxelem = t->maxelem; @@ -1059,7 +1059,7 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, rcu_read_lock_bh(); t = rcu_dereference_bh(h->table); key = HKEY(value, h->initval, t->htable_bits); - r = ahash_region(key, t->htable_bits); + r = ahash_region(key); atomic_inc(&t->uref); rcu_read_unlock_bh();
diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c index cf925906f59b..67d0d4f1f0db 100644 --- a/net/netfilter/ipvs/ip_vs_ftp.c +++ b/net/netfilter/ipvs/ip_vs_ftp.c @@ -53,6 +53,7 @@ enum { IP_VS_FTP_EPSV, };
+static bool exiting_module; /* * List of ports (up to IP_VS_APP_MAX_PORTS) to be handled by helper * First port is set to the default port. @@ -607,7 +608,7 @@ static void __ip_vs_ftp_exit(struct net *net) { struct netns_ipvs *ipvs = net_ipvs(net);
- if (!ipvs) + if (!ipvs || !exiting_module) return;
unregister_ip_vs_app(ipvs, &ip_vs_ftp); @@ -629,6 +630,7 @@ static int __init ip_vs_ftp_init(void) */ static void __exit ip_vs_ftp_exit(void) { + exiting_module = true; unregister_pernet_subsys(&ip_vs_ftp_ops); /* rcu_barrier() is called by netns */ } diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c index 7182c5a450fb..6a434d441dc7 100644 --- a/net/sctp/inqueue.c +++ b/net/sctp/inqueue.c @@ -163,13 +163,14 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue) chunk->head_skb = chunk->skb;
/* skbs with "cover letter" */ - if (chunk->head_skb && chunk->skb->data_len == chunk->skb->len) + if (chunk->head_skb && chunk->skb->data_len == chunk->skb->len) { + if (WARN_ON(!skb_shinfo(chunk->skb)->frag_list)) { + __SCTP_INC_STATS(dev_net(chunk->skb->dev), + SCTP_MIB_IN_PKT_DISCARDS); + sctp_chunk_free(chunk); + goto next_chunk; + } chunk->skb = skb_shinfo(chunk->skb)->frag_list; - - if (WARN_ON(!chunk->skb)) { - __SCTP_INC_STATS(dev_net(chunk->skb->dev), SCTP_MIB_IN_PKT_DISCARDS); - sctp_chunk_free(chunk); - goto next_chunk; } }
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 4eebe708c8e4..0c112134d9e3 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -31,6 +31,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <crypto/hash.h> +#include <crypto/algapi.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/ip.h> @@ -1758,7 +1759,7 @@ struct sctp_association *sctp_unpack_cookie( } }
- if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) { + if (crypto_memneq(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) { *error = -SCTP_IERROR_BAD_SIG; goto fail; } diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 6b613569372a..876c18f70df8 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -30,6 +30,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <crypto/algapi.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/ip.h> @@ -873,7 +874,8 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net, return SCTP_DISPOSITION_CONSUME;
nomem_authev: - sctp_ulpevent_free(ai_ev); + if (ai_ev) + sctp_ulpevent_free(ai_ev); nomem_aiev: sctp_ulpevent_free(ev); nomem_ev: @@ -4302,7 +4304,7 @@ static enum sctp_ierror sctp_sf_authenticate( sh_key, GFP_ATOMIC);
/* Discard the packet if the digests do not match */ - if (memcmp(save_digest, digest, sig_len)) { + if (crypto_memneq(save_digest, digest, sig_len)) { kfree(save_digest); return SCTP_IERROR_BAD_SIG; } diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index cb51a2f46b11..5bf809b09034 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c @@ -181,12 +181,9 @@ int tls_proccess_cmsg(struct sock *sk, struct msghdr *msg, if (msg->msg_flags & MSG_MORE) return -EINVAL;
- rc = tls_handle_open_record(sk, msg->msg_flags); - if (rc) - return rc; - *record_type = *(unsigned char *)CMSG_DATA(cmsg); - rc = 0; + + rc = tls_handle_open_record(sk, msg->msg_flags); break; default: return -EINVAL; diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index 8dabbbf52168..b175f0595a47 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -1052,6 +1052,13 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) else if (ret != -EAGAIN) goto send_end; } + + /* Transmit if any encryptions have completed */ + if (test_and_clear_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask)) { + cancel_delayed_work(&ctx->tx_work.work); + tls_tx_records(sk, msg->msg_flags); + } + continue; rollback_iter: copied -= try_to_copy; @@ -1106,6 +1113,12 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) goto send_end; } } + + /* Transmit if any encryptions have completed */ + if (test_and_clear_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask)) { + cancel_delayed_work(&ctx->tx_work.work); + tls_tx_records(sk, msg->msg_flags); + } }
continue; diff --git a/security/keys/trusted.c b/security/keys/trusted.c index 92a14ab82f72..3ee9749c14fb 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c @@ -9,6 +9,7 @@ */
#include <crypto/hash_info.h> +#include <crypto/algapi.h> #include <linux/uaccess.h> #include <linux/module.h> #include <linux/init.h> @@ -248,7 +249,7 @@ int TSS_checkhmac1(unsigned char *buffer, if (ret < 0) goto out;
- if (memcmp(testhmac, authdata, SHA1_DIGEST_SIZE)) + if (crypto_memneq(testhmac, authdata, SHA1_DIGEST_SIZE)) ret = -EINVAL; out: kzfree(sdesc); @@ -341,7 +342,7 @@ static int TSS_checkhmac2(unsigned char *buffer, TPM_NONCE_SIZE, ononce, 1, continueflag1, 0, 0); if (ret < 0) goto out; - if (memcmp(testhmac1, authdata1, SHA1_DIGEST_SIZE)) { + if (crypto_memneq(testhmac1, authdata1, SHA1_DIGEST_SIZE)) { ret = -EINVAL; goto out; } @@ -350,7 +351,7 @@ static int TSS_checkhmac2(unsigned char *buffer, TPM_NONCE_SIZE, ononce, 1, continueflag2, 0, 0); if (ret < 0) goto out; - if (memcmp(testhmac2, authdata2, SHA1_DIGEST_SIZE)) + if (crypto_memneq(testhmac2, authdata2, SHA1_DIGEST_SIZE)) ret = -EINVAL; out: kzfree(sdesc); diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h index bbbca964b9b4..f1933f7b9f1b 100644 --- a/sound/firewire/amdtp-stream.h +++ b/sound/firewire/amdtp-stream.h @@ -32,7 +32,7 @@ * allows 5 times as large as IEC 61883-6 defines. * @CIP_HEADER_WITHOUT_EOH: Only for in-stream. CIP Header doesn't include * valid EOH. - * @CIP_NO_HEADERS: a lack of headers in packets + * @CIP_NO_HEADER: a lack of headers in packets * @CIP_UNALIGHED_DBC: Only for in-stream. The value of dbc is not alighed to * the value of current SYT_INTERVAL; e.g. initial value is not zero. */ diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c index 00975e86473c..6cf7572779d4 100644 --- a/sound/pci/lx6464es/lx_core.c +++ b/sound/pci/lx6464es/lx_core.c @@ -316,7 +316,7 @@ static int lx_message_send_atomic(struct lx6464es *chip, struct lx_rmh *rmh) /* low-level dsp access */ int lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version) { - u16 ret; + int ret;
mutex_lock(&chip->msg_lock);
@@ -330,10 +330,10 @@ int lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version)
int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq) { - u16 ret = 0; u32 freq_raw = 0; u32 freq = 0; u32 frequency = 0; + int ret;
mutex_lock(&chip->msg_lock);
diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index 57d6d0b48068..006e489e7e89 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c @@ -46,7 +46,8 @@ enum { BYT_CHT_ES8316_INTMIC_IN2_MAP, };
-#define BYT_CHT_ES8316_MAP(quirk) ((quirk) & GENMASK(3, 0)) +#define BYT_CHT_ES8316_MAP_MASK GENMASK(3, 0) +#define BYT_CHT_ES8316_MAP(quirk) ((quirk) & BYT_CHT_ES8316_MAP_MASK) #define BYT_CHT_ES8316_SSP0 BIT(16) #define BYT_CHT_ES8316_MONO_SPEAKER BIT(17) #define BYT_CHT_ES8316_JD_INVERTED BIT(18) @@ -59,10 +60,23 @@ MODULE_PARM_DESC(quirk, "Board-specific quirk override");
static void log_quirks(struct device *dev) { - if (BYT_CHT_ES8316_MAP(quirk) == BYT_CHT_ES8316_INTMIC_IN1_MAP) + int map; + + map = BYT_CHT_ES8316_MAP(quirk); + switch (map) { + case BYT_CHT_ES8316_INTMIC_IN1_MAP: dev_info(dev, "quirk IN1_MAP enabled"); - if (BYT_CHT_ES8316_MAP(quirk) == BYT_CHT_ES8316_INTMIC_IN2_MAP) + break; + case BYT_CHT_ES8316_INTMIC_IN2_MAP: dev_info(dev, "quirk IN2_MAP enabled"); + break; + default: + dev_warn_once(dev, "quirk sets invalid input map: 0x%x, default to INTMIC_IN1_MAP\n", map); + quirk &= ~BYT_CHT_ES8316_MAP_MASK; + quirk |= BYT_CHT_ES8316_INTMIC_IN1_MAP; + break; + } + if (quirk & BYT_CHT_ES8316_SSP0) dev_info(dev, "quirk SSP0 enabled"); if (quirk & BYT_CHT_ES8316_MONO_SPEAKER) diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 5a8e86ba2900..88e84415d5a4 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -60,7 +60,8 @@ enum { BYT_RT5640_OVCD_SF_1P5 = (RT5640_OVCD_SF_1P5 << 13), };
-#define BYT_RT5640_MAP(quirk) ((quirk) & GENMASK(3, 0)) +#define BYT_RT5640_MAP_MASK GENMASK(3, 0) +#define BYT_RT5640_MAP(quirk) ((quirk) & BYT_RT5640_MAP_MASK) #define BYT_RT5640_JDSRC(quirk) (((quirk) & GENMASK(7, 4)) >> 4) #define BYT_RT5640_OVCD_TH(quirk) (((quirk) & GENMASK(12, 8)) >> 8) #define BYT_RT5640_OVCD_SF(quirk) (((quirk) & GENMASK(14, 13)) >> 13) @@ -118,7 +119,9 @@ static void log_quirks(struct device *dev) dev_info(dev, "quirk IN3_MAP enabled\n"); break; default: - dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map); + dev_warn_once(dev, "quirk sets invalid input map: 0x%x, default to DMIC1_MAP\n", map); + byt_rt5640_quirk &= ~BYT_RT5640_MAP_MASK; + byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP; break; } if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) { diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index 0c1c8628b991..6a5098efdaf2 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -58,7 +58,8 @@ enum { BYT_RT5651_OVCD_SF_1P5 = (RT5651_OVCD_SF_1P5 << 13), };
-#define BYT_RT5651_MAP(quirk) ((quirk) & GENMASK(3, 0)) +#define BYT_RT5651_MAP_MASK GENMASK(3, 0) +#define BYT_RT5651_MAP(quirk) ((quirk) & BYT_RT5651_MAP_MASK) #define BYT_RT5651_JDSRC(quirk) (((quirk) & GENMASK(7, 4)) >> 4) #define BYT_RT5651_OVCD_TH(quirk) (((quirk) & GENMASK(12, 8)) >> 8) #define BYT_RT5651_OVCD_SF(quirk) (((quirk) & GENMASK(14, 13)) >> 13) @@ -99,14 +100,29 @@ MODULE_PARM_DESC(quirk, "Board-specific quirk override");
static void log_quirks(struct device *dev) { - if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_DMIC_MAP) + int map; + + map = BYT_RT5651_MAP(byt_rt5651_quirk); + switch (map) { + case BYT_RT5651_DMIC_MAP: dev_info(dev, "quirk DMIC_MAP enabled"); - if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN1_MAP) + break; + case BYT_RT5651_IN1_MAP: dev_info(dev, "quirk IN1_MAP enabled"); - if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN2_MAP) + break; + case BYT_RT5651_IN2_MAP: dev_info(dev, "quirk IN2_MAP enabled"); - if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN1_IN2_MAP) + break; + case BYT_RT5651_IN1_IN2_MAP: dev_info(dev, "quirk IN1_IN2_MAP enabled"); + break; + default: + dev_warn_once(dev, "quirk sets invalid input map: 0x%x, default to DMIC_MAP\n", map); + byt_rt5651_quirk &= ~BYT_RT5651_MAP_MASK; + byt_rt5651_quirk |= BYT_RT5651_DMIC_MAP; + break; + } + if (BYT_RT5651_JDSRC(byt_rt5651_quirk)) { dev_info(dev, "quirk realtek,jack-detect-source %ld\n", BYT_RT5651_JDSRC(byt_rt5651_quirk)); diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile index 8104e505efde..f5b7b1489e1f 100644 --- a/tools/build/feature/Makefile +++ b/tools/build/feature/Makefile @@ -258,10 +258,10 @@ $(OUTPUT)test-sync-compare-and-swap.bin: $(BUILD)
$(OUTPUT)test-compile-32.bin: - $(CC) -m32 -o $@ test-compile.c + $(CC) -m32 -Wall -Werror -o $@ test-compile.c
$(OUTPUT)test-compile-x32.bin: - $(CC) -mx32 -o $@ test-compile.c + $(CC) -mx32 -Wall -Werror -o $@ test-compile.c
$(OUTPUT)test-zlib.bin: $(BUILD) -lz diff --git a/tools/lib/subcmd/help.c b/tools/lib/subcmd/help.c index 4260c8b4257b..10f134c64ada 100644 --- a/tools/lib/subcmd/help.c +++ b/tools/lib/subcmd/help.c @@ -72,6 +72,9 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes) size_t ci, cj, ei; int cmp;
+ if (!excludes->cnt) + return; + ci = cj = ei = 0; while (ci < cmds->cnt && ei < excludes->cnt) { cmp = strcmp(cmds->names[ci]->name, excludes->names[ei]->name); diff --git a/tools/perf/util/lzma.c b/tools/perf/util/lzma.c index 51424cdc3b68..aa9a0ebc1f93 100644 --- a/tools/perf/util/lzma.c +++ b/tools/perf/util/lzma.c @@ -115,7 +115,7 @@ bool lzma_is_compressed(const char *input) ssize_t rc;
if (fd < 0) - return -1; + return false;
rc = read(fd, buf, sizeof(buf)); close(fd); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 01e15b445cb5..cd60a878752f 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1504,7 +1504,7 @@ static s64 perf_session__process_user_event(struct perf_session *session, struct perf_tool *tool = session->tool; struct perf_sample sample = { .time = 0, }; int fd = perf_data__fd(session->data); - int err; + s64 err;
if (event->header.type != PERF_RECORD_COMPRESSED || tool->compressed == perf_session__process_compressed_event_stub) diff --git a/tools/perf/util/zlib.c b/tools/perf/util/zlib.c index 78d2297c1b67..1f7c06523059 100644 --- a/tools/perf/util/zlib.c +++ b/tools/perf/util/zlib.c @@ -88,7 +88,7 @@ bool gzip_is_compressed(const char *input) ssize_t rc;
if (fd < 0) - return -1; + return false;
rc = read(fd, buf, sizeof(buf)); close(fd); diff --git a/tools/testing/selftests/rseq/rseq.c b/tools/testing/selftests/rseq/rseq.c index e20191fb40d4..036b03aaedc3 100644 --- a/tools/testing/selftests/rseq/rseq.c +++ b/tools/testing/selftests/rseq/rseq.c @@ -38,9 +38,9 @@ * Define weak versions to play nice with binaries that are statically linked * against a libc that doesn't support registering its own rseq. */ -__weak ptrdiff_t __rseq_offset; -__weak unsigned int __rseq_size; -__weak unsigned int __rseq_flags; +extern __weak ptrdiff_t __rseq_offset; +extern __weak unsigned int __rseq_size; +extern __weak unsigned int __rseq_flags;
static const ptrdiff_t *libc_rseq_offset_p = &__rseq_offset; static const unsigned int *libc_rseq_size_p = &__rseq_size; @@ -124,7 +124,7 @@ void rseq_init(void) * libc not having registered a restartable sequence. Try to find the * symbols if that's the case. */ - if (!*libc_rseq_size_p) { + if (!libc_rseq_size_p || !*libc_rseq_size_p) { libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset"); libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size"); libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags"); diff --git a/tools/testing/selftests/watchdog/watchdog-test.c b/tools/testing/selftests/watchdog/watchdog-test.c index 09773695d219..4056706d63f7 100644 --- a/tools/testing/selftests/watchdog/watchdog-test.c +++ b/tools/testing/selftests/watchdog/watchdog-test.c @@ -240,6 +240,12 @@ int main(int argc, char *argv[]) if (oneshot) goto end;
+ /* Check if WDIOF_KEEPALIVEPING is supported */ + if (!(info.options & WDIOF_KEEPALIVEPING)) { + printf("WDIOC_KEEPALIVE not supported by this device\n"); + goto end; + } + printf("Watchdog Ticking Away!\n");
/*