diff --git a/Documentation/sphinx/parse-headers.pl b/Documentation/sphinx/parse-headers.pl index db0186a7618f..299b0f82af27 100755 --- a/Documentation/sphinx/parse-headers.pl +++ b/Documentation/sphinx/parse-headers.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl use strict; use Text::Tabs; diff --git a/Documentation/target/tcm_mod_builder.py b/Documentation/target/tcm_mod_builder.py index 94bf6944bb1e..7e79ff6b09e0 100755 --- a/Documentation/target/tcm_mod_builder.py +++ b/Documentation/target/tcm_mod_builder.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # The TCM v4 multi-protocol fabric module generation script for drivers/target/$NEW_MOD # # Copyright (c) 2010 Rising Tide Systems diff --git a/Documentation/trace/postprocess/decode_msr.py b/Documentation/trace/postprocess/decode_msr.py index 0ab40e0db580..aa9cc7abd5c2 100644 --- a/Documentation/trace/postprocess/decode_msr.py +++ b/Documentation/trace/postprocess/decode_msr.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # add symbolic names to read_msr / write_msr in trace # decode_msr msr-index.h < trace import sys diff --git a/Documentation/trace/postprocess/trace-pagealloc-postprocess.pl b/Documentation/trace/postprocess/trace-pagealloc-postprocess.pl index 0a120aae33ce..b9b7d80c2f9d 100644 --- a/Documentation/trace/postprocess/trace-pagealloc-postprocess.pl +++ b/Documentation/trace/postprocess/trace-pagealloc-postprocess.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # This is a POC (proof of concept or piece of crap, take your pick) for reading the # text representation of trace output related to page allocation. It makes an attempt # to extract some high-level information on what is going on. The accuracy of the parser diff --git a/Documentation/trace/postprocess/trace-vmscan-postprocess.pl b/Documentation/trace/postprocess/trace-vmscan-postprocess.pl index 8f961ef2b457..7749cdf372f7 100644 --- a/Documentation/trace/postprocess/trace-vmscan-postprocess.pl +++ b/Documentation/trace/postprocess/trace-vmscan-postprocess.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # This is a POC for reading the text representation of trace output related to # page reclaim. It makes an attempt to extract some high-level information on # what is going on. The accuracy of the parser may vary diff --git a/Makefile b/Makefile index 4cb6aafddfd6..543c29f2778b 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 4 PATCHLEVEL = 9 -SUBLEVEL = 269 +SUBLEVEL = 276 EXTRAVERSION = NAME = Roaring Lionus @@ -799,12 +799,11 @@ KBUILD_CFLAGS += $(call cc-disable-warning, tautological-compare) # See modpost pattern 2 KBUILD_CFLAGS += $(call cc-option, -mno-global-merge,) KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior) -else +endif # These warnings generated too much noise in a regular build. # Use make W=1 to enable them (see scripts/Makefile.extrawarn) KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable) -endif KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable) ifdef CONFIG_FRAME_POINTER diff --git a/arch/arm/boot/dts/am335x-cm-t335.dts b/arch/arm/boot/dts/am335x-cm-t335.dts index 947c81b7aaaf..56a04d3086c3 100644 --- a/arch/arm/boot/dts/am335x-cm-t335.dts +++ b/arch/arm/boot/dts/am335x-cm-t335.dts @@ -552,7 +552,7 @@ status = "okay"; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&spi0_pins>; - ti,pindir-d0-out-d1-in = <1>; + ti,pindir-d0-out-d1-in; /* WLS1271 WiFi */ wlcore: wlcore@1 { compatible = "ti,wl1271"; diff --git a/arch/arm/boot/dts/exynos5422-odroidxu4.dts b/arch/arm/boot/dts/exynos5422-odroidxu4.dts index 2faf88627a48..b45e2a0c3908 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu4.dts +++ b/arch/arm/boot/dts/exynos5422-odroidxu4.dts @@ -26,7 +26,7 @@ label = "blue:heartbeat"; pwms = <&pwm 2 2000000 0>; pwm-names = "pwm2"; - max_brightness = <255>; + max-brightness = <255>; linux,default-trigger = "heartbeat"; }; }; diff --git a/arch/arm/boot/dts/exynos54xx-odroidxu-leds.dtsi b/arch/arm/boot/dts/exynos54xx-odroidxu-leds.dtsi index 0ed30206625c..f547f67f2783 100644 --- a/arch/arm/boot/dts/exynos54xx-odroidxu-leds.dtsi +++ b/arch/arm/boot/dts/exynos54xx-odroidxu-leds.dtsi @@ -25,7 +25,7 @@ * Green LED is much brighter than the others * so limit its max brightness */ - max_brightness = <127>; + max-brightness = <127>; linux,default-trigger = "mmc0"; }; @@ -33,7 +33,7 @@ label = "blue:heartbeat"; pwms = <&pwm 2 2000000 0>; pwm-names = "pwm2"; - max_brightness = <255>; + max-brightness = <255>; linux,default-trigger = "heartbeat"; }; }; diff --git a/arch/arm/boot/dts/r8a7779-marzen.dts b/arch/arm/boot/dts/r8a7779-marzen.dts index 541678df90a9..50ec24bb1d79 100644 --- a/arch/arm/boot/dts/r8a7779-marzen.dts +++ b/arch/arm/boot/dts/r8a7779-marzen.dts @@ -136,7 +136,7 @@ status = "okay"; clocks = <&mstp1_clks R8A7779_CLK_DU>, <&x3_clk>; - clock-names = "du", "dclkin.0"; + clock-names = "du.0", "dclkin.0"; ports { port@0 { diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi index 6c6d4893e92d..3fb0a8d2530b 100644 --- a/arch/arm/boot/dts/r8a7779.dtsi +++ b/arch/arm/boot/dts/r8a7779.dtsi @@ -431,6 +431,7 @@ reg = <0 0xfff80000 0 0x40000>; interrupts = ; clocks = <&mstp1_clks R8A7779_CLK_DU>; + clock-names = "du.0"; power-domains = <&sysc R8A7779_PD_ALWAYS_ON>; status = "disabled"; diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index de0e189711f6..8c94bf57a38c 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -1371,7 +1371,7 @@ 0xffffffff 0x3ffcfe7c 0x1c010101 /* pioA */ 0x7fffffff 0xfffccc3a 0x3f00cc3a /* pioB */ 0xffffffff 0x3ff83fff 0xff00ffff /* pioC */ - 0x0003ff00 0x8002a800 0x00000000 /* pioD */ + 0xb003ff00 0x8002a800 0x00000000 /* pioD */ 0xffffffff 0x7fffffff 0x76fff1bf /* pioE */ >; diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 775d70c81587..108b5d17e89e 100755 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -590,9 +590,11 @@ void notrace cpu_init(void) * In Thumb-2, msr with an immediate value is not allowed. */ #ifdef CONFIG_THUMB2_KERNEL -#define PLC "r" +#define PLC_l "l" +#define PLC_r "r" #else -#define PLC "I" +#define PLC_l "I" +#define PLC_r "I" #endif /* @@ -614,15 +616,15 @@ void notrace cpu_init(void) "msr cpsr_c, %9" : : "r" (stk), - PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE), + PLC_r (PSR_F_BIT | PSR_I_BIT | IRQ_MODE), "I" (offsetof(struct stack, irq[0])), - PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE), + PLC_r (PSR_F_BIT | PSR_I_BIT | ABT_MODE), "I" (offsetof(struct stack, abt[0])), - PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE), + PLC_r (PSR_F_BIT | PSR_I_BIT | UND_MODE), "I" (offsetof(struct stack, und[0])), - PLC (PSR_F_BIT | PSR_I_BIT | FIQ_MODE), + PLC_r (PSR_F_BIT | PSR_I_BIT | FIQ_MODE), "I" (offsetof(struct stack, fiq[0])), - PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE) + PLC_l (PSR_F_BIT | PSR_I_BIT | SVC_MODE) : "r14"); #endif } diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index 6b6fda65fb3b..5eeecf83c9e6 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -327,6 +327,7 @@ static int n8x0_mmc_get_cover_state(struct device *dev, int slot) static void n8x0_mmc_callback(void *data, u8 card_mask) { +#ifdef CONFIG_MMC_OMAP int bit, *openp, index; if (board_is_n800()) { @@ -344,7 +345,6 @@ static void n8x0_mmc_callback(void *data, u8 card_mask) else *openp = 0; -#ifdef CONFIG_MMC_OMAP omap_mmc_notify_cover_event(mmc_device, index, *openp); #else pr_warn("MMC: notify cover event not available\n"); diff --git a/arch/arm/probes/kprobes/test-thumb.c b/arch/arm/probes/kprobes/test-thumb.c index b683b4517458..4254391f3906 100644 --- a/arch/arm/probes/kprobes/test-thumb.c +++ b/arch/arm/probes/kprobes/test-thumb.c @@ -444,21 +444,21 @@ void kprobe_thumb32_test_cases(void) "3: mvn r0, r0 \n\t" "2: nop \n\t") - TEST_RX("tbh [pc, r",7, (9f-(1f+4))>>1,"]", + TEST_RX("tbh [pc, r",7, (9f-(1f+4))>>1,", lsl #1]", "9: \n\t" ".short (2f-1b-4)>>1 \n\t" ".short (3f-1b-4)>>1 \n\t" "3: mvn r0, r0 \n\t" "2: nop \n\t") - TEST_RX("tbh [pc, r",12, ((9f-(1f+4))>>1)+1,"]", + TEST_RX("tbh [pc, r",12, ((9f-(1f+4))>>1)+1,", lsl #1]", "9: \n\t" ".short (2f-1b-4)>>1 \n\t" ".short (3f-1b-4)>>1 \n\t" "3: mvn r0, r0 \n\t" "2: nop \n\t") - TEST_RRX("tbh [r",1,9f, ", r",14,1,"]", + TEST_RRX("tbh [r",1,9f, ", r",14,1,", lsl #1]", "9: \n\t" ".short (2f-1b-4)>>1 \n\t" ".short (3f-1b-4)>>1 \n\t" @@ -471,10 +471,10 @@ void kprobe_thumb32_test_cases(void) TEST_UNSUPPORTED("strexb r0, r1, [r2]") TEST_UNSUPPORTED("strexh r0, r1, [r2]") - TEST_UNSUPPORTED("strexd r0, r1, [r2]") + TEST_UNSUPPORTED("strexd r0, r1, r2, [r2]") TEST_UNSUPPORTED("ldrexb r0, [r1]") TEST_UNSUPPORTED("ldrexh r0, [r1]") - TEST_UNSUPPORTED("ldrexd r0, [r1]") + TEST_UNSUPPORTED("ldrexd r0, r1, [r1]") TEST_GROUP("Data-processing (shifted register) and (modified immediate)") diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 64b892d9c7cd..e6f2efd67513 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -750,6 +750,28 @@ static void armv8pmu_disable_event(struct perf_event *event) raw_spin_unlock_irqrestore(&events->pmu_lock, flags); } +static void armv8pmu_start(struct arm_pmu *cpu_pmu) +{ + unsigned long flags; + struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); + + raw_spin_lock_irqsave(&events->pmu_lock, flags); + /* Enable all counters */ + armv8pmu_pmcr_write(armv8pmu_pmcr_read() | ARMV8_PMU_PMCR_E); + raw_spin_unlock_irqrestore(&events->pmu_lock, flags); +} + +static void armv8pmu_stop(struct arm_pmu *cpu_pmu) +{ + unsigned long flags; + struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); + + raw_spin_lock_irqsave(&events->pmu_lock, flags); + /* Disable all counters */ + armv8pmu_pmcr_write(armv8pmu_pmcr_read() & ~ARMV8_PMU_PMCR_E); + raw_spin_unlock_irqrestore(&events->pmu_lock, flags); +} + static irqreturn_t armv8pmu_handle_irq(int irq_num, void *dev) { u32 pmovsr; @@ -775,6 +797,11 @@ static irqreturn_t armv8pmu_handle_irq(int irq_num, void *dev) */ regs = get_irq_regs(); + /* + * Stop the PMU while processing the counter overflows + * to prevent skews in group events. + */ + armv8pmu_stop(cpu_pmu); for (idx = 0; idx < cpu_pmu->num_events; ++idx) { struct perf_event *event = cpuc->events[idx]; struct hw_perf_event *hwc; @@ -799,6 +826,7 @@ static irqreturn_t armv8pmu_handle_irq(int irq_num, void *dev) if (perf_event_overflow(event, &data, regs)) cpu_pmu->disable(event); } + armv8pmu_start(cpu_pmu); /* * Handle the pending perf events. @@ -812,28 +840,6 @@ static irqreturn_t armv8pmu_handle_irq(int irq_num, void *dev) return IRQ_HANDLED; } -static void armv8pmu_start(struct arm_pmu *cpu_pmu) -{ - unsigned long flags; - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); - - raw_spin_lock_irqsave(&events->pmu_lock, flags); - /* Enable all counters */ - armv8pmu_pmcr_write(armv8pmu_pmcr_read() | ARMV8_PMU_PMCR_E); - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); -} - -static void armv8pmu_stop(struct arm_pmu *cpu_pmu) -{ - unsigned long flags; - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); - - raw_spin_lock_irqsave(&events->pmu_lock, flags); - /* Disable all counters */ - armv8pmu_pmcr_write(armv8pmu_pmcr_read() & ~ARMV8_PMU_PMCR_E); - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); -} - static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc, struct perf_event *event) { diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index e5733cbd0c84..e8c9fe3753a2 100755 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -737,14 +737,6 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs) } #endif - if (show_unhandled_signals_ratelimited()) { - pr_info("%s[%d]: syscall %d\n", current->comm, - task_pid_nr(current), (int)regs->syscallno); - dump_instr("", regs); - if (user_mode(regs)) - __show_regs(regs); - } - return sys_ni_syscall(); } diff --git a/arch/hexagon/kernel/vmlinux.lds.S b/arch/hexagon/kernel/vmlinux.lds.S index ec87e67feb19..22c10102712a 100644 --- a/arch/hexagon/kernel/vmlinux.lds.S +++ b/arch/hexagon/kernel/vmlinux.lds.S @@ -71,13 +71,8 @@ SECTIONS _end = .; - /DISCARD/ : { - EXIT_TEXT - EXIT_DATA - EXIT_CALL - } - STABS_DEBUG DWARF_DEBUG + DISCARDS } diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index 94f8bf777afa..3503d488e9b3 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c @@ -343,7 +343,7 @@ init_record_index_pools(void) /* - 2 - */ sect_min_size = sal_log_sect_min_sizes[0]; - for (i = 1; i < sizeof sal_log_sect_min_sizes/sizeof(size_t); i++) + for (i = 1; i < ARRAY_SIZE(sal_log_sect_min_sizes); i++) if (sect_min_size > sal_log_sect_min_sizes[i]) sect_min_size = sal_log_sect_min_sizes[i]; diff --git a/arch/ia64/scripts/unwcheck.py b/arch/ia64/scripts/unwcheck.py index 2bfd941ff7c7..c27849889e19 100644 --- a/arch/ia64/scripts/unwcheck.py +++ b/arch/ia64/scripts/unwcheck.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Usage: unwcheck.py FILE # diff --git a/arch/mips/alchemy/board-xxs1500.c b/arch/mips/alchemy/board-xxs1500.c index 0fc53e08a894..c05f7376148a 100644 --- a/arch/mips/alchemy/board-xxs1500.c +++ b/arch/mips/alchemy/board-xxs1500.c @@ -30,6 +30,7 @@ #include #include #include +#include #include const char *get_system_type(void) diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index 0fa91c981658..3e93eea5a5f5 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile @@ -33,7 +33,7 @@ KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \ KCOV_INSTRUMENT := n # decompressor objects (linked with vmlinuz) -vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o +vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o $(obj)/bswapsi.o ifdef CONFIG_DEBUG_ZBOOT vmlinuzobjs-$(CONFIG_DEBUG_ZBOOT) += $(obj)/dbg.o @@ -47,7 +47,7 @@ extra-y += uart-ath79.c $(obj)/uart-ath79.c: $(srctree)/arch/mips/ath79/early_printk.c $(call cmd,shipped) -vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o $(obj)/bswapsi.o +vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o extra-y += ashldi3.c bswapsi.c $(obj)/ashldi3.o $(obj)/bswapsi.o: KBUILD_CFLAGS += -I$(srctree)/arch/mips/lib diff --git a/arch/mips/boot/compressed/decompress.c b/arch/mips/boot/compressed/decompress.c index 3a015e41b762..66096c766a60 100644 --- a/arch/mips/boot/compressed/decompress.c +++ b/arch/mips/boot/compressed/decompress.c @@ -11,6 +11,8 @@ * option) any later version. */ +#define DISABLE_BRANCH_PROFILING + #include #include #include diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h index 982bc0685330..4747a4694669 100644 --- a/arch/mips/include/asm/hugetlb.h +++ b/arch/mips/include/asm/hugetlb.h @@ -67,7 +67,13 @@ static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, static inline void huge_ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { - flush_tlb_page(vma, addr & huge_page_mask(hstate_vma(vma))); + /* + * clear the huge pte entry firstly, so that the other smp threads will + * not get old pte entry after finishing flush_tlb_page and before + * setting new huge pte entry + */ + huge_ptep_get_and_clear(vma->vm_mm, addr, ptep); + flush_tlb_page(vma, addr); } static inline int huge_pte_none(pte_t pte) diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h index a03e86969f78..ff982d8b62f6 100644 --- a/arch/mips/include/asm/pgalloc.h +++ b/arch/mips/include/asm/pgalloc.h @@ -107,11 +107,15 @@ do { \ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) { - pmd_t *pmd; + pmd_t *pmd = NULL; + struct page *pg; - pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, PMD_ORDER); - if (pmd) + pg = alloc_pages(GFP_KERNEL | __GFP_ACCOUNT, PMD_ORDER); + if (pg) { + pgtable_pmd_page_ctor(pg); + pmd = (pmd_t *)page_address(pg); pmd_init((unsigned long)pmd, (unsigned long)invalid_pte_table); + } return pmd; } diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c index 5530070e0d05..57497a26e79c 100644 --- a/arch/mips/lib/mips-atomic.c +++ b/arch/mips/lib/mips-atomic.c @@ -37,7 +37,7 @@ */ notrace void arch_local_irq_disable(void) { - preempt_disable(); + preempt_disable_notrace(); __asm__ __volatile__( " .set push \n" @@ -53,7 +53,7 @@ notrace void arch_local_irq_disable(void) : /* no inputs */ : "memory"); - preempt_enable(); + preempt_enable_notrace(); } EXPORT_SYMBOL(arch_local_irq_disable); @@ -61,7 +61,7 @@ notrace unsigned long arch_local_irq_save(void) { unsigned long flags; - preempt_disable(); + preempt_disable_notrace(); __asm__ __volatile__( " .set push \n" @@ -78,7 +78,7 @@ notrace unsigned long arch_local_irq_save(void) : /* no inputs */ : "memory"); - preempt_enable(); + preempt_enable_notrace(); return flags; } @@ -88,7 +88,7 @@ notrace void arch_local_irq_restore(unsigned long flags) { unsigned long __tmp1; - preempt_disable(); + preempt_disable_notrace(); __asm__ __volatile__( " .set push \n" @@ -106,7 +106,7 @@ notrace void arch_local_irq_restore(unsigned long flags) : "0" (flags) : "memory"); - preempt_enable(); + preempt_enable_notrace(); } EXPORT_SYMBOL(arch_local_irq_restore); diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c index 0aa67a2d0ae6..6b7226830354 100644 --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -27,6 +28,7 @@ __iomem void *rt_sysc_membase; __iomem void *rt_memc_membase; +EXPORT_SYMBOL_GPL(rt_sysc_membase); __iomem void *plat_of_remap_node(const char *node) { diff --git a/arch/mips/vdso/vdso.h b/arch/mips/vdso/vdso.h index cfb1be441dec..921589b45bc2 100644 --- a/arch/mips/vdso/vdso.h +++ b/arch/mips/vdso/vdso.h @@ -81,7 +81,7 @@ static inline const union mips_vdso_data *get_vdso_data(void) static inline void __iomem *get_gic(const union mips_vdso_data *data) { - return (void __iomem *)data - PAGE_SIZE; + return (void __iomem *)((unsigned long)data & PAGE_MASK) - PAGE_SIZE; } #endif /* CONFIG_CLKSRC_MIPS_GIC */ diff --git a/arch/openrisc/include/asm/barrier.h b/arch/openrisc/include/asm/barrier.h new file mode 100644 index 000000000000..7538294721be --- /dev/null +++ b/arch/openrisc/include/asm/barrier.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_BARRIER_H +#define __ASM_BARRIER_H + +#define mb() asm volatile ("l.msync" ::: "memory") + +#include + +#endif /* __ASM_BARRIER_H */ diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c index b4ed8b36e078..e5f5b69a7b7b 100644 --- a/arch/openrisc/kernel/setup.c +++ b/arch/openrisc/kernel/setup.c @@ -278,6 +278,8 @@ void calibrate_delay(void) pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n", loops_per_jiffy / (500000 / HZ), (loops_per_jiffy / (5000 / HZ)) % 100, loops_per_jiffy); + + of_node_put(cpu); } void __init setup_arch(char **cmdline_p) diff --git a/arch/powerpc/boot/devtree.c b/arch/powerpc/boot/devtree.c index a7e21a35c03a..27c84b82b588 100644 --- a/arch/powerpc/boot/devtree.c +++ b/arch/powerpc/boot/devtree.c @@ -17,6 +17,7 @@ #include "string.h" #include "stdio.h" #include "ops.h" +#include "of.h" void dt_fixup_memory(u64 start, u64 size) { @@ -27,21 +28,25 @@ void dt_fixup_memory(u64 start, u64 size) root = finddevice("/"); if (getprop(root, "#address-cells", &naddr, sizeof(naddr)) < 0) naddr = 2; + else + naddr = be32_to_cpu(naddr); if (naddr < 1 || naddr > 2) fatal("Can't cope with #address-cells == %d in /\n\r", naddr); if (getprop(root, "#size-cells", &nsize, sizeof(nsize)) < 0) nsize = 1; + else + nsize = be32_to_cpu(nsize); if (nsize < 1 || nsize > 2) fatal("Can't cope with #size-cells == %d in /\n\r", nsize); i = 0; if (naddr == 2) - memreg[i++] = start >> 32; - memreg[i++] = start & 0xffffffff; + memreg[i++] = cpu_to_be32(start >> 32); + memreg[i++] = cpu_to_be32(start & 0xffffffff); if (nsize == 2) - memreg[i++] = size >> 32; - memreg[i++] = size & 0xffffffff; + memreg[i++] = cpu_to_be32(size >> 32); + memreg[i++] = cpu_to_be32(size & 0xffffffff); memory = finddevice("/memory"); if (! memory) { @@ -49,9 +54,9 @@ void dt_fixup_memory(u64 start, u64 size) setprop_str(memory, "device_type", "memory"); } - printf("Memory <- <0x%x", memreg[0]); + printf("Memory <- <0x%x", be32_to_cpu(memreg[0])); for (i = 1; i < (naddr + nsize); i++) - printf(" 0x%x", memreg[i]); + printf(" 0x%x", be32_to_cpu(memreg[i])); printf("> (%ldMB)\n\r", (unsigned long)(size >> 20)); setprop(memory, "reg", memreg, (naddr + nsize)*sizeof(u32)); @@ -69,10 +74,10 @@ void dt_fixup_cpu_clocks(u32 cpu, u32 tb, u32 bus) printf("CPU bus-frequency <- 0x%x (%dMHz)\n\r", bus, MHZ(bus)); while ((devp = find_node_by_devtype(devp, "cpu"))) { - setprop_val(devp, "clock-frequency", cpu); - setprop_val(devp, "timebase-frequency", tb); + setprop_val(devp, "clock-frequency", cpu_to_be32(cpu)); + setprop_val(devp, "timebase-frequency", cpu_to_be32(tb)); if (bus > 0) - setprop_val(devp, "bus-frequency", bus); + setprop_val(devp, "bus-frequency", cpu_to_be32(bus)); } timebase_period_ns = 1000000000 / tb; @@ -84,7 +89,7 @@ void dt_fixup_clock(const char *path, u32 freq) if (devp) { printf("%s: clock-frequency <- %x (%dMHz)\n\r", path, freq, MHZ(freq)); - setprop_val(devp, "clock-frequency", freq); + setprop_val(devp, "clock-frequency", cpu_to_be32(freq)); } } @@ -137,8 +142,12 @@ void dt_get_reg_format(void *node, u32 *naddr, u32 *nsize) { if (getprop(node, "#address-cells", naddr, 4) != 4) *naddr = 2; + else + *naddr = be32_to_cpu(*naddr); if (getprop(node, "#size-cells", nsize, 4) != 4) *nsize = 1; + else + *nsize = be32_to_cpu(*nsize); } static void copy_val(u32 *dest, u32 *src, int naddr) @@ -167,9 +176,9 @@ static int add_reg(u32 *reg, u32 *add, int naddr) int i, carry = 0; for (i = MAX_ADDR_CELLS - 1; i >= MAX_ADDR_CELLS - naddr; i--) { - u64 tmp = (u64)reg[i] + add[i] + carry; + u64 tmp = (u64)be32_to_cpu(reg[i]) + be32_to_cpu(add[i]) + carry; carry = tmp >> 32; - reg[i] = (u32)tmp; + reg[i] = cpu_to_be32((u32)tmp); } return !carry; @@ -184,18 +193,18 @@ static int compare_reg(u32 *reg, u32 *range, u32 *rangesize) u32 end; for (i = 0; i < MAX_ADDR_CELLS; i++) { - if (reg[i] < range[i]) + if (be32_to_cpu(reg[i]) < be32_to_cpu(range[i])) return 0; - if (reg[i] > range[i]) + if (be32_to_cpu(reg[i]) > be32_to_cpu(range[i])) break; } for (i = 0; i < MAX_ADDR_CELLS; i++) { - end = range[i] + rangesize[i]; + end = be32_to_cpu(range[i]) + be32_to_cpu(rangesize[i]); - if (reg[i] < end) + if (be32_to_cpu(reg[i]) < end) break; - if (reg[i] > end) + if (be32_to_cpu(reg[i]) > end) return 0; } @@ -244,7 +253,6 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr, return 0; dt_get_reg_format(parent, &naddr, &nsize); - if (nsize > 2) return 0; @@ -256,10 +264,10 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr, copy_val(last_addr, prop_buf + offset, naddr); - ret_size = prop_buf[offset + naddr]; + ret_size = be32_to_cpu(prop_buf[offset + naddr]); if (nsize == 2) { ret_size <<= 32; - ret_size |= prop_buf[offset + naddr + 1]; + ret_size |= be32_to_cpu(prop_buf[offset + naddr + 1]); } for (;;) { @@ -282,7 +290,6 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr, offset = find_range(last_addr, prop_buf, prev_naddr, naddr, prev_nsize, buflen / 4); - if (offset < 0) return 0; @@ -300,8 +307,7 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr, if (naddr > 2) return 0; - ret_addr = ((u64)last_addr[2] << 32) | last_addr[3]; - + ret_addr = ((u64)be32_to_cpu(last_addr[2]) << 32) | be32_to_cpu(last_addr[3]); if (sizeof(void *) == 4 && (ret_addr >= 0x100000000ULL || ret_size > 0x100000000ULL || ret_addr + ret_size > 0x100000000ULL)) @@ -354,11 +360,14 @@ int dt_is_compatible(void *node, const char *compat) int dt_get_virtual_reg(void *node, void **addr, int nres) { unsigned long xaddr; - int n; + int n, i; n = getprop(node, "virtual-reg", addr, nres * 4); - if (n > 0) + if (n > 0) { + for (i = 0; i < n/4; i ++) + ((u32 *)addr)[i] = be32_to_cpu(((u32 *)addr)[i]); return n / 4; + } for (n = 0; n < nres; n++) { if (!dt_xlate_reg(node, n, &xaddr, NULL)) diff --git a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi index af12ead88c5f..404f570ebe23 100644 --- a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi @@ -122,7 +122,15 @@ }; /include/ "pq3-i2c-0.dtsi" + i2c@3000 { + fsl,i2c-erratum-a004447; + }; + /include/ "pq3-i2c-1.dtsi" + i2c@3100 { + fsl,i2c-erratum-a004447; + }; + /include/ "pq3-duart-0.dtsi" /include/ "pq3-espi-0.dtsi" spi0: spi@7000 { diff --git a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi index 51e975d7631a..8921f17fca42 100644 --- a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi @@ -389,7 +389,23 @@ }; /include/ "qoriq-i2c-0.dtsi" + i2c@118000 { + fsl,i2c-erratum-a004447; + }; + + i2c@118100 { + fsl,i2c-erratum-a004447; + }; + /include/ "qoriq-i2c-1.dtsi" + i2c@119000 { + fsl,i2c-erratum-a004447; + }; + + i2c@119100 { + fsl,i2c-erratum-a004447; + }; + /include/ "qoriq-duart-0.dtsi" /include/ "qoriq-duart-1.dtsi" /include/ "qoriq-gpio-0.dtsi" diff --git a/arch/powerpc/boot/ns16550.c b/arch/powerpc/boot/ns16550.c index 8c9ead94be06..cea34a20085c 100644 --- a/arch/powerpc/boot/ns16550.c +++ b/arch/powerpc/boot/ns16550.c @@ -14,6 +14,7 @@ #include "stdio.h" #include "io.h" #include "ops.h" +#include "of.h" #define UART_DLL 0 /* Out: Divisor Latch Low */ #define UART_DLM 1 /* Out: Divisor Latch High */ @@ -57,16 +58,20 @@ int ns16550_console_init(void *devp, struct serial_console_data *scdp) int n; u32 reg_offset; - if (dt_get_virtual_reg(devp, (void **)®_base, 1) < 1) + if (dt_get_virtual_reg(devp, (void **)®_base, 1) < 1) { + printf("virt reg parse fail...\r\n"); return -1; + } n = getprop(devp, "reg-offset", ®_offset, sizeof(reg_offset)); if (n == sizeof(reg_offset)) - reg_base += reg_offset; + reg_base += be32_to_cpu(reg_offset); n = getprop(devp, "reg-shift", ®_shift, sizeof(reg_shift)); if (n != sizeof(reg_shift)) reg_shift = 0; + else + reg_shift = be32_to_cpu(reg_shift); scdp->open = ns16550_open; scdp->putc = ns16550_putc; diff --git a/arch/powerpc/include/asm/barrier.h b/arch/powerpc/include/asm/barrier.h index 80024c4f2093..0dbdf88162b7 100644 --- a/arch/powerpc/include/asm/barrier.h +++ b/arch/powerpc/include/asm/barrier.h @@ -41,6 +41,8 @@ # define SMPWMB eieio #endif +/* clang defines this macro for a builtin, which will not work with runtime patching */ +#undef __lwsync #define __lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : :"memory") #define dma_rmb() __lwsync() #define dma_wmb() __asm__ __volatile__ (stringify_in_c(SMPWMB) : : :"memory") diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h index a19f831a4cc9..83a6d99e9994 100644 --- a/arch/powerpc/include/asm/ps3.h +++ b/arch/powerpc/include/asm/ps3.h @@ -83,6 +83,7 @@ struct ps3_dma_region_ops; * @bus_addr: The 'translated' bus address of the region. * @len: The length in bytes of the region. * @offset: The offset from the start of memory of the region. + * @dma_mask: Device dma_mask. * @ioid: The IOID of the device who owns this region * @chunk_list: Opaque variable used by the ioc page manager. * @region_ops: struct ps3_dma_region_ops - dma region operations @@ -97,6 +98,7 @@ struct ps3_dma_region { enum ps3_dma_region_type region_type; unsigned long len; unsigned long offset; + u64 dma_mask; /* driver variables (set by ps3_dma_region_create) */ unsigned long bus_addr; diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c index 19bae78b1f25..76cbf1be9962 100644 --- a/arch/powerpc/platforms/ps3/mm.c +++ b/arch/powerpc/platforms/ps3/mm.c @@ -18,6 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include #include #include @@ -1132,6 +1133,7 @@ int ps3_dma_region_init(struct ps3_system_bus_device *dev, enum ps3_dma_region_type region_type, void *addr, unsigned long len) { unsigned long lpar_addr; + int result; lpar_addr = addr ? ps3_mm_phys_to_lpar(__pa(addr)) : 0; @@ -1143,6 +1145,16 @@ int ps3_dma_region_init(struct ps3_system_bus_device *dev, r->offset -= map.r1.offset; r->len = len ? len : _ALIGN_UP(map.total, 1 << r->page_size); + dev->core.dma_mask = &r->dma_mask; + + result = dma_set_mask_and_coherent(&dev->core, DMA_BIT_MASK(32)); + + if (result < 0) { + dev_err(&dev->core, "%s:%d: dma_set_mask_and_coherent failed: %d\n", + __func__, __LINE__, result); + return result; + } + switch (dev->dev_type) { case PS3_DEVICE_TYPE_SB: r->region_ops = (USE_DYNAMIC_DMA) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 1c4a595e8224..1dff52abc786 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -833,7 +833,7 @@ config CMM_IUCV config APPLDATA_BASE def_bool n prompt "Linux - VM Monitor Stream, base infrastructure" - depends on PROC_FS + depends on PROC_SYSCTL help This provides a kernel interface for creating and updating z/VM APPLDATA monitor records. The monitor records are updated at certain time diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index ce49c2b9db7e..9939879f5f25 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -137,7 +137,7 @@ static void __init set_preferred_console(void) else if (CONSOLE_IS_3270) add_preferred_console("tty3270", 0, NULL); else if (CONSOLE_IS_VT220) - add_preferred_console("ttyS", 1, NULL); + add_preferred_console("ttysclp", 0, NULL); else if (CONSOLE_IS_HVC) add_preferred_console("hvc", 0, NULL); } diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 3fd7c3efdb18..feb7f5ab4084 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -256,7 +256,8 @@ static int winch_tramp(int fd, struct tty_port *port, int *fd_out, goto out_close; } - if (os_set_fd_block(*fd_out, 0)) { + err = os_set_fd_block(*fd_out, 0); + if (err) { printk(UM_KERN_ERR "winch_tramp: failed to set thread_fd " "non-blocking.\n"); goto out_close; diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index 0d6b66c64a81..76d155631c5d 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -145,7 +145,8 @@ static int slip_open(void *data) } sfd = err; - if (set_up_tty(sfd)) + err = set_up_tty(sfd); + if (err) goto out_close2; pri->slave = sfd; diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h index 21d6fa27b4a9..ebda4718eb8f 100644 --- a/arch/x86/include/asm/fpu/internal.h +++ b/arch/x86/include/asm/fpu/internal.h @@ -94,6 +94,7 @@ static inline void fpstate_init_fxstate(struct fxregs_state *fx) } extern void fpstate_sanitize_xstate(struct fpu *fpu); +/* Returns 0 or the negated trap number, which results in -EFAULT for #PF */ #define user_insn(insn, output, input...) \ ({ \ int err; \ @@ -101,14 +102,14 @@ extern void fpstate_sanitize_xstate(struct fpu *fpu); might_fault(); \ \ asm volatile(ASM_STAC "\n" \ - "1:" #insn "\n\t" \ + "1: " #insn "\n" \ "2: " ASM_CLAC "\n" \ ".section .fixup,\"ax\"\n" \ - "3: movl $-1,%[err]\n" \ + "3: negl %%eax\n" \ " jmp 2b\n" \ ".previous\n" \ - _ASM_EXTABLE(1b, 3b) \ - : [err] "=r" (err), output \ + _ASM_EXTABLE_FAULT(1b, 3b) \ + : [err] "=a" (err), output \ : "0"(0), input); \ err; \ }) @@ -227,16 +228,20 @@ static inline void copy_fxregs_to_kernel(struct fpu *fpu) #define XRSTOR ".byte " REX_PREFIX "0x0f,0xae,0x2f" #define XRSTORS ".byte " REX_PREFIX "0x0f,0xc7,0x1f" +/* + * After this @err contains 0 on success or the negated trap number when + * the operation raises an exception. For faults this results in -EFAULT. + */ #define XSTATE_OP(op, st, lmask, hmask, err) \ asm volatile("1:" op "\n\t" \ "xor %[err], %[err]\n" \ "2:\n\t" \ ".pushsection .fixup,\"ax\"\n\t" \ - "3: movl $-2,%[err]\n\t" \ + "3: negl %%eax\n\t" \ "jmp 2b\n\t" \ ".popsection\n\t" \ - _ASM_EXTABLE(1b, 3b) \ - : [err] "=r" (err) \ + _ASM_EXTABLE_FAULT(1b, 3b) \ + : [err] "=a" (err) \ : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \ : "memory") diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c index 7052d9a65fe9..e1c9e94fcce6 100644 --- a/arch/x86/kernel/fpu/regset.c +++ b/arch/x86/kernel/fpu/regset.c @@ -123,7 +123,7 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset, /* * A whole standard-format XSAVE buffer is needed: */ - if ((pos != 0) || (count < fpu_user_xstate_size)) + if (pos != 0 || count != fpu_user_xstate_size) return -EFAULT; xsave = &fpu->state.xsave; diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c index 769831d9fd11..07b0ebd49576 100644 --- a/arch/x86/kernel/fpu/signal.c +++ b/arch/x86/kernel/fpu/signal.c @@ -276,15 +276,23 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) return 0; } - if (!access_ok(VERIFY_READ, buf, size)) + if (!access_ok(VERIFY_READ, buf, size)) { + fpu__clear(fpu); return -EACCES; + } fpu__activate_curr(fpu); - if (!static_cpu_has(X86_FEATURE_FPU)) - return fpregs_soft_set(current, NULL, - 0, sizeof(struct user_i387_ia32_struct), - NULL, buf) != 0; + if (!static_cpu_has(X86_FEATURE_FPU)) { + int ret = fpregs_soft_set(current, NULL, 0, + sizeof(struct user_i387_ia32_struct), + NULL, buf); + + if (ret) + fpu__clear(fpu); + + return ret != 0; + } if (use_xsave()) { struct _fpx_sw_bytes fx_sw_user; diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 63c3ff9e74d4..a6f8600672d7 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -633,8 +633,14 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, unsigned virt_as = max((entry->eax >> 8) & 0xff, 48U); unsigned phys_as = entry->eax & 0xff; - if (!g_phys_as) + /* + * Use bare metal's MAXPHADDR if the CPU doesn't report guest + * MAXPHYADDR separately, or if TDP (NPT) is disabled, as the + * guest version "applies only to guests using nested paging". + */ + if (!g_phys_as || !tdp_enabled) g_phys_as = phys_as; + entry->eax = g_phys_as | (virt_as << 8); entry->edx = 0; /* diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 29078eaf18c9..cbc7f177bbd8 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -3412,7 +3412,7 @@ static int cr_interception(struct vcpu_svm *svm) err = 0; if (cr >= 16) { /* mov to cr */ cr -= 16; - val = kvm_register_read(&svm->vcpu, reg); + val = kvm_register_readl(&svm->vcpu, reg); switch (cr) { case 0: if (!check_selective_cr0_intercepted(svm, val)) @@ -3457,7 +3457,7 @@ static int cr_interception(struct vcpu_svm *svm) kvm_queue_exception(&svm->vcpu, UD_VECTOR); return 1; } - kvm_register_write(&svm->vcpu, reg, val); + kvm_register_writel(&svm->vcpu, reg, val); } kvm_complete_insn_gp(&svm->vcpu, err); @@ -3489,13 +3489,13 @@ static int dr_interception(struct vcpu_svm *svm) if (dr >= 16) { /* mov to DRn */ if (!kvm_require_dr(&svm->vcpu, dr - 16)) return 1; - val = kvm_register_read(&svm->vcpu, reg); + val = kvm_register_readl(&svm->vcpu, reg); kvm_set_dr(&svm->vcpu, dr - 16, val); } else { if (!kvm_require_dr(&svm->vcpu, dr)) return 1; kvm_get_dr(&svm->vcpu, dr, &val); - kvm_register_write(&svm->vcpu, reg, val); + kvm_register_writel(&svm->vcpu, reg, val); } skip_emulated_instruction(&svm->vcpu); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index b945f362771f..c959720c7593 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7044,6 +7044,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) set_debugreg(vcpu->arch.eff_db[3], 3); set_debugreg(vcpu->arch.dr6, 6); vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD; + } else if (unlikely(hw_breakpoint_active())) { + set_debugreg(0, 7); } kvm_x86_ops->run(vcpu); diff --git a/crypto/shash.c b/crypto/shash.c index a1c7609578ea..7eebf3cde7b7 100644 --- a/crypto/shash.c +++ b/crypto/shash.c @@ -24,12 +24,24 @@ static const struct crypto_type crypto_shash_type; -int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, - unsigned int keylen) +static int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, + unsigned int keylen) { return -ENOSYS; } -EXPORT_SYMBOL_GPL(shash_no_setkey); + +/* + * Check whether an shash algorithm has a setkey function. + * + * For CFI compatibility, this must not be an inline function. This is because + * when CFI is enabled, modules won't get the same address for shash_no_setkey + * (if it were exported, which inlining would require) as the core kernel will. + */ +bool crypto_shash_alg_has_setkey(struct shash_alg *alg) +{ + return alg->setkey != shash_no_setkey; +} +EXPORT_SYMBOL_GPL(crypto_shash_alg_has_setkey); static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key, unsigned int keylen) diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 4c5678cfa9c4..c466d7bc861a 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -7,6 +7,11 @@ ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT # # ACPI Boot-Time Table Parsing # +ifeq ($(CONFIG_ACPI_CUSTOM_DSDT),y) +tables.o: $(src)/../../include/$(subst $\",,$(CONFIG_ACPI_CUSTOM_DSDT_FILE)) ; + +endif + obj-$(CONFIG_ACPI) += tables.o obj-$(CONFIG_X86) += blacklist.o diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c index 7f77c071709a..eb09ee71ceb2 100644 --- a/drivers/acpi/acpi_amba.c +++ b/drivers/acpi/acpi_amba.c @@ -70,6 +70,7 @@ static int amba_handler_attach(struct acpi_device *adev, case IORESOURCE_MEM: if (!address_found) { dev->res = *rentry->res; + dev->res.name = dev_name(&dev->dev); address_found = true; } break; diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 6b2c9d68d810..1c13e5fe10d9 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1184,6 +1184,7 @@ static int __init acpi_init(void) init_acpi_device_notify(); result = acpi_bus_init(); if (result) { + kobject_put(acpi_kobj); disable_acpi(); return result; } diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c index fb610ad495f1..152ba55fd908 100644 --- a/drivers/acpi/device_sysfs.c +++ b/drivers/acpi/device_sysfs.c @@ -452,7 +452,7 @@ static ssize_t description_show(struct device *dev, (wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer, acpi_dev->pnp.str_obj->buffer.length, UTF16_LITTLE_ENDIAN, buf, - PAGE_SIZE); + PAGE_SIZE - 1); buf[result++] = '\n'; diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 2237d3f24f0e..8242e16f57c6 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -29,6 +29,7 @@ #include #include #include /* need_resched() */ +#include #include #include #include @@ -538,10 +539,37 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, return; } +static int acpi_cst_latency_cmp(const void *a, const void *b) +{ + const struct acpi_processor_cx *x = a, *y = b; + + if (!(x->valid && y->valid)) + return 0; + if (x->latency > y->latency) + return 1; + if (x->latency < y->latency) + return -1; + return 0; +} +static void acpi_cst_latency_swap(void *a, void *b, int n) +{ + struct acpi_processor_cx *x = a, *y = b; + u32 tmp; + + if (!(x->valid && y->valid)) + return; + tmp = x->latency; + x->latency = y->latency; + y->latency = tmp; +} + static int acpi_processor_power_verify(struct acpi_processor *pr) { unsigned int i; unsigned int working = 0; + unsigned int last_latency = 0; + unsigned int last_type = 0; + bool buggy_latency = false; pr->power.timer_broadcast_on_state = INT_MAX; @@ -565,12 +593,24 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) } if (!cx->valid) continue; + if (cx->type >= last_type && cx->latency < last_latency) + buggy_latency = true; + last_latency = cx->latency; + last_type = cx->type; lapic_timer_check_state(i, pr, cx); tsc_check_state(cx->type); working++; } + if (buggy_latency) { + pr_notice("FW issue: working around C-state latencies out of order\n"); + sort(&pr->power.states[1], max_cstate, + sizeof(struct acpi_processor_cx), + acpi_cst_latency_cmp, + acpi_cst_latency_swap); + } + lapic_timer_propagate_broadcast(pr); return (working); diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c index b26437430163..98b4f0d898d6 100644 --- a/drivers/ata/ahci_sunxi.c +++ b/drivers/ata/ahci_sunxi.c @@ -165,7 +165,7 @@ static void ahci_sunxi_start_engine(struct ata_port *ap) } static const struct ata_port_info ahci_sunxi_port_info = { - .flags = AHCI_FLAG_COMMON | ATA_FLAG_NCQ, + .flags = AHCI_FLAG_COMMON | ATA_FLAG_NCQ | ATA_FLAG_NO_DIPM, .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &ahci_platform_ops, diff --git a/drivers/ata/pata_ep93xx.c b/drivers/ata/pata_ep93xx.c index 634c814cbeda..ebdd2dfabbeb 100644 --- a/drivers/ata/pata_ep93xx.c +++ b/drivers/ata/pata_ep93xx.c @@ -927,7 +927,7 @@ static int ep93xx_pata_probe(struct platform_device *pdev) /* INT[3] (IRQ_EP93XX_EXT3) line connected as pull down */ irq = platform_get_irq(pdev, 0); if (irq < 0) { - err = -ENXIO; + err = irq; goto err_rel_gpio; } diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index 475a00669427..7e6359e32ab6 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -908,10 +908,11 @@ static int octeon_cf_probe(struct platform_device *pdev) return -EINVAL; } - irq_handler = octeon_cf_interrupt; i = platform_get_irq(dma_dev, 0); - if (i > 0) + if (i > 0) { irq = i; + irq_handler = octeon_cf_interrupt; + } } of_node_put(dma_node); } diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c index c8b6a780a290..76c550e160f6 100644 --- a/drivers/ata/pata_rb532_cf.c +++ b/drivers/ata/pata_rb532_cf.c @@ -120,10 +120,12 @@ static int rb532_pata_driver_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - if (irq <= 0) { + if (irq < 0) { dev_err(&pdev->dev, "no IRQ resource found\n"); - return -ENOENT; + return irq; } + if (!irq) + return -EINVAL; pdata = dev_get_platdata(&pdev->dev); if (!pdata) { diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index aafb8cc03523..13f339f07f2a 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c @@ -483,10 +483,12 @@ static int ahci_highbank_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - if (irq <= 0) { + if (irq < 0) { dev_err(dev, "no irq\n"); - return -EINVAL; + return irq; } + if (!irq) + return -EINVAL; hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); if (!hpriv) { diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index fe47c924dc64..a1427cb9b9ed 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -3301,7 +3301,7 @@ static void __exit ia_module_exit(void) { pci_unregister_driver(&ia_driver); - del_timer(&ia_timer); + del_timer_sync(&ia_timer); } module_init(ia_module_init); diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index 8bcd09fb0feb..8c675c4f6d54 100644 --- a/drivers/atm/nicstar.c +++ b/drivers/atm/nicstar.c @@ -298,7 +298,7 @@ static void __exit nicstar_cleanup(void) { XPRINTK("nicstar: nicstar_cleanup() called.\n"); - del_timer(&ns_timer); + del_timer_sync(&ns_timer); pci_unregister_driver(&nicstar_driver); @@ -526,6 +526,15 @@ static int ns_init_card(int i, struct pci_dev *pcidev) /* Set the VPI/VCI MSb mask to zero so we can receive OAM cells */ writel(0x00000000, card->membase + VPM); + card->intcnt = 0; + if (request_irq + (pcidev->irq, &ns_irq_handler, IRQF_SHARED, "nicstar", card) != 0) { + pr_err("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq); + error = 9; + ns_init_card_error(card, error); + return error; + } + /* Initialize TSQ */ card->tsq.org = dma_alloc_coherent(&card->pcidev->dev, NS_TSQSIZE + NS_TSQ_ALIGNMENT, @@ -752,15 +761,6 @@ static int ns_init_card(int i, struct pci_dev *pcidev) card->efbie = 1; - card->intcnt = 0; - if (request_irq - (pcidev->irq, &ns_irq_handler, IRQF_SHARED, "nicstar", card) != 0) { - printk("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq); - error = 9; - ns_init_card_error(card, error); - return error; - } - /* Register device */ card->atmdev = atm_dev_register("nicstar", &card->pcidev->dev, &atm_ops, -1, NULL); @@ -838,10 +838,12 @@ static void ns_init_card_error(ns_dev *card, int error) dev_kfree_skb_any(hb); } if (error >= 12) { - kfree(card->rsq.org); + dma_free_coherent(&card->pcidev->dev, NS_RSQSIZE + NS_RSQ_ALIGNMENT, + card->rsq.org, card->rsq.dma); } if (error >= 11) { - kfree(card->tsq.org); + dma_free_coherent(&card->pcidev->dev, NS_TSQSIZE + NS_TSQ_ALIGNMENT, + card->tsq.org, card->tsq.dma); } if (error >= 10) { free_irq(card->pcidev->irq, card); diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index e57a1f6e39d5..302260e9002c 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -800,6 +800,8 @@ static int virtblk_freeze(struct virtio_device *vdev) blk_mq_stop_hw_queues(vblk->disk->queue); vdev->config->del_vqs(vdev); + kfree(vblk->vqs); + return 0; } diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 4e3b24a0511f..30c09b9ddbf0 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2508,6 +2508,11 @@ static int btusb_setup_qca_download_fw(struct hci_dev *hdev, sent += size; count -= size; + /* ep2 need time to switch from function acl to function dfu, + * so we add 20ms delay here. + */ + msleep(20); + while (count) { size = min_t(size_t, count, QCA_DFU_PACKET_LEN); diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index 1852d19d0d7b..86110a2abf0f 100644 --- a/drivers/cdrom/gdrom.c +++ b/drivers/cdrom/gdrom.c @@ -773,6 +773,13 @@ static int probe_gdrom_setupqueue(void) static int probe_gdrom(struct platform_device *devptr) { int err; + + /* + * Ensure our "one" device is initialized properly in case of previous + * usages of it + */ + memset(&gd, 0, sizeof(gd)); + /* Start the device */ if (gdrom_execute_diagnostic() != 1) { pr_warning("ATA Probe for GDROM failed\n"); @@ -850,6 +857,8 @@ static int remove_gdrom(struct platform_device *devptr) if (gdrom_major) unregister_blkdev(gdrom_major, GDROM_DEV_NAME); unregister_cdrom(gd.cd_info); + kfree(gd.cd_info); + kfree(gd.toc); return 0; } @@ -865,7 +874,7 @@ static struct platform_driver gdrom_driver = { static int __init init_gdrom(void) { int rc; - gd.toc = NULL; + rc = platform_driver_register(&gdrom_driver); if (rc) return rc; @@ -881,8 +890,6 @@ static void __exit exit_gdrom(void) { platform_device_unregister(pd); platform_driver_unregister(&gdrom_driver); - kfree(gd.toc); - kfree(gd.cd_info); } module_init(init_gdrom); diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index bedfd2412ec1..7975ddd40b35 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -976,6 +976,8 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) if (ACPI_SUCCESS(status)) { hdp->hd_phys_address = addr.address.minimum; hdp->hd_address = ioremap(addr.address.minimum, addr.address.address_length); + if (!hdp->hd_address) + return AE_ERROR; if (hpet_is_known(hdp)) { iounmap(hdp->hd_address); @@ -989,6 +991,8 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) hdp->hd_phys_address = fixmem32->address; hdp->hd_address = ioremap(fixmem32->address, HPET_RANGE_SIZE); + if (!hdp->hd_address) + return AE_ERROR; if (hpet_is_known(hdp)) { iounmap(hdp->hd_address); diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 055d2ce378a7..a5393e678fe9 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -393,16 +393,18 @@ static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg, data[0] = 0; WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); - if ((ipmi_version_major > 1) - || ((ipmi_version_major == 1) && (ipmi_version_minor >= 5))) { - /* This is an IPMI 1.5-only feature. */ - data[0] |= WDOG_DONT_STOP_ON_SET; - } else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { - /* - * In ipmi 1.0, setting the timer stops the watchdog, we - * need to start it back up again. - */ - hbnow = 1; + if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { + if ((ipmi_version_major > 1) || + ((ipmi_version_major == 1) && (ipmi_version_minor >= 5))) { + /* This is an IPMI 1.5-only feature. */ + data[0] |= WDOG_DONT_STOP_ON_SET; + } else { + /* + * In ipmi 1.0, setting the timer stops the watchdog, we + * need to start it back up again. + */ + hbnow = 1; + } } data[1] = 0; diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index c115217c79ae..f8d98f7e6fb7 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -544,6 +544,10 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq) io_read_num_rec_bytes(iobase, &num_bytes_read); if (num_bytes_read >= 4) { DEBUGP(2, dev, "NumRecBytes = %i\n", num_bytes_read); + if (num_bytes_read > 4) { + rc = -EIO; + goto exit_setprotocol; + } break; } mdelay(10); diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 4ec08c7a7b65..2632b0fdb1b5 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -492,7 +492,7 @@ static struct port_buffer *get_inbuf(struct port *port) buf = virtqueue_get_buf(port->in_vq, &len); if (buf) { - buf->len = len; + buf->len = min_t(size_t, len, buf->size); buf->offset = 0; port->stats.bytes_received += len; } @@ -1758,7 +1758,7 @@ static void control_work_handler(struct work_struct *work) while ((buf = virtqueue_get_buf(vq, &len))) { spin_unlock(&portdev->c_ivq_lock); - buf->len = len; + buf->len = min_t(size_t, len, buf->size); buf->offset = 0; handle_control_message(vq->vdev, portdev, buf); diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 1ab36a355daf..789efad791a3 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -1085,7 +1085,8 @@ static int clk_pllu_enable(struct clk_hw *hw) if (pll->lock) spin_lock_irqsave(pll->lock, flags); - _clk_pll_enable(hw); + if (!clk_pll_is_enabled(hw)) + _clk_pll_enable(hw); ret = clk_pll_wait_for_lock(pll); if (ret < 0) @@ -1702,7 +1703,8 @@ static int clk_pllu_tegra114_enable(struct clk_hw *hw) if (pll->lock) spin_lock_irqsave(pll->lock, flags); - _clk_pll_enable(hw); + if (!clk_pll_is_enabled(hw)) + _clk_pll_enable(hw); ret = clk_pll_wait_for_lock(pll); if (ret < 0) diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c index a54de1299e9e..81b61e256f7c 100644 --- a/drivers/crypto/ixp4xx_crypto.c +++ b/drivers/crypto/ixp4xx_crypto.c @@ -334,7 +334,7 @@ static void free_buf_chain(struct device *dev, struct buffer_desc *buf,u32 phys) buf1 = buf->next; phys1 = buf->phys_next; - dma_unmap_single(dev, buf->phys_next, buf->buf_len, buf->dir); + dma_unmap_single(dev, buf->phys_addr, buf->buf_len, buf->dir); dma_pool_free(buffer_pool, buf, phys); buf = buf1; phys = phys1; diff --git a/drivers/crypto/nx/nx-842-pseries.c b/drivers/crypto/nx/nx-842-pseries.c index cddc6d8b55d9..1b8c87770645 100644 --- a/drivers/crypto/nx/nx-842-pseries.c +++ b/drivers/crypto/nx/nx-842-pseries.c @@ -553,13 +553,15 @@ static int nx842_OF_set_defaults(struct nx842_devdata *devdata) * The status field indicates if the device is enabled when the status * is 'okay'. Otherwise the device driver will be disabled. * - * @prop - struct property point containing the maxsyncop for the update + * @devdata: struct nx842_devdata to use for dev_info + * @prop: struct property point containing the maxsyncop for the update * * Returns: * 0 - Device is available * -ENODEV - Device is not available */ -static int nx842_OF_upd_status(struct property *prop) +static int nx842_OF_upd_status(struct nx842_devdata *devdata, + struct property *prop) { const char *status = (const char *)prop->value; @@ -773,7 +775,7 @@ static int nx842_OF_upd(struct property *new_prop) goto out; /* Perform property updates */ - ret = nx842_OF_upd_status(status); + ret = nx842_OF_upd_status(new_devdata, status); if (ret) goto error_out; @@ -1086,6 +1088,7 @@ static struct vio_device_id nx842_vio_driver_ids[] = { {"ibm,compression-v1", "ibm,compression"}, {"", ""}, }; +MODULE_DEVICE_TABLE(vio, nx842_vio_driver_ids); static struct vio_driver nx842_vio_driver = { .name = KBUILD_MODNAME, diff --git a/drivers/crypto/qat/qat_common/qat_hal.c b/drivers/crypto/qat/qat_common/qat_hal.c index 8c4fd255a601..cdf80c16a033 100644 --- a/drivers/crypto/qat/qat_common/qat_hal.c +++ b/drivers/crypto/qat/qat_common/qat_hal.c @@ -1255,7 +1255,11 @@ static int qat_hal_put_rel_wr_xfer(struct icp_qat_fw_loader_handle *handle, pr_err("QAT: bad xfrAddr=0x%x\n", xfr_addr); return -EINVAL; } - qat_hal_rd_rel_reg(handle, ae, ctx, ICP_GPB_REL, gprnum, &gprval); + status = qat_hal_rd_rel_reg(handle, ae, ctx, ICP_GPB_REL, gprnum, &gprval); + if (status) { + pr_err("QAT: failed to read register"); + return status; + } gpr_addr = qat_hal_get_reg_addr(ICP_GPB_REL, gprnum); data16low = 0xffff & data; data16hi = 0xffff & (data >> 0x10); diff --git a/drivers/crypto/qat/qat_common/qat_uclo.c b/drivers/crypto/qat/qat_common/qat_uclo.c index 4f1cd83bf56f..a8e3191e5185 100644 --- a/drivers/crypto/qat/qat_common/qat_uclo.c +++ b/drivers/crypto/qat/qat_common/qat_uclo.c @@ -385,7 +385,6 @@ static int qat_uclo_init_umem_seg(struct icp_qat_fw_loader_handle *handle, return 0; } -#define ICP_DH895XCC_PESRAM_BAR_SIZE 0x80000 static int qat_uclo_init_ae_memory(struct icp_qat_fw_loader_handle *handle, struct icp_qat_uof_initmem *init_mem) { diff --git a/drivers/crypto/ux500/hash/hash_core.c b/drivers/crypto/ux500/hash/hash_core.c index 17c8e2b28c42..7500ec9efa6a 100644 --- a/drivers/crypto/ux500/hash/hash_core.c +++ b/drivers/crypto/ux500/hash/hash_core.c @@ -1006,6 +1006,7 @@ static int hash_hw_final(struct ahash_request *req) goto out; } } else if (req->nbytes == 0 && ctx->keylen > 0) { + ret = -EPERM; dev_err(device_data->dev, "%s: Empty message with keylength > 0, NOT supported\n", __func__); goto out; diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index f5a9bb123188..d8997dafb876 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2579,13 +2579,15 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( for (i = 0; i < len / period_len; i++) { desc = pl330_get_desc(pch); if (!desc) { + unsigned long iflags; + dev_err(pch->dmac->ddma.dev, "%s:%d Unable to fetch desc\n", __func__, __LINE__); if (!first) return NULL; - spin_lock_irqsave(&pl330->pool_lock, flags); + spin_lock_irqsave(&pl330->pool_lock, iflags); while (!list_empty(&first->node)) { desc = list_entry(first->node.next, @@ -2595,7 +2597,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( list_move_tail(&first->node, &pl330->desc_pool); - spin_unlock_irqrestore(&pl330->pool_lock, flags); + spin_unlock_irqrestore(&pl330->pool_lock, iflags); return NULL; } diff --git a/drivers/dma/qcom/Kconfig b/drivers/dma/qcom/Kconfig index 2afceb1627a1..b62ebb5c4fe0 100644 --- a/drivers/dma/qcom/Kconfig +++ b/drivers/dma/qcom/Kconfig @@ -9,6 +9,7 @@ config QCOM_BAM_DMA config QCOM_HIDMA_MGMT tristate "Qualcomm Technologies HIDMA Management support" + depends on HAS_IOMEM select DMA_ENGINE help Enable support for the Qualcomm Technologies HIDMA Management. diff --git a/drivers/dma/qcom/hidma_mgmt.c b/drivers/dma/qcom/hidma_mgmt.c index 82f36e466083..143ea7cad756 100644 --- a/drivers/dma/qcom/hidma_mgmt.c +++ b/drivers/dma/qcom/hidma_mgmt.c @@ -398,6 +398,20 @@ static int __init hidma_mgmt_init(void) of_node_put(child); } #endif + /* + * We do not check for return value here, as it is assumed that + * platform_driver_register must not fail. The reason for this is that + * the (potential) hidma_mgmt_of_populate_channels calls above are not + * cleaned up if it does fail, and to do this work is quite + * complicated. In particular, various calls of of_address_to_resource, + * of_irq_to_resource, platform_device_register_full, of_dma_configure, + * and of_msi_configure which then call other functions and so on, must + * be cleaned up - this is not a trivial exercise. + * + * Currently, this module is not intended to be unloaded, and there is + * no module_exit function defined which does the needed cleanup. For + * this reason, we have to assume success here. + */ platform_driver_register(&hidma_mgmt_driver); return 0; diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 68b41daab3a8..bf7105814ee7 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3674,6 +3674,9 @@ static int __init d40_probe(struct platform_device *pdev) kfree(base->lcla_pool.base_unaligned); + if (base->lcpa_base) + iounmap(base->lcpa_base); + if (base->phy_lcpa) release_mem_region(base->phy_lcpa, base->lcpa_size); diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index b9b48d45a6dc..17d426829f5d 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -783,3 +783,4 @@ module_platform_driver(max8997_muic_driver); MODULE_DESCRIPTION("Maxim MAX8997 Extcon driver"); MODULE_AUTHOR("Donggeun Kim "); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:max8997-muic"); diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c index 9d2d8a6673c8..dbe5fc278f09 100644 --- a/drivers/extcon/extcon-sm5502.c +++ b/drivers/extcon/extcon-sm5502.c @@ -92,7 +92,6 @@ static struct reg_data sm5502_reg_data[] = { | SM5502_REG_INTM2_MHL_MASK, .invert = true, }, - { } }; /* List of detectable cables */ diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c index c0e54396f250..dc8d2603612e 100644 --- a/drivers/firmware/efi/cper.c +++ b/drivers/firmware/efi/cper.c @@ -257,8 +257,7 @@ static int cper_dimm_err_location(struct cper_mem_err_compact *mem, char *msg) if (!msg || !(mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE)) return 0; - n = 0; - len = CPER_REC_LEN - 1; + len = CPER_REC_LEN; dmi_memdev_name(mem->mem_dev_handle, &bank, &device); if (bank && device) n = snprintf(msg, len, "DIMM location: %s %s ", bank, device); @@ -267,7 +266,6 @@ static int cper_dimm_err_location(struct cper_mem_err_compact *mem, char *msg) "DIMM location: not present. DMI handle: 0x%.4x ", mem->mem_dev_handle); - msg[n] = '\0'; return n; } diff --git a/drivers/firmware/efi/memattr.c b/drivers/firmware/efi/memattr.c index 9faa09e7c31f..c2b991b9fa9e 100644 --- a/drivers/firmware/efi/memattr.c +++ b/drivers/firmware/efi/memattr.c @@ -68,11 +68,6 @@ static bool entry_is_valid(const efi_memory_desc_t *in, efi_memory_desc_t *out) return false; } - if (!(in->attribute & (EFI_MEMORY_RO | EFI_MEMORY_XP))) { - pr_warn("Entry attributes invalid: RO and XP bits both cleared\n"); - return false; - } - if (PAGE_SIZE > EFI_PAGE_SIZE && (!PAGE_ALIGNED(in->phys_addr) || !PAGE_ALIGNED(in->num_pages << EFI_PAGE_SHIFT))) { diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index 0e2011636fbb..595bf12e7653 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -192,15 +192,13 @@ static int fw_cfg_do_platform_probe(struct platform_device *pdev) /* fw_cfg revision attribute, in /sys/firmware/qemu_fw_cfg top-level dir. */ static u32 fw_cfg_rev; -static ssize_t fw_cfg_showrev(struct kobject *k, struct attribute *a, char *buf) +static ssize_t fw_cfg_showrev(struct kobject *k, struct kobj_attribute *a, + char *buf) { return sprintf(buf, "%u\n", fw_cfg_rev); } -static const struct { - struct attribute attr; - ssize_t (*show)(struct kobject *k, struct attribute *a, char *buf); -} fw_cfg_rev_attr = { +static const struct kobj_attribute fw_cfg_rev_attr = { .attr = { .name = "rev", .mode = S_IRUSR }, .show = fw_cfg_showrev, }; diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c index 6b4d10d6e10f..5038d771ac6e 100644 --- a/drivers/gpio/gpio-zynq.c +++ b/drivers/gpio/gpio-zynq.c @@ -778,8 +778,11 @@ err_pm_dis: static int zynq_gpio_remove(struct platform_device *pdev) { struct zynq_gpio *gpio = platform_get_drvdata(pdev); + int ret; - pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_get_sync(&pdev->dev); + if (ret < 0) + dev_warn(&pdev->dev, "pm_runtime_get_sync() Failed\n"); gpiochip_remove(&gpio->chip); clk_disable_unprepare(gpio->clk); device_set_wakeup_capable(&pdev->dev, 0); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 7271e3f32d82..ab041ae58b20 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -886,6 +886,7 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm) if (gtt && gtt->userptr) { kfree(ttm->sg); + ttm->sg = NULL; ttm->page_flags &= ~TTM_PAGE_FLAG_SG; return; } diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index 56b2dd9a5b68..315d51ac14b8 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c @@ -244,9 +244,10 @@ int drm_master_open(struct drm_file *file_priv) void drm_master_release(struct drm_file *file_priv) { struct drm_device *dev = file_priv->minor->dev; - struct drm_master *master = file_priv->master; + struct drm_master *master; mutex_lock(&dev->master_mutex); + master = file_priv->master; if (file_priv->magic) idr_remove(&file_priv->master->magic_map, file_priv->magic); diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index a2e6a81669e7..94b7798bdea4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -447,7 +447,7 @@ nouveau_bo_sync_for_device(struct nouveau_bo *nvbo) struct ttm_dma_tt *ttm_dma = (struct ttm_dma_tt *)nvbo->bo.ttm; int i; - if (!ttm_dma) + if (!ttm_dma || !ttm_dma->dma_address) return; /* Don't waste time looping if the object is coherent */ @@ -467,7 +467,7 @@ nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo) struct ttm_dma_tt *ttm_dma = (struct ttm_dma_tt *)nvbo->bo.ttm; int i; - if (!ttm_dma) + if (!ttm_dma || !ttm_dma->dma_address) return; /* Don't waste time looping if the object is coherent */ diff --git a/drivers/gpu/drm/qxl/qxl_dumb.c b/drivers/gpu/drm/qxl/qxl_dumb.c index 5e65d5d2d937..e7b7b8a31e52 100644 --- a/drivers/gpu/drm/qxl/qxl_dumb.c +++ b/drivers/gpu/drm/qxl/qxl_dumb.c @@ -57,6 +57,8 @@ int qxl_mode_dumb_create(struct drm_file *file_priv, surf.height = args->height; surf.stride = pitch; surf.format = format; + surf.data = 0; + r = qxl_gem_object_create_with_handle(qdev, file_priv, QXL_GEM_DOMAIN_VRAM, args->size, &surf, &qobj, diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 16239b07ce45..2610919eb709 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -286,7 +286,7 @@ int radeon_uvd_resume(struct radeon_device *rdev) if (rdev->uvd.vcpu_bo == NULL) return -EINVAL; - memcpy(rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size); + memcpy_toio((void __iomem *)rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size); size = radeon_bo_size(rdev->uvd.vcpu_bo); size -= rdev->uvd_fw->size; @@ -294,7 +294,7 @@ int radeon_uvd_resume(struct radeon_device *rdev) ptr = rdev->uvd.cpu_addr; ptr += rdev->uvd_fw->size; - memset(ptr, 0, size); + memset_io((void __iomem *)ptr, 0, size); return 0; } diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index ba7855da7c7f..6058bdab5fb8 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -234,6 +234,7 @@ err_ttm: err_vbufs: vgdev->vdev->config->del_vqs(vgdev->vdev); err_vqs: + dev->dev_private = NULL; kfree(vgdev); return ret; } diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 34ad9fbc6ea8..9a037ea46a90 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1804,6 +1804,9 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) case BUS_I2C: bus = "I2C"; break; + case BUS_VIRTUAL: + bus = "VIRTUAL"; + break; default: bus = ""; } diff --git a/drivers/hid/hid-gt683r.c b/drivers/hid/hid-gt683r.c index a298fbd8db6b..8ca4c1baeda8 100644 --- a/drivers/hid/hid-gt683r.c +++ b/drivers/hid/hid-gt683r.c @@ -64,6 +64,7 @@ static const struct hid_device_id gt683r_led_id[] = { { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) }, { } }; +MODULE_DEVICE_TABLE(hid, gt683r_led_id); static void gt683r_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness) diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 7001f07ca399..4ea18f07c65b 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -223,16 +223,21 @@ int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, buffer_size = buffer_size / sizeof(__s32); if (buffer_size) { for (i = 0; i < buffer_size; ++i) { - hid_set_field(report->field[field_index], i, - (__force __s32)cpu_to_le32(*buf32)); + ret = hid_set_field(report->field[field_index], i, + (__force __s32)cpu_to_le32(*buf32)); + if (ret) + goto done_proc; + ++buf32; } } if (remaining_bytes) { value = 0; memcpy(&value, (u8 *)buf32, remaining_bytes); - hid_set_field(report->field[field_index], i, - (__force __s32)cpu_to_le32(value)); + ret = hid_set_field(report->field[field_index], i, + (__force __s32)cpu_to_le32(value)); + if (ret) + goto done_proc; } hid_hw_request(hsdev->hdev, report, HID_REQ_SET_REPORT); hid_hw_wait(hsdev->hdev); diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 606fd875740c..800c477dd076 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -1157,8 +1157,8 @@ static int i2c_hid_probe(struct i2c_client *client, hid->vendor = le16_to_cpu(ihid->hdesc.wVendorID); hid->product = le16_to_cpu(ihid->hdesc.wProductID); - snprintf(hid->name, sizeof(hid->name), "%s %04hX:%04hX", - client->name, hid->vendor, hid->product); + snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", + client->name, (u16)hid->vendor, (u16)hid->product); strlcpy(hid->phys, dev_name(&client->dev), sizeof(hid->phys)); ihid->quirks = i2c_hid_lookup_quirk(hid->vendor, hid->product); diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 7838343eb37c..b6600329a272 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -372,7 +372,7 @@ static int hid_submit_ctrl(struct hid_device *hid) raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report; dir = usbhid->ctrl[usbhid->ctrltail].dir; - len = ((report->size - 1) >> 3) + 1 + (report->id > 0); + len = hid_report_len(report); if (dir == USB_DIR_OUT) { usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0); usbhid->urbctrl->transfer_buffer_length = len; diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c index 08174d341f4a..bc75f1efa0f4 100644 --- a/drivers/hid/usbhid/hid-pidff.c +++ b/drivers/hid/usbhid/hid-pidff.c @@ -1304,6 +1304,7 @@ int hid_pidff_init(struct hid_device *hid) if (pidff->pool[PID_DEVICE_MANAGED_POOL].value && pidff->pool[PID_DEVICE_MANAGED_POOL].value[0] == 0) { + error = -EPERM; hid_notice(hid, "device does not support device managed pool\n"); goto fail; diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index be60bd5bab78..ee6d499edc1b 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c @@ -630,7 +630,6 @@ static int lm80_probe(struct i2c_client *client, struct device *dev = &client->dev; struct device *hwmon_dev; struct lm80_data *data; - int rv; data = devm_kzalloc(dev, sizeof(struct lm80_data), GFP_KERNEL); if (!data) @@ -643,14 +642,8 @@ static int lm80_probe(struct i2c_client *client, lm80_init_client(client); /* A few vars need to be filled upon startup */ - rv = lm80_read_value(client, LM80_REG_FAN_MIN(1)); - if (rv < 0) - return rv; - data->fan[f_min][0] = rv; - rv = lm80_read_value(client, LM80_REG_FAN_MIN(2)); - if (rv < 0) - return rv; - data->fan[f_min][1] = rv; + data->fan[f_min][0] = lm80_read_value(client, LM80_REG_FAN_MIN(1)); + data->fan[f_min][1] = lm80_read_value(client, LM80_REG_FAN_MIN(2)); hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, data, lm80_groups); diff --git a/drivers/hwmon/max31722.c b/drivers/hwmon/max31722.c index 30a100e70a0d..877c3d7dca01 100644 --- a/drivers/hwmon/max31722.c +++ b/drivers/hwmon/max31722.c @@ -9,7 +9,6 @@ * directory of this archive for more details. */ -#include #include #include #include @@ -138,20 +137,12 @@ static const struct spi_device_id max31722_spi_id[] = { {"max31723", 0}, {} }; - -static const struct acpi_device_id __maybe_unused max31722_acpi_id[] = { - {"MAX31722", 0}, - {"MAX31723", 0}, - {} -}; - MODULE_DEVICE_TABLE(spi, max31722_spi_id); static struct spi_driver max31722_driver = { .driver = { .name = "max31722", .pm = &max31722_pm_ops, - .acpi_match_table = ACPI_PTR(max31722_acpi_id), }, .probe = max31722_probe, .remove = max31722_remove, diff --git a/drivers/hwmon/max31790.c b/drivers/hwmon/max31790.c index 281491cca510..66cf772de7d2 100644 --- a/drivers/hwmon/max31790.c +++ b/drivers/hwmon/max31790.c @@ -179,7 +179,7 @@ static int max31790_read_fan(struct device *dev, u32 attr, int channel, switch (attr) { case hwmon_fan_input: - sr = get_tach_period(data->fan_dynamics[channel]); + sr = get_tach_period(data->fan_dynamics[channel % NR_CHANNEL]); rpm = RPM_FROM_REG(data->tach[channel], sr); *val = rpm; return 0; diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 26f1691f67ab..0e04b27e3158 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -375,11 +375,9 @@ static int i801_check_post(struct i801_priv *priv, int status) dev_err(&priv->pci_dev->dev, "Transaction timeout\n"); /* try to stop the current command */ dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n"); - outb_p(inb_p(SMBHSTCNT(priv)) | SMBHSTCNT_KILL, - SMBHSTCNT(priv)); + outb_p(SMBHSTCNT_KILL, SMBHSTCNT(priv)); usleep_range(1000, 2000); - outb_p(inb_p(SMBHSTCNT(priv)) & (~SMBHSTCNT_KILL), - SMBHSTCNT(priv)); + outb_p(0, SMBHSTCNT(priv)); /* Check if it worked */ status = inb_p(SMBHSTSTS(priv)); diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 565a49a0c564..90e4f839eb1c 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -49,6 +50,7 @@ #define CCR_MTX 0x10 #define CCR_TXAK 0x08 #define CCR_RSTA 0x04 +#define CCR_RSVD 0x02 #define CSR_MCF 0x80 #define CSR_MAAS 0x40 @@ -70,6 +72,7 @@ struct mpc_i2c { u8 fdr, dfsrr; #endif struct clk *clk_per; + bool has_errata_A004447; }; struct mpc_i2c_divider { @@ -178,6 +181,75 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) return 0; } +static int i2c_mpc_wait_sr(struct mpc_i2c *i2c, int mask) +{ + void __iomem *addr = i2c->base + MPC_I2C_SR; + u8 val; + + return readb_poll_timeout(addr, val, val & mask, 0, 100); +} + +/* + * Workaround for Erratum A004447. From the P2040CE Rev Q + * + * 1. Set up the frequency divider and sampling rate. + * 2. I2CCR - a0h + * 3. Poll for I2CSR[MBB] to get set. + * 4. If I2CSR[MAL] is set (an indication that SDA is stuck low), then go to + * step 5. If MAL is not set, then go to step 13. + * 5. I2CCR - 00h + * 6. I2CCR - 22h + * 7. I2CCR - a2h + * 8. Poll for I2CSR[MBB] to get set. + * 9. Issue read to I2CDR. + * 10. Poll for I2CSR[MIF] to be set. + * 11. I2CCR - 82h + * 12. Workaround complete. Skip the next steps. + * 13. Issue read to I2CDR. + * 14. Poll for I2CSR[MIF] to be set. + * 15. I2CCR - 80h + */ +static void mpc_i2c_fixup_A004447(struct mpc_i2c *i2c) +{ + int ret; + u32 val; + + writeccr(i2c, CCR_MEN | CCR_MSTA); + ret = i2c_mpc_wait_sr(i2c, CSR_MBB); + if (ret) { + dev_err(i2c->dev, "timeout waiting for CSR_MBB\n"); + return; + } + + val = readb(i2c->base + MPC_I2C_SR); + + if (val & CSR_MAL) { + writeccr(i2c, 0x00); + writeccr(i2c, CCR_MSTA | CCR_RSVD); + writeccr(i2c, CCR_MEN | CCR_MSTA | CCR_RSVD); + ret = i2c_mpc_wait_sr(i2c, CSR_MBB); + if (ret) { + dev_err(i2c->dev, "timeout waiting for CSR_MBB\n"); + return; + } + val = readb(i2c->base + MPC_I2C_DR); + ret = i2c_mpc_wait_sr(i2c, CSR_MIF); + if (ret) { + dev_err(i2c->dev, "timeout waiting for CSR_MIF\n"); + return; + } + writeccr(i2c, CCR_MEN | CCR_RSVD); + } else { + val = readb(i2c->base + MPC_I2C_DR); + ret = i2c_mpc_wait_sr(i2c, CSR_MIF); + if (ret) { + dev_err(i2c->dev, "timeout waiting for CSR_MIF\n"); + return; + } + writeccr(i2c, CCR_MEN); + } +} + #if defined(CONFIG_PPC_MPC52xx) || defined(CONFIG_PPC_MPC512x) static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = { {20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23}, @@ -581,7 +653,7 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) { writeb(status & ~CSR_MAL, i2c->base + MPC_I2C_SR); - mpc_i2c_fixup(i2c); + i2c_recover_bus(&i2c->adap); } return -EIO; } @@ -617,7 +689,7 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) { writeb(status & ~CSR_MAL, i2c->base + MPC_I2C_SR); - mpc_i2c_fixup(i2c); + i2c_recover_bus(&i2c->adap); } return -EIO; } @@ -632,6 +704,18 @@ static u32 mpc_functionality(struct i2c_adapter *adap) | I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL; } +static int fsl_i2c_bus_recovery(struct i2c_adapter *adap) +{ + struct mpc_i2c *i2c = i2c_get_adapdata(adap); + + if (i2c->has_errata_A004447) + mpc_i2c_fixup_A004447(i2c); + else + mpc_i2c_fixup(i2c); + + return 0; +} + static const struct i2c_algorithm mpc_algo = { .master_xfer = mpc_xfer, .functionality = mpc_functionality, @@ -643,6 +727,10 @@ static struct i2c_adapter mpc_ops = { .timeout = HZ, }; +static struct i2c_bus_recovery_info fsl_i2c_recovery_info = { + .recover_bus = fsl_i2c_bus_recovery, +}; + static const struct of_device_id mpc_i2c_of_match[]; static int fsl_i2c_probe(struct platform_device *op) { @@ -727,6 +815,8 @@ static int fsl_i2c_probe(struct platform_device *op) dev_info(i2c->dev, "timeout %u us\n", mpc_ops.timeout * 1000000 / HZ); platform_set_drvdata(op, i2c); + if (of_property_read_bool(op->dev.of_node, "fsl,i2c-erratum-a004447")) + i2c->has_errata_A004447 = true; i2c->adap = mpc_ops; of_address_to_resource(op->dev.of_node, 0, &res); @@ -735,6 +825,7 @@ static int fsl_i2c_probe(struct platform_device *op) i2c_set_adapdata(&i2c->adap, i2c); i2c->adap.dev.parent = &op->dev; i2c->adap.dev.of_node = of_node_get(op->dev.of_node); + i2c->adap.bus_recovery_info = &fsl_i2c_recovery_info; result = i2c_add_adapter(&i2c->adap); if (result < 0) diff --git a/drivers/i2c/busses/i2c-robotfuzz-osif.c b/drivers/i2c/busses/i2c-robotfuzz-osif.c index 89d8b41b6668..032e8535e860 100644 --- a/drivers/i2c/busses/i2c-robotfuzz-osif.c +++ b/drivers/i2c/busses/i2c-robotfuzz-osif.c @@ -89,7 +89,7 @@ static int osif_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, } } - ret = osif_usb_read(adapter, OSIFI2C_STOP, 0, 0, NULL, 0); + ret = osif_usb_write(adapter, OSIFI2C_STOP, 0, 0, NULL, 0); if (ret) { dev_err(&adapter->dev, "failure sending STOP\n"); return -EREMOTEIO; @@ -159,7 +159,7 @@ static int osif_probe(struct usb_interface *interface, * Set bus frequency. The frequency is: * 120,000,000 / ( 16 + 2 * div * 4^prescale). * Using dev = 52, prescale = 0 give 100KHz */ - ret = osif_usb_read(&priv->adapter, OSIFI2C_SET_BIT_RATE, 52, 0, + ret = osif_usb_write(&priv->adapter, OSIFI2C_SET_BIT_RATE, 52, 0, NULL, 0); if (ret) { dev_err(&interface->dev, "failure sending bit rate"); diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 499af26e736e..acccdfb95420 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -495,7 +495,10 @@ static int i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat) * forces us to send a new START * when we change direction */ + dev_dbg(i2c->dev, + "missing START before write->read\n"); s3c24xx_i2c_stop(i2c, -EINVAL); + break; } goto retry_write; diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 4fd7bfda2f9d..67e44e990777 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -1003,6 +1004,8 @@ static void i2c_device_shutdown(struct device *dev) driver = to_i2c_driver(dev->driver); if (driver->shutdown) driver->shutdown(client); + else if (client->irq > 0) + disable_irq(client->irq); } static void i2c_client_dev_release(struct device *dev) diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index 0890934ef66f..73ea64a2bff0 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -120,7 +120,11 @@ struct bma180_data { int scale; int bw; bool pmode; - u8 buff[16]; /* 3x 16-bit + 8-bit + padding + timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + s16 chan[4]; + s64 timestamp __aligned(8); + } scan; }; enum bma180_chan { @@ -667,12 +671,12 @@ static irqreturn_t bma180_trigger_handler(int irq, void *p) mutex_unlock(&data->mutex); goto err; } - ((s16 *)data->buff)[i++] = ret; + data->scan.chan[i++] = ret; } mutex_unlock(&data->mutex); - iio_push_to_buffers_with_timestamp(indio_dev, data->buff, time_ns); + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, time_ns); err: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/accel/bma220_spi.c b/drivers/iio/accel/bma220_spi.c index 5099f295dd37..a96f2d530ae3 100644 --- a/drivers/iio/accel/bma220_spi.c +++ b/drivers/iio/accel/bma220_spi.c @@ -76,7 +76,11 @@ static const int bma220_scale_table[][4] = { struct bma220_data { struct spi_device *spi_device; struct mutex lock; - s8 buffer[16]; /* 3x8-bit channels + 5x8 padding + 8x8 timestamp */ + struct { + s8 chans[3]; + /* Ensure timestamp is naturally aligned. */ + s64 timestamp __aligned(8); + } scan; u8 tx_buf[2] ____cacheline_aligned; }; @@ -107,12 +111,12 @@ static irqreturn_t bma220_trigger_handler(int irq, void *p) mutex_lock(&data->lock); data->tx_buf[0] = BMA220_REG_ACCEL_X | BMA220_READ_MASK; - ret = spi_write_then_read(spi, data->tx_buf, 1, data->buffer, + ret = spi_write_then_read(spi, data->tx_buf, 1, &data->scan.chans, ARRAY_SIZE(bma220_channels) - 1); if (ret < 0) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: mutex_unlock(&data->lock); diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index 261fbdb88fe1..626a605a0c0e 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -96,12 +96,23 @@ enum kx_acpi_type { ACPI_SMO8500, }; +enum kxcjk1013_axis { + AXIS_X, + AXIS_Y, + AXIS_Z, + AXIS_MAX +}; + struct kxcjk1013_data { struct i2c_client *client; struct iio_trigger *dready_trig; struct iio_trigger *motion_trig; struct mutex mutex; - s16 buffer[8]; + /* Ensure timestamp naturally aligned */ + struct { + s16 chans[AXIS_MAX]; + s64 timestamp __aligned(8); + } scan; u8 odr_bits; u8 range; int wake_thres; @@ -115,13 +126,6 @@ struct kxcjk1013_data { enum kx_acpi_type acpi_type; }; -enum kxcjk1013_axis { - AXIS_X, - AXIS_Y, - AXIS_Z, - AXIS_MAX, -}; - enum kxcjk1013_mode { STANDBY, OPERATION, @@ -971,12 +975,12 @@ static irqreturn_t kxcjk1013_trigger_handler(int irq, void *p) ret = i2c_smbus_read_i2c_block_data_or_emulated(data->client, KXCJK1013_REG_XOUT_L, AXIS_MAX * 2, - (u8 *)data->buffer); + (u8 *)data->scan.chans); mutex_unlock(&data->mutex); if (ret < 0) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, data->timestamp); err: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/accel/stk8312.c b/drivers/iio/accel/stk8312.c index e31023dc5f1b..24a7499049f1 100644 --- a/drivers/iio/accel/stk8312.c +++ b/drivers/iio/accel/stk8312.c @@ -106,7 +106,11 @@ struct stk8312_data { u8 mode; struct iio_trigger *dready_trig; bool dready_trigger_on; - s8 buffer[16]; /* 3x8-bit channels + 5x8 padding + 64-bit timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + s8 chans[3]; + s64 timestamp __aligned(8); + } scan; }; static IIO_CONST_ATTR(in_accel_scale_available, STK8312_SCALE_AVAIL); @@ -443,7 +447,7 @@ static irqreturn_t stk8312_trigger_handler(int irq, void *p) ret = i2c_smbus_read_i2c_block_data(data->client, STK8312_REG_XOUT, STK8312_ALL_CHANNEL_SIZE, - data->buffer); + data->scan.chans); if (ret < STK8312_ALL_CHANNEL_SIZE) { dev_err(&data->client->dev, "register read failed\n"); mutex_unlock(&data->lock); @@ -457,12 +461,12 @@ static irqreturn_t stk8312_trigger_handler(int irq, void *p) mutex_unlock(&data->lock); goto err; } - data->buffer[i++] = ret; + data->scan.chans[i++] = ret; } } mutex_unlock(&data->lock); - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/accel/stk8ba50.c b/drivers/iio/accel/stk8ba50.c index 300d955bad00..5ca179cea2fb 100644 --- a/drivers/iio/accel/stk8ba50.c +++ b/drivers/iio/accel/stk8ba50.c @@ -94,12 +94,11 @@ struct stk8ba50_data { u8 sample_rate_idx; struct iio_trigger *dready_trig; bool dready_trigger_on; - /* - * 3 x 16-bit channels (10-bit data, 6-bit padding) + - * 1 x 16 padding + - * 4 x 16 64-bit timestamp - */ - s16 buffer[8]; + /* Ensure timestamp is naturally aligned */ + struct { + s16 chans[3]; + s64 timetamp __aligned(8); + } scan; }; #define STK8BA50_ACCEL_CHANNEL(index, reg, axis) { \ @@ -329,7 +328,7 @@ static irqreturn_t stk8ba50_trigger_handler(int irq, void *p) ret = i2c_smbus_read_i2c_block_data(data->client, STK8BA50_REG_XOUT, STK8BA50_ALL_CHANNEL_SIZE, - (u8 *)data->buffer); + (u8 *)data->scan.chans); if (ret < STK8BA50_ALL_CHANNEL_SIZE) { dev_err(&data->client->dev, "register read failed\n"); goto err; @@ -342,10 +341,10 @@ static irqreturn_t stk8ba50_trigger_handler(int irq, void *p) if (ret < 0) goto err; - data->buffer[i++] = ret; + data->scan.chans[i++] = ret; } } - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: mutex_unlock(&data->lock); diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c index 437762a1e487..f940b1607ef4 100644 --- a/drivers/iio/adc/ad7793.c +++ b/drivers/iio/adc/ad7793.c @@ -279,6 +279,7 @@ static int ad7793_setup(struct iio_dev *indio_dev, id &= AD7793_ID_MASK; if (id != st->chip_info->id) { + ret = -ENODEV; dev_err(&st->sd.spi->dev, "device ID query failed\n"); goto out; } diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c index 5afe32f6587b..d892c0fe5c31 100644 --- a/drivers/iio/adc/ti-ads1015.c +++ b/drivers/iio/adc/ti-ads1015.c @@ -292,10 +292,14 @@ static irqreturn_t ads1015_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct ads1015_data *data = iio_priv(indio_dev); - s16 buf[8]; /* 1x s16 ADC val + 3x s16 padding + 4x s16 timestamp */ + /* Ensure natural alignment of timestamp */ + struct { + s16 chan; + s64 timestamp __aligned(8); + } scan; int chan, ret, res; - memset(buf, 0, sizeof(buf)); + memset(&scan, 0, sizeof(scan)); mutex_lock(&data->lock); chan = find_first_bit(indio_dev->active_scan_mask, @@ -306,10 +310,10 @@ static irqreturn_t ads1015_trigger_handler(int irq, void *p) goto err; } - buf[0] = res; + scan.chan = res; mutex_unlock(&data->lock); - iio_push_to_buffers_with_timestamp(indio_dev, buf, + iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev)); err: diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index d1bde6d2721e..2a14800e6514 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -180,7 +180,11 @@ struct vf610_adc { u32 sample_freq_avail[5]; struct completion completion; - u16 buffer[8]; + /* Ensure the timestamp is naturally aligned */ + struct { + u16 chan; + s64 timestamp __aligned(8); + } scan; }; static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 }; @@ -592,9 +596,9 @@ static irqreturn_t vf610_adc_isr(int irq, void *dev_id) if (coco & VF610_ADC_HS_COCO0) { info->value = vf610_adc_read_data(info); if (iio_buffer_enabled(indio_dev)) { - info->buffer[0] = info->value; + info->scan.chan = info->value; iio_push_to_buffers_with_timestamp(indio_dev, - info->buffer, + &info->scan, iio_get_time_ns(indio_dev)); iio_trigger_notify_done(indio_dev->trig); } else diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c index b5a5517e3ce1..ec2830c16433 100644 --- a/drivers/iio/gyro/bmg160_core.c +++ b/drivers/iio/gyro/bmg160_core.c @@ -104,7 +104,11 @@ struct bmg160_data { struct iio_trigger *dready_trig; struct iio_trigger *motion_trig; struct mutex mutex; - s16 buffer[8]; + /* Ensure naturally aligned timestamp */ + struct { + s16 chans[3]; + s64 timestamp __aligned(8); + } scan; u32 dps_range; int ev_enable_state; int slope_thres; @@ -874,12 +878,12 @@ static irqreturn_t bmg160_trigger_handler(int irq, void *p) mutex_lock(&data->mutex); ret = regmap_bulk_read(data->regmap, BMG160_REG_XOUT_L, - data->buffer, AXIS_MAX * 2); + data->scan.chans, AXIS_MAX * 2); mutex_unlock(&data->mutex); if (ret < 0) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/humidity/am2315.c b/drivers/iio/humidity/am2315.c index ff96b6d0fdae..77513fd84b99 100644 --- a/drivers/iio/humidity/am2315.c +++ b/drivers/iio/humidity/am2315.c @@ -36,7 +36,11 @@ struct am2315_data { struct i2c_client *client; struct mutex lock; - s16 buffer[8]; /* 2x16-bit channels + 2x16 padding + 4x16 timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + s16 chans[2]; + s64 timestamp __aligned(8); + } scan; }; struct am2315_sensor_data { @@ -170,20 +174,20 @@ static irqreturn_t am2315_trigger_handler(int irq, void *p) mutex_lock(&data->lock); if (*(indio_dev->active_scan_mask) == AM2315_ALL_CHANNEL_MASK) { - data->buffer[0] = sensor_data.hum_data; - data->buffer[1] = sensor_data.temp_data; + data->scan.chans[0] = sensor_data.hum_data; + data->scan.chans[1] = sensor_data.temp_data; } else { i = 0; for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->masklength) { - data->buffer[i] = (bit ? sensor_data.temp_data : - sensor_data.hum_data); + data->scan.chans[i] = (bit ? sensor_data.temp_data : + sensor_data.hum_data); i++; } } mutex_unlock(&data->lock); - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c index 9de553e8c214..625f54d9e382 100644 --- a/drivers/iio/imu/adis_buffer.c +++ b/drivers/iio/imu/adis_buffer.c @@ -83,9 +83,6 @@ static irqreturn_t adis_trigger_handler(int irq, void *p) struct adis *adis = iio_device_get_drvdata(indio_dev); int ret; - if (!adis->buffer) - return -ENOMEM; - if (adis->data->has_paging) { mutex_lock(&adis->txrx_lock); if (adis->current_page != 0) { diff --git a/drivers/iio/light/isl29125.c b/drivers/iio/light/isl29125.c index 1d2c0c8a1d4f..207b856cef8c 100644 --- a/drivers/iio/light/isl29125.c +++ b/drivers/iio/light/isl29125.c @@ -54,7 +54,11 @@ struct isl29125_data { struct i2c_client *client; u8 conf1; - u16 buffer[8]; /* 3x 16-bit, padding, 8 bytes timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + u16 chans[3]; + s64 timestamp __aligned(8); + } scan; }; #define ISL29125_CHANNEL(_color, _si) { \ @@ -187,10 +191,10 @@ static irqreturn_t isl29125_trigger_handler(int irq, void *p) if (ret < 0) goto done; - data->buffer[j++] = ret; + data->scan.chans[j++] = ret; } - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); done: diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c index a8f9bc12ee23..414fe857fa9d 100644 --- a/drivers/iio/light/ltr501.c +++ b/drivers/iio/light/ltr501.c @@ -35,9 +35,12 @@ #define LTR501_PART_ID 0x86 #define LTR501_MANUFAC_ID 0x87 #define LTR501_ALS_DATA1 0x88 /* 16-bit, little endian */ +#define LTR501_ALS_DATA1_UPPER 0x89 /* upper 8 bits of LTR501_ALS_DATA1 */ #define LTR501_ALS_DATA0 0x8a /* 16-bit, little endian */ +#define LTR501_ALS_DATA0_UPPER 0x8b /* upper 8 bits of LTR501_ALS_DATA0 */ #define LTR501_ALS_PS_STATUS 0x8c #define LTR501_PS_DATA 0x8d /* 16-bit, little endian */ +#define LTR501_PS_DATA_UPPER 0x8e /* upper 8 bits of LTR501_PS_DATA */ #define LTR501_INTR 0x8f /* output mode, polarity, mode */ #define LTR501_PS_THRESH_UP 0x90 /* 11 bit, ps upper threshold */ #define LTR501_PS_THRESH_LOW 0x92 /* 11 bit, ps lower threshold */ @@ -408,18 +411,19 @@ static int ltr501_read_als(struct ltr501_data *data, __le16 buf[2]) static int ltr501_read_ps(struct ltr501_data *data) { - int ret, status; + __le16 status; + int ret; ret = ltr501_drdy(data, LTR501_STATUS_PS_RDY); if (ret < 0) return ret; ret = regmap_bulk_read(data->regmap, LTR501_PS_DATA, - &status, 2); + &status, sizeof(status)); if (ret < 0) return ret; - return status; + return le16_to_cpu(status); } static int ltr501_read_intr_prst(struct ltr501_data *data, @@ -1180,7 +1184,7 @@ static struct ltr501_chip_info ltr501_chip_info_tbl[] = { .als_gain_tbl_size = ARRAY_SIZE(ltr559_als_gain_tbl), .ps_gain = ltr559_ps_gain_tbl, .ps_gain_tbl_size = ARRAY_SIZE(ltr559_ps_gain_tbl), - .als_mode_active = BIT(1), + .als_mode_active = BIT(0), .als_gain_mask = BIT(2) | BIT(3) | BIT(4), .als_gain_shift = 2, .info = <r501_info, @@ -1329,9 +1333,12 @@ static bool ltr501_is_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { case LTR501_ALS_DATA1: + case LTR501_ALS_DATA1_UPPER: case LTR501_ALS_DATA0: + case LTR501_ALS_DATA0_UPPER: case LTR501_ALS_PS_STATUS: case LTR501_PS_DATA: + case LTR501_PS_DATA_UPPER: return true; default: return false; diff --git a/drivers/iio/light/tcs3414.c b/drivers/iio/light/tcs3414.c index a795afb7667b..b51cd43ef824 100644 --- a/drivers/iio/light/tcs3414.c +++ b/drivers/iio/light/tcs3414.c @@ -56,7 +56,11 @@ struct tcs3414_data { u8 control; u8 gain; u8 timing; - u16 buffer[8]; /* 4x 16-bit + 8 bytes timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + u16 chans[4]; + s64 timestamp __aligned(8); + } scan; }; #define TCS3414_CHANNEL(_color, _si, _addr) { \ @@ -212,10 +216,10 @@ static irqreturn_t tcs3414_trigger_handler(int irq, void *p) if (ret < 0) goto done; - data->buffer[j++] = ret; + data->scan.chans[j++] = ret; } - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); done: diff --git a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c index 46e969a3a9b7..ed7397f0b4c8 100644 --- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c +++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c @@ -51,7 +51,11 @@ struct lidar_data { int (*xfer)(struct lidar_data *data, u8 reg, u8 *val, int len); int i2c_enabled; - u16 buffer[8]; /* 2 byte distance + 8 byte timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + u16 chan; + s64 timestamp __aligned(8); + } scan; }; static const struct iio_chan_spec lidar_channels[] = { @@ -236,9 +240,9 @@ static irqreturn_t lidar_trigger_handler(int irq, void *private) struct lidar_data *data = iio_priv(indio_dev); int ret; - ret = lidar_get_measurement(data, data->buffer); + ret = lidar_get_measurement(data, &data->scan.chan); if (!ret) { - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); } else if (ret != -EINVAL) { dev_err(&data->client->dev, "cannot read LIDAR measurement"); diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 0a6cc78ebcf7..149d210c68ab 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -2370,7 +2370,8 @@ static int cma_resolve_ib_route(struct rdma_id_private *id_priv, int timeout_ms) work->new_state = RDMA_CM_ROUTE_RESOLVED; work->event.event = RDMA_CM_EVENT_ROUTE_RESOLVED; - route->path_rec = kmalloc(sizeof *route->path_rec, GFP_KERNEL); + if (!route->path_rec) + route->path_rec = kmalloc(sizeof *route->path_rec, GFP_KERNEL); if (!route->path_rec) { ret = -ENOMEM; goto err1; diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 36bdb04f8f01..87bc7b0db892 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -277,6 +277,7 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, if (user && (!wq->sq.bar2_pa || !wq->rq.bar2_pa)) { pr_warn(MOD "%s: sqid %u or rqid %u not in BAR2 range.\n", pci_name(rdev->lldi.pdev), wq->sq.qid, wq->rq.qid); + ret = -EINVAL; goto free_dma; } diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c index 6d1ba75398a1..e23b322224ab 100644 --- a/drivers/infiniband/sw/rxe/rxe_mr.c +++ b/drivers/infiniband/sw/rxe/rxe_mr.c @@ -175,7 +175,7 @@ int rxe_mem_init_user(struct rxe_dev *rxe, struct rxe_pd *pd, u64 start, if (IS_ERR(umem)) { pr_warn("err %d from rxe_umem_get\n", (int)PTR_ERR(umem)); - err = -EINVAL; + err = PTR_ERR(umem); goto err1; } diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c index e39261234528..f431cecd8b56 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.c +++ b/drivers/infiniband/sw/rxe/rxe_net.c @@ -259,10 +259,8 @@ static struct socket *rxe_setup_udp_tunnel(struct net *net, __be16 port, /* Create UDP socket */ err = udp_sock_create(net, &udp_cfg, &sock); - if (err < 0) { - pr_err("failed to create udp socket. err = %d\n", err); + if (err < 0) return ERR_PTR(err); - } tnl_cfg.encap_type = 1; tnl_cfg.encap_rcv = rxe_udp_encap_recv; @@ -665,6 +663,12 @@ int rxe_net_ipv6_init(void) recv_sockets.sk6 = rxe_setup_udp_tunnel(&init_net, htons(ROCE_V2_UDP_DPORT), true); + if (PTR_ERR(recv_sockets.sk6) == -EAFNOSUPPORT) { + recv_sockets.sk6 = NULL; + pr_warn("IPv6 is not supported, can not create a UDPv6 socket\n"); + return 0; + } + if (IS_ERR(recv_sockets.sk6)) { recv_sockets.sk6 = NULL; pr_err("Failed to create IPv6 UDP tunnel\n"); diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c index 186da467060c..5fa1442fd4f1 100644 --- a/drivers/infiniband/sw/rxe/rxe_qp.c +++ b/drivers/infiniband/sw/rxe/rxe_qp.c @@ -258,6 +258,7 @@ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp, if (err) { vfree(qp->sq.queue->buf); kfree(qp->sq.queue); + qp->sq.queue = NULL; return err; } @@ -315,6 +316,7 @@ static int rxe_qp_init_resp(struct rxe_dev *rxe, struct rxe_qp *qp, if (err) { vfree(qp->rq.queue->buf); kfree(qp->rq.queue); + qp->rq.queue = NULL; return err; } } @@ -374,6 +376,11 @@ int rxe_qp_from_init(struct rxe_dev *rxe, struct rxe_qp *qp, struct rxe_pd *pd, err2: rxe_queue_cleanup(qp->sq.queue); err1: + qp->pd = NULL; + qp->rcq = NULL; + qp->scq = NULL; + qp->srq = NULL; + if (srq) rxe_drop_ref(srq); rxe_drop_ref(scq); diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 1ebce211d875..39a7abe4b48c 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -492,7 +492,7 @@ static int joydev_handle_JSIOCSBTNMAP(struct joydev *joydev, memcpy(joydev->keypam, keypam, len); for (i = 0; i < joydev->nkey; i++) - joydev->keymap[keypam[i] - BTN_MISC] = i; + joydev->keymap[joydev->keypam[i] - BTN_MISC] = i; out: kfree(keypam); diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index 5b152f25a8e1..da07742fd9a4 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c @@ -512,6 +512,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv) HIL_IDD_NUM_AXES_PER_SET(*idd)) { printk(KERN_INFO PREFIX "combo devices are not supported.\n"); + error = -EINVAL; goto bail1; } diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 499402a975b3..c5d34a782372 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -266,7 +266,7 @@ static int e2i_init(struct usbtouch_usb *usbtouch) int ret; struct usb_device *udev = interface_to_usbdev(usbtouch->interface); - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01, 0x02, 0x0000, 0x0081, NULL, 0, USB_CTRL_SET_TIMEOUT); @@ -462,7 +462,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) int ret, i; struct usb_device *udev = interface_to_usbdev(usbtouch->interface); - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), MTOUCHUSB_RESET, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); @@ -474,7 +474,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) msleep(150); for (i = 0; i < 3; i++) { - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), MTOUCHUSB_ASYNC_REPORT, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); @@ -645,7 +645,7 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) } /* start sending data */ - ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), TSC10_CMD_DATA1, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); diff --git a/drivers/ipack/carriers/tpci200.c b/drivers/ipack/carriers/tpci200.c index 9b23843dcad4..7ba1a94497f5 100644 --- a/drivers/ipack/carriers/tpci200.c +++ b/drivers/ipack/carriers/tpci200.c @@ -591,8 +591,11 @@ static int tpci200_pci_probe(struct pci_dev *pdev, out_err_bus_register: tpci200_uninstall(tpci200); + /* tpci200->info->cfg_regs is unmapped in tpci200_uninstall */ + tpci200->info->cfg_regs = NULL; out_err_install: - iounmap(tpci200->info->cfg_regs); + if (tpci200->info->cfg_regs) + iounmap(tpci200->info->cfg_regs); out_err_ioremap: pci_release_region(pdev, TPCI200_CFG_MEM_BAR); out_err_pci_request: diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c index ff48da61c94c..89cf1d695a01 100644 --- a/drivers/isdn/hardware/mISDN/hfcpci.c +++ b/drivers/isdn/hardware/mISDN/hfcpci.c @@ -2352,7 +2352,7 @@ static void __exit HFC_cleanup(void) { if (timer_pending(&hfc_tl)) - del_timer(&hfc_tl); + del_timer_sync(&hfc_tl); pci_unregister_driver(&hfc_driver); } diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c index 1fc290659e94..64060429aa50 100644 --- a/drivers/isdn/hardware/mISDN/mISDNinfineon.c +++ b/drivers/isdn/hardware/mISDN/mISDNinfineon.c @@ -645,17 +645,19 @@ static void release_io(struct inf_hw *hw) { if (hw->cfg.mode) { - if (hw->cfg.p) { + if (hw->cfg.mode == AM_MEMIO) { release_mem_region(hw->cfg.start, hw->cfg.size); - iounmap(hw->cfg.p); + if (hw->cfg.p) + iounmap(hw->cfg.p); } else release_region(hw->cfg.start, hw->cfg.size); hw->cfg.mode = AM_NONE; } if (hw->addr.mode) { - if (hw->addr.p) { + if (hw->addr.mode == AM_MEMIO) { release_mem_region(hw->addr.start, hw->addr.size); - iounmap(hw->addr.p); + if (hw->addr.p) + iounmap(hw->addr.p); } else release_region(hw->addr.start, hw->addr.size); hw->addr.mode = AM_NONE; @@ -685,9 +687,12 @@ setup_io(struct inf_hw *hw) (ulong)hw->cfg.start, (ulong)hw->cfg.size); return err; } - if (hw->ci->cfg_mode == AM_MEMIO) - hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size); hw->cfg.mode = hw->ci->cfg_mode; + if (hw->ci->cfg_mode == AM_MEMIO) { + hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size); + if (!hw->cfg.p) + return -ENOMEM; + } if (debug & DEBUG_HW) pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n", hw->name, (ulong)hw->cfg.start, @@ -712,9 +717,12 @@ setup_io(struct inf_hw *hw) (ulong)hw->addr.start, (ulong)hw->addr.size); return err; } - if (hw->ci->addr_mode == AM_MEMIO) - hw->addr.p = ioremap(hw->addr.start, hw->addr.size); hw->addr.mode = hw->ci->addr_mode; + if (hw->ci->addr_mode == AM_MEMIO) { + hw->addr.p = ioremap(hw->addr.start, hw->addr.size); + if (!hw->addr.p) + return -ENOMEM; + } if (debug & DEBUG_HW) pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n", hw->name, (ulong)hw->addr.start, diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c index e9fcae4569af..6656fcf502aa 100644 --- a/drivers/isdn/hardware/mISDN/netjet.c +++ b/drivers/isdn/hardware/mISDN/netjet.c @@ -1114,7 +1114,6 @@ nj_probe(struct pci_dev *pdev, const struct pci_device_id *ent) card->typ = NETJET_S_TJ300; card->base = pci_resource_start(pdev, 0); - card->irq = pdev->irq; pci_set_drvdata(pdev, card); err = setup_instance(card); if (err) diff --git a/drivers/leds/leds-ktd2692.c b/drivers/leds/leds-ktd2692.c index 45296aaca9da..02738b5b1dbf 100644 --- a/drivers/leds/leds-ktd2692.c +++ b/drivers/leds/leds-ktd2692.c @@ -259,6 +259,17 @@ static void ktd2692_setup(struct ktd2692_context *led) | KTD2692_REG_FLASH_CURRENT_BASE); } +static void regulator_disable_action(void *_data) +{ + struct device *dev = _data; + struct ktd2692_context *led = dev_get_drvdata(dev); + int ret; + + ret = regulator_disable(led->regulator); + if (ret) + dev_err(dev, "Failed to disable supply: %d\n", ret); +} + static int ktd2692_parse_dt(struct ktd2692_context *led, struct device *dev, struct ktd2692_led_config_data *cfg) { @@ -289,8 +300,14 @@ static int ktd2692_parse_dt(struct ktd2692_context *led, struct device *dev, if (led->regulator) { ret = regulator_enable(led->regulator); - if (ret) + if (ret) { dev_err(dev, "Failed to enable supply: %d\n", ret); + } else { + ret = devm_add_action_or_reset(dev, + regulator_disable_action, dev); + if (ret) + return ret; + } } child_node = of_get_next_available_child(np, NULL); @@ -380,17 +397,9 @@ static int ktd2692_probe(struct platform_device *pdev) static int ktd2692_remove(struct platform_device *pdev) { struct ktd2692_context *led = platform_get_drvdata(pdev); - int ret; led_classdev_flash_unregister(&led->fled_cdev); - if (led->regulator) { - ret = regulator_disable(led->regulator); - if (ret) - dev_err(&pdev->dev, - "Failed to disable supply: %d\n", ret); - } - mutex_destroy(&led->lock); return 0; diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c index 44ceed7ac3c5..7cebcd458943 100644 --- a/drivers/leds/leds-lp5523.c +++ b/drivers/leds/leds-lp5523.c @@ -320,7 +320,7 @@ static int lp5523_init_program_engine(struct lp55xx_chip *chip) usleep_range(3000, 6000); ret = lp55xx_read(chip, LP5523_REG_STATUS, &status); if (ret) - return ret; + goto out; status &= LP5523_ENG_STATUS_MASK; if (status != LP5523_ENG_STATUS_MASK) { diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index c04d9f22d160..d85d13a4c57a 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -788,7 +788,7 @@ static int dm_add_exception(void *context, chunk_t old, chunk_t new) static uint32_t __minimum_chunk_size(struct origin *o) { struct dm_snapshot *snap; - unsigned chunk_size = 0; + unsigned chunk_size = rounddown_pow_of_two(UINT_MAX); if (o) list_for_each_entry(snap, &o->snapshots, list) @@ -1264,6 +1264,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) if (!s->store->chunk_size) { ti->error = "Chunk size not set"; + r = -EINVAL; goto bad_read_metadata; } diff --git a/drivers/md/persistent-data/dm-btree-remove.c b/drivers/md/persistent-data/dm-btree-remove.c index eff04fa23dfa..9e4d1212f4c1 100644 --- a/drivers/md/persistent-data/dm-btree-remove.c +++ b/drivers/md/persistent-data/dm-btree-remove.c @@ -549,7 +549,8 @@ int dm_btree_remove(struct dm_btree_info *info, dm_block_t root, delete_at(n, index); } - *new_root = shadow_root(&spine); + if (!r) + *new_root = shadow_root(&spine); exit_shadow_spine(&spine); return r; diff --git a/drivers/md/persistent-data/dm-space-map-disk.c b/drivers/md/persistent-data/dm-space-map-disk.c index bf4c5e2ccb6f..e0acae7a3815 100644 --- a/drivers/md/persistent-data/dm-space-map-disk.c +++ b/drivers/md/persistent-data/dm-space-map-disk.c @@ -171,6 +171,14 @@ static int sm_disk_new_block(struct dm_space_map *sm, dm_block_t *b) * Any block we allocate has to be free in both the old and current ll. */ r = sm_ll_find_common_free_block(&smd->old_ll, &smd->ll, smd->begin, smd->ll.nr_blocks, b); + if (r == -ENOSPC) { + /* + * There's no free block between smd->begin and the end of the metadata device. + * We search before smd->begin in case something has been freed. + */ + r = sm_ll_find_common_free_block(&smd->old_ll, &smd->ll, 0, smd->begin, b); + } + if (r) return r; @@ -199,7 +207,6 @@ static int sm_disk_commit(struct dm_space_map *sm) return r; memcpy(&smd->old_ll, &smd->ll, sizeof(smd->old_ll)); - smd->begin = 0; smd->nr_allocated_this_transaction = 0; r = sm_disk_get_nr_free(sm, &nr_free); diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c index 967d8f2a731f..62a4d7da9bd9 100644 --- a/drivers/md/persistent-data/dm-space-map-metadata.c +++ b/drivers/md/persistent-data/dm-space-map-metadata.c @@ -451,6 +451,14 @@ static int sm_metadata_new_block_(struct dm_space_map *sm, dm_block_t *b) * Any block we allocate has to be free in both the old and current ll. */ r = sm_ll_find_common_free_block(&smm->old_ll, &smm->ll, smm->begin, smm->ll.nr_blocks, b); + if (r == -ENOSPC) { + /* + * There's no free block between smm->begin and the end of the metadata device. + * We search before smm->begin in case something has been freed. + */ + r = sm_ll_find_common_free_block(&smm->old_ll, &smm->ll, 0, smm->begin, b); + } + if (r) return r; @@ -502,7 +510,6 @@ static int sm_metadata_commit(struct dm_space_map *sm) return r; memcpy(&smm->old_ll, &smm->ll, sizeof(smm->old_ll)); - smm->begin = 0; smm->allocated_this_transaction = 0; return 0; diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index f3a42834d7d6..b10bd45da9c5 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -914,7 +914,7 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, void *buffer, size_t size) { struct sms_firmware *firmware = (struct sms_firmware *) buffer; - struct sms_msg_data4 *msg; + struct sms_msg_data5 *msg; u32 mem_address, calc_checksum = 0; u32 i, *ptr; u8 *payload = firmware->payload; @@ -995,24 +995,20 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, goto exit_fw_download; if (coredev->mode == DEVICE_MODE_NONE) { - struct sms_msg_data *trigger_msg = - (struct sms_msg_data *) msg; - pr_debug("sending MSG_SMS_SWDOWNLOAD_TRIGGER_REQ\n"); SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, - sizeof(struct sms_msg_hdr) + - sizeof(u32) * 5); + sizeof(*msg)); - trigger_msg->msg_data[0] = firmware->start_address; + msg->msg_data[0] = firmware->start_address; /* Entry point */ - trigger_msg->msg_data[1] = 6; /* Priority */ - trigger_msg->msg_data[2] = 0x200; /* Stack size */ - trigger_msg->msg_data[3] = 0; /* Parameter */ - trigger_msg->msg_data[4] = 4; /* Task ID */ + msg->msg_data[1] = 6; /* Priority */ + msg->msg_data[2] = 0x200; /* Stack size */ + msg->msg_data[3] = 0; /* Parameter */ + msg->msg_data[4] = 4; /* Task ID */ - rc = smscore_sendrequest_and_wait(coredev, trigger_msg, - trigger_msg->x_msg_header.msg_length, + rc = smscore_sendrequest_and_wait(coredev, msg, + msg->x_msg_header.msg_length, &coredev->trigger_done); } else { SMS_INIT_MSG(&msg->x_msg_header, MSG_SW_RELOAD_EXEC_REQ, diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index 4cc39e4a8318..55d02c27f124 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h @@ -636,9 +636,9 @@ struct sms_msg_data2 { u32 msg_data[2]; }; -struct sms_msg_data4 { +struct sms_msg_data5 { struct sms_msg_hdr x_msg_header; - u32 msg_data[4]; + u32 msg_data[5]; }; struct sms_data_download { diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index 9d5eb8b6aede..3a5b5f94398a 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c @@ -1187,6 +1187,10 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, return 0; media_graph_error: + mutex_lock(&g_smsdvb_clientslock); + list_del(&client->entry); + mutex_unlock(&g_smsdvb_clientslock); + smsdvb_debugfs_release(client); client_error: diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index efb7d5284946..99a225bbc77a 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -1350,14 +1351,20 @@ static int dvb_net_do_ioctl(struct file *file, struct net_device *netdev; struct dvb_net_priv *priv_data; struct dvb_net_if *dvbnetif = parg; + int if_num = dvbnetif->if_num; - if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || - !dvbnet->state[dvbnetif->if_num]) { + if (if_num >= DVB_NET_DEVICES_MAX) { + ret = -EINVAL; + goto ioctl_error; + } + if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX); + + if (!dvbnet->state[if_num]) { ret = -EINVAL; goto ioctl_error; } - netdev = dvbnet->device[dvbnetif->if_num]; + netdev = dvbnet->device[if_num]; priv_data = netdev_priv(netdev); dvbnetif->pid=priv_data->pid; @@ -1410,14 +1417,20 @@ static int dvb_net_do_ioctl(struct file *file, struct net_device *netdev; struct dvb_net_priv *priv_data; struct __dvb_net_if_old *dvbnetif = parg; + int if_num = dvbnetif->if_num; - if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || - !dvbnet->state[dvbnetif->if_num]) { + if (if_num >= DVB_NET_DEVICES_MAX) { + ret = -EINVAL; + goto ioctl_error; + } + if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX); + + if (!dvbnet->state[if_num]) { ret = -EINVAL; goto ioctl_error; } - netdev = dvbnet->device[dvbnetif->if_num]; + netdev = dvbnet->device[if_num]; priv_data = netdev_priv(netdev); dvbnetif->pid=priv_data->pid; diff --git a/drivers/media/dvb-frontends/sp8870.c b/drivers/media/dvb-frontends/sp8870.c index e87ac30d7fb8..b43135c5a960 100644 --- a/drivers/media/dvb-frontends/sp8870.c +++ b/drivers/media/dvb-frontends/sp8870.c @@ -293,7 +293,9 @@ static int sp8870_set_frontend_parameters(struct dvb_frontend *fe) sp8870_writereg(state, 0xc05, reg0xc05); // read status reg in order to clear pending irqs - sp8870_readreg(state, 0x200); + err = sp8870_readreg(state, 0x200); + if (err < 0) + return err; // system controller start sp8870_microcontroller_start(state); diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index 3844853ab0a0..9d55abfe070f 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1393,7 +1393,7 @@ static int __s5c73m3_power_on(struct s5c73m3 *state) s5c73m3_gpio_deassert(state, STBY); usleep_range(100, 200); - s5c73m3_gpio_deassert(state, RST); + s5c73m3_gpio_deassert(state, RSET); usleep_range(50, 100); return 0; @@ -1408,7 +1408,7 @@ static int __s5c73m3_power_off(struct s5c73m3 *state) { int i, ret; - if (s5c73m3_gpio_assert(state, RST)) + if (s5c73m3_gpio_assert(state, RSET)) usleep_range(10, 50); if (s5c73m3_gpio_assert(state, STBY)) @@ -1613,7 +1613,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state) state->mclk_frequency = pdata->mclk_frequency; state->gpio[STBY] = pdata->gpio_stby; - state->gpio[RST] = pdata->gpio_reset; + state->gpio[RSET] = pdata->gpio_reset; return 0; } diff --git a/drivers/media/i2c/s5c73m3/s5c73m3.h b/drivers/media/i2c/s5c73m3/s5c73m3.h index 653f68e7ea07..e267b2522149 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3.h +++ b/drivers/media/i2c/s5c73m3/s5c73m3.h @@ -361,7 +361,7 @@ struct s5c73m3_ctrls { enum s5c73m3_gpio_id { STBY, - RST, + RSET, GPIO_NUM, }; diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c index 6ebcf254989a..75fb13a33eab 100644 --- a/drivers/media/i2c/s5k4ecgx.c +++ b/drivers/media/i2c/s5k4ecgx.c @@ -177,7 +177,7 @@ static const char * const s5k4ecgx_supply_names[] = { enum s5k4ecgx_gpio_id { STBY, - RST, + RSET, GPIO_NUM, }; @@ -482,7 +482,7 @@ static int __s5k4ecgx_power_on(struct s5k4ecgx *priv) if (s5k4ecgx_gpio_set_value(priv, STBY, priv->gpio[STBY].level)) usleep_range(30, 50); - if (s5k4ecgx_gpio_set_value(priv, RST, priv->gpio[RST].level)) + if (s5k4ecgx_gpio_set_value(priv, RSET, priv->gpio[RSET].level)) usleep_range(30, 50); return 0; @@ -490,7 +490,7 @@ static int __s5k4ecgx_power_on(struct s5k4ecgx *priv) static int __s5k4ecgx_power_off(struct s5k4ecgx *priv) { - if (s5k4ecgx_gpio_set_value(priv, RST, !priv->gpio[RST].level)) + if (s5k4ecgx_gpio_set_value(priv, RSET, !priv->gpio[RSET].level)) usleep_range(30, 50); if (s5k4ecgx_gpio_set_value(priv, STBY, !priv->gpio[STBY].level)) @@ -878,7 +878,7 @@ static int s5k4ecgx_config_gpios(struct s5k4ecgx *priv, int ret; priv->gpio[STBY].gpio = -EINVAL; - priv->gpio[RST].gpio = -EINVAL; + priv->gpio[RSET].gpio = -EINVAL; ret = s5k4ecgx_config_gpio(gpio->gpio, gpio->level, "S5K4ECGX_STBY"); @@ -897,7 +897,7 @@ static int s5k4ecgx_config_gpios(struct s5k4ecgx *priv, s5k4ecgx_free_gpios(priv); return ret; } - priv->gpio[RST] = *gpio; + priv->gpio[RSET] = *gpio; if (gpio_is_valid(gpio->gpio)) gpio_set_value(gpio->gpio, 0); diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index db82ed05792e..e8c820cb418b 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -238,7 +238,7 @@ struct s5k5baf_gpio { enum s5k5baf_gpio_id { STBY, - RST, + RSET, NUM_GPIOS, }; @@ -973,7 +973,7 @@ static int s5k5baf_power_on(struct s5k5baf *state) s5k5baf_gpio_deassert(state, STBY); usleep_range(50, 100); - s5k5baf_gpio_deassert(state, RST); + s5k5baf_gpio_deassert(state, RSET); return 0; err_reg_dis: @@ -991,7 +991,7 @@ static int s5k5baf_power_off(struct s5k5baf *state) state->apply_cfg = 0; state->apply_crop = 0; - s5k5baf_gpio_assert(state, RST); + s5k5baf_gpio_assert(state, RSET); s5k5baf_gpio_assert(state, STBY); if (!IS_ERR(state->clock)) diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c index 4b615b4b0463..4d92aac279dc 100644 --- a/drivers/media/i2c/s5k6aa.c +++ b/drivers/media/i2c/s5k6aa.c @@ -181,7 +181,7 @@ static const char * const s5k6aa_supply_names[] = { enum s5k6aa_gpio_id { STBY, - RST, + RSET, GPIO_NUM, }; @@ -845,7 +845,7 @@ static int __s5k6aa_power_on(struct s5k6aa *s5k6aa) ret = s5k6aa->s_power(1); usleep_range(4000, 4000); - if (s5k6aa_gpio_deassert(s5k6aa, RST)) + if (s5k6aa_gpio_deassert(s5k6aa, RSET)) msleep(20); return ret; @@ -855,7 +855,7 @@ static int __s5k6aa_power_off(struct s5k6aa *s5k6aa) { int ret; - if (s5k6aa_gpio_assert(s5k6aa, RST)) + if (s5k6aa_gpio_assert(s5k6aa, RSET)) usleep_range(100, 150); if (s5k6aa->s_power) { @@ -1514,7 +1514,7 @@ static int s5k6aa_configure_gpios(struct s5k6aa *s5k6aa, int ret; s5k6aa->gpio[STBY].gpio = -EINVAL; - s5k6aa->gpio[RST].gpio = -EINVAL; + s5k6aa->gpio[RSET].gpio = -EINVAL; gpio = &pdata->gpio_stby; if (gpio_is_valid(gpio->gpio)) { @@ -1537,7 +1537,7 @@ static int s5k6aa_configure_gpios(struct s5k6aa *s5k6aa, if (ret < 0) return ret; - s5k6aa->gpio[RST] = *gpio; + s5k6aa->gpio[RSET] = *gpio; } return 0; diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 3e47b432d0f4..c799071be66f 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -1763,6 +1763,7 @@ static int tc358743_probe_of(struct tc358743_state *state) bps_pr_lane = 2 * endpoint->link_frequencies[0]; if (bps_pr_lane < 62500000U || bps_pr_lane > 1000000000U) { dev_err(dev, "unsupported bps per lane: %u bps\n", bps_pr_lane); + ret = -EINVAL; goto disable_clk; } diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c index 90fcccc05b56..c678d7120727 100644 --- a/drivers/media/pci/bt8xx/bt878.c +++ b/drivers/media/pci/bt8xx/bt878.c @@ -494,6 +494,9 @@ static int bt878_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) btwrite(0, BT878_AINT_MASK); bt878_num++; + if (!bt->tasklet.func) + tasklet_disable(&bt->tasklet); + return 0; fail2: diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c index 979634000597..17b717a1c7fa 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.c +++ b/drivers/media/pci/cobalt/cobalt-driver.c @@ -689,6 +689,7 @@ static int cobalt_probe(struct pci_dev *pci_dev, return -ENOMEM; cobalt->pci_dev = pci_dev; cobalt->instance = i; + mutex_init(&cobalt->pci_lock); retval = v4l2_device_register(&pci_dev->dev, &cobalt->v4l2_dev); if (retval) { diff --git a/drivers/media/pci/cobalt/cobalt-driver.h b/drivers/media/pci/cobalt/cobalt-driver.h index ed00dc9d9399..8f9454d30b95 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.h +++ b/drivers/media/pci/cobalt/cobalt-driver.h @@ -262,6 +262,8 @@ struct cobalt { int instance; struct pci_dev *pci_dev; struct v4l2_device v4l2_dev; + /* serialize PCI access in cobalt_s_bit_sysctrl() */ + struct mutex pci_lock; void __iomem *bar0, *bar1; @@ -333,10 +335,13 @@ static inline u32 cobalt_g_sysctrl(struct cobalt *cobalt) static inline void cobalt_s_bit_sysctrl(struct cobalt *cobalt, int bit, int val) { - u32 ctrl = cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE); + u32 ctrl; + mutex_lock(&cobalt->pci_lock); + ctrl = cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE); cobalt_write_bar1(cobalt, COBALT_SYS_CTRL_BASE, (ctrl & ~(1UL << bit)) | (val << bit)); + mutex_unlock(&cobalt->pci_lock); } static inline u32 cobalt_g_sysstat(struct cobalt *cobalt) diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c index 5f6ccf492111..8f083f28dcf3 100644 --- a/drivers/media/platform/s5p-g2d/g2d.c +++ b/drivers/media/platform/s5p-g2d/g2d.c @@ -283,6 +283,9 @@ static int g2d_release(struct file *file) struct g2d_dev *dev = video_drvdata(file); struct g2d_ctx *ctx = fh2ctx(file->private_data); + mutex_lock(&dev->mutex); + v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); + mutex_unlock(&dev->mutex); v4l2_ctrl_handler_free(&ctx->ctrl_handler); v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); diff --git a/drivers/media/platform/sti/hva/hva-hw.c b/drivers/media/platform/sti/hva/hva-hw.c index c4d97fb80aae..1653892da9a5 100644 --- a/drivers/media/platform/sti/hva/hva-hw.c +++ b/drivers/media/platform/sti/hva/hva-hw.c @@ -127,8 +127,7 @@ static irqreturn_t hva_hw_its_irq_thread(int irq, void *arg) ctx_id = (hva->sts_reg & 0xFF00) >> 8; if (ctx_id >= HVA_MAX_INSTANCES) { dev_err(dev, "%s %s: bad context identifier: %d\n", - ctx->name, __func__, ctx_id); - ctx->hw_err = true; + HVA_PREFIX, __func__, ctx_id); goto out; } diff --git a/drivers/media/usb/cpia2/cpia2.h b/drivers/media/usb/cpia2/cpia2.h index cdef677d57ec..80a7af6482ae 100644 --- a/drivers/media/usb/cpia2/cpia2.h +++ b/drivers/media/usb/cpia2/cpia2.h @@ -442,6 +442,7 @@ int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd); int cpia2_do_command(struct camera_data *cam, unsigned int command, unsigned char direction, unsigned char param); +void cpia2_deinit_camera_struct(struct camera_data *cam, struct usb_interface *intf); struct camera_data *cpia2_init_camera_struct(struct usb_interface *intf); int cpia2_init_camera(struct camera_data *cam); int cpia2_allocate_buffers(struct camera_data *cam); diff --git a/drivers/media/usb/cpia2/cpia2_core.c b/drivers/media/usb/cpia2/cpia2_core.c index 0310fd6ed103..828f9689f4a1 100644 --- a/drivers/media/usb/cpia2/cpia2_core.c +++ b/drivers/media/usb/cpia2/cpia2_core.c @@ -2158,6 +2158,18 @@ static void reset_camera_struct(struct camera_data *cam) cam->height = cam->params.roi.height; } +/****************************************************************************** + * + * cpia2_init_camera_struct + * + * Deinitialize camera struct + *****************************************************************************/ +void cpia2_deinit_camera_struct(struct camera_data *cam, struct usb_interface *intf) +{ + v4l2_device_unregister(&cam->v4l2_dev); + kfree(cam); +} + /****************************************************************************** * * cpia2_init_camera_struct diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c index 30e27844e0e9..4f4a130f17af 100644 --- a/drivers/media/usb/cpia2/cpia2_usb.c +++ b/drivers/media/usb/cpia2/cpia2_usb.c @@ -860,15 +860,13 @@ static int cpia2_usb_probe(struct usb_interface *intf, ret = set_alternate(cam, USBIF_CMDONLY); if (ret < 0) { ERR("%s: usb_set_interface error (ret = %d)\n", __func__, ret); - kfree(cam); - return ret; + goto alt_err; } if((ret = cpia2_init_camera(cam)) < 0) { ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret); - kfree(cam); - return ret; + goto alt_err; } LOG(" CPiA Version: %d.%02d (%d.%d)\n", cam->params.version.firmware_revision_hi, @@ -888,11 +886,14 @@ static int cpia2_usb_probe(struct usb_interface *intf, ret = cpia2_register_camera(cam); if (ret < 0) { ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret); - kfree(cam); - return ret; + goto alt_err; } return 0; + +alt_err: + cpia2_deinit_camera_struct(cam, intf); + return ret; } /****************************************************************************** diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index 2b7a1b569db0..184a9b827d56 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c @@ -1791,7 +1791,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = { .size_of_priv = sizeof(struct cxusb_state), - .num_adapters = 2, + .num_adapters = 1, .adapter = { { .num_frontends = 1, diff --git a/drivers/media/usb/dvb-usb/dtv5100.c b/drivers/media/usb/dvb-usb/dtv5100.c index c60fb54f445f..66f34988fdf0 100644 --- a/drivers/media/usb/dvb-usb/dtv5100.c +++ b/drivers/media/usb/dvb-usb/dtv5100.c @@ -39,6 +39,7 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr, u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) { struct dtv5100_state *st = d->priv; + unsigned int pipe; u8 request; u8 type; u16 value; @@ -47,6 +48,7 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr, switch (wlen) { case 1: /* write { reg }, read { value } */ + pipe = usb_rcvctrlpipe(d->udev, 0); request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_READ : DTV5100_TUNER_READ); type = USB_TYPE_VENDOR | USB_DIR_IN; @@ -54,6 +56,7 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr, break; case 2: /* write { reg, value } */ + pipe = usb_sndctrlpipe(d->udev, 0); request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_WRITE : DTV5100_TUNER_WRITE); type = USB_TYPE_VENDOR | USB_DIR_OUT; @@ -67,7 +70,7 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr, memcpy(st->data, rbuf, rlen); msleep(1); /* avoid I2C errors */ - return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), request, + return usb_control_msg(d->udev, pipe, request, type, value, index, st->data, rlen, DTV5100_USB_TIMEOUT); } @@ -154,7 +157,7 @@ static int dtv5100_probe(struct usb_interface *intf, /* initialize non qt1010/zl10353 part? */ for (i = 0; dtv5100_init[i].request; i++) { - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), dtv5100_init[i].request, USB_TYPE_VENDOR | USB_DIR_OUT, dtv5100_init[i].value, diff --git a/drivers/media/usb/gspca/m5602/m5602_po1030.c b/drivers/media/usb/gspca/m5602/m5602_po1030.c index a0a90dd34ca8..a098aeb290c3 100644 --- a/drivers/media/usb/gspca/m5602/m5602_po1030.c +++ b/drivers/media/usb/gspca/m5602/m5602_po1030.c @@ -159,6 +159,7 @@ static const struct v4l2_ctrl_config po1030_greenbal_cfg = { int po1030_probe(struct sd *sd) { u8 dev_id_h = 0, i; + int err; struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; if (force_sensor) { @@ -177,10 +178,13 @@ int po1030_probe(struct sd *sd) for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) { u8 data = preinit_po1030[i][2]; if (preinit_po1030[i][0] == SENSOR) - m5602_write_sensor(sd, - preinit_po1030[i][1], &data, 1); + err = m5602_write_sensor(sd, preinit_po1030[i][1], + &data, 1); else - m5602_write_bridge(sd, preinit_po1030[i][1], data); + err = m5602_write_bridge(sd, preinit_po1030[i][1], + data); + if (err < 0) + return err; } if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1)) diff --git a/drivers/media/usb/gspca/sq905.c b/drivers/media/usb/gspca/sq905.c index 03322d2b2e82..efb5e553b772 100644 --- a/drivers/media/usb/gspca/sq905.c +++ b/drivers/media/usb/gspca/sq905.c @@ -130,7 +130,7 @@ static int sq905_command(struct gspca_dev *gspca_dev, u16 index) } ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), + usb_rcvctrlpipe(gspca_dev->dev, 0), USB_REQ_SYNCH_FRAME, /* request */ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, SQ905_PING, 0, gspca_dev->usb_buf, 1, diff --git a/drivers/media/usb/gspca/sunplus.c b/drivers/media/usb/gspca/sunplus.c index cc3e1478c5a0..949915734d57 100644 --- a/drivers/media/usb/gspca/sunplus.c +++ b/drivers/media/usb/gspca/sunplus.c @@ -255,6 +255,10 @@ static void reg_r(struct gspca_dev *gspca_dev, PERR("reg_r: buffer overflow\n"); return; } + if (len == 0) { + PERR("reg_r: zero-length read\n"); + return; + } if (gspca_dev->usb_err < 0) return; ret = usb_control_msg(gspca_dev->dev, @@ -263,7 +267,7 @@ static void reg_r(struct gspca_dev *gspca_dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ index, - len ? gspca_dev->usb_buf : NULL, len, + gspca_dev->usb_buf, len, 500); if (ret < 0) { pr_err("reg_r err %d\n", ret); @@ -739,7 +743,7 @@ static int sd_start(struct gspca_dev *gspca_dev) case MegaImageVI: reg_w_riv(gspca_dev, 0xf0, 0, 0); spca504B_WaitCmdStatus(gspca_dev); - reg_r(gspca_dev, 0xf0, 4, 0); + reg_w_riv(gspca_dev, 0xf0, 4, 0); spca504B_WaitCmdStatus(gspca_dev); break; default: diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index ff489645e070..0cb8dd585235 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @@ -2722,9 +2722,8 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) pvr2_stream_destroy(hdw->vid_stream); hdw->vid_stream = NULL; } - pvr2_i2c_core_done(hdw); v4l2_device_unregister(&hdw->v4l2_dev); - pvr2_hdw_remove_usb_stuff(hdw); + pvr2_hdw_disconnect(hdw); mutex_lock(&pvr2_unit_mtx); do { if ((hdw->unit_number >= 0) && @@ -2751,6 +2750,7 @@ void pvr2_hdw_disconnect(struct pvr2_hdw *hdw) { pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw); LOCK_TAKE(hdw->big_lock); + pvr2_i2c_core_done(hdw); LOCK_TAKE(hdw->ctl_lock); pvr2_hdw_remove_usb_stuff(hdw); LOCK_GIVE(hdw->ctl_lock); diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index dcca723f7155..1d724e86f378 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -89,10 +89,37 @@ int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, struct uvc_streaming_control *ctrl) { + static const struct usb_device_id elgato_cam_link_4k = { + USB_DEVICE(0x0fd9, 0x0066) + }; struct uvc_format *format = NULL; struct uvc_frame *frame = NULL; unsigned int i; + /* + * The response of the Elgato Cam Link 4K is incorrect: The second byte + * contains bFormatIndex (instead of being the second byte of bmHint). + * The first byte is always zero. The third byte is always 1. + * + * The UVC 1.5 class specification defines the first five bits in the + * bmHint bitfield. The remaining bits are reserved and should be zero. + * Therefore a valid bmHint will be less than 32. + * + * Latest Elgato Cam Link 4K firmware as of 2021-03-23 needs this fix. + * MCU: 20.02.19, FPGA: 67 + */ + if (usb_match_one_id(stream->dev->intf, &elgato_cam_link_4k) && + ctrl->bmHint > 255) { + u8 corrected_format_index = ctrl->bmHint >> 8; + + /* uvc_dbg(stream->dev, VIDEO, + "Correct USB video probe response from {bmHint: 0x%04x, bFormatIndex: %u} to {bmHint: 0x%04x, bFormatIndex: %u}\n", + ctrl->bmHint, ctrl->bFormatIndex, + 1, corrected_format_index); */ + ctrl->bmHint = 1; + ctrl->bFormatIndex = corrected_format_index; + } + for (i = 0; i < stream->nformats; ++i) { if (stream->format[i].index == ctrl->bFormatIndex) { format = &stream->format[i]; diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c index c5513f55e64e..05b9012f9902 100644 --- a/drivers/media/usb/zr364xx/zr364xx.c +++ b/drivers/media/usb/zr364xx/zr364xx.c @@ -1066,6 +1066,7 @@ static int zr364xx_start_readpipe(struct zr364xx_camera *cam) DBG("submitting URB %p\n", pipe_info->stream_urb); retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL); if (retval) { + usb_free_urb(pipe_info->stream_urb); printk(KERN_ERR KBUILD_MODNAME ": start read pipe failed\n"); return retval; } diff --git a/drivers/media/v4l2-core/v4l2-fh.c b/drivers/media/v4l2-core/v4l2-fh.c index 0c5e69070586..d44b289205b4 100644 --- a/drivers/media/v4l2-core/v4l2-fh.c +++ b/drivers/media/v4l2-core/v4l2-fh.c @@ -109,6 +109,7 @@ int v4l2_fh_release(struct file *filp) v4l2_fh_del(fh); v4l2_fh_exit(fh); kfree(fh); + filp->private_data = NULL; } return 0; } diff --git a/drivers/memory/fsl_ifc.c b/drivers/memory/fsl_ifc.c index 1b182b117f9c..38b945eb410f 100644 --- a/drivers/memory/fsl_ifc.c +++ b/drivers/memory/fsl_ifc.c @@ -109,7 +109,6 @@ static int fsl_ifc_ctrl_remove(struct platform_device *dev) iounmap(ctrl->gregs); dev_set_drvdata(&dev->dev, NULL); - kfree(ctrl); return 0; } @@ -221,7 +220,8 @@ static int fsl_ifc_ctrl_probe(struct platform_device *dev) dev_info(&dev->dev, "Freescale Integrated Flash Controller\n"); - fsl_ifc_ctrl_dev = kzalloc(sizeof(*fsl_ifc_ctrl_dev), GFP_KERNEL); + fsl_ifc_ctrl_dev = devm_kzalloc(&dev->dev, sizeof(*fsl_ifc_ctrl_dev), + GFP_KERNEL); if (!fsl_ifc_ctrl_dev) return -ENOMEM; @@ -231,8 +231,7 @@ static int fsl_ifc_ctrl_probe(struct platform_device *dev) fsl_ifc_ctrl_dev->gregs = of_iomap(dev->dev.of_node, 0); if (!fsl_ifc_ctrl_dev->gregs) { dev_err(&dev->dev, "failed to get memory region\n"); - ret = -ENODEV; - goto err; + return -ENODEV; } if (of_property_read_bool(dev->dev.of_node, "little-endian")) { @@ -308,6 +307,7 @@ err_irq: free_irq(fsl_ifc_ctrl_dev->irq, fsl_ifc_ctrl_dev); irq_dispose_mapping(fsl_ifc_ctrl_dev->irq); err: + iounmap(fsl_ifc_ctrl_dev->gregs); return ret; } diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c index 578e881067a5..4094f97ec7dc 100644 --- a/drivers/mfd/da9052-i2c.c +++ b/drivers/mfd/da9052-i2c.c @@ -118,6 +118,7 @@ static const struct i2c_device_id da9052_i2c_id[] = { {"da9053-bc", DA9053_BC}, {} }; +MODULE_DEVICE_TABLE(i2c, da9052_i2c_id); #ifdef CONFIG_OF static const struct of_device_id dialog_dt_ids[] = { diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c index 863c39a3353c..d284df25c76b 100644 --- a/drivers/mfd/stmpe-i2c.c +++ b/drivers/mfd/stmpe-i2c.c @@ -109,7 +109,7 @@ static const struct i2c_device_id stmpe_i2c_id[] = { { "stmpe2403", STMPE2403 }, { } }; -MODULE_DEVICE_TABLE(i2c, stmpe_id); +MODULE_DEVICE_TABLE(i2c, stmpe_i2c_id); static struct i2c_driver stmpe_i2c_driver = { .driver = { diff --git a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c index 6b3bf9ab051d..706decef68a0 100644 --- a/drivers/misc/ibmasm/module.c +++ b/drivers/misc/ibmasm/module.c @@ -123,7 +123,7 @@ static int ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id) result = ibmasm_init_remote_input_dev(sp); if (result) { dev_err(sp->dev, "Failed to initialize remote queue\n"); - goto error_send_message; + goto error_init_remote; } result = ibmasm_send_driver_vpd(sp); @@ -143,8 +143,9 @@ static int ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id) return 0; error_send_message: - disable_sp_interrupts(sp->base_address); ibmasm_free_remote_input_dev(sp); +error_init_remote: + disable_sp_interrupts(sp->base_address); free_irq(sp->irq, (void *)sp); error_request_irq: iounmap(sp->base_address); diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c index 098fbbf5a554..71becb5c4dec 100644 --- a/drivers/misc/kgdbts.c +++ b/drivers/misc/kgdbts.c @@ -110,8 +110,9 @@ printk(KERN_INFO a); \ } while (0) #define v2printk(a...) do { \ - if (verbose > 1) \ + if (verbose > 1) { \ printk(KERN_INFO a); \ + } \ touch_nmi_watchdog(); \ } while (0) #define eprintk(a...) do { \ diff --git a/drivers/misc/lis3lv02d/lis3lv02d.h b/drivers/misc/lis3lv02d/lis3lv02d.h index c439c827eea8..0ef759671b54 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.h +++ b/drivers/misc/lis3lv02d/lis3lv02d.h @@ -284,6 +284,7 @@ struct lis3lv02d { int regs_size; u8 *reg_cache; bool regs_stored; + bool init_required; u8 odr_mask; /* ODR bit mask */ u8 whoami; /* indicates measurement precision */ s16 (*read_data) (struct lis3lv02d *lis3, int reg); diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 5a4893ce9c24..857bf1f8f4c0 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -226,6 +226,9 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb, return ret; } + pm_runtime_mark_last_busy(dev->dev); + pm_request_autosuspend(dev->dev); + list_move_tail(&cb->list, &cl->rd_pending); return 0; diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 2a3d8a8da54a..3f360791e0b0 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2630,11 +2630,14 @@ int mmc_execute_tuning(struct mmc_card *card) err = host->ops->execute_tuning(host, opcode); mmc_host_clk_release(host); - if (err) + if (err) { pr_err("%s: tuning execution failed: %d\n", mmc_hostname(host), err); - else + } else { + host->retune_now = 0; + host->need_retune = 0; mmc_retune_enable(host); + } return err; } diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 1ef8bf9f4b1a..f150a502b20f 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1386,6 +1386,10 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host) u16 preset = 0; switch (host->timing) { + case MMC_TIMING_MMC_HS: + case MMC_TIMING_SD_HS: + preset = sdhci_readw(host, SDHCI_PRESET_FOR_HIGH_SPEED); + break; case MMC_TIMING_UHS_SDR12: preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12); break; diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 2b67d0a616db..beea93b10a89 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -249,6 +249,7 @@ /* 60-FB reserved */ +#define SDHCI_PRESET_FOR_HIGH_SPEED 0x64 #define SDHCI_PRESET_FOR_SDR12 0x66 #define SDHCI_PRESET_FOR_SDR25 0x68 #define SDHCI_PRESET_FOR_SDR50 0x6A diff --git a/drivers/mmc/host/usdhi6rol0.c b/drivers/mmc/host/usdhi6rol0.c index 003aecc44122..ad0a467bb464 100644 --- a/drivers/mmc/host/usdhi6rol0.c +++ b/drivers/mmc/host/usdhi6rol0.c @@ -1809,6 +1809,7 @@ static int usdhi6_probe(struct platform_device *pdev) version = usdhi6_read(host, USDHI6_VERSION); if ((version & 0xfff) != 0xa0d) { + ret = -EPERM; dev_err(dev, "Version not recognized %x\n", version); goto e_clk_off; } diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c index b455e9cf95af..a3472127bea3 100644 --- a/drivers/mmc/host/via-sdmmc.c +++ b/drivers/mmc/host/via-sdmmc.c @@ -859,6 +859,9 @@ static void via_sdc_data_isr(struct via_crdr_mmc_host *host, u16 intmask) { BUG_ON(intmask == 0); + if (!host->data) + return; + if (intmask & VIA_CRDR_SDSTS_DT) host->data->error = -ETIMEDOUT; else if (intmask & (VIA_CRDR_SDSTS_RC | VIA_CRDR_SDSTS_WC)) diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c index bb3e0d1dd355..a3e4288e5391 100644 --- a/drivers/mmc/host/vub300.c +++ b/drivers/mmc/host/vub300.c @@ -2292,7 +2292,7 @@ static int vub300_probe(struct usb_interface *interface, if (retval < 0) goto error5; retval = - usb_control_msg(vub300->udev, usb_rcvctrlpipe(vub300->udev, 0), + usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0), SET_ROM_WAIT_STATES, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, firmware_rom_wait_states, 0x0000, NULL, 0, HZ); diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c index 1b2e9217ec78..d520ce32ddbf 100644 --- a/drivers/net/appletalk/cops.c +++ b/drivers/net/appletalk/cops.c @@ -324,6 +324,8 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr) break; } + dev->base_addr = ioaddr; + /* Reserve any actual interrupt. */ if (dev->irq) { retval = request_irq(dev->irq, cops_interrupt, 0, dev->name, dev); @@ -331,8 +333,6 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr) goto err_out; } - dev->base_addr = ioaddr; - lp = netdev_priv(dev); spin_lock_init(&lp->lock); diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 16437aa35bc4..2b721ed392ad 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1280,6 +1280,7 @@ static struct slave *bond_alloc_slave(struct bonding *bond, slave->bond = bond; slave->dev = slave_dev; + INIT_DELAYED_WORK(&slave->notify_work, bond_netdev_notify_work); if (bond_kobj_init(slave)) return NULL; @@ -1292,7 +1293,6 @@ static struct slave *bond_alloc_slave(struct bonding *bond, return NULL; } } - INIT_DELAYED_WORK(&slave->notify_work, bond_netdev_notify_work); return slave; } diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index c2dea4916e5d..1243c2e5a86a 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -281,7 +281,6 @@ static int caif_xmit(struct sk_buff *skb, struct net_device *dev) { struct ser_device *ser; - BUG_ON(dev == NULL); ser = netdev_priv(dev); /* Send flow off once, on high water mark */ @@ -363,6 +362,7 @@ static int ldisc_open(struct tty_struct *tty) rtnl_lock(); result = register_netdevice(dev); if (result) { + tty_kref_put(tty); rtnl_unlock(); free_netdev(dev); return -ENODEV; diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index d0846ae9e0e4..022a9b3c7d4e 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -1064,7 +1064,6 @@ static void ems_usb_disconnect(struct usb_interface *intf) if (dev) { unregister_netdev(dev->netdev); - free_candev(dev->netdev); unlink_all_urbs(dev); @@ -1072,6 +1071,8 @@ static void ems_usb_disconnect(struct usb_interface *intf) kfree(dev->intr_in_buffer); kfree(dev->tx_msg_buffer); + + free_candev(dev->netdev); } } diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c index f8df8248035e..31e02ca56572 100644 --- a/drivers/net/ethernet/aeroflex/greth.c +++ b/drivers/net/ethernet/aeroflex/greth.c @@ -1554,10 +1554,11 @@ static int greth_of_remove(struct platform_device *of_dev) mdiobus_unregister(greth->mdio); unregister_netdev(ndev); - free_netdev(ndev); of_iounmap(&of_dev->resource[0], greth->regs, resource_size(&of_dev->resource[0])); + free_netdev(ndev); + return 0; } diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index 9de0f9f5b11c..59af298f99e0 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c @@ -1653,6 +1653,7 @@ out_free_netdev: free_netdev(netdev); out_pci_release: pci_release_mem_regions(pdev); + pci_disable_pcie_error_reporting(pdev); out_pci_disable: pci_disable_device(pdev); return err; diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 1f7034d739b0..e15e487c14dd 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -8256,9 +8256,9 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) BNX2_WR(bp, PCI_COMMAND, reg); } else if ((BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5706_A1) && !(bp->flags & BNX2_FLAG_PCIX)) { - dev_err(&pdev->dev, "5706 A1 can only be used in a PCIX bus, aborting\n"); + rc = -EPERM; goto err_out_unmap; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index e8a09d0afe1c..545b59ff5d7e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -1240,8 +1240,10 @@ int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, goto failed; /* SR-IOV capability was enabled but there are no VFs*/ - if (iov->total == 0) + if (iov->total == 0) { + err = -EINVAL; goto failed; + } iov->nr_virtfn = min_t(u16, iov->total, num_vfs_param); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 148e1ff2e5e0..77dadbe1a446 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -4262,7 +4262,6 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp) pf->fw_fid = le16_to_cpu(resp->fid); pf->port_id = le16_to_cpu(resp->port_id); - bp->dev->dev_port = pf->port_id; memcpy(pf->mac_addr, resp->mac_address, ETH_ALEN); memcpy(bp->dev->dev_addr, pf->mac_addr, ETH_ALEN); pf->max_rsscos_ctxs = le16_to_cpu(resp->max_rsscos_ctx); diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index f20718b730e5..69fa47351a32 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -2031,6 +2031,9 @@ static struct net_device_stats *gem_get_stats(struct macb *bp) struct gem_stats *hwstat = &bp->hw_stats.gem; struct net_device_stats *nstat = &bp->stats; + if (!netif_running(bp->dev)) + return nstat; + gem_update_stats(bp); nstat->rx_errors = (hwstat->rx_frame_check_sequence_errors + diff --git a/drivers/net/ethernet/ec_bhf.c b/drivers/net/ethernet/ec_bhf.c index f7b42483921c..0ade0c6d81ee 100644 --- a/drivers/net/ethernet/ec_bhf.c +++ b/drivers/net/ethernet/ec_bhf.c @@ -589,10 +589,12 @@ static void ec_bhf_remove(struct pci_dev *dev) struct ec_bhf_priv *priv = netdev_priv(net_dev); unregister_netdev(net_dev); - free_netdev(net_dev); pci_iounmap(dev, priv->dma_io); pci_iounmap(dev, priv->io); + + free_netdev(net_dev); + pci_release_regions(dev); pci_clear_master(dev); pci_disable_device(dev); diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 289560b0f643..b0b9f77c3740 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -5998,6 +5998,7 @@ drv_cleanup: unmap_bars: be_unmap_pci_bars(adapter); free_netdev: + pci_disable_pcie_error_reporting(pdev); free_netdev(netdev); rel_reg: pci_release_regions(pdev); diff --git a/drivers/net/ethernet/ezchip/nps_enet.c b/drivers/net/ethernet/ezchip/nps_enet.c index 223f35cc034c..6de29f2a0a09 100644 --- a/drivers/net/ethernet/ezchip/nps_enet.c +++ b/drivers/net/ethernet/ezchip/nps_enet.c @@ -624,7 +624,7 @@ static s32 nps_enet_probe(struct platform_device *pdev) /* Get IRQ number */ priv->irq = platform_get_irq(pdev, 0); - if (!priv->irq) { + if (priv->irq < 0) { dev_err(dev, "failed to retrieve value from device tree\n"); err = -ENODEV; goto out_netdev; @@ -659,8 +659,8 @@ static s32 nps_enet_remove(struct platform_device *pdev) struct nps_enet_priv *priv = netdev_priv(ndev); unregister_netdev(ndev); - free_netdev(ndev); netif_napi_del(&priv->napi); + free_netdev(ndev); return 0; } diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index 123181612595..031d4b3a544c 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -586,6 +586,10 @@ void fec_ptp_init(struct platform_device *pdev) fep->ptp_caps.enable = fec_ptp_enable; fep->cycle_speed = clk_get_rate(fep->clk_ptp); + if (!fep->cycle_speed) { + fep->cycle_speed = NSEC_PER_SEC; + dev_err(&fep->pdev->dev, "clk_ptp clock rate is zero\n"); + } fep->ptp_inc = NSEC_PER_SEC / fep->cycle_speed; spin_lock_init(&fep->tmreg_lock); diff --git a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c index 399cfd217288..cfda55bfa811 100644 --- a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c +++ b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c @@ -548,6 +548,11 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id) return -1; base = ioremap(link->resource[2]->start, resource_size(link->resource[2])); + if (!base) { + pcmcia_release_window(link, link->resource[2]); + return -1; + } + pcmcia_map_mem_page(link, link->resource[2], 0); /* diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index 3692adb8902d..6c70cba92df0 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -2656,10 +2656,8 @@ static int ehea_restart_qps(struct net_device *dev) u16 dummy16 = 0; cb0 = (void *)get_zeroed_page(GFP_KERNEL); - if (!cb0) { - ret = -ENOMEM; - goto out; - } + if (!cb0) + return -ENOMEM; for (i = 0; i < (port->num_def_qps); i++) { struct ehea_port_res *pr = &port->port_res[i]; @@ -2679,6 +2677,7 @@ static int ehea_restart_qps(struct net_device *dev) cb0); if (hret != H_SUCCESS) { netdev_err(dev, "query_ehea_qp failed (1)\n"); + ret = -EFAULT; goto out; } @@ -2691,6 +2690,7 @@ static int ehea_restart_qps(struct net_device *dev) &dummy64, &dummy16, &dummy16); if (hret != H_SUCCESS) { netdev_err(dev, "modify_ehea_qp failed (1)\n"); + ret = -EFAULT; goto out; } @@ -2699,6 +2699,7 @@ static int ehea_restart_qps(struct net_device *dev) cb0); if (hret != H_SUCCESS) { netdev_err(dev, "query_ehea_qp failed (2)\n"); + ret = -EFAULT; goto out; } diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index 93c29094ceff..9035cb5fc70d 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c @@ -1423,7 +1423,7 @@ static int e100_phy_check_without_mii(struct nic *nic) u8 phy_type; int without_mii; - phy_type = (nic->eeprom[eeprom_phy_iface] >> 8) & 0x0f; + phy_type = (le16_to_cpu(nic->eeprom[eeprom_phy_iface]) >> 8) & 0x0f; switch (phy_type) { case NoSuchPhy: /* Non-MII PHY; UNTESTED! */ @@ -1543,7 +1543,7 @@ static int e100_phy_init(struct nic *nic) mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr); } else if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) && (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) && - (nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) { + (le16_to_cpu(nic->eeprom[eeprom_cnfg_mdix]) & eeprom_mdix_enabled))) { /* enable/disable MDI/MDI-X auto-switching. */ mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, nic->mii.force_media ? 0 : NCONFIG_AUTO_SWITCH); @@ -2298,9 +2298,9 @@ static int e100_asf(struct nic *nic) { /* ASF can be enabled from eeprom */ return (nic->pdev->device >= 0x1050) && (nic->pdev->device <= 0x1057) && - (nic->eeprom[eeprom_config_asf] & eeprom_asf) && - !(nic->eeprom[eeprom_config_asf] & eeprom_gcl) && - ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE); + (le16_to_cpu(nic->eeprom[eeprom_config_asf]) & eeprom_asf) && + !(le16_to_cpu(nic->eeprom[eeprom_config_asf]) & eeprom_gcl) && + ((le16_to_cpu(nic->eeprom[eeprom_smbus_addr]) & 0xFF) != 0xFE); } static int e100_up(struct nic *nic) @@ -2952,7 +2952,7 @@ static int e100_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* Wol magic packet can be enabled from eeprom */ if ((nic->mac >= mac_82558_D101_A4) && - (nic->eeprom[eeprom_id] & eeprom_id_wol)) { + (le16_to_cpu(nic->eeprom[eeprom_id]) & eeprom_id_wol)) { nic->flags |= wol_magic; device_set_wakeup_enable(&pdev->dev, true); } diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 40644657b1b7..832fffed4a1f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -5478,6 +5478,8 @@ int i40e_vsi_open(struct i40e_vsi *vsi) dev_driver_string(&pf->pdev->dev), dev_name(&pf->pdev->dev)); err = i40e_vsi_request_irq(vsi, int_name); + if (err) + goto err_setup_rx; } else { err = -EINVAL; @@ -9059,10 +9061,6 @@ static int i40e_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, 0, 0, nlflags, filter_mask, NULL); } -/* Hardware supports L4 tunnel length of 128B (=2^7) which includes - * inner mac plus all inner ethertypes. - */ -#define I40E_MAX_TUNNEL_HDR_LEN 128 /** * i40e_features_check - Validate encapsulated packet conforms to limits * @skb: skb buff @@ -9073,12 +9071,52 @@ static netdev_features_t i40e_features_check(struct sk_buff *skb, struct net_device *dev, netdev_features_t features) { - if (skb->encapsulation && - ((skb_inner_network_header(skb) - skb_transport_header(skb)) > - I40E_MAX_TUNNEL_HDR_LEN)) - return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); + size_t len; + + /* No point in doing any of this if neither checksum nor GSO are + * being requested for this frame. We can rule out both by just + * checking for CHECKSUM_PARTIAL + */ + if (skb->ip_summed != CHECKSUM_PARTIAL) + return features; + + /* We cannot support GSO if the MSS is going to be less than + * 64 bytes. If it is then we need to drop support for GSO. + */ + if (skb_is_gso(skb) && (skb_shinfo(skb)->gso_size < 64)) + features &= ~NETIF_F_GSO_MASK; + + /* MACLEN can support at most 63 words */ + len = skb_network_header(skb) - skb->data; + if (len & ~(63 * 2)) + goto out_err; + + /* IPLEN and EIPLEN can support at most 127 dwords */ + len = skb_transport_header(skb) - skb_network_header(skb); + if (len & ~(127 * 4)) + goto out_err; + + if (skb->encapsulation) { + /* L4TUNLEN can support 127 words */ + len = skb_inner_network_header(skb) - skb_transport_header(skb); + if (len & ~(127 * 2)) + goto out_err; + + /* IPLEN can support at most 127 dwords */ + len = skb_inner_transport_header(skb) - + skb_inner_network_header(skb); + if (len & ~(127 * 4)) + goto out_err; + } + + /* No need to validate L4LEN as TCP is the only protocol with a + * a flexible value and we support all possible values supported + * by TCP, which is at most 15 dwords + */ return features; +out_err: + return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); } static const struct net_device_ops i40e_netdev_ops = { diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index d1224d33ecfa..410a36c98241 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -1931,8 +1931,6 @@ static int mlx4_en_set_tunable(struct net_device *dev, return ret; } -#define MLX4_EEPROM_PAGE_LEN 256 - static int mlx4_en_get_module_info(struct net_device *dev, struct ethtool_modinfo *modinfo) { @@ -1967,7 +1965,7 @@ static int mlx4_en_get_module_info(struct net_device *dev, break; case MLX4_MODULE_ID_SFP: modinfo->type = ETH_MODULE_SFF_8472; - modinfo->eeprom_len = MLX4_EEPROM_PAGE_LEN; + modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; break; default: return -ENOSYS; diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c index 3173875a715f..231f09712850 100644 --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c @@ -1856,6 +1856,7 @@ EXPORT_SYMBOL(mlx4_get_roce_gid_from_slave); #define I2C_ADDR_LOW 0x50 #define I2C_ADDR_HIGH 0x51 #define I2C_PAGE_SIZE 256 +#define I2C_HIGH_PAGE_SIZE 128 /* Module Info Data */ struct mlx4_cable_info { @@ -1909,6 +1910,88 @@ static inline const char *cable_info_mad_err_str(u16 mad_status) return "Unknown Error"; } +static int mlx4_get_module_id(struct mlx4_dev *dev, u8 port, u8 *module_id) +{ + struct mlx4_cmd_mailbox *inbox, *outbox; + struct mlx4_mad_ifc *inmad, *outmad; + struct mlx4_cable_info *cable_info; + int ret; + + inbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(inbox)) + return PTR_ERR(inbox); + + outbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(outbox)) { + mlx4_free_cmd_mailbox(dev, inbox); + return PTR_ERR(outbox); + } + + inmad = (struct mlx4_mad_ifc *)(inbox->buf); + outmad = (struct mlx4_mad_ifc *)(outbox->buf); + + inmad->method = 0x1; /* Get */ + inmad->class_version = 0x1; + inmad->mgmt_class = 0x1; + inmad->base_version = 0x1; + inmad->attr_id = cpu_to_be16(0xFF60); /* Module Info */ + + cable_info = (struct mlx4_cable_info *)inmad->data; + cable_info->dev_mem_address = 0; + cable_info->page_num = 0; + cable_info->i2c_addr = I2C_ADDR_LOW; + cable_info->size = cpu_to_be16(1); + + ret = mlx4_cmd_box(dev, inbox->dma, outbox->dma, port, 3, + MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C, + MLX4_CMD_NATIVE); + if (ret) + goto out; + + if (be16_to_cpu(outmad->status)) { + /* Mad returned with bad status */ + ret = be16_to_cpu(outmad->status); + mlx4_warn(dev, + "MLX4_CMD_MAD_IFC Get Module ID attr(%x) port(%d) i2c_addr(%x) offset(%d) size(%d): Response Mad Status(%x) - %s\n", + 0xFF60, port, I2C_ADDR_LOW, 0, 1, ret, + cable_info_mad_err_str(ret)); + ret = -ret; + goto out; + } + cable_info = (struct mlx4_cable_info *)outmad->data; + *module_id = cable_info->data[0]; +out: + mlx4_free_cmd_mailbox(dev, inbox); + mlx4_free_cmd_mailbox(dev, outbox); + return ret; +} + +static void mlx4_sfp_eeprom_params_set(u8 *i2c_addr, u8 *page_num, u16 *offset) +{ + *i2c_addr = I2C_ADDR_LOW; + *page_num = 0; + + if (*offset < I2C_PAGE_SIZE) + return; + + *i2c_addr = I2C_ADDR_HIGH; + *offset -= I2C_PAGE_SIZE; +} + +static void mlx4_qsfp_eeprom_params_set(u8 *i2c_addr, u8 *page_num, u16 *offset) +{ + /* Offsets 0-255 belong to page 0. + * Offsets 256-639 belong to pages 01, 02, 03. + * For example, offset 400 is page 02: 1 + (400 - 256) / 128 = 2 + */ + if (*offset < I2C_PAGE_SIZE) + *page_num = 0; + else + *page_num = 1 + (*offset - I2C_PAGE_SIZE) / I2C_HIGH_PAGE_SIZE; + *i2c_addr = I2C_ADDR_LOW; + *offset -= *page_num * I2C_HIGH_PAGE_SIZE; +} + /** * mlx4_get_module_info - Read cable module eeprom data * @dev: mlx4_dev. @@ -1928,12 +2011,30 @@ int mlx4_get_module_info(struct mlx4_dev *dev, u8 port, struct mlx4_cmd_mailbox *inbox, *outbox; struct mlx4_mad_ifc *inmad, *outmad; struct mlx4_cable_info *cable_info; - u16 i2c_addr; + u8 module_id, i2c_addr, page_num; int ret; if (size > MODULE_INFO_MAX_READ) size = MODULE_INFO_MAX_READ; + ret = mlx4_get_module_id(dev, port, &module_id); + if (ret) + return ret; + + switch (module_id) { + case MLX4_MODULE_ID_SFP: + mlx4_sfp_eeprom_params_set(&i2c_addr, &page_num, &offset); + break; + case MLX4_MODULE_ID_QSFP: + case MLX4_MODULE_ID_QSFP_PLUS: + case MLX4_MODULE_ID_QSFP28: + mlx4_qsfp_eeprom_params_set(&i2c_addr, &page_num, &offset); + break; + default: + mlx4_err(dev, "Module ID not recognized: %#x\n", module_id); + return -EINVAL; + } + inbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(inbox)) return PTR_ERR(inbox); @@ -1959,11 +2060,9 @@ int mlx4_get_module_info(struct mlx4_dev *dev, u8 port, */ size -= offset + size - I2C_PAGE_SIZE; - i2c_addr = I2C_ADDR_LOW; - cable_info = (struct mlx4_cable_info *)inmad->data; cable_info->dev_mem_address = cpu_to_be16(offset); - cable_info->page_num = 0; + cable_info->page_num = page_num; cable_info->i2c_addr = i2c_addr; cable_info->size = cpu_to_be16(size); diff --git a/drivers/net/ethernet/micrel/ks8842.c b/drivers/net/ethernet/micrel/ks8842.c index cb0102dd7f70..d691c33dffc6 100644 --- a/drivers/net/ethernet/micrel/ks8842.c +++ b/drivers/net/ethernet/micrel/ks8842.c @@ -1150,6 +1150,10 @@ static int ks8842_probe(struct platform_device *pdev) unsigned i; iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!iomem) { + dev_err(&pdev->dev, "Invalid resource\n"); + return -EINVAL; + } if (!request_mem_region(iomem->start, resource_size(iomem), DRV_NAME)) goto err_mem_region; diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index 02ec326cb129..5eeba263b5f8 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c @@ -4050,6 +4050,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_err(&pdev->dev, "invalid sram_size %dB or board span %ldB\n", mgp->sram_size, mgp->board_span); + status = -EINVAL; goto abort_with_ioremap; } memcpy_fromio(mgp->eeprom_strings, diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index 3cd87a41ac92..cd59577a0c92 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -124,7 +124,7 @@ static int pch_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid) { u8 *data = skb->data; unsigned int offset; - u16 *hi, *id; + u16 hi, id; u32 lo; if (ptp_classify_raw(skb) == PTP_CLASS_NONE) @@ -135,14 +135,11 @@ static int pch_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid) if (skb->len < offset + OFF_PTP_SEQUENCE_ID + sizeof(seqid)) return 0; - hi = (u16 *)(data + offset + OFF_PTP_SOURCE_UUID); - id = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID); + hi = get_unaligned_be16(data + offset + OFF_PTP_SOURCE_UUID + 0); + lo = get_unaligned_be32(data + offset + OFF_PTP_SOURCE_UUID + 2); + id = get_unaligned_be16(data + offset + OFF_PTP_SEQUENCE_ID); - memcpy(&lo, &hi[1], sizeof(lo)); - - return (uid_hi == *hi && - uid_lo == lo && - seqid == *id); + return (uid_hi == hi && uid_lo == lo && seqid == id); } static void @@ -152,7 +149,6 @@ pch_rx_timestamp(struct pch_gbe_adapter *adapter, struct sk_buff *skb) struct pci_dev *pdev; u64 ns; u32 hi, lo, val; - u16 uid, seq; if (!adapter->hwts_rx_en) return; @@ -168,10 +164,7 @@ pch_rx_timestamp(struct pch_gbe_adapter *adapter, struct sk_buff *skb) lo = pch_src_uuid_lo_read(pdev); hi = pch_src_uuid_hi_read(pdev); - uid = hi & 0xffff; - seq = (hi >> 16) & 0xffff; - - if (!pch_ptp_match(skb, htons(uid), htonl(lo), htons(seq))) + if (!pch_ptp_match(skb, hi, lo, hi >> 16)) goto out; ns = pch_rx_snap_read(pdev); @@ -2617,9 +2610,13 @@ static int pch_gbe_probe(struct pci_dev *pdev, adapter->pdev = pdev; adapter->hw.back = adapter; adapter->hw.reg = pcim_iomap_table(pdev)[PCH_GBE_PCI_BAR]; + adapter->pdata = (struct pch_gbe_privdata *)pci_id->driver_data; - if (adapter->pdata && adapter->pdata->platform_init) - adapter->pdata->platform_init(pdev); + if (adapter->pdata && adapter->pdata->platform_init) { + ret = adapter->pdata->platform_init(pdev); + if (ret) + goto err_free_netdev; + } adapter->ptp_pdev = pci_get_bus_and_slot(adapter->pdev->bus->number, PCI_DEVFN(12, 4)); @@ -2709,7 +2706,7 @@ err_free_netdev: */ static int pch_gbe_minnow_platform_init(struct pci_dev *pdev) { - unsigned long flags = GPIOF_DIR_OUT | GPIOF_INIT_HIGH | GPIOF_EXPORT; + unsigned long flags = GPIOF_OUT_INIT_HIGH; unsigned gpio = MINNOW_PHY_RESET_GPIO; int ret; diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index a5ee3d328f3d..75e25a3fe4a7 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -1617,6 +1617,8 @@ err_out_free_netdev: free_netdev(netdev); err_out_free_res: + if (NX_IS_REVISION_P3(pdev->revision)) + pci_disable_pcie_error_reporting(pdev); pci_release_regions(pdev); err_out_disable_pdev: diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c index 7b6824e560d2..59e59878a3a7 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c @@ -1205,9 +1205,11 @@ int qed_dcbx_get_config_params(struct qed_hwfn *p_hwfn, p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_IEEE; p_hwfn->p_dcbx_info->set.enabled = dcbx_info->operational.enabled; + BUILD_BUG_ON(sizeof(dcbx_info->operational.params) != + sizeof(p_hwfn->p_dcbx_info->set.config.params)); memcpy(&p_hwfn->p_dcbx_info->set.config.params, &dcbx_info->operational.params, - sizeof(struct qed_dcbx_admin_params)); + sizeof(p_hwfn->p_dcbx_info->set.config.params)); p_hwfn->p_dcbx_info->set.config.valid = true; memcpy(params, &p_hwfn->p_dcbx_info->set, sizeof(struct qed_dcbx_set)); diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c index f2cb77c3b199..192950a112c9 100644 --- a/drivers/net/ethernet/qlogic/qla3xxx.c +++ b/drivers/net/ethernet/qlogic/qla3xxx.c @@ -115,7 +115,7 @@ static int ql_sem_spinlock(struct ql3_adapter *qdev, value = readl(&port_regs->CommonRegs.semaphoreReg); if ((value & (sem_mask >> 16)) == sem_bits) return 0; - ssleep(1); + mdelay(1000); } while (--seconds); return -1; } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index 63ebc491057b..99fc0121da93 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c @@ -1039,7 +1039,7 @@ int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode) for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) { skb = netdev_alloc_skb(adapter->netdev, QLCNIC_ILB_PKT_SIZE); if (!skb) - break; + goto error; qlcnic_create_loopback_buff(skb->data, adapter->mac_addr); skb_put(skb, QLCNIC_ILB_PKT_SIZE); adapter->ahw->diag_cnt = 0; @@ -1063,6 +1063,7 @@ int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode) cnt++; } if (cnt != i) { +error: dev_err(&adapter->pdev->dev, "LB Test: failed, TX[%d], RX[%d]\n", i, cnt); if (mode != QLCNIC_ILB_MODE) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 0928da21efd0..19dca845042e 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -2707,6 +2707,7 @@ err_out_free_hw_res: kfree(ahw); err_out_free_res: + pci_disable_pcie_error_reporting(pdev); pci_release_regions(pdev); err_out_disable_pdev: diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 3521e3a77556..f321b115719a 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -2338,7 +2338,7 @@ static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data) { switch(stringset) { case ETH_SS_STATS: - memcpy(data, *rtl8169_gstrings, sizeof(rtl8169_gstrings)); + memcpy(data, rtl8169_gstrings, sizeof(rtl8169_gstrings)); break; } } diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 0e5b1935af50..468f02beccee 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -2117,7 +2117,7 @@ static void sh_eth_get_strings(struct net_device *ndev, u32 stringset, u8 *data) { switch (stringset) { case ETH_SS_STATS: - memcpy(data, *sh_eth_gstrings_stats, + memcpy(data, sh_eth_gstrings_stats, sizeof(sh_eth_gstrings_stats)); break; } diff --git a/drivers/net/ethernet/sfc/ef10_sriov.c b/drivers/net/ethernet/sfc/ef10_sriov.c index a949b9d27329..bef23e19cbbd 100644 --- a/drivers/net/ethernet/sfc/ef10_sriov.c +++ b/drivers/net/ethernet/sfc/ef10_sriov.c @@ -405,12 +405,17 @@ fail1: return rc; } +/* Disable SRIOV and remove VFs + * If some VFs are attached to a guest (using Xen, only) nothing is + * done if force=false, and vports are freed if force=true (for the non + * attachedc ones, only) but SRIOV is not disabled and VFs are not + * removed in either case. + */ static int efx_ef10_pci_sriov_disable(struct efx_nic *efx, bool force) { struct pci_dev *dev = efx->pci_dev; - unsigned int vfs_assigned = 0; - - vfs_assigned = pci_vfs_assigned(dev); + unsigned int vfs_assigned = pci_vfs_assigned(dev); + int rc = 0; if (vfs_assigned && !force) { netif_info(efx, drv, efx->net_dev, "VFs are assigned to guests; " @@ -420,10 +425,12 @@ static int efx_ef10_pci_sriov_disable(struct efx_nic *efx, bool force) if (!vfs_assigned) pci_disable_sriov(dev); + else + rc = -EBUSY; efx_ef10_sriov_free_vf_vswitching(efx); efx->vf_count = 0; - return 0; + return rc; } int efx_ef10_sriov_configure(struct efx_nic *efx, int num_vfs) @@ -442,7 +449,6 @@ int efx_ef10_sriov_init(struct efx_nic *efx) void efx_ef10_sriov_fini(struct efx_nic *efx) { struct efx_ef10_nic_data *nic_data = efx->nic_data; - unsigned int i; int rc; if (!nic_data->vf) { @@ -452,14 +458,7 @@ void efx_ef10_sriov_fini(struct efx_nic *efx) return; } - /* Remove any VFs in the host */ - for (i = 0; i < efx->vf_count; ++i) { - struct efx_nic *vf_efx = nic_data->vf[i].efx; - - if (vf_efx) - vf_efx->pci_dev->driver->remove(vf_efx->pci_dev); - } - + /* Disable SRIOV and remove any VFs in the host */ rc = efx_ef10_pci_sriov_disable(efx, true); if (rc) netif_dbg(efx, drv, efx->net_dev, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c index fc1fa0f9f338..fe4128405bbb 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c @@ -39,7 +39,7 @@ struct sunxi_priv_data { static int sun7i_gmac_init(struct platform_device *pdev, void *priv) { struct sunxi_priv_data *gmac = priv; - int ret; + int ret = 0; if (gmac->regulator) { ret = regulator_enable(gmac->regulator); @@ -60,11 +60,11 @@ static int sun7i_gmac_init(struct platform_device *pdev, void *priv) } else { clk_set_rate(gmac->tx_clk, SUN7I_GMAC_MII_RATE); ret = clk_prepare(gmac->tx_clk); - if (ret) - return ret; + if (ret && gmac->regulator) + regulator_disable(gmac->regulator); } - return 0; + return ret; } static void sun7i_gmac_exit(struct platform_device *pdev, void *priv) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h index ff3e5ab39bd0..24fb7a2bba62 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h @@ -91,10 +91,10 @@ enum power_event { #define LPI_CTRL_STATUS_TLPIEN 0x00000001 /* Transmit LPI Entry */ /* GMAC HW ADDR regs */ -#define GMAC_ADDR_HIGH(reg) (((reg > 15) ? 0x00000800 : 0x00000040) + \ - (reg * 8)) -#define GMAC_ADDR_LOW(reg) (((reg > 15) ? 0x00000804 : 0x00000044) + \ - (reg * 8)) +#define GMAC_ADDR_HIGH(reg) ((reg > 15) ? 0x00000800 + (reg - 16) * 8 : \ + 0x00000040 + (reg * 8)) +#define GMAC_ADDR_LOW(reg) ((reg > 15) ? 0x00000804 + (reg - 16) * 8 : \ + 0x00000044 + (reg * 8)) #define GMAC_MAX_PERFECT_ADDRESSES 1 #define GMAC_PCS_BASE 0x000000c0 /* PCS register base */ diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index 5bf47279f9c1..306d5d08141e 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -8166,10 +8166,10 @@ static int niu_pci_vpd_scan_props(struct niu *np, u32 start, u32 end) "VPD_SCAN: Reading in property [%s] len[%d]\n", namebuf, prop_len); for (i = 0; i < prop_len; i++) { - err = niu_pci_eeprom_read(np, off + i); - if (err >= 0) - *prop_buf = err; - ++prop_buf; + err = niu_pci_eeprom_read(np, off + i); + if (err < 0) + return err; + *prop_buf++ = err; } } @@ -8180,14 +8180,14 @@ static int niu_pci_vpd_scan_props(struct niu *np, u32 start, u32 end) } /* ESPC_PIO_EN_ENABLE must be set */ -static void niu_pci_vpd_fetch(struct niu *np, u32 start) +static int niu_pci_vpd_fetch(struct niu *np, u32 start) { u32 offset; int err; err = niu_pci_eeprom_read16_swp(np, start + 1); if (err < 0) - return; + return err; offset = err + 3; @@ -8196,12 +8196,14 @@ static void niu_pci_vpd_fetch(struct niu *np, u32 start) u32 end; err = niu_pci_eeprom_read(np, here); + if (err < 0) + return err; if (err != 0x90) - return; + return -EINVAL; err = niu_pci_eeprom_read16_swp(np, here + 1); if (err < 0) - return; + return err; here = start + offset + 3; end = start + offset + err; @@ -8209,9 +8211,12 @@ static void niu_pci_vpd_fetch(struct niu *np, u32 start) offset += err; err = niu_pci_vpd_scan_props(np, here, end); - if (err < 0 || err == 1) - return; + if (err < 0) + return err; + if (err == 1) + return -EINVAL; } + return 0; } /* ESPC_PIO_EN_ENABLE must be set */ @@ -9304,8 +9309,11 @@ static int niu_get_invariants(struct niu *np) offset = niu_pci_vpd_offset(np); netif_printk(np, probe, KERN_DEBUG, np->dev, "%s() VPD offset [%08x]\n", __func__, offset); - if (offset) - niu_pci_vpd_fetch(np, offset); + if (offset) { + err = niu_pci_vpd_fetch(np, offset); + if (err < 0) + return err; + } nw64(ESPC_PIO_EN, 0); if (np->flags & NIU_FLAGS_VPD_VALID) { diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c index 32516661f180..c17967b23d3c 100644 --- a/drivers/net/ethernet/ti/netcp_core.c +++ b/drivers/net/ethernet/ti/netcp_core.c @@ -1325,9 +1325,9 @@ int netcp_txpipe_open(struct netcp_tx_pipe *tx_pipe) tx_pipe->dma_queue = knav_queue_open(name, tx_pipe->dma_queue_id, KNAV_QUEUE_SHARED); if (IS_ERR(tx_pipe->dma_queue)) { + ret = PTR_ERR(tx_pipe->dma_queue); dev_err(dev, "Could not open DMA queue for channel \"%s\": %d\n", name, ret); - ret = PTR_ERR(tx_pipe->dma_queue); goto err; } diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index 545f60877bb7..9ba36c930ce3 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -735,6 +735,11 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) /* Kick off the transfer */ lp->dma_out(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */ + if (temac_check_tx_bd_space(lp, MAX_SKB_FRAGS + 1)) { + netdev_info(ndev, "%s -> netif_stop_queue\n", __func__); + netif_stop_queue(ndev); + } + return NETDEV_TX_OK; } diff --git a/drivers/net/fjes/fjes_main.c b/drivers/net/fjes/fjes_main.c index 3511d40ba3f1..440047a239f5 100644 --- a/drivers/net/fjes/fjes_main.c +++ b/drivers/net/fjes/fjes_main.c @@ -1212,6 +1212,10 @@ static int fjes_probe(struct platform_device *plat_dev) adapter->interrupt_watch_enable = false; res = platform_get_resource(plat_dev, IORESOURCE_MEM, 0); + if (!res) { + err = -EINVAL; + goto err_free_control_wq; + } hw->hw_res.start = res->start; hw->hw_res.size = resource_size(res); hw->hw_res.irq = platform_get_irq(plat_dev, 0); diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 088fe5d34f50..76340bc3cf44 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -810,6 +810,7 @@ static void mkiss_close(struct tty_struct *tty) ax->tty = NULL; unregister_netdev(ax->dev); + free_netdev(ax->dev); } /* Perform I/O control on an active ax25 channel. */ diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c index ab6914f8bd50..1da104150f44 100644 --- a/drivers/net/phy/mdio-octeon.c +++ b/drivers/net/phy/mdio-octeon.c @@ -75,7 +75,6 @@ static int octeon_mdiobus_probe(struct platform_device *pdev) return 0; fail_register: - mdiobus_free(bus->mii_bus); smi_en.u64 = 0; oct_mdio_writeq(smi_en.u64, bus->register_base + SMI_EN); return err; @@ -89,7 +88,6 @@ static int octeon_mdiobus_remove(struct platform_device *pdev) bus = platform_get_drvdata(pdev); mdiobus_unregister(bus->mii_bus); - mdiobus_free(bus->mii_bus); smi_en.u64 = 0; oct_mdio_writeq(smi_en.u64, bus->register_base + SMI_EN); return 0; diff --git a/drivers/net/phy/mdio-thunder.c b/drivers/net/phy/mdio-thunder.c index 564616968cad..c0c922eff760 100644 --- a/drivers/net/phy/mdio-thunder.c +++ b/drivers/net/phy/mdio-thunder.c @@ -129,7 +129,6 @@ static void thunder_mdiobus_pci_remove(struct pci_dev *pdev) continue; mdiobus_unregister(bus->mii_bus); - mdiobus_free(bus->mii_bus); oct_mdio_writeq(0, bus->register_base + SMI_EN); } pci_set_drvdata(pdev, NULL); diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index a9bbdcec0bad..8cc7563ab103 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -362,7 +362,8 @@ void mdiobus_unregister(struct mii_bus *bus) struct mdio_device *mdiodev; int i; - BUG_ON(bus->state != MDIOBUS_REGISTERED); + if (WARN_ON_ONCE(bus->state != MDIOBUS_REGISTERED)) + return; bus->state = MDIOBUS_UNREGISTERED; for (i = 0; i < PHY_MAX_ADDR; i++) { diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c index f7180f8db39e..9c15e1a1261b 100644 --- a/drivers/net/usb/cdc_eem.c +++ b/drivers/net/usb/cdc_eem.c @@ -138,10 +138,10 @@ static struct sk_buff *eem_tx_fixup(struct usbnet *dev, struct sk_buff *skb, } skb2 = skb_copy_expand(skb, EEM_HEAD, ETH_FCS_LEN + padlen, flags); + dev_kfree_skb_any(skb); if (!skb2) return NULL; - dev_kfree_skb_any(skb); skb = skb2; done: diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index d418542924e1..5a5db2f09f78 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -1563,6 +1563,15 @@ cdc_ncm_speed_change(struct usbnet *dev, uint32_t rx_speed = le32_to_cpu(data->DLBitRRate); uint32_t tx_speed = le32_to_cpu(data->ULBitRate); + /* if the speed hasn't changed, don't report it. + * RTL8156 shipped before 2021 sends notification about every 32ms. + */ + if (dev->rx_speed == rx_speed && dev->tx_speed == tx_speed) + return; + + dev->rx_speed = rx_speed; + dev->tx_speed = tx_speed; + /* * Currently the USB-NET API does not support reporting the actual * device speed. Do print it instead. @@ -1606,7 +1615,8 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb) * USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be * sent by device after USB_CDC_NOTIFY_SPEED_CHANGE. */ - usbnet_link_change(dev, !!event->wValue, 0); + if (netif_carrier_ok(dev->net) != !!event->wValue) + usbnet_link_change(dev, !!event->wValue, 0); break; case USB_CDC_NOTIFY_SPEED_CHANGE: @@ -1629,7 +1639,7 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb) static const struct driver_info cdc_ncm_info = { .description = "CDC NCM", .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET - | FLAG_LINK_INTR, + | FLAG_LINK_INTR | FLAG_ETHER, .bind = cdc_ncm_bind, .unbind = cdc_ncm_unbind, .manage_power = usbnet_manage_power, diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 6ecccc737974..5066b7bc67da 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1703,7 +1703,7 @@ static int hso_serial_tiocmset(struct tty_struct *tty, spin_unlock_irqrestore(&serial->serial_lock, flags); return usb_control_msg(serial->parent->usb, - usb_rcvctrlpipe(serial->parent->usb, 0), 0x22, + usb_sndctrlpipe(serial->parent->usb, 0), 0x22, 0x21, val, if_num, NULL, 0, USB_CTRL_SET_TIMEOUT); } @@ -2451,7 +2451,7 @@ static int hso_rfkill_set_block(void *data, bool blocked) if (hso_dev->usb_gone) rv = 0; else - rv = usb_control_msg(hso_dev->usb, usb_rcvctrlpipe(hso_dev->usb, 0), + rv = usb_control_msg(hso_dev->usb, usb_sndctrlpipe(hso_dev->usb, 0), enabled ? 0x82 : 0x81, 0x40, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); mutex_unlock(&hso_dev->mutex); diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 6e74965d26a0..64fdea332886 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -3938,7 +3938,7 @@ static void rtl8152_get_strings(struct net_device *dev, u32 stringset, u8 *data) { switch (stringset) { case ETH_SS_STATS: - memcpy(data, *rtl8152_gstrings, sizeof(rtl8152_gstrings)); + memcpy(data, rtl8152_gstrings, sizeof(rtl8152_gstrings)); break; } } diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 977d9c772554..841d97491592 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -1497,7 +1497,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) ret = smsc75xx_wait_ready(dev, 0); if (ret < 0) { netdev_warn(dev->net, "device not ready in smsc75xx_bind\n"); - return ret; + goto free_pdata; } smsc75xx_init_mac_address(dev); @@ -1506,7 +1506,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) ret = smsc75xx_reset(dev); if (ret < 0) { netdev_warn(dev->net, "smsc75xx_reset error %d\n", ret); - return ret; + goto cancel_work; } dev->net->netdev_ops = &smsc75xx_netdev_ops; @@ -1515,6 +1515,13 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD; dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; return 0; + +cancel_work: + cancel_work_sync(&pdata->set_multicast); +free_pdata: + kfree(pdata); + dev->data[0] = 0; + return ret; } static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf) @@ -1524,7 +1531,6 @@ static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf) cancel_work_sync(&pdata->set_multicast); netif_dbg(dev, ifdown, dev->net, "free pdata\n"); kfree(pdata); - pdata = NULL; dev->data[0] = 0; } } diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 088bb5870ac5..0bfadec8b79c 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -1594,6 +1594,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb) struct neighbour *n; struct inet6_dev *in6_dev; + rcu_read_lock(); in6_dev = __in6_dev_get(dev); if (!in6_dev) goto out; @@ -1650,6 +1651,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb) } out: + rcu_read_unlock(); consume_skb(skb); return NETDEV_TX_OK; } diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 3cbc71fa70d1..381bff3a2103 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -1582,14 +1582,62 @@ static void ath10k_htt_rx_h_unchain(struct ath10k *ar, ath10k_unchain_msdu(amsdu); } +static bool ath10k_htt_rx_validate_amsdu(struct ath10k *ar, + struct sk_buff_head *amsdu) +{ + u8 *subframe_hdr; + struct sk_buff *first; + bool is_first, is_last; + struct htt_rx_desc *rxd; + struct ieee80211_hdr *hdr; + size_t hdr_len, crypto_len; + enum htt_rx_mpdu_encrypt_type enctype; + int bytes_aligned = ar->hw_params.decap_align_bytes; + + first = skb_peek(amsdu); + + rxd = (void *)first->data - sizeof(*rxd); + hdr = (void *)rxd->rx_hdr_status; + + is_first = !!(rxd->msdu_end.common.info0 & + __cpu_to_le32(RX_MSDU_END_INFO0_FIRST_MSDU)); + is_last = !!(rxd->msdu_end.common.info0 & + __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU)); + + /* Return in case of non-aggregated msdu */ + if (is_first && is_last) + return true; + + /* First msdu flag is not set for the first msdu of the list */ + if (!is_first) + return false; + + enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), + RX_MPDU_START_INFO0_ENCRYPT_TYPE); + + hdr_len = ieee80211_hdrlen(hdr->frame_control); + crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype); + + subframe_hdr = (u8 *)hdr + round_up(hdr_len, bytes_aligned) + + crypto_len; + + /* Validate if the amsdu has a proper first subframe. + * There are chances a single msdu can be received as amsdu when + * the unauthenticated amsdu flag of a QoS header + * gets flipped in non-SPP AMSDU's, in such cases the first + * subframe has llc/snap header in place of a valid da. + * return false if the da matches rfc1042 pattern + */ + if (ether_addr_equal(subframe_hdr, rfc1042_header)) + return false; + + return true; +} + static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, struct sk_buff_head *amsdu, struct ieee80211_rx_status *rx_status) { - /* FIXME: It might be a good idea to do some fuzzy-testing to drop - * invalid/dangerous frames. - */ - if (!rx_status->freq) { ath10k_warn(ar, "no channel configured; ignoring frame(s)!\n"); return false; @@ -1600,6 +1648,11 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, return false; } + if (!ath10k_htt_rx_validate_amsdu(ar, amsdu)) { + ath10k_dbg(ar, ATH10K_DBG_HTT, "invalid amsdu received\n"); + return false; + } + return true; } diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 564181bb0906..314cac2ce087 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -4947,6 +4947,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, if (arvif->nohwcrypt && !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) { + ret = -EINVAL; ath10k_warn(ar, "cryptmode module param needed for sw crypto\n"); goto err; } diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 58af2fe5be3c..454bf16d6b30 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -302,6 +302,11 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) hchan = ah->curchan; } + if (!hchan) { + fastcc = false; + hchan = ath9k_cmn_get_channel(sc->hw, ah, &sc->cur_chan->chandef); + } + if (!ath_prepare_reset(sc)) fastcc = false; diff --git a/drivers/net/wireless/ath/carl9170/Kconfig b/drivers/net/wireless/ath/carl9170/Kconfig index 2e34baeaf764..2b782db20fde 100644 --- a/drivers/net/wireless/ath/carl9170/Kconfig +++ b/drivers/net/wireless/ath/carl9170/Kconfig @@ -15,13 +15,11 @@ config CARL9170 config CARL9170_LEDS bool "SoftLED Support" - depends on CARL9170 - select MAC80211_LEDS - select LEDS_CLASS - select NEW_LEDS default y + depends on CARL9170 + depends on MAC80211_LEDS help - This option is necessary, if you want your device' LEDs to blink + This option is necessary, if you want your device's LEDs to blink. Say Y, unless you need the LEDs for firmware debugging. diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c index b820e80d4b4c..8b56aa627487 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c @@ -1221,6 +1221,7 @@ static int brcms_bcma_probe(struct bcma_device *pdev) { struct brcms_info *wl; struct ieee80211_hw *hw; + int ret; dev_info(&pdev->dev, "mfg %x core %x rev %d class %d irq %d\n", pdev->id.manuf, pdev->id.id, pdev->id.rev, pdev->id.class, @@ -1245,11 +1246,16 @@ static int brcms_bcma_probe(struct bcma_device *pdev) wl = brcms_attach(pdev); if (!wl) { pr_err("%s: brcms_attach failed!\n", __func__); - return -ENODEV; + ret = -ENODEV; + goto err_free_ieee80211; } brcms_led_register(wl); return 0; + +err_free_ieee80211: + ieee80211_free_hw(hw); + return ret; } static int brcms_suspend(struct bcma_device *pdev) diff --git a/drivers/net/wireless/marvell/libertas/mesh.c b/drivers/net/wireless/marvell/libertas/mesh.c index d0c881dd5846..f1e9cbcfdc16 100644 --- a/drivers/net/wireless/marvell/libertas/mesh.c +++ b/drivers/net/wireless/marvell/libertas/mesh.c @@ -797,19 +797,6 @@ static const struct attribute_group mesh_ie_group = { .attrs = mesh_ie_attrs, }; -static void lbs_persist_config_init(struct net_device *dev) -{ - int ret; - ret = sysfs_create_group(&(dev->dev.kobj), &boot_opts_group); - ret = sysfs_create_group(&(dev->dev.kobj), &mesh_ie_group); -} - -static void lbs_persist_config_remove(struct net_device *dev) -{ - sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group); - sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group); -} - /*************************************************************************** * Initializing and starting, stopping mesh @@ -1021,6 +1008,10 @@ static int lbs_add_mesh(struct lbs_private *priv) SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent); mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST; + mesh_dev->sysfs_groups[0] = &lbs_mesh_attr_group; + mesh_dev->sysfs_groups[1] = &boot_opts_group; + mesh_dev->sysfs_groups[2] = &mesh_ie_group; + /* Register virtual mesh interface */ ret = register_netdev(mesh_dev); if (ret) { @@ -1028,19 +1019,10 @@ static int lbs_add_mesh(struct lbs_private *priv) goto err_free_netdev; } - ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group); - if (ret) - goto err_unregister; - - lbs_persist_config_init(mesh_dev); - /* Everything successful */ ret = 0; goto done; -err_unregister: - unregister_netdev(mesh_dev); - err_free_netdev: free_netdev(mesh_dev); @@ -1063,8 +1045,6 @@ void lbs_remove_mesh(struct lbs_private *priv) lbs_deb_enter(LBS_DEB_MESH); netif_stop_queue(mesh_dev); netif_carrier_off(mesh_dev); - sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group); - lbs_persist_config_remove(mesh_dev); unregister_netdev(mesh_dev); priv->mesh_dev = NULL; kfree(mesh_dev->ieee80211_ptr); diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c index 7de18ed10db8..e1992de500b0 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.c +++ b/drivers/net/wireless/realtek/rtlwifi/base.c @@ -454,9 +454,14 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw) } } -static void _rtl_init_deferred_work(struct ieee80211_hw *hw) +static int _rtl_init_deferred_work(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); + struct workqueue_struct *wq; + + wq = alloc_workqueue("%s", 0, 0, rtlpriv->cfg->name); + if (!wq) + return -ENOMEM; /* <1> timer */ setup_timer(&rtlpriv->works.watchdog_timer, @@ -465,11 +470,7 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw) rtl_easy_concurrent_retrytimer_callback, (unsigned long)hw); /* <2> work queue */ rtlpriv->works.hw = hw; - rtlpriv->works.rtl_wq = alloc_workqueue("%s", 0, 0, rtlpriv->cfg->name); - if (unlikely(!rtlpriv->works.rtl_wq)) { - pr_err("Failed to allocate work queue\n"); - return; - } + rtlpriv->works.rtl_wq = wq; INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq, (void *)rtl_watchdog_wq_callback); @@ -481,7 +482,7 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw) (void *)rtl_swlps_rfon_wq_callback); INIT_DELAYED_WORK(&rtlpriv->works.fwevt_wq, (void *)rtl_fwevt_wq_callback); - + return 0; } void rtl_deinit_deferred_work(struct ieee80211_hw *hw) @@ -573,9 +574,7 @@ int rtl_init_core(struct ieee80211_hw *hw) rtlmac->link_state = MAC80211_NOLINK; /* <6> init deferred work */ - _rtl_init_deferred_work(hw); - - return 0; + return _rtl_init_deferred_work(hw); } EXPORT_SYMBOL_GPL(rtl_init_core); diff --git a/drivers/net/wireless/st/cw1200/cw1200_sdio.c b/drivers/net/wireless/st/cw1200/cw1200_sdio.c index d3acc85932a5..de92107549ee 100644 --- a/drivers/net/wireless/st/cw1200/cw1200_sdio.c +++ b/drivers/net/wireless/st/cw1200/cw1200_sdio.c @@ -62,6 +62,7 @@ static const struct sdio_device_id cw1200_sdio_ids[] = { { SDIO_DEVICE(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200) }, { /* end: all zeroes */ }, }; +MODULE_DEVICE_TABLE(sdio, cw1200_sdio_ids); /* hwbus_ops implemetation */ diff --git a/drivers/net/wireless/ti/wl1251/cmd.c b/drivers/net/wireless/ti/wl1251/cmd.c index ede31f048ef9..247f4310a38f 100644 --- a/drivers/net/wireless/ti/wl1251/cmd.c +++ b/drivers/net/wireless/ti/wl1251/cmd.c @@ -465,9 +465,12 @@ int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len, cmd->channels[i].channel = channels[i]->hw_value; } - cmd->params.ssid_len = ssid_len; - if (ssid) - memcpy(cmd->params.ssid, ssid, ssid_len); + if (ssid) { + int len = clamp_val(ssid_len, 0, IEEE80211_MAX_SSID_LEN); + + cmd->params.ssid_len = len; + memcpy(cmd->params.ssid, ssid, len); + } ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd)); if (ret < 0) { diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 9bd635ec7827..72991d3a55f1 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1516,6 +1516,13 @@ static int wl12xx_get_fuse_mac(struct wl1271 *wl) u32 mac1, mac2; int ret; + /* Device may be in ELP from the bootloader or kexec */ + ret = wlcore_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); + if (ret < 0) + goto out; + + usleep_range(500000, 700000); + ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]); if (ret < 0) goto out; diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 744f6250dc98..69d2eeb75b8b 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -607,11 +607,11 @@ static int __init __reserved_mem_reserve_reg(unsigned long node, if (size && early_init_dt_reserve_memory_arch(base, size, nomap) == 0) - pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n", - uname, &base, (unsigned long)size / SZ_1M); + pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n", + uname, &base, (unsigned long)(size / SZ_1M)); else - pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %ld MiB\n", - uname, &base, (unsigned long)size / SZ_1M); + pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n", + uname, &base, (unsigned long)(size / SZ_1M)); len -= t_len; if (first) { diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index fc461b98e69b..2f72b86555bc 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -161,9 +161,9 @@ static int __init __reserved_mem_alloc_size(unsigned long node, ret = early_init_dt_alloc_reserved_memory_arch(size, align, start, end, nomap, &base); if (ret == 0) { - pr_debug("allocated memory for '%s' node: base %pa, size %ld MiB\n", + pr_debug("allocated memory for '%s' node: base %pa, size %lu MiB\n", uname, &base, - (unsigned long)size / SZ_1M); + (unsigned long)(size / SZ_1M)); break; } len -= t_len; @@ -173,8 +173,8 @@ static int __init __reserved_mem_alloc_size(unsigned long node, ret = early_init_dt_alloc_reserved_memory_arch(size, align, 0, 0, nomap, &base); if (ret == 0) - pr_debug("allocated memory for '%s' node: base %pa, size %ld MiB\n", - uname, &base, (unsigned long)size / SZ_1M); + pr_debug("allocated memory for '%s' node: base %pa, size %lu MiB\n", + uname, &base, (unsigned long)(size / SZ_1M)); } if (base == 0) { diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c index 51357377efbc..ac169cf0fa02 100644 --- a/drivers/pci/pci-label.c +++ b/drivers/pci/pci-label.c @@ -157,7 +157,7 @@ static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf) len = utf16s_to_utf8s((const wchar_t *)obj->buffer.pointer, obj->buffer.length, UTF16_LITTLE_ENDIAN, - buf, PAGE_SIZE); + buf, PAGE_SIZE - 1); buf[len] = '\n'; } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index acd89fa9820c..e09653c73ab4 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1378,11 +1378,21 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) int err; int i, bars = 0; - if (atomic_inc_return(&dev->enable_cnt) > 1) { - pci_update_current_state(dev, dev->current_state); - return 0; /* already enabled */ + /* + * Power state could be unknown at this point, either due to a fresh + * boot or a device removal call. So get the current power state + * so that things like MSI message writing will behave as expected + * (e.g. if the device really is in D0 at enable time). + */ + if (dev->pm_cap) { + u16 pmcsr; + pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); + dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); } + if (atomic_inc_return(&dev->enable_cnt) > 1) + return 0; /* already enabled */ + bridge = pci_upstream_bridge(dev); if (bridge) pci_enable_bridge(bridge); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 0ebf7500e171..096ba11ac105 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3345,6 +3345,18 @@ static void quirk_no_bus_reset(struct pci_dev *dev) dev->dev_flags |= PCI_DEV_FLAGS_NO_BUS_RESET; } +/* + * Some NVIDIA GPU devices do not work with bus reset, SBR needs to be + * prevented for those affected devices. + */ +static void quirk_nvidia_no_bus_reset(struct pci_dev *dev) +{ + if ((dev->device & 0xffc0) == 0x2340) + quirk_no_bus_reset(dev); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, + quirk_nvidia_no_bus_reset); + /* * Some Atheros AR9xxx and QCA988x chips do not behave after a bus reset. * The device will throw a Link Down error on AER-capable systems and @@ -3358,6 +3370,16 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003c, quirk_no_bus_reset); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0033, quirk_no_bus_reset); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0034, quirk_no_bus_reset); +/* + * Some TI KeyStone C667X devices do not support bus/hot reset. The PCIESS + * automatically disables LTSSM when Secondary Bus Reset is received and + * the device stops working. Prevent bus reset for these devices. With + * this change, the device can be assigned to VMs with VFIO, but it will + * leak state between VMs. Reference + * https://e2e.ti.com/support/processors/f/791/t/954382 + */ +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, 0xb005, quirk_no_bus_reset); + static void quirk_no_pm_reset(struct pci_dev *dev) { /* diff --git a/drivers/phy/phy-dm816x-usb.c b/drivers/phy/phy-dm816x-usb.c index cbcce7cf0028..2ed5fe20d779 100644 --- a/drivers/phy/phy-dm816x-usb.c +++ b/drivers/phy/phy-dm816x-usb.c @@ -246,19 +246,28 @@ static int dm816x_usb_phy_probe(struct platform_device *pdev) pm_runtime_enable(phy->dev); generic_phy = devm_phy_create(phy->dev, NULL, &ops); - if (IS_ERR(generic_phy)) - return PTR_ERR(generic_phy); + if (IS_ERR(generic_phy)) { + error = PTR_ERR(generic_phy); + goto clk_unprepare; + } phy_set_drvdata(generic_phy, phy); phy_provider = devm_of_phy_provider_register(phy->dev, of_phy_simple_xlate); - if (IS_ERR(phy_provider)) - return PTR_ERR(phy_provider); + if (IS_ERR(phy_provider)) { + error = PTR_ERR(phy_provider); + goto clk_unprepare; + } usb_add_phy_dev(&phy->phy); return 0; + +clk_unprepare: + pm_runtime_disable(phy->dev); + clk_unprepare(phy->refclk); + return error; } static int dm816x_usb_phy_remove(struct platform_device *pdev) diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index 1bb2493ad1d0..c762caba551f 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -896,6 +896,7 @@ static int amd_gpio_remove(struct platform_device *pdev) static const struct acpi_device_id amd_gpio_acpi_match[] = { { "AMD0030", 0 }, { "AMDI0030", 0}, + { "AMDI0031", 0}, { }, }; MODULE_DEVICE_TABLE(acpi, amd_gpio_acpi_match); diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index abd9d83f6009..403d966223ee 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c @@ -101,6 +101,9 @@ MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids); static int lis3lv02d_acpi_init(struct lis3lv02d *lis3) { struct acpi_device *dev = lis3->bus_priv; + if (!lis3->init_required) + return 0; + if (acpi_evaluate_object(dev->handle, METHOD_NAME__INI, NULL, NULL) != AE_OK) return -EINVAL; @@ -366,6 +369,7 @@ static int lis3lv02d_add(struct acpi_device *device) } /* call the core layer do its init */ + lis3_dev.init_required = true; ret = lis3lv02d_init_device(&lis3_dev); if (ret) return ret; @@ -413,11 +417,27 @@ static int lis3lv02d_suspend(struct device *dev) static int lis3lv02d_resume(struct device *dev) { + lis3_dev.init_required = false; lis3lv02d_poweron(&lis3_dev); return 0; } -static SIMPLE_DEV_PM_OPS(hp_accel_pm, lis3lv02d_suspend, lis3lv02d_resume); +static int lis3lv02d_restore(struct device *dev) +{ + lis3_dev.init_required = true; + lis3lv02d_poweron(&lis3_dev); + return 0; +} + +static const struct dev_pm_ops hp_accel_pm = { + .suspend = lis3lv02d_suspend, + .resume = lis3lv02d_resume, + .freeze = lis3lv02d_suspend, + .thaw = lis3lv02d_resume, + .poweroff = lis3lv02d_suspend, + .restore = lis3lv02d_restore, +}; + #define HP_ACCEL_PM (&hp_accel_pm) #else #define HP_ACCEL_PM NULL diff --git a/drivers/platform/x86/intel_punit_ipc.c b/drivers/platform/x86/intel_punit_ipc.c index b7dfe06261f1..9865d11eda75 100644 --- a/drivers/platform/x86/intel_punit_ipc.c +++ b/drivers/platform/x86/intel_punit_ipc.c @@ -330,6 +330,7 @@ static const struct acpi_device_id punit_ipc_acpi_ids[] = { { "INT34D4", 0 }, { } }; +MODULE_DEVICE_TABLE(acpi, punit_ipc_acpi_ids); static struct platform_driver intel_punit_ipc_driver = { .probe = intel_punit_ipc_probe, diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index f25278bb3e1a..90b17cf74e9f 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -2866,6 +2866,7 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) if (!dev->info_supported && !dev->system_event_supported) { pr_warn("No hotkey query interface found\n"); + error = -EINVAL; goto err_remove_filter; } diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c index be3d81ff51cc..a44e3427fdeb 100644 --- a/drivers/power/reset/gpio-poweroff.c +++ b/drivers/power/reset/gpio-poweroff.c @@ -84,6 +84,7 @@ static const struct of_device_id of_gpio_poweroff_match[] = { { .compatible = "gpio-poweroff", }, {}, }; +MODULE_DEVICE_TABLE(of, of_gpio_poweroff_match); static struct platform_driver gpio_poweroff_driver = { .probe = gpio_poweroff_probe, diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index c216f38d47f6..aac0ed71a9ca 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -490,7 +490,8 @@ config BATTERY_GOLDFISH config BATTERY_RT5033 tristate "RT5033 fuel gauge support" - depends on MFD_RT5033 + depends on I2C + select REGMAP_I2C help This adds support for battery fuel gauge in Richtek RT5033 PMIC. The fuelgauge calculates and determines the battery state of charge diff --git a/drivers/power/supply/ab8500_btemp.c b/drivers/power/supply/ab8500_btemp.c index 6ffdc18f2599..9f17d81767ea 100644 --- a/drivers/power/supply/ab8500_btemp.c +++ b/drivers/power/supply/ab8500_btemp.c @@ -1181,6 +1181,7 @@ static const struct of_device_id ab8500_btemp_match[] = { { .compatible = "stericsson,ab8500-btemp", }, { }, }; +MODULE_DEVICE_TABLE(of, ab8500_btemp_match); static struct platform_driver ab8500_btemp_driver = { .probe = ab8500_btemp_probe, diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c index 48a11fd86a7f..56b502331433 100644 --- a/drivers/power/supply/ab8500_charger.c +++ b/drivers/power/supply/ab8500_charger.c @@ -409,6 +409,14 @@ disable_otp: static void ab8500_power_supply_changed(struct ab8500_charger *di, struct power_supply *psy) { + /* + * This happens if we get notifications or interrupts and + * the platform has been configured not to support one or + * other type of charging. + */ + if (!psy) + return; + if (di->autopower_cfg) { if (!di->usb.charger_connected && !di->ac.charger_connected && @@ -435,7 +443,15 @@ static void ab8500_charger_set_usb_connected(struct ab8500_charger *di, if (!connected) di->flags.vbus_drop_end = false; - sysfs_notify(&di->usb_chg.psy->dev.kobj, NULL, "present"); + /* + * Sometimes the platform is configured not to support + * USB charging and no psy has been created, but we still + * will get these notifications. + */ + if (di->usb_chg.psy) { + sysfs_notify(&di->usb_chg.psy->dev.kobj, NULL, + "present"); + } if (connected) { mutex_lock(&di->charger_attached_mutex); @@ -3736,6 +3752,7 @@ static const struct of_device_id ab8500_charger_match[] = { { .compatible = "stericsson,ab8500-charger", }, { }, }; +MODULE_DEVICE_TABLE(of, ab8500_charger_match); static struct platform_driver ab8500_charger_driver = { .probe = ab8500_charger_probe, diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c index ea8c26a108f0..d6079e892e11 100644 --- a/drivers/power/supply/ab8500_fg.c +++ b/drivers/power/supply/ab8500_fg.c @@ -3229,6 +3229,7 @@ static const struct of_device_id ab8500_fg_match[] = { { .compatible = "stericsson,ab8500-fg", }, { }, }; +MODULE_DEVICE_TABLE(of, ab8500_fg_match); static struct platform_driver ab8500_fg_driver = { .probe = ab8500_fg_probe, diff --git a/drivers/power/supply/charger-manager.c b/drivers/power/supply/charger-manager.c index 13f23c00538b..043836e6d347 100644 --- a/drivers/power/supply/charger-manager.c +++ b/drivers/power/supply/charger-manager.c @@ -1489,6 +1489,7 @@ static const struct of_device_id charger_manager_match[] = { }, {}, }; +MODULE_DEVICE_TABLE(of, charger_manager_match); static struct charger_desc *of_cm_parse_desc(struct device *dev) { diff --git a/drivers/power/supply/rt5033_battery.c b/drivers/power/supply/rt5033_battery.c index bcdd83048492..9310b85f3405 100644 --- a/drivers/power/supply/rt5033_battery.c +++ b/drivers/power/supply/rt5033_battery.c @@ -167,9 +167,16 @@ static const struct i2c_device_id rt5033_battery_id[] = { }; MODULE_DEVICE_TABLE(i2c, rt5033_battery_id); +static const struct of_device_id rt5033_battery_of_match[] = { + { .compatible = "richtek,rt5033-battery", }, + { } +}; +MODULE_DEVICE_TABLE(of, rt5033_battery_of_match); + static struct i2c_driver rt5033_battery_driver = { .driver = { .name = "rt5033-battery", + .of_match_table = rt5033_battery_of_match, }, .probe = rt5033_battery_probe, .remove = rt5033_battery_remove, diff --git a/drivers/pwm/pwm-spear.c b/drivers/pwm/pwm-spear.c index 6c6b44fd3f43..2d11ac277de8 100644 --- a/drivers/pwm/pwm-spear.c +++ b/drivers/pwm/pwm-spear.c @@ -231,10 +231,6 @@ static int spear_pwm_probe(struct platform_device *pdev) static int spear_pwm_remove(struct platform_device *pdev) { struct spear_pwm_chip *pc = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < NUM_PWM; i++) - pwm_disable(&pc->chip.pwms[i]); /* clk was prepared in probe, hence unprepare it here */ clk_unprepare(pc->clk); diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c index 7e8906d6ab7a..d76698ce6472 100644 --- a/drivers/pwm/pwm-tegra.c +++ b/drivers/pwm/pwm-tegra.c @@ -228,7 +228,6 @@ static int tegra_pwm_probe(struct platform_device *pdev) static int tegra_pwm_remove(struct platform_device *pdev) { struct tegra_pwm_chip *pc = platform_get_drvdata(pdev); - unsigned int i; int err; if (WARN_ON(!pc)) @@ -238,18 +237,6 @@ static int tegra_pwm_remove(struct platform_device *pdev) if (err < 0) return err; - for (i = 0; i < pc->chip.npwm; i++) { - struct pwm_device *pwm = &pc->chip.pwms[i]; - - if (!pwm_is_enabled(pwm)) - if (clk_prepare_enable(pc->clk) < 0) - continue; - - pwm_writel(pc, i, 0); - - clk_disable_unprepare(pc->clk); - } - reset_control_assert(pc->rst); clk_disable_unprepare(pc->clk); diff --git a/drivers/rapidio/rio_cm.c b/drivers/rapidio/rio_cm.c index b29fc258eeba..ab57a1eb519f 100644 --- a/drivers/rapidio/rio_cm.c +++ b/drivers/rapidio/rio_cm.c @@ -2136,6 +2136,14 @@ static int riocm_add_mport(struct device *dev, return -ENODEV; } + cm->rx_wq = create_workqueue(DRV_NAME "/rxq"); + if (!cm->rx_wq) { + rio_release_inb_mbox(mport, cmbox); + rio_release_outb_mbox(mport, cmbox); + kfree(cm); + return -ENOMEM; + } + /* * Allocate and register inbound messaging buffers to be ready * to receive channel and system management requests @@ -2146,15 +2154,6 @@ static int riocm_add_mport(struct device *dev, cm->rx_slots = RIOCM_RX_RING_SIZE; mutex_init(&cm->rx_lock); riocm_rx_fill(cm, RIOCM_RX_RING_SIZE); - cm->rx_wq = create_workqueue(DRV_NAME "/rxq"); - if (!cm->rx_wq) { - riocm_error("failed to allocate IBMBOX_%d on %s", - cmbox, mport->name); - rio_release_outb_mbox(mport, cmbox); - kfree(cm); - return -ENOMEM; - } - INIT_WORK(&cm->rx_work, rio_ibmsg_handler); cm->tx_slot = 0; diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index 9ececfef42d6..bd91c95f73e0 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c @@ -258,7 +258,8 @@ static int da9052_regulator_set_voltage_time_sel(struct regulator_dev *rdev, case DA9052_ID_BUCK3: case DA9052_ID_LDO2: case DA9052_ID_LDO3: - ret = (new_sel - old_sel) * info->step_uV / 6250; + ret = DIV_ROUND_UP(abs(new_sel - old_sel) * info->step_uV, + 6250); break; } diff --git a/drivers/reset/core.c b/drivers/reset/core.c index d0ebca301afc..c15c898fe0dc 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -263,7 +263,10 @@ static struct reset_control *__reset_control_get_internal( if (!rstc) return ERR_PTR(-ENOMEM); - try_module_get(rcdev->owner); + if (!try_module_get(rcdev->owner)) { + kfree(rstc); + return ERR_PTR(-ENODEV); + } rstc->rcdev = rcdev; list_add(&rstc->list, &rcdev->reset_control_head); diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c index 31e7e23cc5be..9396b69f75e8 100644 --- a/drivers/rtc/rtc-proc.c +++ b/drivers/rtc/rtc-proc.c @@ -26,8 +26,8 @@ static bool is_rtc_hctosys(struct rtc_device *rtc) int size; char name[NAME_SIZE]; - size = scnprintf(name, NAME_SIZE, "rtc%d", rtc->id); - if (size > NAME_SIZE) + size = snprintf(name, NAME_SIZE, "rtc%d", rtc->id); + if (size >= NAME_SIZE) return false; return !strncmp(name, CONFIG_RTC_HCTOSYS_DEVICE, NAME_SIZE); diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 68d6ee7ae504..3e8b5906548f 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -34,8 +34,8 @@ #define SCLP_VT220_MINOR 65 #define SCLP_VT220_DRIVER_NAME "sclp_vt220" #define SCLP_VT220_DEVICE_NAME "ttysclp" -#define SCLP_VT220_CONSOLE_NAME "ttyS" -#define SCLP_VT220_CONSOLE_INDEX 1 /* console=ttyS1 */ +#define SCLP_VT220_CONSOLE_NAME "ttysclp" +#define SCLP_VT220_CONSOLE_INDEX 0 /* console=ttysclp0 */ /* Representation of a single write request */ struct sclp_vt220_request { diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 876c7e6e3a99..6b8e7086c807 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -254,6 +254,9 @@ static ssize_t chp_status_write(struct device *dev, if (!num_args) return count; + /* Wait until previous actions have settled. */ + css_wait_for_slow_path(); + if (!strncasecmp(cmd, "on", 2) || !strcmp(cmd, "1")) { mutex_lock(&cp->lock); error = s390_vary_chpid(cp->chpid, 1); diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 67903c93328b..6e695bc96b88 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -769,8 +769,6 @@ int chsc_chp_vary(struct chp_id chpid, int on) { struct channel_path *chp = chpid_to_chp(chpid); - /* Wait until previous actions have settled. */ - css_wait_for_slow_path(); /* * Redo PathVerification on the devices the chpid connects to */ diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index c7be7bb37209..b9b4491d732a 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -3081,11 +3081,11 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command, ccb->opcode = BLOGIC_INITIATOR_CCB_SG; ccb->datalen = count * sizeof(struct blogic_sg_seg); if (blogic_multimaster_type(adapter)) - ccb->data = (void *)((unsigned int) ccb->dma_handle + + ccb->data = (unsigned int) ccb->dma_handle + ((unsigned long) &ccb->sglist - - (unsigned long) ccb)); + (unsigned long) ccb); else - ccb->data = ccb->sglist; + ccb->data = virt_to_32bit_virt(ccb->sglist); scsi_for_each_sg(command, sg, count, i) { ccb->sglist[i].segbytes = sg_dma_len(sg); diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h index b53ec2f1e8cd..5c950a7a1b1c 100644 --- a/drivers/scsi/BusLogic.h +++ b/drivers/scsi/BusLogic.h @@ -821,7 +821,7 @@ struct blogic_ccb { unsigned char cdblen; /* Byte 2 */ unsigned char sense_datalen; /* Byte 3 */ u32 datalen; /* Bytes 4-7 */ - void *data; /* Bytes 8-11 */ + u32 data; /* Bytes 8-11 */ unsigned char:8; /* Byte 12 */ unsigned char:8; /* Byte 13 */ enum blogic_adapter_status adapter_status; /* Byte 14 */ diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c index 867b864f5047..4bca37d52bad 100644 --- a/drivers/scsi/FlashPoint.c +++ b/drivers/scsi/FlashPoint.c @@ -40,7 +40,7 @@ struct sccb_mgr_info { u16 si_per_targ_ultra_nego; u16 si_per_targ_no_disc; u16 si_per_targ_wide_nego; - u16 si_flags; + u16 si_mflags; unsigned char si_card_family; unsigned char si_bustype; unsigned char si_card_model[3]; @@ -1070,22 +1070,22 @@ static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo) ScamFlg = (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2); - pCardInfo->si_flags = 0x0000; + pCardInfo->si_mflags = 0x0000; if (i & 0x01) - pCardInfo->si_flags |= SCSI_PARITY_ENA; + pCardInfo->si_mflags |= SCSI_PARITY_ENA; if (!(i & 0x02)) - pCardInfo->si_flags |= SOFT_RESET; + pCardInfo->si_mflags |= SOFT_RESET; if (i & 0x10) - pCardInfo->si_flags |= EXTENDED_TRANSLATION; + pCardInfo->si_mflags |= EXTENDED_TRANSLATION; if (ScamFlg & SCAM_ENABLED) - pCardInfo->si_flags |= FLAG_SCAM_ENABLED; + pCardInfo->si_mflags |= FLAG_SCAM_ENABLED; if (ScamFlg & SCAM_LEVEL2) - pCardInfo->si_flags |= FLAG_SCAM_LEVEL2; + pCardInfo->si_mflags |= FLAG_SCAM_LEVEL2; j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L); if (i & 0x04) { @@ -1101,7 +1101,7 @@ static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo) if (!(RD_HARPOON(ioport + hp_page_ctrl) & NARROW_SCSI_CARD)) - pCardInfo->si_flags |= SUPPORT_16TAR_32LUN; + pCardInfo->si_mflags |= SUPPORT_16TAR_32LUN; pCardInfo->si_card_family = HARPOON_FAMILY; pCardInfo->si_bustype = BUSTYPE_PCI; @@ -1137,15 +1137,15 @@ static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo) if (pCardInfo->si_card_model[1] == '3') { if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)) - pCardInfo->si_flags |= LOW_BYTE_TERM; + pCardInfo->si_mflags |= LOW_BYTE_TERM; } else if (pCardInfo->si_card_model[2] == '0') { temp = RD_HARPOON(ioport + hp_xfer_pad); WR_HARPOON(ioport + hp_xfer_pad, (temp & ~BIT(4))); if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)) - pCardInfo->si_flags |= LOW_BYTE_TERM; + pCardInfo->si_mflags |= LOW_BYTE_TERM; WR_HARPOON(ioport + hp_xfer_pad, (temp | BIT(4))); if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)) - pCardInfo->si_flags |= HIGH_BYTE_TERM; + pCardInfo->si_mflags |= HIGH_BYTE_TERM; WR_HARPOON(ioport + hp_xfer_pad, temp); } else { temp = RD_HARPOON(ioport + hp_ee_ctrl); @@ -1163,9 +1163,9 @@ static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo) WR_HARPOON(ioport + hp_ee_ctrl, temp); WR_HARPOON(ioport + hp_xfer_pad, temp2); if (!(temp3 & BIT(7))) - pCardInfo->si_flags |= LOW_BYTE_TERM; + pCardInfo->si_mflags |= LOW_BYTE_TERM; if (!(temp3 & BIT(6))) - pCardInfo->si_flags |= HIGH_BYTE_TERM; + pCardInfo->si_mflags |= HIGH_BYTE_TERM; } ARAM_ACCESS(ioport); @@ -1272,7 +1272,7 @@ static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info WR_HARPOON(ioport + hp_arb_id, pCardInfo->si_id); CurrCard->ourId = pCardInfo->si_id; - i = (unsigned char)pCardInfo->si_flags; + i = (unsigned char)pCardInfo->si_mflags; if (i & SCSI_PARITY_ENA) WR_HARPOON(ioport + hp_portctrl_1, (HOST_MODE8 | CHK_SCSI_P)); @@ -1286,14 +1286,14 @@ static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info j |= SCSI_TERM_ENA_H; WR_HARPOON(ioport + hp_ee_ctrl, j); - if (!(pCardInfo->si_flags & SOFT_RESET)) { + if (!(pCardInfo->si_mflags & SOFT_RESET)) { FPT_sresb(ioport, thisCard); FPT_scini(thisCard, pCardInfo->si_id, 0); } - if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS) + if (pCardInfo->si_mflags & POST_ALL_UNDERRRUNS) CurrCard->globalFlags |= F_NO_FILTER; if (pCurrNvRam) { diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 741cc96379cb..628bf2e6a526 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -5847,6 +5847,7 @@ hba_free: pci_disable_msix(phba->pcidev); pci_dev_put(phba->pcidev); iscsi_host_free(phba->shost); + pci_disable_pcie_error_reporting(pcidev); pci_set_drvdata(pcidev, NULL); disable_pci: pci_release_regions(pcidev); diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 258a3f9a2519..b6a9773326e3 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -265,12 +265,11 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, device_enable_async_suspend(&shost->shost_dev); + get_device(&shost->shost_gendev); error = device_add(&shost->shost_dev); if (error) goto out_del_gendev; - get_device(&shost->shost_gendev); - if (shost->transportt->host_size) { shost->shost_data = kzalloc(shost->transportt->host_size, GFP_KERNEL); @@ -307,6 +306,11 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, out_del_dev: device_del(&shost->shost_dev); out_del_gendev: + /* + * Host state is SHOST_RUNNING so we have to explicitly release + * ->shost_dev. + */ + put_device(&shost->shost_dev); device_del(&shost->shost_gendev); out_destroy_freelist: device_disable_async_suspend(&shost->shost_gendev); @@ -368,7 +372,7 @@ static void scsi_host_dev_release(struct device *dev) ida_simple_remove(&host_index_ida, shost->host_no); - if (parent) + if (shost->shost_state != SHOST_CREATED) put_device(parent); kfree(shost); } @@ -421,8 +425,10 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) mutex_init(&shost->scan_mutex); index = ida_simple_get(&host_index_ida, 0, 0, GFP_KERNEL); - if (index < 0) - goto fail_kfree; + if (index < 0) { + kfree(shost); + return NULL; + } shost->host_no = index; shost->dma_channel = 0xff; @@ -509,7 +515,8 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) shost_printk(KERN_WARNING, shost, "error handler thread failed to spawn, error = %ld\n", PTR_ERR(shost->ehandler)); - goto fail_index_remove; + shost->ehandler = NULL; + goto fail; } shost->tmf_work_q = alloc_workqueue("scsi_tmf_%d", @@ -518,17 +525,18 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) if (!shost->tmf_work_q) { shost_printk(KERN_WARNING, shost, "failed to create tmf workq\n"); - goto fail_kthread; + goto fail; } scsi_proc_hostdir_add(shost->hostt); return shost; + fail: + /* + * Host state is still SHOST_CREATED and that is enough to release + * ->shost_gendev. scsi_host_dev_release() will free + * dev_name(&shost->shost_dev). + */ + put_device(&shost->shost_gendev); - fail_kthread: - kthread_stop(shost->ehandler); - fail_index_remove: - ida_simple_remove(&host_index_ida, shost->host_no); - fail_kfree: - kfree(shost); return NULL; } EXPORT_SYMBOL(scsi_host_alloc); diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 50e2943c3337..30e954bb6c81 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -1384,7 +1384,6 @@ void iscsi_session_failure(struct iscsi_session *session, enum iscsi_err err) { struct iscsi_conn *conn; - struct device *dev; spin_lock_bh(&session->frwd_lock); conn = session->leadconn; @@ -1393,10 +1392,8 @@ void iscsi_session_failure(struct iscsi_session *session, return; } - dev = get_device(&conn->cls_conn->dev); + iscsi_get_conn(conn->cls_conn); spin_unlock_bh(&session->frwd_lock); - if (!dev) - return; /* * if the host is being removed bypass the connection * recovery initialization because we are going to kill @@ -1406,7 +1403,7 @@ void iscsi_session_failure(struct iscsi_session *session, iscsi_conn_error_event(conn->cls_conn, err); else iscsi_conn_failure(conn, err); - put_device(dev); + iscsi_put_conn(conn->cls_conn); } EXPORT_SYMBOL_GPL(iscsi_session_failure); diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c index d3c5297c6c89..30e0730f613e 100644 --- a/drivers/scsi/libsas/sas_port.c +++ b/drivers/scsi/libsas/sas_port.c @@ -41,7 +41,7 @@ static bool phy_is_wideport_member(struct asd_sas_port *port, struct asd_sas_phy static void sas_resume_port(struct asd_sas_phy *phy) { - struct domain_device *dev; + struct domain_device *dev, *n; struct asd_sas_port *port = phy->port; struct sas_ha_struct *sas_ha = phy->ha; struct sas_internal *si = to_sas_internal(sas_ha->core.shost->transportt); @@ -60,7 +60,7 @@ static void sas_resume_port(struct asd_sas_phy *phy) * 1/ presume every device came back * 2/ force the next revalidation to check all expander phys */ - list_for_each_entry(dev, &port->dev_list, dev_list_node) { + list_for_each_entry_safe(dev, n, &port->dev_list, dev_list_node) { int i, rc; rc = sas_notify_lldd_dev_found(dev); diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 7d4a5bb91606..f17adfe1326b 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1159,6 +1159,15 @@ stop_rr_fcf_flogi: phba->fcf.fcf_redisc_attempted = 0; /* reset */ goto out; } + } else if (vport->port_state > LPFC_FLOGI && + vport->fc_flag & FC_PT2PT) { + /* + * In a p2p topology, it is possible that discovery has + * already progressed, and this completion can be ignored. + * Recheck the indicated topology. + */ + if (!sp->cmn.fPort) + goto out; } flogifail: diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index f0a3bb4961e5..e832a67bf638 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -5199,8 +5199,10 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle) handle, parent_handle, (unsigned long long) sas_expander->sas_address, sas_expander->num_phys); - if (!sas_expander->num_phys) + if (!sas_expander->num_phys) { + rc = -1; goto out_fail; + } sas_expander->phy = kcalloc(sas_expander->num_phys, sizeof(struct _sas_phy), GFP_KERNEL); if (!sas_expander->phy) { diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 104e13ae3428..9ec18463b452 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -1102,7 +1102,8 @@ qla82xx_write_flash_dword(struct qla_hw_data *ha, uint32_t flashaddr, return ret; } - if (qla82xx_flash_set_write_enable(ha)) + ret = qla82xx_flash_set_write_enable(ha); + if (ret < 0) goto done_write; qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_WDATA, data); diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index b889caa556a0..6ef7a094ee51 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -1224,6 +1224,7 @@ void qlt_stop_phase2(struct qla_tgt *tgt) "Waiting for %d IRQ commands to complete (tgt %p)", tgt->irq_cmd_count, tgt); + mutex_lock(&tgt->ha->optrom_mutex); mutex_lock(&vha->vha_tgt.tgt_mutex); spin_lock_irqsave(&ha->hardware_lock, flags); while ((tgt->irq_cmd_count != 0) || (tgt->atio_irq_cmd_count != 0)) { @@ -1235,6 +1236,7 @@ void qlt_stop_phase2(struct qla_tgt *tgt) tgt->tgt_stopped = 1; spin_unlock_irqrestore(&ha->hardware_lock, flags); mutex_unlock(&vha->vha_tgt.tgt_mutex); + mutex_unlock(&tgt->ha->optrom_mutex); ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00c, "Stop of tgt %p finished", tgt); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 03d00370dc59..d135bd3051a6 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -919,6 +919,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) case 0x07: /* operation in progress */ case 0x08: /* Long write in progress */ case 0x09: /* self test in progress */ + case 0x11: /* notify (enable spinup) required */ case 0x14: /* space allocation in progress */ action = ACTION_DELAYED_RETRY; break; diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 4f4d2d65a4a7..337aad0660fa 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -2327,6 +2327,18 @@ int iscsi_destroy_conn(struct iscsi_cls_conn *conn) } EXPORT_SYMBOL_GPL(iscsi_destroy_conn); +void iscsi_put_conn(struct iscsi_cls_conn *conn) +{ + put_device(&conn->dev); +} +EXPORT_SYMBOL_GPL(iscsi_put_conn); + +void iscsi_get_conn(struct iscsi_cls_conn *conn) +{ + get_device(&conn->dev); +} +EXPORT_SYMBOL_GPL(iscsi_get_conn); + /* * iscsi interface functions */ diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 67a73ea0a615..5e51a39a0c27 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -216,6 +216,8 @@ static unsigned int sr_get_events(struct scsi_device *sdev) return DISK_EVENT_EJECT_REQUEST; else if (med->media_event_code == 2) return DISK_EVENT_MEDIA_CHANGE; + else if (med->media_event_code == 3) + return DISK_EVENT_EJECT_REQUEST; return 0; } diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c index df6fabcce4f7..4d2172c115c6 100644 --- a/drivers/scsi/vmw_pvscsi.c +++ b/drivers/scsi/vmw_pvscsi.c @@ -577,7 +577,13 @@ static void pvscsi_complete_request(struct pvscsi_adapter *adapter, case BTSTAT_SUCCESS: case BTSTAT_LINKED_COMMAND_COMPLETED: case BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG: - /* If everything went fine, let's move on.. */ + /* + * Commands like INQUIRY may transfer less data than + * requested by the initiator via bufflen. Set residual + * count to make upper layer aware of the actual amount + * of data returned. + */ + scsi_set_resid(cmd, scsi_bufflen(cmd) - e->dataLen); cmd->result = (DID_OK << 16); break; diff --git a/drivers/spi/spi-loopback-test.c b/drivers/spi/spi-loopback-test.c index 7120083fe761..cac38753d0cd 100644 --- a/drivers/spi/spi-loopback-test.c +++ b/drivers/spi/spi-loopback-test.c @@ -803,7 +803,7 @@ static int spi_test_run_iter(struct spi_device *spi, test.transfers[i].len = len; if (test.transfers[i].tx_buf) test.transfers[i].tx_buf += tx_off; - if (test.transfers[i].tx_buf) + if (test.transfers[i].rx_buf) test.transfers[i].rx_buf += rx_off; } diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c index 1eccdc4a4581..2eeb0fe2eed2 100644 --- a/drivers/spi/spi-omap-100k.c +++ b/drivers/spi/spi-omap-100k.c @@ -251,7 +251,7 @@ static int omap1_spi100k_setup_transfer(struct spi_device *spi, else word_len = spi->bits_per_word; - if (spi->bits_per_word > 32) + if (word_len > 32) return -EINVAL; cs->word_len = word_len; diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c index 17068e62e792..8c3f5a00fd9e 100644 --- a/drivers/spi/spi-sun6i.c +++ b/drivers/spi/spi-sun6i.c @@ -251,6 +251,10 @@ static int sun6i_spi_transfer_one(struct spi_master *master, } sun6i_spi_write(sspi, SUN6I_CLK_CTL_REG, reg); + /* Finally enable the bus - doing so before might raise SCK to HIGH */ + reg = sun6i_spi_read(sspi, SUN6I_GBL_CTL_REG); + reg |= SUN6I_GBL_CTL_BUS_ENABLE; + sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, reg); /* Setup the transfer now... */ if (sspi->tx_buf) @@ -334,7 +338,7 @@ static int sun6i_spi_runtime_resume(struct device *dev) } sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, - SUN6I_GBL_CTL_BUS_ENABLE | SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP); + SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP); return 0; diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index fe707440f8c3..9b24ebbba346 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -585,8 +585,10 @@ static void pch_spi_set_tx(struct pch_spi_data *data, int *bpw) data->pkt_tx_buff = kzalloc(size, GFP_KERNEL); if (data->pkt_tx_buff != NULL) { data->pkt_rx_buff = kzalloc(size, GFP_KERNEL); - if (!data->pkt_rx_buff) + if (!data->pkt_rx_buff) { kfree(data->pkt_tx_buff); + data->pkt_tx_buff = NULL; + } } if (!data->pkt_rx_buff) { diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index f0ba5eb26128..84e2296c45a2 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1869,6 +1869,7 @@ struct spi_master *devm_spi_alloc_master(struct device *dev, unsigned int size) master = spi_alloc_master(dev, size); if (master) { + master->devm_allocated = true; *ptr = master; devres_add(dev, ptr); } else { @@ -2059,11 +2060,6 @@ int devm_spi_register_master(struct device *dev, struct spi_master *master) } EXPORT_SYMBOL_GPL(devm_spi_register_master); -static int devm_spi_match_master(struct device *dev, void *res, void *master) -{ - return *(struct spi_master **)res == master; -} - static int __unregister(struct device *dev, void *null) { spi_unregister_device(to_spi_device(dev)); @@ -2102,8 +2098,7 @@ void spi_unregister_master(struct spi_master *master) /* Release the last reference on the master if its driver * has not yet been converted to devm_spi_alloc_master(). */ - if (!devres_find(master->dev.parent, devm_spi_release_master, - devm_spi_match_master, master)) + if (!master->devm_allocated) put_device(&master->dev); if (IS_ENABLED(CONFIG_SPI_DYNAMIC)) diff --git a/drivers/ssb/sdio.c b/drivers/ssb/sdio.c index 2278e43614bd..5e10514ef80c 100644 --- a/drivers/ssb/sdio.c +++ b/drivers/ssb/sdio.c @@ -411,7 +411,6 @@ static void ssb_sdio_block_write(struct ssb_device *dev, const void *buffer, sdio_claim_host(bus->host_sdio); if (unlikely(ssb_sdio_switch_core(bus, dev))) { error = -EIO; - memset((void *)buffer, 0xff, count); goto err_out; } offset |= bus->sdio_sbaddr & 0xffff; diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index 1055649f034c..59266650e071 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -2173,7 +2173,7 @@ static int _nbu2ss_nuke(struct nbu2ss_udc *udc, struct nbu2ss_ep *ep, int status) { - struct nbu2ss_req *req; + struct nbu2ss_req *req, *n; /* Endpoint Disable */ _nbu2ss_epn_exit(udc, ep); @@ -2185,7 +2185,7 @@ static int _nbu2ss_nuke(struct nbu2ss_udc *udc, return 0; /* called with irqs blocked */ - list_for_each_entry(req, &ep->queue, queue) { + list_for_each_entry_safe(req, n, &ep->queue, queue) { _nbu2ss_ep_done(ep, req, status); } diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c index e72dfa9699f3..454e47424ade 100644 --- a/drivers/staging/gdm724x/gdm_lte.c +++ b/drivers/staging/gdm724x/gdm_lte.c @@ -624,10 +624,12 @@ static void gdm_lte_netif_rx(struct net_device *dev, char *buf, * bytes (99,130,83,99 dec) */ } __packed; - void *addr = buf + sizeof(struct iphdr) + - sizeof(struct udphdr) + - offsetof(struct dhcp_packet, chaddr); - ether_addr_copy(nic->dest_mac_addr, addr); + int offset = sizeof(struct iphdr) + + sizeof(struct udphdr) + + offsetof(struct dhcp_packet, chaddr); + if (offset + ETH_ALEN > len) + return; + ether_addr_copy(nic->dest_mac_addr, buf + offset); } } @@ -689,6 +691,7 @@ static void gdm_lte_multi_sdu_pkt(struct phy_dev *phy_dev, char *buf, int len) struct multi_sdu *multi_sdu = (struct multi_sdu *)buf; struct sdu *sdu = NULL; u8 *data = (u8 *)multi_sdu->data; + int copied; u16 i = 0; u16 num_packet; u16 hci_len; @@ -702,6 +705,12 @@ static void gdm_lte_multi_sdu_pkt(struct phy_dev *phy_dev, char *buf, int len) multi_sdu->num_packet); for (i = 0; i < num_packet; i++) { + copied = data - multi_sdu->data; + if (len < copied + sizeof(*sdu)) { + pr_err("rx prevent buffer overflow"); + return; + } + sdu = (struct sdu *)data; cmd_evt = gdm_dev16_to_cpu(phy_dev-> @@ -715,7 +724,8 @@ static void gdm_lte_multi_sdu_pkt(struct phy_dev *phy_dev, char *buf, int len) pr_err("rx sdu wrong hci %04x\n", cmd_evt); return; } - if (hci_len < 12) { + if (hci_len < 12 || + len < copied + sizeof(*sdu) + (hci_len - 12)) { pr_err("rx sdu invalid len %d\n", hci_len); return; } diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c index 5771d4ee8ef1..1a71bca4e698 100644 --- a/drivers/staging/iio/cdc/ad7746.c +++ b/drivers/staging/iio/cdc/ad7746.c @@ -714,7 +714,6 @@ static int ad7746_probe(struct i2c_client *client, indio_dev->num_channels = ARRAY_SIZE(ad7746_channels); else indio_dev->num_channels = ARRAY_SIZE(ad7746_channels) - 2; - indio_dev->num_channels = ARRAY_SIZE(ad7746_channels); indio_dev->modes = INDIO_DIRECT_MODE; if (pdata) { diff --git a/drivers/staging/iio/light/tsl2583.c b/drivers/staging/iio/light/tsl2583.c index 08f1583ee34e..fb3ec56d45b6 100644 --- a/drivers/staging/iio/light/tsl2583.c +++ b/drivers/staging/iio/light/tsl2583.c @@ -382,6 +382,15 @@ static int taos_als_calibrate(struct iio_dev *indio_dev) dev_err(&chip->client->dev, "taos_als_calibrate failed to get lux\n"); return lux_val; } + + /* Avoid division by zero of lux_value later on */ + if (lux_val == 0) { + dev_err(&chip->client->dev, + "%s: lux_val of 0 will produce out of range trim_value\n", + __func__); + return -ENODATA; + } + gain_trim_val = (unsigned int)(((chip->taos_settings.als_cal_target) * chip->taos_settings.als_gain_trim) / lux_val); diff --git a/drivers/staging/media/s5p-cec/s5p_cec.c b/drivers/staging/media/s5p-cec/s5p_cec.c index 58d756231136..bebd44d9bd51 100644 --- a/drivers/staging/media/s5p-cec/s5p_cec.c +++ b/drivers/staging/media/s5p-cec/s5p_cec.c @@ -54,7 +54,7 @@ static int s5p_cec_adap_enable(struct cec_adapter *adap, bool enable) } else { s5p_cec_mask_tx_interrupts(cec); s5p_cec_mask_rx_interrupts(cec); - pm_runtime_disable(cec->dev); + pm_runtime_put(cec->dev); } return 0; diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index ecd707f74ddc..6afb65387be6 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -2779,9 +2779,7 @@ __transport_wait_for_tasks(struct se_cmd *cmd, bool fabric_stop, __releases(&cmd->t_state_lock) __acquires(&cmd->t_state_lock) { - - assert_spin_locked(&cmd->t_state_lock); - WARN_ON_ONCE(!irqs_disabled()); + lockdep_assert_held(&cmd->t_state_lock); if (fabric_stop) cmd->transport_state |= CMD_T_FABRIC_STOP; diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index d6fd0e802ef5..37c7cea8c34f 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -1437,7 +1437,7 @@ static int nozomi_card_init(struct pci_dev *pdev, NOZOMI_NAME, dc); if (unlikely(ret)) { dev_err(&pdev->dev, "can't request irq %d\n", pdev->irq); - goto err_free_kfifo; + goto err_free_all_kfifo; } DBG1("base_addr: %p", dc->base_addr); @@ -1475,12 +1475,15 @@ static int nozomi_card_init(struct pci_dev *pdev, return 0; err_free_tty: - for (i = 0; i < MAX_PORT; ++i) { + for (i--; i >= 0; i--) { tty_unregister_device(ntty_driver, dc->index_start + i); tty_port_destroy(&dc->port[i].port); } + free_irq(pdev->irq, dc); +err_free_all_kfifo: + i = MAX_PORT; err_free_kfifo: - for (i = 0; i < MAX_PORT; i++) + for (i--; i >= PORT_MDM; i--) kfifo_free(&dc->port[i].fifo_ul); err_free_sbuf: kfree(dc->send_buf); diff --git a/drivers/tty/serial/8250/serial_cs.c b/drivers/tty/serial/8250/serial_cs.c index 8106353ce7aa..3747991024d5 100644 --- a/drivers/tty/serial/8250/serial_cs.c +++ b/drivers/tty/serial/8250/serial_cs.c @@ -305,6 +305,7 @@ static int serial_resume(struct pcmcia_device *link) static int serial_probe(struct pcmcia_device *link) { struct serial_info *info; + int ret; dev_dbg(&link->dev, "serial_attach()\n"); @@ -319,7 +320,15 @@ static int serial_probe(struct pcmcia_device *link) if (do_sound) link->config_flags |= CONF_ENABLE_SPKR; - return serial_config(link); + ret = serial_config(link); + if (ret) + goto free_info; + + return 0; + +free_info: + kfree(info); + return ret; } static void serial_detach(struct pcmcia_device *link) @@ -779,6 +788,7 @@ static const struct pcmcia_device_id serial_ids[] = { PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT2834LT", 0x5f73be51, 0x4cd7c09e), PCMCIA_DEVICE_PROD_ID12("OEM ", "C288MX ", 0xb572d360, 0xd2385b7a), PCMCIA_DEVICE_PROD_ID12("Option International", "V34bis GSM/PSTN Data/Fax Modem", 0x9d7cd6f5, 0x5cb8bf41), + PCMCIA_DEVICE_PROD_ID12("Option International", "GSM-Ready 56K/ISDN", 0x9d7cd6f5, 0xb23844aa), PCMCIA_DEVICE_PROD_ID12("PCMCIA ", "C336MX ", 0x99bcafe9, 0xaa25bcab), PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f), PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d), @@ -806,7 +816,6 @@ static const struct pcmcia_device_id serial_ids[] = { PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"), PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"), PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"), - PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "cis/GLOBETROTTER.cis"), PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.", "SERIAL CARD: SL100 1.00.", 0x19ca78af, 0xf964f42b), PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.", "SERIAL CARD: SL100", 0x19ca78af, 0x71d98e83), PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.", "SERIAL CARD: SL232 1.00.", 0x19ca78af, 0x69fb7490), diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 5b6093dc3ff2..a4c1797e30d7 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1766,6 +1766,9 @@ lpuart32_console_get_options(struct lpuart_port *sport, int *baud, bd = lpuart32_read(sport->port.membase + UARTBAUD); bd &= UARTBAUD_SBR_MASK; + if (!bd) + return; + sbr = bd; uartclk = clk_get_rate(sport->clk); /* diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 80ab672d61cc..febbacecb3ba 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -1385,10 +1385,12 @@ static int __init max310x_uart_init(void) return ret; #ifdef CONFIG_SPI_MASTER - spi_register_driver(&max310x_spi_driver); + ret = spi_register_driver(&max310x_spi_driver); + if (ret) + uart_unregister_driver(&max310x_uart); #endif - return 0; + return ret; } module_init(max310x_uart_init); diff --git a/drivers/tty/serial/rp2.c b/drivers/tty/serial/rp2.c index 056f91b3a4ca..b7d1b1645c84 100644 --- a/drivers/tty/serial/rp2.c +++ b/drivers/tty/serial/rp2.c @@ -198,7 +198,6 @@ struct rp2_card { void __iomem *bar0; void __iomem *bar1; spinlock_t card_lock; - struct completion fw_loaded; }; #define RP_ID(prod) PCI_VDEVICE(RP, (prod)) @@ -667,17 +666,10 @@ static void rp2_remove_ports(struct rp2_card *card) card->initialized_ports = 0; } -static void rp2_fw_cb(const struct firmware *fw, void *context) +static int rp2_load_firmware(struct rp2_card *card, const struct firmware *fw) { - struct rp2_card *card = context; resource_size_t phys_base; - int i, rc = -ENOENT; - - if (!fw) { - dev_err(&card->pdev->dev, "cannot find '%s' firmware image\n", - RP2_FW_NAME); - goto no_fw; - } + int i, rc = 0; phys_base = pci_resource_start(card->pdev, 1); @@ -723,23 +715,13 @@ static void rp2_fw_cb(const struct firmware *fw, void *context) card->initialized_ports++; } - release_firmware(fw); -no_fw: - /* - * rp2_fw_cb() is called from a workqueue long after rp2_probe() - * has already returned success. So if something failed here, - * we'll just leave the now-dormant device in place until somebody - * unbinds it. - */ - if (rc) - dev_warn(&card->pdev->dev, "driver initialization failed\n"); - - complete(&card->fw_loaded); + return rc; } static int rp2_probe(struct pci_dev *pdev, const struct pci_device_id *id) { + const struct firmware *fw; struct rp2_card *card; struct rp2_uart_port *ports; void __iomem * const *bars; @@ -750,7 +732,6 @@ static int rp2_probe(struct pci_dev *pdev, return -ENOMEM; pci_set_drvdata(pdev, card); spin_lock_init(&card->card_lock); - init_completion(&card->fw_loaded); rc = pcim_enable_device(pdev); if (rc) @@ -783,22 +764,24 @@ static int rp2_probe(struct pci_dev *pdev, return -ENOMEM; card->ports = ports; + rc = request_firmware(&fw, RP2_FW_NAME, &pdev->dev); + if (rc < 0) { + dev_err(&pdev->dev, "cannot find '%s' firmware image\n", + RP2_FW_NAME); + return rc; + } + + rc = rp2_load_firmware(card, fw); + + release_firmware(fw); + if (rc < 0) + return rc; + rc = devm_request_irq(&pdev->dev, pdev->irq, rp2_uart_interrupt, IRQF_SHARED, DRV_NAME, card); if (rc) return rc; - /* - * Only catastrophic errors (e.g. ENOMEM) are reported here. - * If the FW image is missing, we'll find out in rp2_fw_cb() - * and print an error message. - */ - rc = request_firmware_nowait(THIS_MODULE, 1, RP2_FW_NAME, &pdev->dev, - GFP_KERNEL, card, rp2_fw_cb); - if (rc) - return rc; - dev_dbg(&pdev->dev, "waiting for firmware blob...\n"); - return 0; } @@ -806,7 +789,6 @@ static void rp2_remove(struct pci_dev *pdev) { struct rp2_card *card = pci_get_drvdata(pdev); - wait_for_completion(&card->fw_loaded); rp2_remove_ports(card); } diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index ea35f5144237..b4f528d26bf1 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -612,6 +612,14 @@ static void sci_stop_tx(struct uart_port *port) ctrl &= ~SCSCR_TIE; serial_port_out(port, SCSCR, ctrl); + +#ifdef CONFIG_SERIAL_SH_SCI_DMA + if (to_sci_port(port)->chan_tx && + !dma_submit_error(to_sci_port(port)->cookie_tx)) { + dmaengine_terminate_async(to_sci_port(port)->chan_tx); + to_sci_port(port)->cookie_tx = -EINVAL; + } +#endif } static void sci_start_rx(struct uart_port *port) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 2fa7527b1230..8c74d9ebfc50 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -838,7 +838,7 @@ static inline int resize_screen(struct vc_data *vc, int width, int height, /* Resizes the resolution of the display adapater */ int err = 0; - if (vc->vc_mode != KD_GRAPHICS && vc->vc_sw->con_resize) + if (vc->vc_sw->con_resize) err = vc->vc_sw->con_resize(vc, width, height, user); return err; diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 275ec49b30b9..9206fd248935 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -898,17 +898,17 @@ int vt_ioctl(struct tty_struct *tty, if (vcp) { int ret; int save_scan_lines = vcp->vc_scan_lines; - int save_font_height = vcp->vc_font.height; + int save_cell_height = vcp->vc_cell_height; if (v.v_vlin) vcp->vc_scan_lines = v.v_vlin; if (v.v_clin) - vcp->vc_font.height = v.v_clin; + vcp->vc_cell_height = v.v_clin; vcp->vc_resize_user = 1; ret = vc_resize(vcp, v.v_cols, v.v_rows); if (ret) { vcp->vc_scan_lines = save_scan_lines; - vcp->vc_font.height = save_font_height; + vcp->vc_cell_height = save_cell_height; console_unlock(); return ret; } diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index a70d2341ada6..23df1549eb0d 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1894,6 +1894,11 @@ static const struct usb_device_id acm_ids[] = { .driver_info = IGNORE_DEVICE, }, + /* Exclude Heimann Sensor GmbH USB appset demo */ + { USB_DEVICE(0x32a7, 0x0000), + .driver_info = IGNORE_DEVICE, + }, + /* control interfaces without any protocol set */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, USB_CDC_PROTO_NONE) }, diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index 34c1a7e22aae..be5075d41406 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h @@ -151,8 +151,10 @@ static inline unsigned hub_power_on_good_delay(struct usb_hub *hub) { unsigned delay = hub->descriptor->bPwrOn2PwrGood * 2; - /* Wait at least 100 msec for power to become stable */ - return max(delay, 100U); + if (!hub->hdev->parent) /* root hub */ + return delay; + else /* Wait at least 100 msec for power to become stable */ + return max(delay, 100U); } static inline int hub_port_debounce_be_connected(struct usb_hub *hub, diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 66e0112d9983..6adc3c956b77 100755 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1404,8 +1404,8 @@ static int dwc3_remove(struct platform_device *pdev) */ res->start -= DWC3_GLOBALS_REGS_START; - dwc3_debugfs_exit(dwc); dwc3_core_exit_mode(dwc); + dwc3_debugfs_exit(dwc); dwc3_core_exit(dwc); dwc3_ulpi_exit(dwc); diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 96ec3340bc43..9652610745ff 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -354,6 +354,9 @@ static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le) epnum |= 1; dep = dwc->eps[epnum]; + if (dep == NULL) + return NULL; + if (dep->flags & DWC3_EP_ENABLED) return dep; diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index 9b9d31eb6037..2695a4db3829 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c @@ -168,6 +168,14 @@ int usb_assign_descriptors(struct usb_function *f, { struct usb_gadget *g = f->config->cdev->gadget; + /* super-speed-plus descriptor falls back to super-speed one, + * if such a descriptor was provided, thus avoiding a NULL + * pointer dereference if a 5gbps capable gadget is used with + * a 10gbps capable config (device port + cable + host port) + */ + if (!ssp) + ssp = ss; + if (fs) { f->fs_descriptors = usb_copy_descriptors(fs); if (!f->fs_descriptors) diff --git a/drivers/usb/gadget/function/f_ecm.c b/drivers/usb/gadget/function/f_ecm.c index a3a4e5da90f7..65f74437c0ea 100644 --- a/drivers/usb/gadget/function/f_ecm.c +++ b/drivers/usb/gadget/function/f_ecm.c @@ -811,7 +811,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) fs_ecm_notify_desc.bEndpointAddress; status = usb_assign_descriptors(f, ecm_fs_function, ecm_hs_function, - ecm_ss_function, NULL); + ecm_ss_function, ecm_ss_function); if (status) goto fail; diff --git a/drivers/usb/gadget/function/f_eem.c b/drivers/usb/gadget/function/f_eem.c index 007ec6e4a5d4..b8fcc202e0a3 100644 --- a/drivers/usb/gadget/function/f_eem.c +++ b/drivers/usb/gadget/function/f_eem.c @@ -34,6 +34,11 @@ struct f_eem { u8 ctrl_id; }; +struct in_context { + struct sk_buff *skb; + struct usb_ep *ep; +}; + static inline struct f_eem *func_to_eem(struct usb_function *f) { return container_of(f, struct f_eem, port.func); @@ -309,7 +314,7 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f) eem_ss_out_desc.bEndpointAddress = eem_fs_out_desc.bEndpointAddress; status = usb_assign_descriptors(f, eem_fs_function, eem_hs_function, - eem_ss_function, NULL); + eem_ss_function, eem_ss_function); if (status) goto fail; @@ -327,9 +332,12 @@ fail: static void eem_cmd_complete(struct usb_ep *ep, struct usb_request *req) { - struct sk_buff *skb = (struct sk_buff *)req->context; + struct in_context *ctx = req->context; - dev_kfree_skb_any(skb); + dev_kfree_skb_any(ctx->skb); + kfree(req->buf); + usb_ep_free_request(ctx->ep, req); + kfree(ctx); } /* @@ -417,7 +425,9 @@ static int eem_unwrap(struct gether *port, * b15: bmType (0 == data, 1 == command) */ if (header & BIT(15)) { - struct usb_request *req = cdev->req; + struct usb_request *req; + struct in_context *ctx; + struct usb_ep *ep; u16 bmEEMCmd; /* EEM command packet format: @@ -446,11 +456,36 @@ static int eem_unwrap(struct gether *port, skb_trim(skb2, len); put_unaligned_le16(BIT(15) | BIT(11) | len, skb_push(skb2, 2)); + + ep = port->in_ep; + req = usb_ep_alloc_request(ep, GFP_ATOMIC); + if (!req) { + dev_kfree_skb_any(skb2); + goto next; + } + + req->buf = kmalloc(skb2->len, GFP_KERNEL); + if (!req->buf) { + usb_ep_free_request(ep, req); + dev_kfree_skb_any(skb2); + goto next; + } + + ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) { + kfree(req->buf); + usb_ep_free_request(ep, req); + dev_kfree_skb_any(skb2); + goto next; + } + ctx->skb = skb2; + ctx->ep = ep; + skb_copy_bits(skb2, 0, req->buf, skb2->len); req->length = skb2->len; req->complete = eem_cmd_complete; req->zero = 1; - req->context = skb2; + req->context = ctx; if (usb_ep_queue(port->in_ep, req, GFP_ATOMIC)) DBG(cdev, "echo response queue fail\n"); break; @@ -502,7 +537,7 @@ static int eem_unwrap(struct gether *port, skb2 = skb_clone(skb, GFP_ATOMIC); if (unlikely(!skb2)) { DBG(cdev, "unable to unframe EEM packet\n"); - continue; + goto next; } skb_trim(skb2, len - ETH_FCS_LEN); @@ -513,7 +548,7 @@ static int eem_unwrap(struct gether *port, if (unlikely(!skb3)) { DBG(cdev, "unable to realign EEM packet\n"); dev_kfree_skb_any(skb2); - continue; + goto next; } dev_kfree_skb_any(skb2); skb_queue_tail(list, skb3); diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 42e5677d932d..dd415b1589b5 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -91,7 +91,7 @@ static struct usb_interface_descriptor hidg_interface_desc = { static struct hid_descriptor hidg_desc = { .bLength = sizeof hidg_desc, .bDescriptorType = HID_DT_HID, - .bcdHID = 0x0101, + .bcdHID = cpu_to_le16(0x0101), .bCountryCode = 0x00, .bNumDescriptors = 0x1, /*.desc[0].bDescriptorType = DYNAMIC */ diff --git a/drivers/usb/gadget/function/f_loopback.c b/drivers/usb/gadget/function/f_loopback.c index e70093835e14..8c1810d65598 100644 --- a/drivers/usb/gadget/function/f_loopback.c +++ b/drivers/usb/gadget/function/f_loopback.c @@ -211,7 +211,7 @@ autoconf_fail: ss_loop_sink_desc.bEndpointAddress = fs_loop_sink_desc.bEndpointAddress; ret = usb_assign_descriptors(f, fs_loopback_descs, hs_loopback_descs, - ss_loopback_descs, NULL); + ss_loopback_descs, ss_loopback_descs); if (ret) return ret; diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index 9191653ffccc..494e7148d6f2 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -587,7 +587,7 @@ static void ncm_do_notify(struct f_ncm *ncm) data[0] = cpu_to_le32(ncm_bitrate(cdev->gadget)); data[1] = data[0]; - DBG(cdev, "notify speed %d\n", ncm_bitrate(cdev->gadget)); + DBG(cdev, "notify speed %u\n", ncm_bitrate(cdev->gadget)); ncm->notify_state = NCM_NOTIFY_CONNECT; break; } diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index b3d036d06553..c347fe13d45d 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -1057,7 +1057,8 @@ autoconf_fail: ss_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; ret = usb_assign_descriptors(f, fs_printer_function, - hs_printer_function, ss_printer_function, NULL); + hs_printer_function, ss_printer_function, + ss_printer_function); if (ret) return ret; diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index 4db5b76bc397..970f7bea89d4 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c @@ -912,7 +912,7 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) ss_notify_desc.bEndpointAddress = fs_notify_desc.bEndpointAddress; status = usb_assign_descriptors(f, eth_fs_function, eth_hs_function, - eth_ss_function, NULL); + eth_ss_function, eth_ss_function); if (status) goto fail; diff --git a/drivers/usb/gadget/function/f_serial.c b/drivers/usb/gadget/function/f_serial.c index 405becf941f6..89d15954d337 100644 --- a/drivers/usb/gadget/function/f_serial.c +++ b/drivers/usb/gadget/function/f_serial.c @@ -665,7 +665,7 @@ static int gser_bind(struct usb_configuration *c, struct usb_function *f) } status = usb_assign_descriptors(f, gser_fs_function, gser_hs_function, - gser_ss_function, NULL); + gser_ss_function, gser_ss_function); if (status) goto fail; dev_dbg(&cdev->gadget->dev, "generic ttyGS%d: %s speed IN/%s OUT/%s\n", diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index 6e9d958004a0..1c5745f7abea 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c @@ -435,7 +435,8 @@ no_iso: ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress; ret = usb_assign_descriptors(f, fs_source_sink_descs, - hs_source_sink_descs, ss_source_sink_descs, NULL); + hs_source_sink_descs, ss_source_sink_descs, + ss_source_sink_descs); if (ret) return ret; diff --git a/drivers/usb/gadget/function/f_subset.c b/drivers/usb/gadget/function/f_subset.c index 434b983f3b4c..055bd0706cdd 100644 --- a/drivers/usb/gadget/function/f_subset.c +++ b/drivers/usb/gadget/function/f_subset.c @@ -362,7 +362,7 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) fs_subset_out_desc.bEndpointAddress; status = usb_assign_descriptors(f, fs_eth_function, hs_eth_function, - ss_eth_function, NULL); + ss_eth_function, ss_eth_function); if (status) goto fail; diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index 7e8e262b3629..821f470c6a2f 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -2071,7 +2071,8 @@ static int tcm_bind(struct usb_configuration *c, struct usb_function *f) uasp_fs_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress; ret = usb_assign_descriptors(f, uasp_fs_function_desc, - uasp_hs_function_desc, uasp_ss_function_desc, NULL); + uasp_hs_function_desc, uasp_ss_function_desc, + uasp_ss_function_desc); if (ret) goto ep_fail; diff --git a/drivers/usb/gadget/legacy/hid.c b/drivers/usb/gadget/legacy/hid.c index a71a884f79fc..cccbb948821b 100644 --- a/drivers/usb/gadget/legacy/hid.c +++ b/drivers/usb/gadget/legacy/hid.c @@ -175,8 +175,10 @@ static int hid_bind(struct usb_composite_dev *cdev) struct usb_descriptor_header *usb_desc; usb_desc = usb_otg_descriptor_alloc(gadget); - if (!usb_desc) + if (!usb_desc) { + status = -ENOMEM; goto put; + } usb_otg_descriptor_init(gadget, usb_desc); otg_desc[0] = usb_desc; otg_desc[1] = NULL; diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c index 9795457723d8..ad71840db899 100644 --- a/drivers/usb/misc/trancevibrator.c +++ b/drivers/usb/misc/trancevibrator.c @@ -74,9 +74,9 @@ static ssize_t set_speed(struct device *dev, struct device_attribute *attr, /* Set speed */ retval = usb_control_msg(tv->udev, usb_sndctrlpipe(tv->udev, 0), 0x01, /* vendor request: set speed */ - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, tv->speed, /* speed value */ - 0, NULL, 0, USB_CTRL_GET_TIMEOUT); + 0, NULL, 0, USB_CTRL_SET_TIMEOUT); if (retval) { tv->speed = old; dev_dbg(&tv->udev->dev, "retval = %d\n", retval); diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index e77465a30ac6..0ec6d76d1563 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c @@ -750,6 +750,7 @@ static int uss720_probe(struct usb_interface *intf, parport_announce_port(pp); usb_set_intfdata(intf, pp); + usb_put_dev(usbdev); return 0; probe_abort: diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index c9f979063af1..8f4bd9fa8244 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -606,6 +606,7 @@ static const struct usb_device_id id_table_combined[] = { .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(FTDI_VID, FTDI_NT_ORIONLX_PLUS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_NT_ORION_IO_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_NT_ORIONMX_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SYNAPSE_SS200_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CUSTOMWARE_MINIPLEX_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CUSTOMWARE_MINIPLEX2_PID) }, @@ -1029,6 +1030,9 @@ static const struct usb_device_id id_table_combined[] = { /* Sienna devices */ { USB_DEVICE(FTDI_VID, FTDI_SIENNA_PID) }, { USB_DEVICE(ECHELON_VID, ECHELON_U20_PID) }, + /* IDS GmbH devices */ + { USB_DEVICE(IDS_VID, IDS_SI31A_PID) }, + { USB_DEVICE(IDS_VID, IDS_CM31A_PID) }, /* U-Blox devices */ { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ZED_PID) }, { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ODIN_PID) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index f3302516a1e4..54ded2bc9eb6 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -580,6 +580,7 @@ #define FTDI_NT_ORIONLXM_PID 0x7c90 /* OrionLXm Substation Automation Platform */ #define FTDI_NT_ORIONLX_PLUS_PID 0x7c91 /* OrionLX+ Substation Automation Platform */ #define FTDI_NT_ORION_IO_PID 0x7c92 /* Orion I/O */ +#define FTDI_NT_ORIONMX_PID 0x7c93 /* OrionMX */ /* * Synapse Wireless product ids (FTDI_VID) @@ -1566,6 +1567,13 @@ #define UNJO_VID 0x22B7 #define UNJO_ISODEBUG_V1_PID 0x150D +/* + * IDS GmbH + */ +#define IDS_VID 0x2CAF +#define IDS_SI31A_PID 0x13A2 +#define IDS_CM31A_PID 0x13A3 + /* * U-Blox products (http://www.u-blox.com). */ diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 76564b3bebb9..cc0bf59bd08d 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -27,6 +27,7 @@ #define ZYXEL_VENDOR_ID 0x0586 #define ZYXEL_OMNINET_ID 0x1000 +#define ZYXEL_OMNI_56K_PLUS_ID 0x1500 /* This one seems to be a re-branded ZyXEL device */ #define BT_IGNITIONPRO_ID 0x2000 @@ -44,6 +45,7 @@ static int omninet_port_remove(struct usb_serial_port *port); static const struct usb_device_id id_table[] = { { USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) }, + { USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNI_56K_PLUS_ID) }, { USB_DEVICE(ZYXEL_VENDOR_ID, BT_IGNITIONPRO_ID) }, { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 351be7386280..6faa9ac53887 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1222,6 +1222,10 @@ static const struct usb_device_id option_ids[] = { .driver_info = NCTRL(0) | RSVD(1) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1901, 0xff), /* Telit LN940 (MBIM) */ .driver_info = NCTRL(0) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x7010, 0xff), /* Telit LE910-S1 (RNDIS) */ + .driver_info = NCTRL(2) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x7011, 0xff), /* Telit LE910-S1 (ECM) */ + .driver_info = NCTRL(2) }, { USB_DEVICE(TELIT_VENDOR_ID, 0x9010), /* Telit SBL FN980 flashing device */ .driver_info = NCTRL(0) | ZLP }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index bf5533d6d83b..3dd0bbb36dd2 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -102,6 +102,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, + { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530GC_PRODUCT_ID) }, { USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) }, { USB_DEVICE(AT_VENDOR_ID, AT_VTKIT3_PRODUCT_ID) }, { } /* Terminating entry */ diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 9d27c076f477..62b8cd673aa1 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -156,6 +156,7 @@ /* ADLINK ND-6530 RS232,RS485 and RS422 adapter */ #define ADLINK_VENDOR_ID 0x0b63 #define ADLINK_ND6530_PRODUCT_ID 0x6530 +#define ADLINK_ND6530GC_PRODUCT_ID 0x653a /* SMART USB Serial Adapter */ #define SMART_VENDOR_ID 0x0b8c diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 19952ccd028a..ba69acaa7a30 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c @@ -419,7 +419,7 @@ static void qt2_close(struct usb_serial_port *port) /* flush the port transmit buffer */ i = usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), + usb_sndctrlpipe(serial->dev, 0), QT2_FLUSH_DEVICE, 0x40, 1, port_priv->device_port, NULL, 0, QT2_USB_TIMEOUT); @@ -429,7 +429,7 @@ static void qt2_close(struct usb_serial_port *port) /* flush the port receive buffer */ i = usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), + usb_sndctrlpipe(serial->dev, 0), QT2_FLUSH_DEVICE, 0x40, 0, port_priv->device_port, NULL, 0, QT2_USB_TIMEOUT); @@ -701,7 +701,7 @@ static int qt2_attach(struct usb_serial *serial) int status; /* power on unit */ - status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), + status = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 0xc2, 0x40, 0x8000, 0, NULL, 0, QT2_USB_TIMEOUT); if (status < 0) { diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index a7e41723c34c..720bcf29d4f6 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -41,6 +41,7 @@ /* Vendor and product ids */ #define TI_VENDOR_ID 0x0451 #define IBM_VENDOR_ID 0x04b3 +#define STARTECH_VENDOR_ID 0x14b0 #define TI_3410_PRODUCT_ID 0x3410 #define IBM_4543_PRODUCT_ID 0x4543 #define IBM_454B_PRODUCT_ID 0x454b @@ -378,6 +379,7 @@ static const struct usb_device_id ti_id_table_3410[] = { { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1131_PRODUCT_ID) }, { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1150_PRODUCT_ID) }, { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1151_PRODUCT_ID) }, + { USB_DEVICE(STARTECH_VENDOR_ID, TI_3410_PRODUCT_ID) }, { } /* terminator */ }; @@ -416,6 +418,7 @@ static const struct usb_device_id ti_id_table_combined[] = { { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1131_PRODUCT_ID) }, { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1150_PRODUCT_ID) }, { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1151_PRODUCT_ID) }, + { USB_DEVICE(STARTECH_VENDOR_ID, TI_3410_PRODUCT_ID) }, { } /* terminator */ }; diff --git a/drivers/vfio/pci/Kconfig b/drivers/vfio/pci/Kconfig index 24ee2605b9f0..0da884bfc7a8 100644 --- a/drivers/vfio/pci/Kconfig +++ b/drivers/vfio/pci/Kconfig @@ -1,6 +1,7 @@ config VFIO_PCI tristate "VFIO support for PCI devices" depends on VFIO && PCI && EVENTFD + depends on MMU select VFIO_VIRQFD select IRQ_BYPASS_MANAGER help diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c index f3c2de04b20d..5b0f09b211be 100644 --- a/drivers/vfio/pci/vfio_pci_config.c +++ b/drivers/vfio/pci/vfio_pci_config.c @@ -1576,7 +1576,7 @@ static int vfio_ecap_init(struct vfio_pci_device *vdev) if (len == 0xFF) { len = vfio_ext_cap_len(vdev, ecap, epos); if (len < 0) - return ret; + return len; } } diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c index d143d08c4f0f..9b1b6c1e218d 100644 --- a/drivers/vfio/platform/vfio_platform_common.c +++ b/drivers/vfio/platform/vfio_platform_common.c @@ -288,7 +288,7 @@ err_irq: vfio_platform_regions_cleanup(vdev); err_reg: mutex_unlock(&driver_lock); - module_put(THIS_MODULE); + module_put(vdev->parent_module); return ret; } diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c index 1771220b2437..90a24b975240 100644 --- a/drivers/video/backlight/lm3630a_bl.c +++ b/drivers/video/backlight/lm3630a_bl.c @@ -183,7 +183,7 @@ static int lm3630a_bank_a_update_status(struct backlight_device *bl) if ((pwm_ctrl & LM3630A_PWM_BANK_A) != 0) { lm3630a_pwm_ctrl(pchip, bl->props.brightness, bl->props.max_brightness); - return bl->props.brightness; + return 0; } /* disable sleep */ @@ -203,8 +203,8 @@ static int lm3630a_bank_a_update_status(struct backlight_device *bl) return 0; out_i2c_err: - dev_err(pchip->dev, "i2c failed to access\n"); - return bl->props.brightness; + dev_err(pchip->dev, "i2c failed to access (%pe)\n", ERR_PTR(ret)); + return ret; } static int lm3630a_bank_a_get_brightness(struct backlight_device *bl) @@ -260,7 +260,7 @@ static int lm3630a_bank_b_update_status(struct backlight_device *bl) if ((pwm_ctrl & LM3630A_PWM_BANK_B) != 0) { lm3630a_pwm_ctrl(pchip, bl->props.brightness, bl->props.max_brightness); - return bl->props.brightness; + return 0; } /* disable sleep */ @@ -280,8 +280,8 @@ static int lm3630a_bank_b_update_status(struct backlight_device *bl) return 0; out_i2c_err: - dev_err(pchip->dev, "i2c failed to access REG_CTRL\n"); - return bl->props.brightness; + dev_err(pchip->dev, "i2c failed to access (%pe)\n", ERR_PTR(ret)); + return ret; } static int lm3630a_bank_b_get_brightness(struct backlight_device *bl) diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 44df6f6fd063..510bc3f51dcc 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -1986,7 +1986,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, return -EINVAL; DPRINTK("resize now %ix%i\n", var.xres, var.yres); - if (con_is_visible(vc)) { + if (con_is_visible(vc) && vc->vc_mode == KD_TEXT) { var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; fb_set_var(info, &var); diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index b38ee2354cbf..cb9b87963129 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -434,7 +434,7 @@ static void vgacon_init(struct vc_data *c, int init) vc_resize(c, vga_video_num_columns, vga_video_num_lines); c->vc_scan_lines = vga_scan_lines; - c->vc_font.height = vga_video_font_height; + c->vc_font.height = c->vc_cell_height = vga_video_font_height; c->vc_complement_mask = 0x7700; if (vga_512_chars) c->vc_hi_font_mask = 0x0800; @@ -572,32 +572,32 @@ static void vgacon_cursor(struct vc_data *c, int mode) switch (c->vc_cursor_type & 0x0f) { case CUR_UNDERLINE: vgacon_set_cursor_size(c->vc_x, - c->vc_font.height - - (c->vc_font.height < + c->vc_cell_height - + (c->vc_cell_height < 10 ? 2 : 3), - c->vc_font.height - - (c->vc_font.height < + c->vc_cell_height - + (c->vc_cell_height < 10 ? 1 : 2)); break; case CUR_TWO_THIRDS: vgacon_set_cursor_size(c->vc_x, - c->vc_font.height / 3, - c->vc_font.height - - (c->vc_font.height < + c->vc_cell_height / 3, + c->vc_cell_height - + (c->vc_cell_height < 10 ? 1 : 2)); break; case CUR_LOWER_THIRD: vgacon_set_cursor_size(c->vc_x, - (c->vc_font.height * 2) / 3, - c->vc_font.height - - (c->vc_font.height < + (c->vc_cell_height * 2) / 3, + c->vc_cell_height - + (c->vc_cell_height < 10 ? 1 : 2)); break; case CUR_LOWER_HALF: vgacon_set_cursor_size(c->vc_x, - c->vc_font.height / 2, - c->vc_font.height - - (c->vc_font.height < + c->vc_cell_height / 2, + c->vc_cell_height - + (c->vc_cell_height < 10 ? 1 : 2)); break; case CUR_NONE: @@ -608,7 +608,7 @@ static void vgacon_cursor(struct vc_data *c, int mode) break; default: vgacon_set_cursor_size(c->vc_x, 1, - c->vc_font.height); + c->vc_cell_height); break; } break; @@ -619,13 +619,13 @@ static int vgacon_doresize(struct vc_data *c, unsigned int width, unsigned int height) { unsigned long flags; - unsigned int scanlines = height * c->vc_font.height; + unsigned int scanlines = height * c->vc_cell_height; u8 scanlines_lo = 0, r7 = 0, vsync_end = 0, mode, max_scan; raw_spin_lock_irqsave(&vga_lock, flags); vgacon_xres = width * VGA_FONTWIDTH; - vgacon_yres = height * c->vc_font.height; + vgacon_yres = height * c->vc_cell_height; if (vga_video_type >= VIDEO_TYPE_VGAC) { outb_p(VGA_CRTC_MAX_SCAN, vga_video_port_reg); max_scan = inb_p(vga_video_port_val); @@ -680,9 +680,9 @@ static int vgacon_doresize(struct vc_data *c, static int vgacon_switch(struct vc_data *c) { int x = c->vc_cols * VGA_FONTWIDTH; - int y = c->vc_rows * c->vc_font.height; + int y = c->vc_rows * c->vc_cell_height; int rows = screen_info.orig_video_lines * vga_default_font_height/ - c->vc_font.height; + c->vc_cell_height; /* * We need to save screen size here as it's the only way * we can spot the screen has been resized and we need to @@ -1120,7 +1120,7 @@ static int vgacon_adjust_height(struct vc_data *vc, unsigned fontheight) cursor_size_lastto = 0; c->vc_sw->con_cursor(c, CM_DRAW); } - c->vc_font.height = fontheight; + c->vc_font.height = c->vc_cell_height = fontheight; vc_resize(c, 0, rows); /* Adjust console size */ } } @@ -1174,12 +1174,20 @@ static int vgacon_resize(struct vc_data *c, unsigned int width, if ((width << 1) * height > vga_vram_size) return -EINVAL; + if (user) { + /* + * Ho ho! Someone (svgatextmode, eh?) may have reprogrammed + * the video mode! Set the new defaults then and go away. + */ + screen_info.orig_video_cols = width; + screen_info.orig_video_lines = height; + vga_default_font_height = c->vc_cell_height; + return 0; + } if (width % 2 || width > screen_info.orig_video_cols || height > (screen_info.orig_video_lines * vga_default_font_height)/ - c->vc_font.height) - /* let svgatextmode tinker with video timings and - return success */ - return (user) ? 0 : -EINVAL; + c->vc_cell_height) + return -EINVAL; if (con_is_visible(c) && !vga_is_gfx) /* who knows */ vgacon_doresize(c, width, height); diff --git a/drivers/video/fbdev/hgafb.c b/drivers/video/fbdev/hgafb.c index 59e1cae57948..03c0b1b8747b 100644 --- a/drivers/video/fbdev/hgafb.c +++ b/drivers/video/fbdev/hgafb.c @@ -286,7 +286,7 @@ static int hga_card_detect(void) hga_vram = ioremap(0xb0000, hga_vram_len); if (!hga_vram) - goto error; + return -ENOMEM; if (request_region(0x3b0, 12, "hgafb")) release_io_ports = 1; @@ -346,13 +346,18 @@ static int hga_card_detect(void) hga_type_name = "Hercules"; break; } - return 1; + return 0; error: if (release_io_ports) release_region(0x3b0, 12); if (release_io_port) release_region(0x3bf, 1); - return 0; + + iounmap(hga_vram); + + pr_err("hgafb: HGA card not detected.\n"); + + return -EINVAL; } /** @@ -550,13 +555,11 @@ static struct fb_ops hgafb_ops = { static int hgafb_probe(struct platform_device *pdev) { struct fb_info *info; + int ret; - if (! hga_card_detect()) { - printk(KERN_INFO "hgafb: HGA card not detected.\n"); - if (hga_vram) - iounmap(hga_vram); - return -EINVAL; - } + ret = hga_card_detect(); + if (ret) + return ret; printk(KERN_INFO "hgafb: %s with %ldK of memory detected.\n", hga_type_name, hga_vram_len/1024); diff --git a/drivers/video/fbdev/imsttfb.c b/drivers/video/fbdev/imsttfb.c index 4ef9dc94e813..4363c64d74e8 100644 --- a/drivers/video/fbdev/imsttfb.c +++ b/drivers/video/fbdev/imsttfb.c @@ -1516,11 +1516,6 @@ static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) info->fix.smem_start = addr; info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ? 0x400000 : 0x800000); - if (!info->screen_base) { - release_mem_region(addr, size); - framebuffer_release(info); - return -ENOMEM; - } info->fix.mmio_start = addr + 0x800000; par->dc_regs = ioremap(addr + 0x800000, 0x1000); par->cmap_regs_phys = addr + 0x840000; diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c index f5ad8023c2e6..1c47e6345b57 100644 --- a/drivers/watchdog/aspeed_wdt.c +++ b/drivers/watchdog/aspeed_wdt.c @@ -100,7 +100,7 @@ static int aspeed_wdt_set_timeout(struct watchdog_device *wdd, wdd->timeout = timeout; - actual = min(timeout, wdd->max_hw_heartbeat_ms * 1000); + actual = min(timeout, wdd->max_hw_heartbeat_ms / 1000); writel(actual * WDT_RATE_1MHZ, wdt->base + WDT_RELOAD_VALUE); writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART); diff --git a/drivers/watchdog/lpc18xx_wdt.c b/drivers/watchdog/lpc18xx_wdt.c index fd171e6caa16..1b63d1d85aa0 100644 --- a/drivers/watchdog/lpc18xx_wdt.c +++ b/drivers/watchdog/lpc18xx_wdt.c @@ -300,7 +300,7 @@ static int lpc18xx_wdt_remove(struct platform_device *pdev) struct lpc18xx_wdt_dev *lpc18xx_wdt = platform_get_drvdata(pdev); dev_warn(&pdev->dev, "I quit now, hardware will probably reboot!\n"); - del_timer(&lpc18xx_wdt->timer); + del_timer_sync(&lpc18xx_wdt->timer); watchdog_unregister_device(&lpc18xx_wdt->wdt_dev); clk_disable_unprepare(lpc18xx_wdt->wdt_clk); diff --git a/drivers/watchdog/sbc60xxwdt.c b/drivers/watchdog/sbc60xxwdt.c index 2eef58a0cf05..152db059d5aa 100644 --- a/drivers/watchdog/sbc60xxwdt.c +++ b/drivers/watchdog/sbc60xxwdt.c @@ -152,7 +152,7 @@ static void wdt_startup(void) static void wdt_turnoff(void) { /* Stop the timer */ - del_timer(&timer); + del_timer_sync(&timer); inb_p(wdt_stop); pr_info("Watchdog timer is now disabled...\n"); } diff --git a/drivers/watchdog/sc520_wdt.c b/drivers/watchdog/sc520_wdt.c index 1cfd3f6a13d5..08500db8324f 100644 --- a/drivers/watchdog/sc520_wdt.c +++ b/drivers/watchdog/sc520_wdt.c @@ -190,7 +190,7 @@ static int wdt_startup(void) static int wdt_turnoff(void) { /* Stop the timer */ - del_timer(&timer); + del_timer_sync(&timer); /* Stop the watchdog */ wdt_config(0); diff --git a/drivers/watchdog/w83877f_wdt.c b/drivers/watchdog/w83877f_wdt.c index f0483c75ed32..4b52cf321747 100644 --- a/drivers/watchdog/w83877f_wdt.c +++ b/drivers/watchdog/w83877f_wdt.c @@ -170,7 +170,7 @@ static void wdt_startup(void) static void wdt_turnoff(void) { /* Stop the timer */ - del_timer(&timer); + del_timer_sync(&timer); wdt_change(WDT_DISABLE); diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c index ea307f40cab1..c6e6b7470cbf 100644 --- a/drivers/xen/events/events_base.c +++ b/drivers/xen/events/events_base.c @@ -533,6 +533,9 @@ static void xen_irq_lateeoi_locked(struct irq_info *info, bool spurious) } info->eoi_time = 0; + + /* is_active hasn't been reset yet, do it now. */ + smp_store_release(&info->is_active, 0); do_unmask(info, EVT_MASK_REASON_EOI_PENDING); } @@ -1778,10 +1781,22 @@ static void lateeoi_ack_dynirq(struct irq_data *data) struct irq_info *info = info_for_irq(data->irq); evtchn_port_t evtchn = info ? info->evtchn : 0; - if (VALID_EVTCHN(evtchn)) { - do_mask(info, EVT_MASK_REASON_EOI_PENDING); - ack_dynirq(data); - } + if (!VALID_EVTCHN(evtchn)) + return; + + do_mask(info, EVT_MASK_REASON_EOI_PENDING); + + if (unlikely(irqd_is_setaffinity_pending(data)) && + likely(!irqd_irq_disabled(data))) { + do_mask(info, EVT_MASK_REASON_TEMPORARY); + + clear_evtchn(evtchn); + + irq_move_masked_irq(data); + + do_unmask(info, EVT_MASK_REASON_TEMPORARY); + } else + clear_evtchn(evtchn); } static void lateeoi_mask_ack_dynirq(struct irq_data *data) diff --git a/drivers/xen/xen-pciback/vpci.c b/drivers/xen/xen-pciback/vpci.c index c99f8bb1c56c..e6c7509a3d87 100644 --- a/drivers/xen/xen-pciback/vpci.c +++ b/drivers/xen/xen-pciback/vpci.c @@ -68,7 +68,7 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, struct pci_dev *dev, int devid, publish_pci_dev_cb publish_cb) { - int err = 0, slot, func = -1; + int err = 0, slot, func = PCI_FUNC(dev->devfn); struct pci_dev_entry *t, *dev_entry; struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; @@ -93,23 +93,26 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, /* * Keep multi-function devices together on the virtual PCI bus, except - * virtual functions. + * that we want to keep virtual functions at func 0 on their own. They + * aren't multi-function devices and hence their presence at func 0 + * may cause guests to not scan the other functions. */ - if (!dev->is_virtfn) { + if (!dev->is_virtfn || func) { for (slot = 0; slot < PCI_SLOT_MAX; slot++) { if (list_empty(&vpci_dev->dev_list[slot])) continue; t = list_entry(list_first(&vpci_dev->dev_list[slot]), struct pci_dev_entry, list); + if (t->dev->is_virtfn && !PCI_FUNC(t->dev->devfn)) + continue; if (match_slot(dev, t->dev)) { pr_info("vpci: %s: assign to virtual slot %d func %d\n", pci_name(dev), slot, - PCI_FUNC(dev->devfn)); + func); list_add_tail(&dev_entry->list, &vpci_dev->dev_list[slot]); - func = PCI_FUNC(dev->devfn); goto unlock; } } @@ -122,7 +125,6 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, pci_name(dev), slot); list_add_tail(&dev_entry->list, &vpci_dev->dev_list[slot]); - func = dev->is_virtfn ? 0 : PCI_FUNC(dev->devfn); goto unlock; } } diff --git a/drivers/xen/xen-pciback/xenbus.c b/drivers/xen/xen-pciback/xenbus.c index 36ec99cff507..291290533102 100644 --- a/drivers/xen/xen-pciback/xenbus.c +++ b/drivers/xen/xen-pciback/xenbus.c @@ -357,7 +357,8 @@ out: return err; } -static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev) +static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev, + enum xenbus_state state) { int err = 0; int num_devs; @@ -371,9 +372,7 @@ static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev) dev_dbg(&pdev->xdev->dev, "Reconfiguring device ...\n"); mutex_lock(&pdev->dev_lock); - /* Make sure we only reconfigure once */ - if (xenbus_read_driver_state(pdev->xdev->nodename) != - XenbusStateReconfiguring) + if (xenbus_read_driver_state(pdev->xdev->nodename) != state) goto out; err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "num_devs", "%d", @@ -500,6 +499,10 @@ static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev) } } + if (state != XenbusStateReconfiguring) + /* Make sure we only reconfigure once. */ + goto out; + err = xenbus_switch_state(pdev->xdev, XenbusStateReconfigured); if (err) { xenbus_dev_fatal(pdev->xdev, err, @@ -525,7 +528,7 @@ static void xen_pcibk_frontend_changed(struct xenbus_device *xdev, break; case XenbusStateReconfiguring: - xen_pcibk_reconfigure(pdev); + xen_pcibk_reconfigure(pdev, XenbusStateReconfiguring); break; case XenbusStateConnected: @@ -664,6 +667,15 @@ static void xen_pcibk_be_watch(struct xenbus_watch *watch, xen_pcibk_setup_backend(pdev); break; + case XenbusStateInitialised: + /* + * We typically move to Initialised when the first device was + * added. Hence subsequent devices getting added may need + * reconfiguring. + */ + xen_pcibk_reconfigure(pdev, XenbusStateInitialised); + break; + default: break; } diff --git a/fs/btrfs/Kconfig b/fs/btrfs/Kconfig index 80e9c18ea64f..fd6b67c40d9d 100644 --- a/fs/btrfs/Kconfig +++ b/fs/btrfs/Kconfig @@ -9,6 +9,8 @@ config BTRFS_FS select RAID6_PQ select XOR_BLOCKS select SRCU + depends on !PPC_256K_PAGES # powerpc + depends on !PAGE_SIZE_256KB # hexagon help Btrfs is a general purpose copy-on-write filesystem with extents, diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 4d8f8a8c9c90..29e75fba5376 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c @@ -1076,6 +1076,14 @@ err_out: btrfs_delayed_inode_release_metadata(root, node); btrfs_release_delayed_inode(node); + /* + * If we fail to update the delayed inode we need to abort the + * transaction, because we could leave the inode with the improper + * counts behind. + */ + if (ret && ret != -ENOENT) + btrfs_abort_transaction(trans, ret); + return ret; search: diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index 4f919628137c..374d91830a90 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c @@ -608,7 +608,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, u64 end_byte = bytenr + len; u64 csum_end; struct extent_buffer *leaf; - int ret; + int ret = 0; u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy); int blocksize_bits = root->fs_info->sb->s_blocksize_bits; @@ -626,6 +626,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, path->leave_spinning = 1; ret = btrfs_search_slot(trans, root, &key, path, -1, 1); if (ret > 0) { + ret = 0; if (path->slots[0] == 0) break; path->slots[0]--; @@ -656,7 +657,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, if (key.offset >= bytenr && csum_end <= end_byte) { ret = btrfs_del_item(trans, root, path); if (ret) - goto out; + break; if (key.offset == bytenr) break; } else if (key.offset < bytenr && csum_end > end_byte) { @@ -700,8 +701,9 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, ret = btrfs_split_item(trans, root, path, &key, offset); if (ret && ret != -EAGAIN) { btrfs_abort_transaction(trans, ret); - goto out; + break; } + ret = 0; key.offset = end_byte - 1; } else { @@ -711,8 +713,6 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, } btrfs_release_path(path); } - ret = 0; -out: btrfs_free_path(path); return ret; } diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 03661b744eaf..79454ea77153 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1089,7 +1089,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, int del_nr = 0; int del_slot = 0; int recow; - int ret; + int ret = 0; u64 ino = btrfs_ino(inode); path = btrfs_alloc_path(); @@ -1309,7 +1309,7 @@ again: } out: btrfs_free_path(path); - return 0; + return ret; } /* diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 31df020634cd..d0fbe49420fc 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -1287,8 +1287,10 @@ int btrfs_defrag_root(struct btrfs_root *root) while (1) { trans = btrfs_start_transaction(root, 0); - if (IS_ERR(trans)) - return PTR_ERR(trans); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + break; + } ret = btrfs_defrag_leaves(trans, root); diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 9909b63d2acd..11ecd798864c 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -1529,6 +1529,7 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, break; if (ret == 1) { + ret = 0; if (path->slots[0] == 0) break; path->slots[0]--; @@ -1541,17 +1542,19 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, ret = btrfs_del_item(trans, root, path); if (ret) - goto out; + break; btrfs_release_path(path); inode = read_one_inode(root, key.offset); - if (!inode) - return -EIO; + if (!inode) { + ret = -EIO; + break; + } ret = fixup_inode_link_count(trans, root, inode); iput(inode); if (ret) - goto out; + break; /* * fixup on a directory may create new entries, @@ -1560,8 +1563,6 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, */ key.offset = (u64)-1; } - ret = 0; -out: btrfs_release_path(path); return ret; } @@ -1600,8 +1601,6 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans, ret = btrfs_update_inode(trans, root, inode); } else if (ret == -EEXIST) { ret = 0; - } else { - BUG(); /* Logic Error */ } iput(inode); diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 167221234d50..72ff09d0438c 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -72,10 +72,6 @@ static int ceph_set_page_dirty(struct page *page) struct inode *inode; struct ceph_inode_info *ci; struct ceph_snap_context *snapc; - int ret; - - if (unlikely(!mapping)) - return !TestSetPageDirty(page); if (PageDirty(page)) { dout("%p set_page_dirty %p idx %lu -- already dirty\n", @@ -121,11 +117,7 @@ static int ceph_set_page_dirty(struct page *page) page->private = (unsigned long)snapc; SetPagePrivate(page); - ret = __set_page_dirty_nobuffers(page); - WARN_ON(!PageLocked(page)); - WARN_ON(!page->mapping); - - return ret; + return __set_page_dirty_nobuffers(page); } /* diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 67edd6e03f80..fffba1b1da2e 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -629,6 +629,8 @@ smb2_clone_range(const unsigned int xid, cpu_to_le32(min_t(u32, len, tcon->max_bytes_chunk)); /* Request server copy to target from src identified by key */ + kfree(retbuf); + retbuf = NULL; rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid, trgtfile->fid.volatile_fid, FSCTL_SRV_COPYCHUNK_WRITE, true /* is_fsctl */, (char *)pcchunk, diff --git a/fs/configfs/file.c b/fs/configfs/file.c index 896e90dc9193..71f665eb0316 100644 --- a/fs/configfs/file.c +++ b/fs/configfs/file.c @@ -496,13 +496,13 @@ static int configfs_release_bin_file(struct inode *inode, struct file *file) buffer->bin_buffer_size); } up_read(&frag->frag_sem); - /* vfree on NULL is safe */ - vfree(buffer->bin_buffer); - buffer->bin_buffer = NULL; - buffer->bin_buffer_size = 0; - buffer->needs_read_fill = 1; } + vfree(buffer->bin_buffer); + buffer->bin_buffer = NULL; + buffer->bin_buffer_size = 0; + buffer->needs_read_fill = 1; + configfs_release(inode, file); return 0; } diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c index 019247b51718..8b208406dca8 100644 --- a/fs/crypto/fname.c +++ b/fs/crypto/fname.c @@ -276,13 +276,8 @@ int fscrypt_fname_disk_to_usr(struct inode *inode, oname->name); return 0; } - if (hash) { - digested_name.hash = hash; - digested_name.minor_hash = minor_hash; - } else { - digested_name.hash = 0; - digested_name.minor_hash = 0; - } + digested_name.hash = hash; + digested_name.minor_hash = minor_hash; memcpy(digested_name.digest, FSCRYPT_FNAME_DIGEST(iname->name, iname->len), FSCRYPT_FNAME_DIGEST_SIZE); diff --git a/fs/dlm/config.c b/fs/dlm/config.c index 6def89d2209d..10d25b7830bf 100644 --- a/fs/dlm/config.c +++ b/fs/dlm/config.c @@ -80,6 +80,9 @@ struct dlm_cluster { unsigned int cl_new_rsb_count; unsigned int cl_recover_callbacks; char cl_cluster_name[DLM_LOCKSPACE_LEN]; + + struct dlm_spaces *sps; + struct dlm_comms *cms; }; static struct dlm_cluster *config_item_to_cluster(struct config_item *i) @@ -356,6 +359,9 @@ static struct config_group *make_cluster(struct config_group *g, if (!cl || !sps || !cms) goto fail; + cl->sps = sps; + cl->cms = cms; + config_group_init_type_name(&cl->group, name, &cluster_type); config_group_init_type_name(&sps->ss_group, "spaces", &spaces_type); config_group_init_type_name(&cms->cs_group, "comms", &comms_type); @@ -405,6 +411,9 @@ static void drop_cluster(struct config_group *g, struct config_item *i) static void release_cluster(struct config_item *i) { struct dlm_cluster *cl = config_item_to_cluster(i); + + kfree(cl->sps); + kfree(cl->cms); kfree(cl); } diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 609998de533e..0d8aaf9c61be 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -599,7 +599,7 @@ static void close_connection(struct connection *con, bool and_other, } if (con->othercon && and_other) { /* Will only re-enter once. */ - close_connection(con->othercon, false, true, true); + close_connection(con->othercon, false, tx, rx); } if (con->rx_page) { __free_page(con->rx_page); diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index ff6cf23be8a2..cb77e7ee2c9f 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -339,10 +339,8 @@ static int crypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, struct extent_crypt_result ecr; int rc = 0; - if (!crypt_stat || !crypt_stat->tfm - || !(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED)) - return -EINVAL; - + BUG_ON(!crypt_stat || !crypt_stat->tfm + || !(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED)); if (unlikely(ecryptfs_verbosity > 0)) { ecryptfs_printk(KERN_DEBUG, "Key size [%zd]; key:\n", crypt_stat->key_size); diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index cdce2f0dc544..eab980f4adc0 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -870,6 +870,7 @@ int ext4_ext_tree_init(handle_t *handle, struct inode *inode) eh->eh_entries = 0; eh->eh_magic = EXT4_EXT_MAGIC; eh->eh_max = cpu_to_le16(ext4_ext_space_root(inode, 0)); + eh->eh_generation = 0; ext4_mark_inode_dirty(handle, inode); return 0; } @@ -1126,6 +1127,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, neh->eh_max = cpu_to_le16(ext4_ext_space_block(inode, 0)); neh->eh_magic = EXT4_EXT_MAGIC; neh->eh_depth = 0; + neh->eh_generation = 0; /* move remainder of path[depth] to the new leaf */ if (unlikely(path[depth].p_hdr->eh_entries != @@ -1203,6 +1205,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, neh->eh_magic = EXT4_EXT_MAGIC; neh->eh_max = cpu_to_le16(ext4_ext_space_block_idx(inode, 0)); neh->eh_depth = cpu_to_le16(depth - i); + neh->eh_generation = 0; fidx = EXT_FIRST_INDEX(neh); fidx->ei_block = border; ext4_idx_store_pblock(fidx, oldblock); @@ -3274,7 +3277,10 @@ static int ext4_split_extent_at(handle_t *handle, ext4_ext_mark_unwritten(ex2); err = ext4_ext_insert_extent(handle, inode, ppath, &newex, flags); - if (err == -ENOSPC && (EXT4_EXT_MAY_ZEROOUT & split_flag)) { + if (err != -ENOSPC && err != -EDQUOT) + goto out; + + if (EXT4_EXT_MAY_ZEROOUT & split_flag) { if (split_flag & (EXT4_EXT_DATA_VALID1|EXT4_EXT_DATA_VALID2)) { if (split_flag & EXT4_EXT_DATA_VALID1) { err = ext4_ext_zeroout(inode, ex2); @@ -3300,30 +3306,30 @@ static int ext4_split_extent_at(handle_t *handle, ext4_ext_pblock(&orig_ex)); } - if (err) - goto fix_extent_len; - /* update the extent length and mark as initialized */ - ex->ee_len = cpu_to_le16(ee_len); - ext4_ext_try_to_merge(handle, inode, path, ex); - err = ext4_ext_dirty(handle, inode, path + path->p_depth); - if (err) - goto fix_extent_len; - - /* update extent status tree */ - err = ext4_zeroout_es(inode, &zero_ex); - - goto out; - } else if (err) - goto fix_extent_len; - -out: - ext4_ext_show_leaf(inode, path); - return err; + if (!err) { + /* update the extent length and mark as initialized */ + ex->ee_len = cpu_to_le16(ee_len); + ext4_ext_try_to_merge(handle, inode, path, ex); + err = ext4_ext_dirty(handle, inode, path + path->p_depth); + if (!err) + /* update extent status tree */ + err = ext4_zeroout_es(inode, &zero_ex); + /* If we failed at this point, we don't know in which + * state the extent tree exactly is so don't try to fix + * length of the original extent as it may do even more + * damage. + */ + goto out; + } + } fix_extent_len: ex->ee_len = orig_ex.ee_len; ext4_ext_dirty(handle, inode, path + path->p_depth); return err; +out: + ext4_ext_show_leaf(inode, path); + return err; } /* diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c index 37e059202cd2..ce0f58c84b0a 100644 --- a/fs/ext4/extents_status.c +++ b/fs/ext4/extents_status.c @@ -1080,11 +1080,9 @@ static unsigned long ext4_es_scan(struct shrinker *shrink, ret = percpu_counter_read_positive(&sbi->s_es_stats.es_stats_shk_cnt); trace_ext4_es_shrink_scan_enter(sbi->s_sb, nr_to_scan, ret); - if (!nr_to_scan) - return ret; - nr_shrunk = __es_shrink(sbi, nr_to_scan, NULL); + ret = percpu_counter_read_positive(&sbi->s_es_stats.es_stats_shk_cnt); trace_ext4_es_shrink_scan_exit(sbi->s_sb, nr_shrunk, ret); return nr_shrunk; } diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 5f92f6539a5d..fbf58d87c3f6 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -405,7 +405,7 @@ static void get_orlov_stats(struct super_block *sb, ext4_group_t g, * * We always try to spread first-level directories. * - * If there are blockgroups with both free inodes and free blocks counts + * If there are blockgroups with both free inodes and free clusters counts * not worse than average we return one with smallest directory count. * Otherwise we simply return a random group. * @@ -414,7 +414,7 @@ static void get_orlov_stats(struct super_block *sb, ext4_group_t g, * It's OK to put directory into a group unless * it has too many directories already (max_dirs) or * it has too few free inodes left (min_inodes) or - * it has too few free blocks left (min_blocks) or + * it has too few free clusters left (min_clusters) or * Parent's group is preferred, if it doesn't satisfy these * conditions we search cyclically through the rest. If none * of the groups look good we just look for a group with more @@ -430,7 +430,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent, ext4_group_t real_ngroups = ext4_get_groups_count(sb); int inodes_per_group = EXT4_INODES_PER_GROUP(sb); unsigned int freei, avefreei, grp_free; - ext4_fsblk_t freeb, avefreec; + ext4_fsblk_t freec, avefreec; unsigned int ndirs; int max_dirs, min_inodes; ext4_grpblk_t min_clusters; @@ -449,9 +449,8 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent, freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter); avefreei = freei / ngroups; - freeb = EXT4_C2B(sbi, - percpu_counter_read_positive(&sbi->s_freeclusters_counter)); - avefreec = freeb; + freec = percpu_counter_read_positive(&sbi->s_freeclusters_counter); + avefreec = freec; do_div(avefreec, ngroups); ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter); diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 18dfc6d3fab2..e7815bebaeb8 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -512,9 +512,14 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id) /* find and pin the new wb */ rcu_read_lock(); memcg_css = css_from_id(new_wb_id, &memory_cgrp_subsys); - if (memcg_css) - isw->new_wb = wb_get_create(bdi, memcg_css, GFP_ATOMIC); + if (memcg_css && !css_tryget(memcg_css)) + memcg_css = NULL; rcu_read_unlock(); + if (!memcg_css) + goto out_free; + + isw->new_wb = wb_get_create(bdi, memcg_css, GFP_ATOMIC); + css_put(memcg_css); if (!isw->new_wb) goto out_free; @@ -2088,28 +2093,6 @@ int dirtytime_interval_handler(struct ctl_table *table, int write, return ret; } -static noinline void block_dump___mark_inode_dirty(struct inode *inode) -{ - if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) { - struct dentry *dentry; - const char *name = "?"; - - dentry = d_find_alias(inode); - if (dentry) { - spin_lock(&dentry->d_lock); - name = (const char *) dentry->d_name.name; - } - printk(KERN_DEBUG - "%s(%d): dirtied inode %lu (%s) on %s\n", - current->comm, task_pid_nr(current), inode->i_ino, - name, inode->i_sb->s_id); - if (dentry) { - spin_unlock(&dentry->d_lock); - dput(dentry); - } - } -} - /** * __mark_inode_dirty - internal function * @inode: inode to mark @@ -2168,9 +2151,6 @@ void __mark_inode_dirty(struct inode *inode, int flags) (dirtytime && (inode->i_state & I_DIRTY_INODE))) return; - if (unlikely(block_dump > 1)) - block_dump___mark_inode_dirty(inode); - spin_lock(&inode->i_lock); if (dirtytime && (inode->i_state & I_DIRTY_INODE)) goto out_unlock_inode; diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index ac6f73240cf6..5a0f089fbc47 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1308,6 +1308,15 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file, goto restart; } spin_lock(&fpq->lock); + /* + * Must not put request on fpq->io queue after having been shut down by + * fuse_abort_conn() + */ + if (!fpq->connected) { + req->out.h.error = err = -ECONNABORTED; + goto out_end; + + } list_add(&req->list, &fpq->io); spin_unlock(&fpq->lock); cs->req = req; @@ -1884,7 +1893,7 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud, } err = -EINVAL; - if (oh.error <= -1000 || oh.error > 0) + if (oh.error <= -512 || oh.error > 0) goto err_finish; spin_lock(&fpq->lock); diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index f19e49a5d032..3d4d35083438 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1350,6 +1350,7 @@ __acquires(&lru_lock) while(!list_empty(list)) { gl = list_entry(list->next, struct gfs2_glock, gl_lru); list_del_init(&gl->gl_lru); + clear_bit(GLF_LRU, &gl->gl_flags); if (!spin_trylock(&gl->gl_lockref.lock)) { add_back_to_lru: list_add(&gl->gl_lru, &lru_list); @@ -1396,7 +1397,6 @@ static long gfs2_scan_glock_lru(int nr) if (!test_bit(GLF_LOCK, &gl->gl_flags)) { list_move(&gl->gl_lru, &dispose); atomic_dec(&lru_count); - clear_bit(GLF_LRU, &gl->gl_flags); freed++; continue; } diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index ba1909b887ef..e7339a39e718 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -451,7 +451,7 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart, if (next >= end) break; - hash = hugetlb_fault_mutex_hash(h, mapping, next, 0); + hash = hugetlb_fault_mutex_hash(h, mapping, next); mutex_lock(&hugetlb_fault_mutex_table[hash]); /* @@ -634,7 +634,7 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset, addr = index * hpage_size; /* mutex taken here, fault path and hole punch */ - hash = hugetlb_fault_mutex_hash(h, mapping, index, addr); + hash = hugetlb_fault_mutex_hash(h, mapping, index); mutex_lock(&hugetlb_fault_mutex_table[hash]); /* See if already present in mapping to avoid alloc/free */ diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index 054cc761b426..87b41edc800d 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c @@ -161,7 +161,8 @@ void jfs_evict_inode(struct inode *inode) if (test_cflag(COMMIT_Freewmap, inode)) jfs_free_zero_link(inode); - diFree(inode); + if (JFS_SBI(inode->i_sb)->ipimap) + diFree(inode); /* * Free the inode from the quota allocation. diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index a21ea8b3e5fa..12555c4eeb2b 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -1338,6 +1338,7 @@ int lmLogInit(struct jfs_log * log) } else { if (memcmp(logsuper->uuid, log->uuid, 16)) { jfs_warn("wrong uuid on JFS log device"); + rc = -EINVAL; goto errout20; } log->size = le32_to_cpu(logsuper->size); diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 28d8a57a9908..d322ed5cbc1c 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -379,7 +379,7 @@ nfs_get_client(const struct nfs_client_initdata *cl_init, if (cl_init->hostname == NULL) { WARN_ON(1); - return NULL; + return ERR_PTR(-EINVAL); } dprintk("--> nfs_get_client(%s,v%u)\n", diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c index a3fc48ba4931..dec7e5ad525a 100644 --- a/fs/nfs/filelayout/filelayout.c +++ b/fs/nfs/filelayout/filelayout.c @@ -726,7 +726,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, if (unlikely(!p)) goto out_err; fl->fh_array[i]->size = be32_to_cpup(p++); - if (sizeof(struct nfs_fh) < fl->fh_array[i]->size) { + if (fl->fh_array[i]->size > NFS_MAXFHSIZE) { printk(KERN_ERR "NFS: Too big fh %d received %d\n", i, fl->fh_array[i]->size); goto out_err; diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index dc925b531f32..41bda33b630f 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -363,7 +363,7 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, break; case NFS3_CREATE_UNCHECKED: - goto out; + goto out_release_acls; } nfs_fattr_init(data->res.dir_attr); nfs_fattr_init(data->res.fattr); @@ -708,7 +708,7 @@ nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, break; default: status = -EINVAL; - goto out; + goto out_release_acls; } status = nfs3_do_create(dir, dentry, data); diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 7138383382ff..80718d9999ed 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -147,7 +147,7 @@ static loff_t nfs4_file_llseek(struct file *filep, loff_t offset, int whence) case SEEK_HOLE: case SEEK_DATA: ret = nfs42_proc_llseek(filep, offset, whence); - if (ret != -ENOTSUPP) + if (ret != -EOPNOTSUPP) return ret; default: return nfs_file_llseek(filep, offset, whence); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 94130588ebf5..2ea772f596e3 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -5183,6 +5183,14 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen do { err = __nfs4_proc_set_acl(inode, buf, buflen); trace_nfs4_set_acl(inode, err); + if (err == -NFS4ERR_BADOWNER || err == -NFS4ERR_BADNAME) { + /* + * no need to retry since the kernel + * isn't involved in encoding the ACEs. + */ + err = -EINVAL; + break; + } err = nfs4_handle_exception(NFS_SERVER(inode), err, &exception); } while (exception.retry); diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 529f3a576263..3e0fcb86390a 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -952,17 +952,16 @@ static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc) { struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc); - if (!list_empty(&mirror->pg_list)) { int error = desc->pg_ops->pg_doio(desc); if (error < 0) desc->pg_error = error; - else + if (list_empty(&mirror->pg_list)) { mirror->pg_bytes_written += mirror->pg_count; - } - if (list_empty(&mirror->pg_list)) { - mirror->pg_count = 0; - mirror->pg_base = 0; + mirror->pg_count = 0; + mirror->pg_base = 0; + mirror->pg_recoalesce = 0; + } } } @@ -1061,7 +1060,6 @@ static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc) do { list_splice_init(&mirror->pg_list, &head); - mirror->pg_bytes_written -= mirror->pg_count; mirror->pg_count = 0; mirror->pg_base = 0; mirror->pg_recoalesce = 0; diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index d347d95a1bac..f19cded49b29 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -1070,6 +1070,11 @@ _pnfs_return_layout(struct inode *ino) { struct pnfs_layout_hdr *lo = NULL; struct nfs_inode *nfsi = NFS_I(ino); + struct pnfs_layout_range range = { + .iomode = IOMODE_ANY, + .offset = 0, + .length = NFS4_MAX_UINT64, + }; LIST_HEAD(tmp_list); nfs4_stateid stateid; int status = 0, empty; @@ -1088,16 +1093,10 @@ _pnfs_return_layout(struct inode *ino) pnfs_get_layout_hdr(lo); empty = list_empty(&lo->plh_segs); pnfs_clear_layoutcommit(ino, &tmp_list); - pnfs_mark_matching_lsegs_return(lo, &tmp_list, NULL, 0); + pnfs_mark_matching_lsegs_return(lo, &tmp_list, &range, 0); - if (NFS_SERVER(ino)->pnfs_curr_ld->return_range) { - struct pnfs_layout_range range = { - .iomode = IOMODE_ANY, - .offset = 0, - .length = NFS4_MAX_UINT64, - }; + if (NFS_SERVER(ino)->pnfs_curr_ld->return_range) NFS_SERVER(ino)->pnfs_curr_ld->return_range(lo, &range); - } /* Don't send a LAYOUTRETURN if list was initially empty */ if (empty) { diff --git a/fs/nilfs2/sysfs.c b/fs/nilfs2/sysfs.c index 490303e3d517..e9903bceb2bf 100644 --- a/fs/nilfs2/sysfs.c +++ b/fs/nilfs2/sysfs.c @@ -1064,6 +1064,7 @@ void nilfs_sysfs_delete_device_group(struct the_nilfs *nilfs) nilfs_sysfs_delete_superblock_group(nilfs); nilfs_sysfs_delete_segctor_group(nilfs); kobject_del(&nilfs->ns_dev_kobj); + kobject_put(&nilfs->ns_dev_kobj); kfree(nilfs->ns_dev_subgroups); } diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index a4fa548785d6..8cd134750ebb 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -502,7 +502,7 @@ err_corrupt_attr: } file_name_attr = (FILE_NAME_ATTR*)((u8*)attr + le16_to_cpu(attr->data.resident.value_offset)); - p2 = (u8*)attr + le32_to_cpu(attr->data.resident.value_length); + p2 = (u8 *)file_name_attr + le32_to_cpu(attr->data.resident.value_length); if (p2 < (u8*)attr || p2 > p) goto err_corrupt_attr; /* This attribute is ok, but is it in the $Extend directory? */ diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index c17285df12be..3aa4441f5ab5 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1838,6 +1838,45 @@ out: return ret; } +/* + * zero out partial blocks of one cluster. + * + * start: file offset where zero starts, will be made upper block aligned. + * len: it will be trimmed to the end of current cluster if "start + len" + * is bigger than it. + */ +static int ocfs2_zeroout_partial_cluster(struct inode *inode, + u64 start, u64 len) +{ + int ret; + u64 start_block, end_block, nr_blocks; + u64 p_block, offset; + u32 cluster, p_cluster, nr_clusters; + struct super_block *sb = inode->i_sb; + u64 end = ocfs2_align_bytes_to_clusters(sb, start); + + if (start + len < end) + end = start + len; + + start_block = ocfs2_blocks_for_bytes(sb, start); + end_block = ocfs2_blocks_for_bytes(sb, end); + nr_blocks = end_block - start_block; + if (!nr_blocks) + return 0; + + cluster = ocfs2_bytes_to_clusters(sb, start); + ret = ocfs2_get_clusters(inode, cluster, &p_cluster, + &nr_clusters, NULL); + if (ret) + return ret; + if (!p_cluster) + return 0; + + offset = start_block - ocfs2_clusters_to_blocks(sb, cluster); + p_block = ocfs2_clusters_to_blocks(sb, p_cluster) + offset; + return sb_issue_zeroout(sb, p_block, nr_blocks, GFP_NOFS); +} + /* * Parts of this function taken from xfs_change_file_space() */ @@ -1848,7 +1887,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, { int ret; s64 llen; - loff_t size; + loff_t size, orig_isize; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); struct buffer_head *di_bh = NULL; handle_t *handle; @@ -1879,6 +1918,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, goto out_inode_unlock; } + orig_isize = i_size_read(inode); switch (sr->l_whence) { case 0: /*SEEK_SET*/ break; @@ -1886,7 +1926,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, sr->l_start += f_pos; break; case 2: /*SEEK_END*/ - sr->l_start += i_size_read(inode); + sr->l_start += orig_isize; break; default: ret = -EINVAL; @@ -1940,6 +1980,14 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, default: ret = -EINVAL; } + + /* zeroout eof blocks in the cluster. */ + if (!ret && change_size && orig_isize < size) { + ret = ocfs2_zeroout_partial_cluster(inode, orig_isize, + size - orig_isize); + if (!ret) + i_size_write(inode, size); + } up_write(&OCFS2_I(inode)->ip_alloc_sem); if (ret) { mlog_errno(ret); @@ -1956,9 +2004,6 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, goto out_inode_unlock; } - if (change_size && i_size_read(inode) < size) - i_size_write(inode, size); - inode->i_ctime = inode->i_mtime = current_time(inode); ret = ocfs2_mark_inode_dirty(handle, inode, di_bh); if (ret < 0) diff --git a/fs/ocfs2/filecheck.c b/fs/ocfs2/filecheck.c index 2cabbcf2f28e..5571268b681c 100644 --- a/fs/ocfs2/filecheck.c +++ b/fs/ocfs2/filecheck.c @@ -431,11 +431,7 @@ static ssize_t ocfs2_filecheck_show(struct kobject *kobj, ret = snprintf(buf + total, remain, "%lu\t\t%u\t%s\n", p->fe_ino, p->fe_done, ocfs2_filecheck_error(p->fe_status)); - if (ret < 0) { - total = ret; - break; - } - if (ret == remain) { + if (ret >= remain) { /* snprintf() didn't fit */ total = -E2BIG; break; diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c index 52c07346bea3..03e1c6cd6f3c 100644 --- a/fs/ocfs2/stackglue.c +++ b/fs/ocfs2/stackglue.c @@ -510,11 +510,7 @@ static ssize_t ocfs2_loaded_cluster_plugins_show(struct kobject *kobj, list_for_each_entry(p, &ocfs2_stack_list, sp_list) { ret = snprintf(buf, remain, "%s\n", p->sp_name); - if (ret < 0) { - total = ret; - break; - } - if (ret == remain) { + if (ret >= remain) { /* snprintf() didn't fit */ total = -E2BIG; break; @@ -541,7 +537,7 @@ static ssize_t ocfs2_active_cluster_plugin_show(struct kobject *kobj, if (active_stack) { ret = snprintf(buf, PAGE_SIZE, "%s\n", active_stack->sp_name); - if (ret == PAGE_SIZE) + if (ret >= PAGE_SIZE) ret = -E2BIG; } spin_unlock(&ocfs2_stack_lock); diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c index 6e35ef6521b4..8972ebc87016 100644 --- a/fs/orangefs/super.c +++ b/fs/orangefs/super.c @@ -185,7 +185,7 @@ static int orangefs_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_bavail = (sector_t) new_op->downcall.resp.statfs.blocks_avail; buf->f_files = (sector_t) new_op->downcall.resp.statfs.files_total; buf->f_ffree = (sector_t) new_op->downcall.resp.statfs.files_avail; - buf->f_frsize = sb->s_blocksize; + buf->f_frsize = 0; out_op_release: op_release(new_op); diff --git a/fs/proc/base.c b/fs/proc/base.c index ca269101cf24..88b796223ddb 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2692,6 +2692,13 @@ out: } #ifdef CONFIG_SECURITY +static int proc_pid_attr_open(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + __mem_open(inode, file, PTRACE_MODE_READ_FSCREDS); + return 0; +} + static ssize_t proc_pid_attr_read(struct file * file, char __user * buf, size_t count, loff_t *ppos) { @@ -2721,6 +2728,10 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf, ssize_t length; struct task_struct *task = get_proc_task(inode); + /* A task may only write when it was the opener. */ + if (file->private_data != current->mm) + return -EPERM; + length = -ESRCH; if (!task) goto out_no_task; @@ -2756,9 +2767,11 @@ out_no_task: } static const struct file_operations proc_pid_attr_operations = { + .open = proc_pid_attr_open, .read = proc_pid_attr_read, .write = proc_pid_attr_write, .llseek = generic_file_llseek, + .release = mem_release, }; static const struct pid_entry attr_dir_stuff[] = { diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 2a5c4813c47d..94871f611fa8 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -2766,6 +2766,20 @@ int journal_init(struct super_block *sb, const char *j_dev_name, goto free_and_return; } + /* + * Sanity check to see if journal first block is correct. + * If journal first block is invalid it can cause + * zeroing important superblock members. + */ + if (!SB_ONDISK_JOURNAL_DEVICE(sb) && + SB_ONDISK_JOURNAL_1st_BLOCK(sb) < SB_JOURNAL_1st_RESERVED_BLOCK(sb)) { + reiserfs_warning(sb, "journal-1393", + "journal 1st super block is invalid: 1st reserved block %d, but actual 1st block is %d", + SB_JOURNAL_1st_RESERVED_BLOCK(sb), + SB_ONDISK_JOURNAL_1st_BLOCK(sb)); + goto free_and_return; + } + if (journal_init_dev(sb, journal, j_dev_name) != 0) { reiserfs_warning(sb, "sh-462", "unable to initialize journal device"); diff --git a/fs/seq_file.c b/fs/seq_file.c index 368bfb92b115..3ade39e02bb7 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -28,6 +28,9 @@ static void *seq_buf_alloc(unsigned long size) void *buf; gfp_t gfp = GFP_KERNEL; + if (unlikely(size > MAX_RW_COUNT)) + return NULL; + /* * For high order allocations, use __GFP_NORETRY to avoid oom-killing - * it's better to fall back to vmalloc() than to kill things. For small diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 87ab02e2d666..56eed54633cf 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -1144,7 +1144,10 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry, return err; } + spin_lock(&whiteout->i_lock); whiteout->i_state |= I_LINKABLE; + spin_unlock(&whiteout->i_lock); + whiteout_ui = ubifs_inode(whiteout); whiteout_ui->data = dev; whiteout_ui->data_len = ubifs_encode_dev(dev, MKDEV(0, 0)); @@ -1239,7 +1242,11 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry, inc_nlink(whiteout); mark_inode_dirty(whiteout); + + spin_lock(&whiteout->i_lock); whiteout->i_state &= ~I_LINKABLE; + spin_unlock(&whiteout->i_lock); + iput(whiteout); } diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 348b922d1b6a..bfa53dead8c8 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -956,6 +956,10 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, iinfo->i_location.partitionReferenceNum, 0); epos.bh = udf_tgetblk(sb, block); + if (unlikely(!epos.bh)) { + err = -ENOMEM; + goto out_no_entry; + } lock_buffer(epos.bh); memset(epos.bh->b_data, 0x00, bsize); set_buffer_uptodate(epos.bh); diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h index 5203560f992e..000c049a75f7 100644 --- a/include/crypto/internal/hash.h +++ b/include/crypto/internal/hash.h @@ -80,13 +80,7 @@ int ahash_register_instance(struct crypto_template *tmpl, struct ahash_instance *inst); void ahash_free_instance(struct crypto_instance *inst); -int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, - unsigned int keylen); - -static inline bool crypto_shash_alg_has_setkey(struct shash_alg *alg) -{ - return alg->setkey != shash_no_setkey; -} +bool crypto_shash_alg_has_setkey(struct shash_alg *alg); bool crypto_hash_alg_has_setkey(struct hash_alg_common *halg); diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h index 6fd3c908a340..a30112ba06e4 100644 --- a/include/linux/console_struct.h +++ b/include/linux/console_struct.h @@ -61,6 +61,7 @@ struct vc_data { unsigned int vc_rows; unsigned int vc_size_row; /* Bytes per row */ unsigned int vc_scan_lines; /* # of scan lines */ + unsigned int vc_cell_height; /* CRTC character cell height */ unsigned long vc_origin; /* [!] Start of real screen */ unsigned long vc_scr_end; /* [!] End of real screen */ unsigned long vc_visible_origin; /* [!] Top of visible window */ diff --git a/include/linux/hid.h b/include/linux/hid.h index 1c189929f4f6..57d4a65b0fda 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -1130,8 +1130,7 @@ static inline void hid_hw_wait(struct hid_device *hdev) */ static inline u32 hid_report_len(struct hid_report *report) { - /* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */ - return ((report->size - 1) >> 3) + 1 + (report->id > 0); + return DIV_ROUND_UP(report->size, 8) + (report->id > 0); } int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 4e4c35a6bfc5..6417bc845db5 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -93,7 +93,7 @@ void free_huge_page(struct page *page); void hugetlb_fix_reserve_counts(struct inode *inode); extern struct mutex *hugetlb_fault_mutex_table; u32 hugetlb_fault_mutex_hash(struct hstate *h, struct address_space *mapping, - pgoff_t idx, unsigned long address); + pgoff_t idx); pte_t *huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud); @@ -451,17 +451,6 @@ static inline int hstate_index(struct hstate *h) return h - hstates; } -pgoff_t __basepage_index(struct page *page); - -/* Return page->index in PAGE_SIZE units */ -static inline pgoff_t basepage_index(struct page *page) -{ - if (!PageCompound(page)) - return page->index; - - return __basepage_index(page); -} - extern int dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn); static inline bool hugepage_migration_supported(struct hstate *h) @@ -529,10 +518,6 @@ static inline unsigned int pages_per_huge_page(struct hstate *h) #define hstate_index_to_shift(index) 0 #define hstate_index(h) 0 -static inline pgoff_t basepage_index(struct page *page) -{ - return page->index; -} #define dissolve_free_huge_pages(s, e) 0 #define hugepage_migration_supported(h) false diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index bb4af1bfcaf4..05aa860daa5c 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -932,7 +933,15 @@ __gfn_to_memslot(struct kvm_memslots *slots, gfn_t gfn) static inline unsigned long __gfn_to_hva_memslot(struct kvm_memory_slot *slot, gfn_t gfn) { - return slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE; + /* + * The index was checked originally in search_memslots. To avoid + * that a malicious guest builds a Spectre gadget out of e.g. page + * table walks, do not let the processor speculate loads outside + * the guest's registered memslots. + */ + unsigned long offset = gfn - slot->base_gfn; + offset = array_index_nospec(offset, slot->npages); + return slot->userspace_addr + offset * PAGE_SIZE; } static inline int memslot_id(struct kvm *kvm, gfn_t gfn) diff --git a/include/linux/mfd/abx500/ux500_chargalg.h b/include/linux/mfd/abx500/ux500_chargalg.h index 67703f23e7ba..821a3b9bc16e 100644 --- a/include/linux/mfd/abx500/ux500_chargalg.h +++ b/include/linux/mfd/abx500/ux500_chargalg.h @@ -15,7 +15,7 @@ * - POWER_SUPPLY_TYPE_USB, * because only them store as drv_data pointer to struct ux500_charger. */ -#define psy_to_ux500_charger(x) power_supply_get_drvdata(psy) +#define psy_to_ux500_charger(x) power_supply_get_drvdata(x) /* Forward declaration */ struct ux500_charger; diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h index 451a811f48f2..d1fb3bbff37a 100644 --- a/include/linux/mmdebug.h +++ b/include/linux/mmdebug.h @@ -36,10 +36,22 @@ void dump_mm(const struct mm_struct *mm); BUG(); \ } \ } while (0) -#define VM_WARN_ON(cond) WARN_ON(cond) -#define VM_WARN_ON_ONCE(cond) WARN_ON_ONCE(cond) -#define VM_WARN_ONCE(cond, format...) WARN_ONCE(cond, format) -#define VM_WARN(cond, format...) WARN(cond, format) +#define VM_WARN_ON_ONCE_PAGE(cond, page) ({ \ + static bool __section(".data.once") __warned; \ + int __ret_warn_once = !!(cond); \ + \ + if (unlikely(__ret_warn_once && !__warned)) { \ + dump_page(page, "VM_WARN_ON_ONCE_PAGE(" __stringify(cond)")");\ + __warned = true; \ + WARN_ON(1); \ + } \ + unlikely(__ret_warn_once); \ +}) + +#define VM_WARN_ON(cond) (void)WARN_ON(cond) +#define VM_WARN_ON_ONCE(cond) (void)WARN_ON_ONCE(cond) +#define VM_WARN_ONCE(cond, format...) (void)WARN_ONCE(cond, format) +#define VM_WARN(cond, format...) (void)WARN(cond, format) #else #define VM_BUG_ON(cond) BUILD_BUG_ON_INVALID(cond) #define VM_BUG_ON_PAGE(cond, page) VM_BUG_ON(cond) @@ -47,6 +59,7 @@ void dump_mm(const struct mm_struct *mm); #define VM_BUG_ON_MM(cond, mm) VM_BUG_ON(cond) #define VM_WARN_ON(cond) BUILD_BUG_ON_INVALID(cond) #define VM_WARN_ON_ONCE(cond) BUILD_BUG_ON_INVALID(cond) +#define VM_WARN_ON_ONCE_PAGE(cond, page) BUILD_BUG_ON_INVALID(cond) #define VM_WARN_ONCE(cond, format...) BUILD_BUG_ON_INVALID(cond) #define VM_WARN(cond, format...) BUILD_BUG_ON_INVALID(cond) #endif diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index ee62bca5e0af..0c106e541d75 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -343,7 +343,7 @@ static inline unsigned int xt_write_recseq_begin(void) * since addend is most likely 1 */ __this_cpu_add(xt_recseq.sequence, addend); - smp_wmb(); + smp_mb(); return addend; } diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 0dfc605b3c6a..c953fd345f43 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -383,7 +383,7 @@ static inline struct page *read_mapping_page(struct address_space *mapping, } /* - * Get index of the page with in radix-tree + * Get index of the page within radix-tree (but not for hugetlb pages). * (TODO: remove once hugetlb pages will have ->index in PAGE_SIZE) */ static inline pgoff_t page_to_index(struct page *page) @@ -402,15 +402,16 @@ static inline pgoff_t page_to_index(struct page *page) return pgoff; } +extern pgoff_t hugetlb_basepage_index(struct page *page); + /* - * Get the offset in PAGE_SIZE. - * (TODO: hugepage should have ->index in PAGE_SIZE) + * Get the offset in PAGE_SIZE (even for hugetlb pages). + * (TODO: hugetlb pages should have ->index in PAGE_SIZE) */ static inline pgoff_t page_to_pgoff(struct page *page) { - if (unlikely(PageHeadHuge(page))) - return page->index << compound_order(page); - + if (unlikely(PageHuge(page))) + return hugetlb_basepage_index(page); return page_to_index(page); } diff --git a/include/linux/prandom.h b/include/linux/prandom.h index cc1e71334e53..e20339c78a84 100644 --- a/include/linux/prandom.h +++ b/include/linux/prandom.h @@ -93,7 +93,7 @@ static inline u32 __seed(u32 x, u32 m) */ static inline void prandom_seed_state(struct rnd_state *state, u64 seed) { - u32 i = (seed >> 32) ^ (seed << 10) ^ seed; + u32 i = ((seed >> 32) ^ (seed << 10) ^ seed) & 0xffffffffUL; state->s1 = __seed(i, 2U); state->s2 = __seed(i, 8U); diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 8470695e5dd7..9c8445f1af0c 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -443,6 +443,9 @@ struct spi_master { #define SPI_MASTER_MUST_RX BIT(3) /* requires rx */ #define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ + /* flag indicating this is a non-devres managed controller */ + bool devm_allocated; + /* * on some hardware transfer / message size may be constrained * the limit may depend on device transfer settings diff --git a/include/linux/swapops.h b/include/linux/swapops.h index 5c3a5f3e7eec..c5ff7b217ee6 100644 --- a/include/linux/swapops.h +++ b/include/linux/swapops.h @@ -196,15 +196,6 @@ static inline void num_poisoned_pages_dec(void) atomic_long_dec(&num_poisoned_pages); } -static inline void num_poisoned_pages_add(long num) -{ - atomic_long_add(num, &num_poisoned_pages); -} - -static inline void num_poisoned_pages_sub(long num) -{ - atomic_long_sub(num, &num_poisoned_pages); -} #else static inline swp_entry_t make_hwpoison_entry(struct page *page) diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index fde7550754df..52f47c2944f8 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -80,6 +80,8 @@ struct usbnet { # define EVENT_LINK_CHANGE 11 # define EVENT_SET_RX_MODE 12 # define EVENT_NO_IP_ALIGN 13 + u32 rx_speed; /* in bps - NOT Mbps */ + u32 tx_speed; /* in bps - NOT Mbps */ }; static inline struct usb_driver *driver_of(struct usb_interface *intf) diff --git a/include/net/caif/caif_dev.h b/include/net/caif/caif_dev.h index 028b754ae9b1..0baf2e21a533 100644 --- a/include/net/caif/caif_dev.h +++ b/include/net/caif/caif_dev.h @@ -119,7 +119,7 @@ void caif_free_client(struct cflayer *adap_layer); * The link_support layer is used to add any Link Layer specific * framing. */ -void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, +int caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, struct cflayer *link_support, int head_room, struct cflayer **layer, int (**rcv_func)( struct sk_buff *, struct net_device *, diff --git a/include/net/caif/cfcnfg.h b/include/net/caif/cfcnfg.h index 70bfd017581f..219094ace893 100644 --- a/include/net/caif/cfcnfg.h +++ b/include/net/caif/cfcnfg.h @@ -62,7 +62,7 @@ void cfcnfg_remove(struct cfcnfg *cfg); * @fcs: Specify if checksum is used in CAIF Framing Layer. * @head_room: Head space needed by link specific protocol. */ -void +int cfcnfg_add_phy_layer(struct cfcnfg *cnfg, struct net_device *dev, struct cflayer *phy_layer, enum cfcnfg_phy_preference pref, diff --git a/include/net/caif/cfserl.h b/include/net/caif/cfserl.h index b5b020f3c72e..bc3fae07a25f 100644 --- a/include/net/caif/cfserl.h +++ b/include/net/caif/cfserl.h @@ -9,4 +9,5 @@ #include struct cflayer *cfserl_create(int instance, bool use_stx); +void cfserl_release(struct cflayer *layer); #endif diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index db31d9f3ee83..be83eae4399b 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -4367,7 +4367,8 @@ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); * Return: 0 on success. Non-zero on error. */ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, - const u8 *addr, enum nl80211_iftype iftype); + const u8 *addr, enum nl80211_iftype iftype, + bool is_amsdu); /** * ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3 @@ -4379,7 +4380,7 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, static inline int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, enum nl80211_iftype iftype) { - return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype); + return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype, false); } /** diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h index 87499b6b35d6..2ba054fe14ac 100644 --- a/include/net/nfc/nci_core.h +++ b/include/net/nfc/nci_core.h @@ -310,6 +310,7 @@ int nci_nfcc_loopback(struct nci_dev *ndev, void *data, size_t data_len, struct sk_buff **resp); struct nci_hci_dev *nci_hci_allocate(struct nci_dev *ndev); +void nci_hci_deallocate(struct nci_dev *ndev); int nci_hci_send_event(struct nci_dev *ndev, u8 gate, u8 event, const u8 *param, size_t param_len); int nci_hci_send_cmd(struct nci_dev *ndev, u8 gate, diff --git a/include/net/sock.h b/include/net/sock.h index 47622934bbad..83dab256b8b5 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1688,7 +1688,8 @@ static inline u32 net_tx_rndhash(void) static inline void sk_set_txhash(struct sock *sk) { - sk->sk_txhash = net_tx_rndhash(); + /* This pairs with READ_ONCE() in skb_set_hash_from_sk() */ + WRITE_ONCE(sk->sk_txhash, net_tx_rndhash()); } static inline void sk_rethink_txhash(struct sock *sk) @@ -1943,9 +1944,12 @@ static inline void sock_poll_wait(struct file *filp, static inline void skb_set_hash_from_sk(struct sk_buff *skb, struct sock *sk) { - if (sk->sk_txhash) { + /* This pairs with WRITE_ONCE() in sk_set_txhash() */ + u32 txhash = READ_ONCE(sk->sk_txhash); + + if (txhash) { skb->l4_hash = 1; - skb->hash = sk->sk_txhash; + skb->hash = txhash; } } diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 6183d20a01fb..e673c7c9c5fb 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -437,6 +437,8 @@ extern void iscsi_free_session(struct iscsi_cls_session *session); extern int iscsi_destroy_session(struct iscsi_cls_session *session); extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess, int dd_size, uint32_t cid); +extern void iscsi_put_conn(struct iscsi_cls_conn *conn); +extern void iscsi_get_conn(struct iscsi_cls_conn *conn); extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn); extern void iscsi_unblock_session(struct iscsi_cls_session *session); extern void iscsi_block_session(struct iscsi_cls_session *session); diff --git a/init/main.c b/init/main.c index b50d95148ae0..a44b00c9cc15 100644 --- a/init/main.c +++ b/init/main.c @@ -1013,7 +1013,7 @@ static noinline void __init kernel_init_freeable(void) */ set_cpus_allowed_ptr(current, cpu_all_mask); - cad_pid = task_pid(current); + cad_pid = get_pid(task_pid(current)); smp_prepare_cpus(setup_max_cpus); diff --git a/kernel/cgroup.c b/kernel/cgroup.c index cb0af37db67b..464200954737 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -3710,6 +3710,10 @@ static int cgroup_rename(struct kernfs_node *kn, struct kernfs_node *new_parent, struct cgroup *cgrp = kn->priv; int ret; + /* do not accept '\n' to prevent making /proc//cgroup unparsable */ + if (strchr(new_name_str, '\n')) + return -EINVAL; + if (kernfs_type(kn) != KERNFS_DIR) return -ENOTDIR; if (kn->parent != new_parent) @@ -5789,8 +5793,6 @@ int __init cgroup_init_early(void) return 0; } -static u16 cgroup_disable_mask __initdata; - /** * cgroup_init - cgroup initialization * @@ -5848,12 +5850,8 @@ int __init cgroup_init(void) * disabled flag and cftype registration needs kmalloc, * both of which aren't available during early_init. */ - if (cgroup_disable_mask & (1 << ssid)) { - static_branch_disable(cgroup_subsys_enabled_key[ssid]); - printk(KERN_INFO "Disabling %s control group subsystem\n", - ss->name); + if (!cgroup_ssid_enabled(ssid)) continue; - } if (cgroup_ssid_no_v1(ssid)) printk(KERN_INFO "Disabling %s control group subsystem in v1 mounts\n", @@ -6296,7 +6294,10 @@ static int __init cgroup_disable(char *str) if (strcmp(token, ss->name) && strcmp(token, ss->legacy_name)) continue; - cgroup_disable_mask |= 1 << i; + + static_branch_disable(cgroup_subsys_enabled_key[i]); + pr_info("Disabling %s control group subsystem\n", + ss->name); } } return 1; diff --git a/kernel/events/core.c b/kernel/events/core.c index 443b775826d4..7a2d3a61a938 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -3888,7 +3888,9 @@ find_get_context(struct pmu *pmu, struct task_struct *task, cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); ctx = &cpuctx->ctx; get_ctx(ctx); + raw_spin_lock_irqsave(&ctx->lock, flags); ++ctx->pin_count; + raw_spin_unlock_irqrestore(&ctx->lock, flags); return ctx; } diff --git a/kernel/futex.c b/kernel/futex.c index 324fb85c8904..b3823736af6f 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -717,7 +717,7 @@ again: key->both.offset |= FUT_OFF_INODE; /* inode-based key */ key->shared.i_seq = get_inode_sequence_number(inode); - key->shared.pgoff = basepage_index(tail); + key->shared.pgoff = page_to_pgoff(tail); rcu_read_unlock(); } diff --git a/kernel/kthread.c b/kernel/kthread.c index f06ef0d6c412..a4f8848b4dee 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -938,8 +938,38 @@ void kthread_flush_work(struct kthread_work *work) EXPORT_SYMBOL_GPL(kthread_flush_work); /* - * This function removes the work from the worker queue. Also it makes sure - * that it won't get queued later via the delayed work's timer. + * Make sure that the timer is neither set nor running and could + * not manipulate the work list_head any longer. + * + * The function is called under worker->lock. The lock is temporary + * released but the timer can't be set again in the meantime. + */ +static void kthread_cancel_delayed_work_timer(struct kthread_work *work, + unsigned long *flags) +{ + struct kthread_delayed_work *dwork = + container_of(work, struct kthread_delayed_work, work); + struct kthread_worker *worker = work->worker; + + /* + * del_timer_sync() must be called to make sure that the timer + * callback is not running. The lock must be temporary released + * to avoid a deadlock with the callback. In the meantime, + * any queuing is blocked by setting the canceling counter. + */ + work->canceling++; + spin_unlock_irqrestore(&worker->lock, *flags); + del_timer_sync(&dwork->timer); + spin_lock_irqsave(&worker->lock, *flags); + work->canceling--; +} + +/* + * This function removes the work from the worker queue. + * + * It is called under worker->lock. The caller must make sure that + * the timer used by delayed work is not running, e.g. by calling + * kthread_cancel_delayed_work_timer(). * * The work might still be in use when this function finishes. See the * current_work proceed by the worker. @@ -947,28 +977,8 @@ EXPORT_SYMBOL_GPL(kthread_flush_work); * Return: %true if @work was pending and successfully canceled, * %false if @work was not pending */ -static bool __kthread_cancel_work(struct kthread_work *work, bool is_dwork, - unsigned long *flags) +static bool __kthread_cancel_work(struct kthread_work *work) { - /* Try to cancel the timer if exists. */ - if (is_dwork) { - struct kthread_delayed_work *dwork = - container_of(work, struct kthread_delayed_work, work); - struct kthread_worker *worker = work->worker; - - /* - * del_timer_sync() must be called to make sure that the timer - * callback is not running. The lock must be temporary released - * to avoid a deadlock with the callback. In the meantime, - * any queuing is blocked by setting the canceling counter. - */ - work->canceling++; - spin_unlock_irqrestore(&worker->lock, *flags); - del_timer_sync(&dwork->timer); - spin_lock_irqsave(&worker->lock, *flags); - work->canceling--; - } - /* * Try to remove the work from a worker list. It might either * be from worker->work_list or from worker->delayed_work_list. @@ -1021,11 +1031,23 @@ bool kthread_mod_delayed_work(struct kthread_worker *worker, /* Work must not be used with >1 worker, see kthread_queue_work() */ WARN_ON_ONCE(work->worker != worker); - /* Do not fight with another command that is canceling this work. */ + /* + * Temporary cancel the work but do not fight with another command + * that is canceling the work as well. + * + * It is a bit tricky because of possible races with another + * mod_delayed_work() and cancel_delayed_work() callers. + * + * The timer must be canceled first because worker->lock is released + * when doing so. But the work can be removed from the queue (list) + * only when it can be queued again so that the return value can + * be used for reference counting. + */ + kthread_cancel_delayed_work_timer(work, &flags); if (work->canceling) goto out; + ret = __kthread_cancel_work(work); - ret = __kthread_cancel_work(work, true, &flags); fast_queue: __kthread_queue_delayed_work(worker, dwork, delay); out: @@ -1047,7 +1069,10 @@ static bool __kthread_cancel_work_sync(struct kthread_work *work, bool is_dwork) /* Work must not be used with >1 worker, see kthread_queue_work(). */ WARN_ON_ONCE(work->worker != worker); - ret = __kthread_cancel_work(work, is_dwork, &flags); + if (is_dwork) + kthread_cancel_delayed_work_timer(work, &flags); + + ret = __kthread_cancel_work(work); if (worker->current_work != work) goto out_fast; diff --git a/kernel/ptrace.c b/kernel/ptrace.c index ea3370e205fb..4f10223bc7b0 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -159,6 +159,21 @@ void __ptrace_unlink(struct task_struct *child) spin_unlock(&child->sighand->siglock); } +static bool looks_like_a_spurious_pid(struct task_struct *task) +{ + if (task->exit_code != ((PTRACE_EVENT_EXEC << 8) | SIGTRAP)) + return false; + + if (task_pid_vnr(task) == task->ptrace_message) + return false; + /* + * The tracee changed its pid but the PTRACE_EVENT_EXEC event + * was not wait()'ed, most probably debugger targets the old + * leader which was destroyed in de_thread(). + */ + return true; +} + /* Ensure that nothing can wake it up, even SIGKILL */ static bool ptrace_freeze_traced(struct task_struct *task) { @@ -169,7 +184,8 @@ static bool ptrace_freeze_traced(struct task_struct *task) return ret; spin_lock_irq(&task->sighand->siglock); - if (task_is_traced(task) && !__fatal_signal_pending(task)) { + if (task_is_traced(task) && !looks_like_a_spurious_pid(task) && + !__fatal_signal_pending(task)) { task->state = __TASK_TRACED; ret = true; } diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index c260d041e748..5be2bfa57535 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1962,12 +1962,18 @@ static int ftrace_hash_ipmodify_update(struct ftrace_ops *ops, static void print_ip_ins(const char *fmt, const unsigned char *p) { + char ins[MCOUNT_INSN_SIZE]; int i; + if (probe_kernel_read(ins, p, MCOUNT_INSN_SIZE)) { + printk(KERN_CONT "%s[FAULT] %px\n", fmt, p); + return; + } + printk(KERN_CONT "%s", fmt); for (i = 0; i < MCOUNT_INSN_SIZE; i++) - printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]); + printk(KERN_CONT "%s%02x", i ? ":" : "", ins[i]); } enum ftrace_bug_type ftrace_bug_type; diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d8270f1eb7a4..33f5755f6d15 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1619,9 +1619,6 @@ struct saved_cmdlines_buffer { }; static struct saved_cmdlines_buffer *savedcmd; -/* temporary disable recording */ -static atomic_t trace_record_cmdline_disabled __read_mostly; - static inline char *get_saved_cmdlines(int idx) { return &savedcmd->saved_cmdlines[idx * TASK_COMM_LEN]; @@ -1929,9 +1926,6 @@ int trace_find_tgid(int pid) void tracing_record_cmdline(struct task_struct *tsk) { - if (atomic_read(&trace_record_cmdline_disabled) || !tracing_is_on()) - return; - if (!__this_cpu_read(trace_cmdline_save)) return; @@ -2130,7 +2124,7 @@ trace_event_buffer_lock_reserve(struct ring_buffer **current_rb, (entry = this_cpu_read(trace_buffered_event))) { /* Try to use the per cpu buffer first */ val = this_cpu_inc_return(trace_buffered_event_cnt); - if ((len < (PAGE_SIZE - sizeof(*entry))) && val == 1) { + if ((len < (PAGE_SIZE - sizeof(*entry) - sizeof(entry->array[0]))) && val == 1) { trace_event_setup(entry, type, flags, pc); entry->array[0] = len; return entry; @@ -2876,9 +2870,6 @@ static void *s_start(struct seq_file *m, loff_t *pos) return ERR_PTR(-EBUSY); #endif - if (!iter->snapshot) - atomic_inc(&trace_record_cmdline_disabled); - if (*pos != iter->pos) { iter->ent = NULL; iter->cpu = 0; @@ -2921,9 +2912,6 @@ static void s_stop(struct seq_file *m, void *p) return; #endif - if (!iter->snapshot) - atomic_dec(&trace_record_cmdline_disabled); - trace_access_unlock(iter->cpu_file); trace_event_read_unlock(); } diff --git a/kernel/trace/trace_clock.c b/kernel/trace/trace_clock.c index b67ea5eed2a8..b70233a9563f 100644 --- a/kernel/trace/trace_clock.c +++ b/kernel/trace/trace_clock.c @@ -113,9 +113,9 @@ u64 notrace trace_clock_global(void) prev_time = READ_ONCE(trace_clock_struct.prev_time); now = sched_clock_cpu(this_cpu); - /* Make sure that now is always greater than prev_time */ + /* Make sure that now is always greater than or equal to prev_time */ if ((s64)(now - prev_time) < 0) - now = prev_time + 1; + now = prev_time; /* * If in an NMI context then dont risk lockups and simply return @@ -129,7 +129,7 @@ u64 notrace trace_clock_global(void) /* Reread prev_time in case it was already updated */ prev_time = READ_ONCE(trace_clock_struct.prev_time); if ((s64)(now - prev_time) < 0) - now = prev_time + 1; + now = prev_time; trace_clock_struct.prev_time = now; diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 766e5ccad60a..57a9341c67e4 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -374,7 +374,9 @@ static struct hist_field *create_hist_field(struct ftrace_event_field *field, if (WARN_ON_ONCE(!field)) goto out; - if (is_string_field(field)) { + /* Pointers to strings are just pointers and dangerous to dereference */ + if (is_string_field(field) && + (field->filter_type != FILTER_PTR_STRING)) { flags |= HIST_FIELD_FL_STRING; if (field->filter_type == FILTER_STATIC_STRING) @@ -863,8 +865,6 @@ static inline void add_to_key(char *compound_key, void *key, field = key_field->field; if (field->filter_type == FILTER_DYN_STRING) size = *(u32 *)(rec + field->offset) >> 16; - else if (field->filter_type == FILTER_PTR_STRING) - size = strlen(key); else if (field->filter_type == FILTER_STATIC_STRING) size = field->size; diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 112b191d970c..c9d628e8f0b6 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -51,6 +51,7 @@ #include #include #include +#include #include "workqueue_internal.h" @@ -5430,6 +5431,7 @@ static void wq_watchdog_timer_fn(unsigned long data) { unsigned long thresh = READ_ONCE(wq_watchdog_thresh) * HZ; bool lockup_detected = false; + unsigned long now = jiffies; struct worker_pool *pool; int pi; @@ -5444,6 +5446,12 @@ static void wq_watchdog_timer_fn(unsigned long data) if (list_empty(&pool->worklist)) continue; + /* + * If a virtual machine is stopped by the host it can look to + * the watchdog like a stall. + */ + kvm_check_and_clear_guest_paused(); + /* get the latest of pool and touched timestamps */ pool_ts = READ_ONCE(pool->watchdog_ts); touched = READ_ONCE(wq_watchdog_touched); @@ -5462,12 +5470,12 @@ static void wq_watchdog_timer_fn(unsigned long data) } /* did we stall? */ - if (time_after(jiffies, ts + thresh)) { + if (time_after(now, ts + thresh)) { lockup_detected = true; pr_emerg("BUG: workqueue lockup - pool"); pr_cont_pool_info(pool); pr_cont(" stuck for %us!\n", - jiffies_to_msecs(jiffies - pool_ts) / 1000); + jiffies_to_msecs(now - pool_ts) / 1000); } } diff --git a/lib/decompress_unlz4.c b/lib/decompress_unlz4.c index 036fc882cd72..f1449244fdd4 100644 --- a/lib/decompress_unlz4.c +++ b/lib/decompress_unlz4.c @@ -115,6 +115,9 @@ STATIC inline int INIT unlz4(u8 *input, long in_len, error("data corrupted"); goto exit_2; } + } else if (size < 4) { + /* empty or end-of-file */ + goto exit_3; } chunksize = get_unaligned_le32(inp); @@ -128,6 +131,10 @@ STATIC inline int INIT unlz4(u8 *input, long in_len, continue; } + if (!fill && chunksize == 0) { + /* empty or end-of-file */ + goto exit_3; + } if (posp) *posp += 4; @@ -184,6 +191,7 @@ STATIC inline int INIT unlz4(u8 *input, long in_len, } } +exit_3: ret = 0; exit_2: if (!input) diff --git a/lib/iov_iter.c b/lib/iov_iter.c index a75ea633b5c4..07d735b2eccf 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -394,7 +394,7 @@ int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes) int err; struct iovec v; - if (!(i->type & (ITER_BVEC|ITER_KVEC))) { + if (iter_is_iovec(i)) { iterate_iovec(i, bytes, v, iov, skip, ({ err = fault_in_pages_readable(v.iov_base, v.iov_len); if (unlikely(err)) diff --git a/lib/seq_buf.c b/lib/seq_buf.c index 5954f9fb6675..b3ec487c9728 100644 --- a/lib/seq_buf.c +++ b/lib/seq_buf.c @@ -227,8 +227,10 @@ int seq_buf_putmem_hex(struct seq_buf *s, const void *mem, WARN_ON(s->size == 0); + BUILD_BUG_ON(MAX_MEMHEX_BYTES * 2 >= HEX_CHARS); + while (len) { - start_len = min(len, HEX_CHARS - 1); + start_len = min(len, MAX_MEMHEX_BYTES); #ifdef __BIG_ENDIAN for (i = 0, j = 0; i < start_len; i++) { #else @@ -241,12 +243,14 @@ int seq_buf_putmem_hex(struct seq_buf *s, const void *mem, break; /* j increments twice per loop */ - len -= j / 2; hex[j++] = ' '; seq_buf_putmem(s, hex, j); if (seq_buf_has_overflowed(s)) return -1; + + len -= start_len; + data += start_len; } return 0; } diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 0898b60de437..d11aef19f184 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1369,7 +1369,7 @@ bool madvise_free_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, * If other processes are mapping this page, we couldn't discard * the page unless they all do MADV_FREE so let's skip the page. */ - if (page_mapcount(page) != 1) + if (total_mapcount(page) != 1) goto out; if (!trylock_page(page)) @@ -1891,7 +1891,7 @@ static void unmap_page(struct page *page) { enum ttu_flags ttu_flags = TTU_IGNORE_MLOCK | TTU_IGNORE_ACCESS | TTU_RMAP_LOCKED; - int i, ret; + int i; VM_BUG_ON_PAGE(!PageHead(page), page); @@ -1899,15 +1899,16 @@ static void unmap_page(struct page *page) ttu_flags |= TTU_MIGRATION; /* We only need TTU_SPLIT_HUGE_PMD once */ - ret = try_to_unmap(page, ttu_flags | TTU_SPLIT_HUGE_PMD); - for (i = 1; !ret && i < HPAGE_PMD_NR; i++) { + try_to_unmap(page, ttu_flags | TTU_SPLIT_HUGE_PMD); + for (i = 1; i < HPAGE_PMD_NR; i++) { /* Cut short if the page is unmapped */ if (page_count(page) == 1) return; - ret = try_to_unmap(page + i, ttu_flags); + try_to_unmap(page + i, ttu_flags); } - VM_BUG_ON_PAGE(ret, page + i - 1); + + VM_WARN_ON_ONCE_PAGE(page_mapped(page), page); } static void remap_page(struct page *page) @@ -2138,7 +2139,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) struct pglist_data *pgdata = NODE_DATA(page_to_nid(head)); struct anon_vma *anon_vma = NULL; struct address_space *mapping = NULL; - int count, mapcount, extra_pins, ret; + int extra_pins, ret; bool mlocked; unsigned long flags; pgoff_t end; @@ -2201,7 +2202,6 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) mlocked = PageMlocked(page); unmap_page(head); - VM_BUG_ON_PAGE(compound_mapcount(head), head); /* Make sure the page is not on per-CPU pagevec as it takes pin */ if (mlocked) @@ -2227,9 +2227,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) /* Prevent deferred_split_scan() touching ->_refcount */ spin_lock(&pgdata->split_queue_lock); - count = page_count(head); - mapcount = total_mapcount(head); - if (!mapcount && page_ref_freeze(head, 1 + extra_pins)) { + if (page_ref_freeze(head, 1 + extra_pins)) { if (!list_empty(page_deferred_list(head))) { pgdata->split_queue_len--; list_del(page_deferred_list(head)); @@ -2240,16 +2238,9 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) __split_huge_page(page, list, end, flags); ret = 0; } else { - if (IS_ENABLED(CONFIG_DEBUG_VM) && mapcount) { - pr_alert("total_mapcount: %u, page_count(): %u\n", - mapcount, count); - if (PageTail(page)) - dump_page(head, NULL); - dump_page(page, "total_mapcount(head) > 0"); - BUG(); - } spin_unlock(&pgdata->split_queue_lock); -fail: if (mapping) +fail: + if (mapping) spin_unlock(&mapping->tree_lock); spin_unlock_irqrestore(zone_lru_lock(page_zone(head)), flags); remap_page(head); diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 9049e8613237..de89e9295f6c 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1380,15 +1380,12 @@ int PageHeadHuge(struct page *page_head) return get_compound_page_dtor(page_head) == free_huge_page; } -pgoff_t __basepage_index(struct page *page) +pgoff_t hugetlb_basepage_index(struct page *page) { struct page *page_head = compound_head(page); pgoff_t index = page_index(page_head); unsigned long compound_idx; - if (!PageHuge(page_head)) - return page_index(page); - if (compound_order(page_head) >= MAX_ORDER) compound_idx = page_to_pfn(page) - page_to_pfn(page_head); else @@ -3887,7 +3884,7 @@ backout_unlocked: #ifdef CONFIG_SMP u32 hugetlb_fault_mutex_hash(struct hstate *h, struct address_space *mapping, - pgoff_t idx, unsigned long address) + pgoff_t idx) { unsigned long key[2]; u32 hash; @@ -3895,7 +3892,7 @@ u32 hugetlb_fault_mutex_hash(struct hstate *h, struct address_space *mapping, key[0] = (unsigned long) mapping; key[1] = idx; - hash = jhash2((u32 *)&key, sizeof(key)/sizeof(u32), 0); + hash = jhash2((u32 *)&key, sizeof(key)/(sizeof(u32)), 0); return hash & (num_fault_mutexes - 1); } @@ -3905,7 +3902,7 @@ u32 hugetlb_fault_mutex_hash(struct hstate *h, struct address_space *mapping, * return 0 and avoid the hashing overhead. */ u32 hugetlb_fault_mutex_hash(struct hstate *h, struct address_space *mapping, - pgoff_t idx, unsigned long address) + pgoff_t idx) { return 0; } @@ -3950,7 +3947,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, * get spurious allocation failures if two CPUs race to instantiate * the same page in the page cache. */ - hash = hugetlb_fault_mutex_hash(h, mapping, idx, address); + hash = hugetlb_fault_mutex_hash(h, mapping, idx); mutex_lock(&hugetlb_fault_mutex_table[hash]); entry = huge_ptep_get(ptep); diff --git a/mm/memory-failure.c b/mm/memory-failure.c index a17d9c0b98fb..14be367f6f6a 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -1010,22 +1010,6 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, return ret; } -static void set_page_hwpoison_huge_page(struct page *hpage) -{ - int i; - int nr_pages = 1 << compound_order(hpage); - for (i = 0; i < nr_pages; i++) - SetPageHWPoison(hpage + i); -} - -static void clear_page_hwpoison_huge_page(struct page *hpage) -{ - int i; - int nr_pages = 1 << compound_order(hpage); - for (i = 0; i < nr_pages; i++) - ClearPageHWPoison(hpage + i); -} - /** * memory_failure - Handle memory failure of a page. * @pfn: Page Number of the corrupted page @@ -1051,7 +1035,6 @@ int memory_failure(unsigned long pfn, int trapno, int flags) struct page *hpage; struct page *orig_head; int res; - unsigned int nr_pages; unsigned long page_flags; if (!sysctl_memory_failure_recovery) @@ -1065,24 +1048,23 @@ int memory_failure(unsigned long pfn, int trapno, int flags) p = pfn_to_page(pfn); orig_head = hpage = compound_head(p); + + /* tmporary check code, to be updated in later patches */ + if (PageHuge(p)) { + if (TestSetPageHWPoison(hpage)) { + pr_err("Memory failure: %#lx: already hardware poisoned\n", pfn); + return 0; + } + goto tmp; + } if (TestSetPageHWPoison(p)) { pr_err("Memory failure: %#lx: already hardware poisoned\n", pfn); return 0; } - /* - * Currently errors on hugetlbfs pages are measured in hugepage units, - * so nr_pages should be 1 << compound_order. OTOH when errors are on - * transparent hugepages, they are supposed to be split and error - * measurement is done in normal page units. So nr_pages should be one - * in this case. - */ - if (PageHuge(p)) - nr_pages = 1 << compound_order(hpage); - else /* normal page or thp */ - nr_pages = 1; - num_poisoned_pages_add(nr_pages); +tmp: + num_poisoned_pages_inc(); /* * We need/can do nothing about count=0 pages. @@ -1110,12 +1092,11 @@ int memory_failure(unsigned long pfn, int trapno, int flags) if (PageHWPoison(hpage)) { if ((hwpoison_filter(p) && TestClearPageHWPoison(p)) || (p != hpage && TestSetPageHWPoison(hpage))) { - num_poisoned_pages_sub(nr_pages); + num_poisoned_pages_dec(); unlock_page(hpage); return 0; } } - set_page_hwpoison_huge_page(hpage); res = dequeue_hwpoisoned_huge_page(hpage); action_result(pfn, MF_MSG_FREE_HUGE, res ? MF_IGNORED : MF_DELAYED); @@ -1138,7 +1119,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags) pr_err("Memory failure: %#lx: thp split failed\n", pfn); if (TestClearPageHWPoison(p)) - num_poisoned_pages_sub(nr_pages); + num_poisoned_pages_dec(); put_hwpoison_page(p); return -EBUSY; } @@ -1202,14 +1183,14 @@ int memory_failure(unsigned long pfn, int trapno, int flags) */ if (!PageHWPoison(p)) { pr_err("Memory failure: %#lx: just unpoisoned\n", pfn); - num_poisoned_pages_sub(nr_pages); + num_poisoned_pages_dec(); unlock_page(hpage); put_hwpoison_page(hpage); return 0; } if (hwpoison_filter(p)) { if (TestClearPageHWPoison(p)) - num_poisoned_pages_sub(nr_pages); + num_poisoned_pages_dec(); unlock_page(hpage); put_hwpoison_page(hpage); return 0; @@ -1228,14 +1209,6 @@ int memory_failure(unsigned long pfn, int trapno, int flags) put_hwpoison_page(hpage); return 0; } - /* - * Set PG_hwpoison on all pages in an error hugepage, - * because containment is done in hugepage unit for now. - * Since we have done TestSetPageHWPoison() for the head page with - * page lock held, we can safely set PG_hwpoison bits on tail pages. - */ - if (PageHuge(p)) - set_page_hwpoison_huge_page(hpage); /* * It's very difficult to mess with pages currently under IO @@ -1407,7 +1380,6 @@ int unpoison_memory(unsigned long pfn) struct page *page; struct page *p; int freeit = 0; - unsigned int nr_pages; static DEFINE_RATELIMIT_STATE(unpoison_rs, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); @@ -1452,8 +1424,6 @@ int unpoison_memory(unsigned long pfn) return 0; } - nr_pages = 1 << compound_order(page); - if (!get_hwpoison_page(p)) { /* * Since HWPoisoned hugepage should have non-zero refcount, @@ -1483,10 +1453,8 @@ int unpoison_memory(unsigned long pfn) if (TestClearPageHWPoison(page)) { unpoison_pr_info("Unpoison: Software-unpoisoned page %#lx\n", pfn, &unpoison_rs); - num_poisoned_pages_sub(nr_pages); + num_poisoned_pages_dec(); freeit = 1; - if (PageHuge(page)) - clear_page_hwpoison_huge_page(page); } unlock_page(page); @@ -1612,14 +1580,10 @@ static int soft_offline_huge_page(struct page *page, int flags) ret = -EIO; } else { /* overcommit hugetlb page will be freed to buddy */ - if (PageHuge(page)) { - set_page_hwpoison_huge_page(hpage); + SetPageHWPoison(page); + if (PageHuge(page)) dequeue_hwpoisoned_huge_page(hpage); - num_poisoned_pages_add(1 << compound_order(hpage)); - } else { - SetPageHWPoison(page); - num_poisoned_pages_inc(); - } + num_poisoned_pages_inc(); } return ret; } @@ -1728,15 +1692,12 @@ static int soft_offline_in_use_page(struct page *page, int flags) static void soft_offline_free_page(struct page *page) { - if (PageHuge(page)) { - struct page *hpage = compound_head(page); + struct page *head = compound_head(page); - set_page_hwpoison_huge_page(hpage); - if (!dequeue_hwpoisoned_huge_page(hpage)) - num_poisoned_pages_add(1 << compound_order(hpage)); - } else { - if (!TestSetPageHWPoison(page)) - num_poisoned_pages_inc(); + if (!TestSetPageHWPoison(head)) { + num_poisoned_pages_inc(); + if (PageHuge(head)) + dequeue_hwpoisoned_huge_page(head); } } diff --git a/mm/vmstat.c b/mm/vmstat.c index 67c229324086..f272a74d9dcf 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -1186,6 +1186,9 @@ static void pagetypeinfo_showfree_print(struct seq_file *m, list_for_each(curr, &area->free_list[mtype]) freecount++; seq_printf(m, "%6lu ", freecount); + spin_unlock_irq(&zone->lock); + cond_resched(); + spin_lock_irq(&zone->lock); } seq_putc(m, '\n'); } diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 2b663622bdb4..f85e6a9ee5ea 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -585,8 +585,10 @@ static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet) if (WARN_ON(!forw_packet->if_outgoing)) return; - if (WARN_ON(forw_packet->if_outgoing->soft_iface != soft_iface)) + if (forw_packet->if_outgoing->soft_iface != soft_iface) { + pr_warn("%s: soft interface switch for queued OGM\n", __func__); return; + } if (forw_packet->if_incoming->if_status != BATADV_IF_ACTIVE) return; diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 1152ce34dad4..0bb150e68c53 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -391,6 +391,11 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) if (!(session->flags & BIT(CMTP_LOOPBACK))) { err = cmtp_attach_device(session); if (err < 0) { + /* Caller will call fput in case of failure, and so + * will cmtp_session kthread. + */ + get_file(session->sock->file); + atomic_inc(&session->terminate); wake_up_interruptible(sk_sleep(session->sock->sk)); up_write(&cmtp_session_sem); diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 02f44a408edb..50b9a0bbe5df 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1422,8 +1422,13 @@ static int hci_dev_do_open(struct hci_dev *hdev) } else { /* Init failed, cleanup */ flush_work(&hdev->tx_work); - flush_work(&hdev->cmd_work); + + /* Since hci_rx_work() is possible to awake new cmd_work + * it should be flushed first to avoid unexpected call of + * hci_cmd_work() + */ flush_work(&hdev->rx_work); + flush_work(&hdev->cmd_work); skb_queue_purge(&hdev->cmd_q); skb_queue_purge(&hdev->rx_q); @@ -1528,14 +1533,6 @@ int hci_dev_do_close(struct hci_dev *hdev) BT_DBG("%s %p", hdev->name, hdev); - if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) && - !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && - test_bit(HCI_UP, &hdev->flags)) { - /* Execute vendor specific shutdown routine */ - if (hdev->shutdown) - hdev->shutdown(hdev); - } - cancel_delayed_work(&hdev->power_off); hci_request_cancel_all(hdev); @@ -1603,6 +1600,14 @@ int hci_dev_do_close(struct hci_dev *hdev) clear_bit(HCI_INIT, &hdev->flags); } + if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) && + !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && + test_bit(HCI_UP, &hdev->flags)) { + /* Execute vendor specific shutdown routine */ + if (hdev->shutdown) + hdev->shutdown(hdev); + } + /* flush cmd work */ flush_work(&hdev->cmd_work); diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 44b3146c6117..35f5585188de 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -750,7 +750,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event) /* Detach sockets from device */ read_lock(&hci_sk_list.lock); sk_for_each(sk, &hci_sk_list.head) { - bh_lock_sock_nested(sk); + lock_sock(sk); if (hci_pi(sk)->hdev == hdev) { hci_pi(sk)->hdev = NULL; sk->sk_err = EPIPE; @@ -759,7 +759,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event) hci_dev_put(hdev); } - bh_unlock_sock(sk); + release_sock(sk); } read_unlock(&hci_sk_list.lock); } diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index bca1408f815f..7aef6d23bc77 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -219,12 +219,15 @@ static u8 mgmt_status_table[] = { MGMT_STATUS_TIMEOUT, /* Instant Passed */ MGMT_STATUS_NOT_SUPPORTED, /* Pairing Not Supported */ MGMT_STATUS_FAILED, /* Transaction Collision */ + MGMT_STATUS_FAILED, /* Reserved for future use */ MGMT_STATUS_INVALID_PARAMS, /* Unacceptable Parameter */ MGMT_STATUS_REJECTED, /* QoS Rejected */ MGMT_STATUS_NOT_SUPPORTED, /* Classification Not Supported */ MGMT_STATUS_REJECTED, /* Insufficient Security */ MGMT_STATUS_INVALID_PARAMS, /* Parameter Out Of Range */ + MGMT_STATUS_FAILED, /* Reserved for future use */ MGMT_STATUS_BUSY, /* Role Switch Pending */ + MGMT_STATUS_FAILED, /* Reserved for future use */ MGMT_STATUS_FAILED, /* Slot Violation */ MGMT_STATUS_FAILED, /* Role Switch Failed */ MGMT_STATUS_INVALID_PARAMS, /* EIR Too Large */ @@ -6087,6 +6090,9 @@ static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data, for (i = 0, cur_len = 0; i < len; i += (cur_len + 1)) { cur_len = data[i]; + if (!cur_len) + continue; + if (data[i + 1] == EIR_FLAGS && (!is_adv_data || flags_managed(adv_flags))) return false; diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 6670b7ffc200..cedfce6f397e 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -2636,6 +2636,15 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb) if (skb->len < sizeof(*key)) return SMP_INVALID_PARAMS; + /* Check if remote and local public keys are the same and debug key is + * not in use. + */ + if (!test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags) && + !crypto_memneq(key, smp->local_pk, 64)) { + bt_dev_err(hdev, "Remote and local public keys are identical"); + return SMP_UNSPECIFIED; + } + memcpy(smp->remote_pk, key, 64); if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags)) { diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index a0443d40d677..a28ffbbf7450 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c @@ -303,7 +303,7 @@ static void dev_flowctrl(struct net_device *dev, int on) caifd_put(caifd); } -void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, +int caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, struct cflayer *link_support, int head_room, struct cflayer **layer, int (**rcv_func)(struct sk_buff *, struct net_device *, @@ -314,11 +314,12 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, enum cfcnfg_phy_preference pref; struct cfcnfg *cfg = get_cfcnfg(dev_net(dev)); struct caif_device_entry_list *caifdevs; + int res; caifdevs = caif_device_list(dev_net(dev)); caifd = caif_device_alloc(dev); if (!caifd) - return; + return -ENOMEM; *layer = &caifd->layer; spin_lock_init(&caifd->flow_lock); @@ -340,7 +341,7 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, sizeof(caifd->layer.name) - 1); caifd->layer.name[sizeof(caifd->layer.name) - 1] = 0; caifd->layer.transmit = transmit; - cfcnfg_add_phy_layer(cfg, + res = cfcnfg_add_phy_layer(cfg, dev, &caifd->layer, pref, @@ -350,6 +351,7 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, mutex_unlock(&caifdevs->lock); if (rcv_func) *rcv_func = receive; + return res; } EXPORT_SYMBOL(caif_enroll_dev); @@ -364,6 +366,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, struct cflayer *layer, *link_support; int head_room = 0; struct caif_device_entry_list *caifdevs; + int res; cfg = get_cfcnfg(dev_net(dev)); caifdevs = caif_device_list(dev_net(dev)); @@ -389,8 +392,10 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, break; } } - caif_enroll_dev(dev, caifdev, link_support, head_room, + res = caif_enroll_dev(dev, caifdev, link_support, head_room, &layer, NULL); + if (res) + cfserl_release(link_support); caifdev->flowctrl = dev_flowctrl; break; diff --git a/net/caif/caif_usb.c b/net/caif/caif_usb.c index 5cd44f001f64..485dde566c1a 100644 --- a/net/caif/caif_usb.c +++ b/net/caif/caif_usb.c @@ -116,6 +116,11 @@ static struct cflayer *cfusbl_create(int phyid, u8 ethaddr[ETH_ALEN], return (struct cflayer *) this; } +static void cfusbl_release(struct cflayer *layer) +{ + kfree(layer); +} + static struct packet_type caif_usb_type __read_mostly = { .type = cpu_to_be16(ETH_P_802_EX1), }; @@ -128,6 +133,7 @@ static int cfusbl_device_notify(struct notifier_block *me, unsigned long what, struct cflayer *layer, *link_support; struct usbnet *usbnet; struct usb_device *usbdev; + int res; /* Check whether we have a NCM device, and find its VID/PID. */ if (!(dev->dev.parent && dev->dev.parent->driver && @@ -170,8 +176,11 @@ static int cfusbl_device_notify(struct notifier_block *me, unsigned long what, if (dev->num_tx_queues > 1) pr_warn("USB device uses more than one tx queue\n"); - caif_enroll_dev(dev, &common, link_support, CFUSB_MAX_HEADLEN, + res = caif_enroll_dev(dev, &common, link_support, CFUSB_MAX_HEADLEN, &layer, &caif_usb_type.func); + if (res) + goto err; + if (!pack_added) dev_add_pack(&caif_usb_type); pack_added = true; @@ -181,6 +190,9 @@ static int cfusbl_device_notify(struct notifier_block *me, unsigned long what, layer->name[sizeof(layer->name) - 1] = 0; return 0; +err: + cfusbl_release(link_support); + return res; } static struct notifier_block caif_device_notifier = { diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index fa39fc298708..c45b531a6cd5 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c @@ -455,7 +455,7 @@ unlock: rcu_read_unlock(); } -void +int cfcnfg_add_phy_layer(struct cfcnfg *cnfg, struct net_device *dev, struct cflayer *phy_layer, enum cfcnfg_phy_preference pref, @@ -464,7 +464,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, { struct cflayer *frml; struct cfcnfg_phyinfo *phyinfo = NULL; - int i; + int i, res = 0; u8 phyid; mutex_lock(&cnfg->lock); @@ -478,12 +478,15 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, goto got_phyid; } pr_warn("Too many CAIF Link Layers (max 6)\n"); + res = -EEXIST; goto out; got_phyid: phyinfo = kzalloc(sizeof(struct cfcnfg_phyinfo), GFP_ATOMIC); - if (!phyinfo) + if (!phyinfo) { + res = -ENOMEM; goto out_err; + } phy_layer->id = phyid; phyinfo->pref = pref; @@ -497,8 +500,10 @@ got_phyid: frml = cffrml_create(phyid, fcs); - if (!frml) + if (!frml) { + res = -ENOMEM; goto out_err; + } phyinfo->frm_layer = frml; layer_set_up(frml, cnfg->mux); @@ -516,11 +521,12 @@ got_phyid: list_add_rcu(&phyinfo->node, &cnfg->phys); out: mutex_unlock(&cnfg->lock); - return; + return res; out_err: kfree(phyinfo); mutex_unlock(&cnfg->lock); + return res; } EXPORT_SYMBOL(cfcnfg_add_phy_layer); diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c index ce60f06d76de..af1e1e36dc90 100644 --- a/net/caif/cfserl.c +++ b/net/caif/cfserl.c @@ -31,6 +31,11 @@ static int cfserl_transmit(struct cflayer *layr, struct cfpkt *pkt); static void cfserl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, int phyid); +void cfserl_release(struct cflayer *layer) +{ + kfree(layer); +} + struct cflayer *cfserl_create(int instance, bool use_stx) { struct cfserl *this = kzalloc(sizeof(struct cfserl), GFP_ATOMIC); diff --git a/net/can/bcm.c b/net/can/bcm.c index c99e7c75eeee..369326715b9c 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -127,7 +127,7 @@ struct bcm_sock { struct sock sk; int bound; int ifindex; - struct notifier_block notifier; + struct list_head notifier; struct list_head rx_ops; struct list_head tx_ops; unsigned long dropped_usr_msgs; @@ -135,6 +135,10 @@ struct bcm_sock { char procname [32]; /* inode number in decimal with \0 */ }; +static LIST_HEAD(bcm_notifier_list); +static DEFINE_SPINLOCK(bcm_notifier_lock); +static struct bcm_sock *bcm_busy_notifier; + static inline struct bcm_sock *bcm_sk(const struct sock *sk) { return (struct bcm_sock *)sk; @@ -405,6 +409,7 @@ static void bcm_tx_timeout_tsklet(unsigned long data) if (!op->count && (op->flags & TX_COUNTEVT)) { /* create notification to user */ + memset(&msg_head, 0, sizeof(msg_head)); msg_head.opcode = TX_EXPIRED; msg_head.flags = op->flags; msg_head.count = op->count; @@ -452,6 +457,7 @@ static void bcm_rx_changed(struct bcm_op *op, struct canfd_frame *data) /* this element is not throttled anymore */ data->flags &= (BCM_CAN_FLAGS_MASK|RX_RECV); + memset(&head, 0, sizeof(head)); head.opcode = RX_CHANGED; head.flags = op->flags; head.count = op->count; @@ -566,6 +572,7 @@ static void bcm_rx_timeout_tsklet(unsigned long data) struct bcm_msg_head msg_head; /* create notification to user */ + memset(&msg_head, 0, sizeof(msg_head)); msg_head.opcode = RX_TIMEOUT; msg_head.flags = op->flags; msg_head.count = op->count; @@ -832,6 +839,7 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh, bcm_rx_handler, op); list_del(&op->list); + synchronize_rcu(); bcm_remove_op(op); return 1; /* done */ } @@ -1436,20 +1444,15 @@ static int bcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) /* * notification handler for netdevice status changes */ -static int bcm_notifier(struct notifier_block *nb, unsigned long msg, - void *ptr) +static void bcm_notify(struct bcm_sock *bo, unsigned long msg, + struct net_device *dev) { - struct net_device *dev = netdev_notifier_info_to_dev(ptr); - struct bcm_sock *bo = container_of(nb, struct bcm_sock, notifier); struct sock *sk = &bo->sk; struct bcm_op *op; int notify_enodev = 0; if (!net_eq(dev_net(dev), &init_net)) - return NOTIFY_DONE; - - if (dev->type != ARPHRD_CAN) - return NOTIFY_DONE; + return; switch (msg) { @@ -1484,7 +1487,28 @@ static int bcm_notifier(struct notifier_block *nb, unsigned long msg, sk->sk_error_report(sk); } } +} +static int bcm_notifier(struct notifier_block *nb, unsigned long msg, + void *ptr) +{ + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + + if (dev->type != ARPHRD_CAN) + return NOTIFY_DONE; + if (msg != NETDEV_UNREGISTER && msg != NETDEV_DOWN) + return NOTIFY_DONE; + if (unlikely(bcm_busy_notifier)) /* Check for reentrant bug. */ + return NOTIFY_DONE; + + spin_lock(&bcm_notifier_lock); + list_for_each_entry(bcm_busy_notifier, &bcm_notifier_list, notifier) { + spin_unlock(&bcm_notifier_lock); + bcm_notify(bcm_busy_notifier, msg, dev); + spin_lock(&bcm_notifier_lock); + } + bcm_busy_notifier = NULL; + spin_unlock(&bcm_notifier_lock); return NOTIFY_DONE; } @@ -1504,9 +1528,9 @@ static int bcm_init(struct sock *sk) INIT_LIST_HEAD(&bo->rx_ops); /* set notifier */ - bo->notifier.notifier_call = bcm_notifier; - - register_netdevice_notifier(&bo->notifier); + spin_lock(&bcm_notifier_lock); + list_add_tail(&bo->notifier, &bcm_notifier_list); + spin_unlock(&bcm_notifier_lock); return 0; } @@ -1527,7 +1551,14 @@ static int bcm_release(struct socket *sock) /* remove bcm_ops, timer, rx_unregister(), etc. */ - unregister_netdevice_notifier(&bo->notifier); + spin_lock(&bcm_notifier_lock); + while (bcm_busy_notifier == bo) { + spin_unlock(&bcm_notifier_lock); + schedule_timeout_uninterruptible(1); + spin_lock(&bcm_notifier_lock); + } + list_del(&bo->notifier); + spin_unlock(&bcm_notifier_lock); lock_sock(sk); @@ -1559,9 +1590,13 @@ static int bcm_release(struct socket *sock) REGMASK(op->can_id), bcm_rx_handler, op); - bcm_remove_op(op); } + synchronize_rcu(); + + list_for_each_entry_safe(op, next, &bo->rx_ops, list) + bcm_remove_op(op); + /* remove procfs entry */ if (proc_dir && bo->bcm_proc_read) remove_proc_entry(bo->procname, proc_dir); @@ -1713,6 +1748,10 @@ static const struct can_proto bcm_can_proto = { .prot = &bcm_proto, }; +static struct notifier_block canbcm_notifier = { + .notifier_call = bcm_notifier +}; + static int __init bcm_module_init(void) { int err; @@ -1727,6 +1766,8 @@ static int __init bcm_module_init(void) /* create /proc/net/can-bcm directory */ proc_dir = proc_mkdir("can-bcm", init_net.proc_net); + register_netdevice_notifier(&canbcm_notifier); + return 0; } @@ -1736,6 +1777,8 @@ static void __exit bcm_module_exit(void) if (proc_dir) remove_proc_entry("can-bcm", init_net.proc_net); + + unregister_netdevice_notifier(&canbcm_notifier); } module_init(bcm_module_init); diff --git a/net/can/gw.c b/net/can/gw.c index 81650affa3fa..1867000f8a65 100644 --- a/net/can/gw.c +++ b/net/can/gw.c @@ -497,6 +497,7 @@ static int cgw_notifier(struct notifier_block *nb, if (gwj->src.dev == dev || gwj->dst.dev == dev) { hlist_del(&gwj->list); cgw_unregister_filter(gwj); + synchronize_rcu(); kmem_cache_free(cgw_cache, gwj); } } @@ -941,6 +942,7 @@ static void cgw_remove_all_jobs(void) hlist_for_each_entry_safe(gwj, nx, &cgw_list, list) { hlist_del(&gwj->list); cgw_unregister_filter(gwj); + synchronize_rcu(); kmem_cache_free(cgw_cache, gwj); } } @@ -1008,6 +1010,7 @@ static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh) hlist_del(&gwj->list); cgw_unregister_filter(gwj); + synchronize_rcu(); kmem_cache_free(cgw_cache, gwj); err = 0; break; diff --git a/net/can/raw.c b/net/can/raw.c index 6dc546a06673..2bb50b1535c2 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -84,7 +84,7 @@ struct raw_sock { struct sock sk; int bound; int ifindex; - struct notifier_block notifier; + struct list_head notifier; int loopback; int recv_own_msgs; int fd_frames; @@ -96,6 +96,10 @@ struct raw_sock { struct uniqframe __percpu *uniq; }; +static LIST_HEAD(raw_notifier_list); +static DEFINE_SPINLOCK(raw_notifier_lock); +static struct raw_sock *raw_busy_notifier; + /* * Return pointer to store the extra msg flags for raw_recvmsg(). * We use the space of one unsigned int beyond the 'struct sockaddr_can' @@ -260,21 +264,16 @@ static int raw_enable_allfilters(struct net_device *dev, struct sock *sk) return err; } -static int raw_notifier(struct notifier_block *nb, - unsigned long msg, void *ptr) +static void raw_notify(struct raw_sock *ro, unsigned long msg, + struct net_device *dev) { - struct net_device *dev = netdev_notifier_info_to_dev(ptr); - struct raw_sock *ro = container_of(nb, struct raw_sock, notifier); struct sock *sk = &ro->sk; if (!net_eq(dev_net(dev), &init_net)) - return NOTIFY_DONE; - - if (dev->type != ARPHRD_CAN) - return NOTIFY_DONE; + return; if (ro->ifindex != dev->ifindex) - return NOTIFY_DONE; + return; switch (msg) { @@ -303,7 +302,28 @@ static int raw_notifier(struct notifier_block *nb, sk->sk_error_report(sk); break; } +} +static int raw_notifier(struct notifier_block *nb, unsigned long msg, + void *ptr) +{ + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + + if (dev->type != ARPHRD_CAN) + return NOTIFY_DONE; + if (msg != NETDEV_UNREGISTER && msg != NETDEV_DOWN) + return NOTIFY_DONE; + if (unlikely(raw_busy_notifier)) /* Check for reentrant bug. */ + return NOTIFY_DONE; + + spin_lock(&raw_notifier_lock); + list_for_each_entry(raw_busy_notifier, &raw_notifier_list, notifier) { + spin_unlock(&raw_notifier_lock); + raw_notify(raw_busy_notifier, msg, dev); + spin_lock(&raw_notifier_lock); + } + raw_busy_notifier = NULL; + spin_unlock(&raw_notifier_lock); return NOTIFY_DONE; } @@ -332,9 +352,9 @@ static int raw_init(struct sock *sk) return -ENOMEM; /* set notifier */ - ro->notifier.notifier_call = raw_notifier; - - register_netdevice_notifier(&ro->notifier); + spin_lock(&raw_notifier_lock); + list_add_tail(&ro->notifier, &raw_notifier_list); + spin_unlock(&raw_notifier_lock); return 0; } @@ -349,7 +369,14 @@ static int raw_release(struct socket *sock) ro = raw_sk(sk); - unregister_netdevice_notifier(&ro->notifier); + spin_lock(&raw_notifier_lock); + while (raw_busy_notifier == ro) { + spin_unlock(&raw_notifier_lock); + schedule_timeout_uninterruptible(1); + spin_lock(&raw_notifier_lock); + } + list_del(&ro->notifier); + spin_unlock(&raw_notifier_lock); lock_sock(sk); @@ -857,6 +884,10 @@ static const struct can_proto raw_can_proto = { .prot = &raw_proto, }; +static struct notifier_block canraw_notifier = { + .notifier_call = raw_notifier +}; + static __init int raw_module_init(void) { int err; @@ -866,6 +897,8 @@ static __init int raw_module_init(void) err = can_proto_register(&raw_can_proto); if (err < 0) printk(KERN_ERR "can: registration of raw protocol failed\n"); + else + register_netdevice_notifier(&canraw_notifier); return err; } @@ -873,6 +906,7 @@ static __init int raw_module_init(void) static __exit void raw_module_exit(void) { can_proto_unregister(&raw_can_proto); + unregister_netdevice_notifier(&canraw_notifier); } module_init(raw_module_init); diff --git a/net/compat.c b/net/compat.c index ce851cf4d0f9..1f08f0e49e07 100644 --- a/net/compat.c +++ b/net/compat.c @@ -159,7 +159,7 @@ int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg, struct sock *sk, if (kcmlen > stackbuf_size) kcmsg_base = kcmsg = sock_kmalloc(sk, kcmlen, GFP_KERNEL); if (kcmsg == NULL) - return -ENOBUFS; + return -ENOMEM; /* Now copy them over neatly. */ memset(kcmsg, 0, kcmlen); diff --git a/net/core/dev.c b/net/core/dev.c index 98d4c361da20..c6ab36e553f8 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5116,11 +5116,18 @@ EXPORT_SYMBOL(__napi_schedule); * __napi_schedule_irqoff - schedule for receive * @n: entry to schedule * - * Variant of __napi_schedule() assuming hard irqs are masked + * Variant of __napi_schedule() assuming hard irqs are masked. + * + * On PREEMPT_RT enabled kernels this maps to __napi_schedule() + * because the interrupt disabled assumption might not be true + * due to force-threaded interrupts and spinlock substitution. */ void __napi_schedule_irqoff(struct napi_struct *n) { - ____napi_schedule(this_cpu_ptr(&softnet_data), n); + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) + ____napi_schedule(this_cpu_ptr(&softnet_data), n); + else + __napi_schedule(n); } EXPORT_SYMBOL(__napi_schedule_irqoff); diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 955fc01a030a..5473af8cb4c9 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -843,7 +843,7 @@ static void notify_rule_change(int event, struct fib_rule *rule, { struct net *net; struct sk_buff *skb; - int err = -ENOBUFS; + int err = -ENOMEM; net = ops->fro_net; skb = nlmsg_new(fib_rule_nlmsg_size(ops, rule), GFP_KERNEL); diff --git a/net/core/filter.c b/net/core/filter.c index cf9d0d194a8b..2b3a03f04cc1 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -1999,8 +1999,6 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb) skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV6; } - /* Due to IPv6 header, MSS needs to be downgraded. */ - skb_shinfo(skb)->gso_size -= len_diff; /* Header must be checked, and gso_segs recomputed. */ skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; skb_shinfo(skb)->gso_segs = 0; @@ -2035,8 +2033,6 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb) skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4; } - /* Due to IPv4 header, MSS can be upgraded. */ - skb_shinfo(skb)->gso_size += len_diff; /* Header must be checked, and gso_segs recomputed. */ skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; skb_shinfo(skb)->gso_segs = 0; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index e652e376fb30..911752e8a3e6 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -3530,6 +3530,10 @@ static int rtnl_bridge_notify(struct net_device *dev) if (err < 0) goto errout; + /* Notification info is only filled for bridge ports, not the bridge + * device itself. Therefore, a zero notification length is valid and + * should not result in an error. + */ if (!skb->len) goto errout; diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c index c0930b9fe848..7531cb1665d2 100644 --- a/net/ieee802154/nl-mac.c +++ b/net/ieee802154/nl-mac.c @@ -688,8 +688,10 @@ int ieee802154_llsec_getparams(struct sk_buff *skb, struct genl_info *info) nla_put_u8(msg, IEEE802154_ATTR_LLSEC_SECLEVEL, params.out_level) || nla_put_u32(msg, IEEE802154_ATTR_LLSEC_FRAME_COUNTER, be32_to_cpu(params.frame_counter)) || - ieee802154_llsec_fill_key_id(msg, ¶ms.out_key)) + ieee802154_llsec_fill_key_id(msg, ¶ms.out_key)) { + rc = -ENOBUFS; goto out_free; + } dev_put(dev); diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c index 77d73014bde3..11f53dc0c1c0 100644 --- a/net/ieee802154/nl-phy.c +++ b/net/ieee802154/nl-phy.c @@ -249,8 +249,10 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info) } if (nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) || - nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name)) + nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name)) { + rc = -EMSGSIZE; goto nla_put_failure; + } dev_put(dev); wpan_phy_put(phy); diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index cfc01314958f..936371340dc3 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -1330,19 +1330,20 @@ ieee802154_llsec_parse_dev_addr(struct nlattr *nla, nl802154_dev_addr_policy)) return -EINVAL; - if (!attrs[NL802154_DEV_ADDR_ATTR_PAN_ID] || - !attrs[NL802154_DEV_ADDR_ATTR_MODE] || - !(attrs[NL802154_DEV_ADDR_ATTR_SHORT] || - attrs[NL802154_DEV_ADDR_ATTR_EXTENDED])) + if (!attrs[NL802154_DEV_ADDR_ATTR_PAN_ID] || !attrs[NL802154_DEV_ADDR_ATTR_MODE]) return -EINVAL; addr->pan_id = nla_get_le16(attrs[NL802154_DEV_ADDR_ATTR_PAN_ID]); addr->mode = nla_get_u32(attrs[NL802154_DEV_ADDR_ATTR_MODE]); switch (addr->mode) { case NL802154_DEV_ADDR_SHORT: + if (!attrs[NL802154_DEV_ADDR_ATTR_SHORT]) + return -EINVAL; addr->short_addr = nla_get_le16(attrs[NL802154_DEV_ADDR_ATTR_SHORT]); break; case NL802154_DEV_ADDR_EXTENDED: + if (!attrs[NL802154_DEV_ADDR_ATTR_EXTENDED]) + return -EINVAL; addr->extended_addr = nla_get_le64(attrs[NL802154_DEV_ADDR_ATTR_EXTENDED]); break; default: diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 71409928763b..553cda6f887a 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -486,6 +486,7 @@ void cipso_v4_doi_free(struct cipso_v4_doi *doi_def) kfree(doi_def->map.std->lvl.local); kfree(doi_def->map.std->cat.cipso); kfree(doi_def->map.std->cat.local); + kfree(doi_def->map.std); break; } kfree(doi_def); diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 02c1736c0b89..f4a827964b68 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -1782,6 +1782,7 @@ void ip_mc_destroy_dev(struct in_device *in_dev) while ((i = rtnl_dereference(in_dev->mc_list)) != NULL) { in_dev->mc_list = i->next_rcu; in_dev->mc_count--; + ip_mc_clear_src(i); ip_ma_put(i); } } diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index d278b06459ac..79d8ea98a5b1 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -880,7 +880,7 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d /* - * Copy BOOTP-supplied string if not already set. + * Copy BOOTP-supplied string */ static int __init ic_bootp_string(char *dest, char *src, int len, int max) { @@ -929,12 +929,15 @@ static void __init ic_do_bootp_ext(u8 *ext) } break; case 12: /* Host name */ - ic_bootp_string(utsname()->nodename, ext+1, *ext, - __NEW_UTS_LEN); - ic_host_name_set = 1; + if (!ic_host_name_set) { + ic_bootp_string(utsname()->nodename, ext+1, *ext, + __NEW_UTS_LEN); + ic_host_name_set = 1; + } break; case 15: /* Domain name (DNS) */ - ic_bootp_string(ic_domain, ext+1, *ext, sizeof(ic_domain)); + if (!ic_domain[0]) + ic_bootp_string(ic_domain, ext+1, *ext, sizeof(ic_domain)); break; case 17: /* Root path */ if (!root_server_path[0]) diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 65662922c961..1d8c9fa4addf 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -977,6 +977,7 @@ bool ping_rcv(struct sk_buff *skb) struct sock *sk; struct net *net = dev_net(skb->dev); struct icmphdr *icmph = icmp_hdr(skb); + bool rc = false; /* We assume the packet has already been checked by icmp_rcv */ @@ -991,14 +992,15 @@ bool ping_rcv(struct sk_buff *skb) struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); pr_debug("rcv on socket %p\n", sk); - if (skb2) - ping_queue_rcv_skb(sk, skb2); + if (skb2 && !ping_queue_rcv_skb(sk, skb2)) + rc = true; sock_put(sk); - return true; } - pr_debug("no socket, dropping\n"); - return false; + if (!rc) + pr_debug("no socket, dropping\n"); + + return rc; } EXPORT_SYMBOL_GPL(ping_rcv); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 0c02c858ba93..4a5cccfe20af 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -463,8 +464,10 @@ static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, return neigh_create(&arp_tbl, pkey, dev); } -#define IP_IDENTS_SZ 2048u - +/* Hash tables of size 2048..262144 depending on RAM size. + * Each bucket uses 8 bytes. + */ +static u32 ip_idents_mask __read_mostly; static atomic_t *ip_idents __read_mostly; static u32 *ip_tstamps __read_mostly; @@ -474,12 +477,16 @@ static u32 *ip_tstamps __read_mostly; */ u32 ip_idents_reserve(u32 hash, int segs) { - u32 *p_tstamp = ip_tstamps + hash % IP_IDENTS_SZ; - atomic_t *p_id = ip_idents + hash % IP_IDENTS_SZ; - u32 old = ACCESS_ONCE(*p_tstamp); - u32 now = (u32)jiffies; + u32 bucket, old, now = (u32)jiffies; + atomic_t *p_id; + u32 *p_tstamp; u32 delta = 0; + bucket = hash & ip_idents_mask; + p_tstamp = ip_tstamps + bucket; + p_id = ip_idents + bucket; + old = ACCESS_ONCE(*p_tstamp); + if (old != now && cmpxchg(p_tstamp, old, now) == old) delta = prandom_u32_max(now - old); @@ -2954,18 +2961,27 @@ struct ip_rt_acct __percpu *ip_rt_acct __read_mostly; int __init ip_rt_init(void) { + void *idents_hash; int rc = 0; int cpu; - ip_idents = kmalloc(IP_IDENTS_SZ * sizeof(*ip_idents), GFP_KERNEL); - if (!ip_idents) - panic("IP: failed to allocate ip_idents\n"); + /* For modern hosts, this will use 2 MB of memory */ + idents_hash = alloc_large_system_hash("IP idents", + sizeof(*ip_idents) + sizeof(*ip_tstamps), + 0, + 16, /* one bucket per 64 KB */ + 0, + NULL, + &ip_idents_mask, + 2048, + 256*1024); - prandom_bytes(ip_idents, IP_IDENTS_SZ * sizeof(*ip_idents)); + ip_idents = idents_hash; - ip_tstamps = kcalloc(IP_IDENTS_SZ, sizeof(*ip_tstamps), GFP_KERNEL); - if (!ip_tstamps) - panic("IP: failed to allocate ip_tstamps\n"); + prandom_bytes(ip_idents, (ip_idents_mask + 1) * sizeof(*ip_idents)); + + ip_tstamps = idents_hash + (ip_idents_mask + 1) * sizeof(*ip_idents); + memset(ip_tstamps, 0, (ip_idents_mask + 1) * sizeof(*ip_tstamps)); for_each_possible_cpu(cpu) { struct uncached_list *ul = &per_cpu(rt_uncached_list, cpu); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 5e76b274ef5b..19658c1b1d07 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -2006,6 +2006,9 @@ void udp_destroy_sock(struct sock *sk) { struct udp_sock *up = udp_sk(sk); bool slow = lock_sock_fast(sk); + + /* protects from races with udp_abort() */ + sock_set_flag(sk, SOCK_DEAD); udp_flush_pending_frames(sk); unlock_sock_fast(sk, slow); if (static_key_false(&udp_encap_needed) && up->encap_type) { @@ -2236,10 +2239,17 @@ int udp_abort(struct sock *sk, int err) { lock_sock(sk); + /* udp{v6}_destroy_sock() sets it under the sk lock, avoid racing + * with close() + */ + if (sock_flag(sk, SOCK_DEAD)) + goto out; + sk->sk_err = err; sk->sk_error_report(sk); __udp_disconnect(sk, 0); +out: release_sock(sk); return 0; diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index f904b9b24027..9a78b89690bd 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -1580,10 +1580,7 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu) IPV6_TLV_PADN, 0 }; /* we assume size > sizeof(ra) here */ - /* limit our allocations to order-0 page */ - size = min_t(int, size, SKB_MAX_ORDER(0, 0)); skb = sock_alloc_send_skb(sk, size, 1, &err); - if (!skb) return NULL; diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c index 6a6d01cb1ace..9c25e8b09306 100644 --- a/net/ipv6/output_core.c +++ b/net/ipv6/output_core.c @@ -14,29 +14,11 @@ static u32 __ipv6_select_ident(struct net *net, const struct in6_addr *dst, const struct in6_addr *src) { - const struct { - struct in6_addr dst; - struct in6_addr src; - } __aligned(SIPHASH_ALIGNMENT) combined = { - .dst = *dst, - .src = *src, - }; - u32 hash, id; + u32 id; - /* Note the following code is not safe, but this is okay. */ - if (unlikely(siphash_key_is_zero(&net->ipv4.ip_id_key))) - get_random_bytes(&net->ipv4.ip_id_key, - sizeof(net->ipv4.ip_id_key)); - - hash = siphash(&combined, sizeof(combined), &net->ipv4.ip_id_key); - - /* Treat id of 0 as unset and if we get 0 back from ip_idents_reserve, - * set the hight order instead thus minimizing possible future - * collisions. - */ - id = ip_idents_reserve(hash, 1); - if (unlikely(!id)) - id = 1 << 31; + do { + id = prandom_u32(); + } while (!id); return id; } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index a3f2df4d941a..3a7c0e5be1c0 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1410,6 +1410,9 @@ void udpv6_destroy_sock(struct sock *sk) { struct udp_sock *up = udp_sk(sk); lock_sock(sk); + + /* protects from races with udp_abort() */ + sock_set_flag(sk, SOCK_DEAD); udp_v6_flush_pending_frames(sk); release_sock(sk); diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 9c20c53f6729..f5532a3ce72e 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -52,12 +52,6 @@ struct ieee80211_local; #define IEEE80211_ENCRYPT_HEADROOM 8 #define IEEE80211_ENCRYPT_TAILROOM 18 -/* IEEE 802.11 (Ch. 9.5 Defragmentation) requires support for concurrent - * reception of at least three fragmented frames. This limit can be increased - * by changing this define, at the cost of slower frame reassembly and - * increased memory use (about 2 kB of RAM per entry). */ -#define IEEE80211_FRAGMENT_MAX 4 - /* power level hasn't been configured (or set to automatic) */ #define IEEE80211_UNSET_POWER_LEVEL INT_MIN @@ -88,18 +82,6 @@ struct ieee80211_local; #define IEEE80211_MAX_NAN_INSTANCE_ID 255 -struct ieee80211_fragment_entry { - struct sk_buff_head skb_list; - unsigned long first_frag_time; - u16 seq; - u16 extra_len; - u16 last_frag; - u8 rx_queue; - bool check_sequential_pn; /* needed for CCMP/GCMP */ - u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ -}; - - struct ieee80211_bss { u32 device_ts_beacon, device_ts_presp; @@ -239,8 +221,15 @@ struct ieee80211_rx_data { */ int security_idx; - u32 tkip_iv32; - u16 tkip_iv16; + union { + struct { + u32 iv32; + u16 iv16; + } tkip; + struct { + u8 pn[IEEE80211_CCMP_PN_LEN]; + } ccm_gcm; + }; }; struct ieee80211_csa_settings { @@ -869,9 +858,7 @@ struct ieee80211_sub_if_data { char name[IFNAMSIZ]; - /* Fragment table for host-based reassembly */ - struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; - unsigned int fragment_next; + struct ieee80211_fragment_cache frags; /* TID bitmap for NoAck policy */ u16 noack_map; @@ -1404,7 +1391,7 @@ ieee80211_get_sband(struct ieee80211_sub_if_data *sdata) rcu_read_lock(); chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (WARN_ON_ONCE(!chanctx_conf)) { + if (!chanctx_conf) { rcu_read_unlock(); return NULL; } @@ -2136,4 +2123,7 @@ extern const struct ethtool_ops ieee80211_ethtool_ops; #define debug_noinline #endif +void ieee80211_init_frag_cache(struct ieee80211_fragment_cache *cache); +void ieee80211_destroy_frag_cache(struct ieee80211_fragment_cache *cache); + #endif /* IEEE80211_I_H */ diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 7d43e0085cfc..deebf42c740e 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1120,16 +1120,12 @@ static void ieee80211_set_multicast_list(struct net_device *dev) */ static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) { - int i; - /* free extra data */ ieee80211_free_keys(sdata, false); ieee80211_debugfs_remove_netdev(sdata); - for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) - __skb_queue_purge(&sdata->fragments[i].skb_list); - sdata->fragment_next = 0; + ieee80211_destroy_frag_cache(&sdata->frags); if (ieee80211_vif_is_mesh(&sdata->vif)) ieee80211_mesh_teardown_sdata(sdata); @@ -1863,8 +1859,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, sdata->wdev.wiphy = local->hw.wiphy; sdata->local = local; - for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) - skb_queue_head_init(&sdata->fragments[i].skb_list); + ieee80211_init_frag_cache(&sdata->frags); INIT_LIST_HEAD(&sdata->key_list); diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 6e02f8dfce2b..4e23f240f599 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -647,6 +647,7 @@ int ieee80211_key_link(struct ieee80211_key *key, struct sta_info *sta) { struct ieee80211_local *local = sdata->local; + static atomic_t key_color = ATOMIC_INIT(0); struct ieee80211_key *old_key; int idx = key->conf.keyidx; bool pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE; @@ -658,6 +659,12 @@ int ieee80211_key_link(struct ieee80211_key *key, bool delay_tailroom = sdata->vif.type == NL80211_IFTYPE_STATION; int ret; + /* + * Assign a unique ID to every key so we can easily prevent mixed + * key and fragment cache attacks. + */ + key->color = atomic_inc_return(&key_color); + mutex_lock(&sdata->local->key_mtx); if (sta && pairwise) diff --git a/net/mac80211/key.h b/net/mac80211/key.h index 4aa20cef0859..2749a7d05e76 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h @@ -127,6 +127,8 @@ struct ieee80211_key { } debugfs; #endif + unsigned int color; + /* * key config, must be last because it contains key * material as variable length member diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index c38d68131d02..b40e71a5d795 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1873,19 +1873,34 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) return result; } +void ieee80211_init_frag_cache(struct ieee80211_fragment_cache *cache) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cache->entries); i++) + skb_queue_head_init(&cache->entries[i].skb_list); +} + +void ieee80211_destroy_frag_cache(struct ieee80211_fragment_cache *cache) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cache->entries); i++) + __skb_queue_purge(&cache->entries[i].skb_list); +} + static inline struct ieee80211_fragment_entry * -ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, +ieee80211_reassemble_add(struct ieee80211_fragment_cache *cache, unsigned int frag, unsigned int seq, int rx_queue, struct sk_buff **skb) { struct ieee80211_fragment_entry *entry; - entry = &sdata->fragments[sdata->fragment_next++]; - if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) - sdata->fragment_next = 0; + entry = &cache->entries[cache->next++]; + if (cache->next >= IEEE80211_FRAGMENT_MAX) + cache->next = 0; - if (!skb_queue_empty(&entry->skb_list)) - __skb_queue_purge(&entry->skb_list); + __skb_queue_purge(&entry->skb_list); __skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */ *skb = NULL; @@ -1900,14 +1915,14 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, } static inline struct ieee80211_fragment_entry * -ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, +ieee80211_reassemble_find(struct ieee80211_fragment_cache *cache, unsigned int frag, unsigned int seq, int rx_queue, struct ieee80211_hdr *hdr) { struct ieee80211_fragment_entry *entry; int i, idx; - idx = sdata->fragment_next; + idx = cache->next; for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) { struct ieee80211_hdr *f_hdr; @@ -1915,7 +1930,7 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, if (idx < 0) idx = IEEE80211_FRAGMENT_MAX - 1; - entry = &sdata->fragments[idx]; + entry = &cache->entries[idx]; if (skb_queue_empty(&entry->skb_list) || entry->seq != seq || entry->rx_queue != rx_queue || entry->last_frag + 1 != frag) @@ -1942,16 +1957,27 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, return NULL; } +static bool requires_sequential_pn(struct ieee80211_rx_data *rx, __le16 fc) +{ + return rx->key && + (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP || + rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 || + rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP || + rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) && + ieee80211_has_protected(fc); +} + static ieee80211_rx_result debug_noinline ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) { + struct ieee80211_fragment_cache *cache = &rx->sdata->frags; struct ieee80211_hdr *hdr; u16 sc; __le16 fc; unsigned int frag, seq; struct ieee80211_fragment_entry *entry; struct sk_buff *skb; - struct ieee80211_rx_status *status; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); hdr = (struct ieee80211_hdr *)rx->skb->data; fc = hdr->frame_control; @@ -1962,14 +1988,15 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) sc = le16_to_cpu(hdr->seq_ctrl); frag = sc & IEEE80211_SCTL_FRAG; - if (is_multicast_ether_addr(hdr->addr1)) { - I802_DEBUG_INC(rx->local->dot11MulticastReceivedFrameCount); - goto out_no_led; - } + if (rx->sta) + cache = &rx->sta->frags; if (likely(!ieee80211_has_morefrags(fc) && frag == 0)) goto out; + if (is_multicast_ether_addr(hdr->addr1)) + return RX_DROP_MONITOR; + I802_DEBUG_INC(rx->local->rx_handlers_fragments); if (skb_linearize(rx->skb)) @@ -1985,20 +2012,17 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) if (frag == 0) { /* This is the first fragment of a new frame. */ - entry = ieee80211_reassemble_add(rx->sdata, frag, seq, + entry = ieee80211_reassemble_add(cache, frag, seq, rx->seqno_idx, &(rx->skb)); - if (rx->key && - (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP || - rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 || - rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP || - rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) && - ieee80211_has_protected(fc)) { + if (requires_sequential_pn(rx, fc)) { int queue = rx->security_idx; /* Store CCMP/GCMP PN so that we can verify that the * next fragment has a sequential PN value. */ entry->check_sequential_pn = true; + entry->is_protected = true; + entry->key_color = rx->key->color; memcpy(entry->last_pn, rx->key->u.ccmp.rx_pn[queue], IEEE80211_CCMP_PN_LEN); @@ -2010,6 +2034,11 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) sizeof(rx->key->u.gcmp.rx_pn[queue])); BUILD_BUG_ON(IEEE80211_CCMP_PN_LEN != IEEE80211_GCMP_PN_LEN); + } else if (rx->key && + (ieee80211_has_protected(fc) || + (status->flag & RX_FLAG_DECRYPTED))) { + entry->is_protected = true; + entry->key_color = rx->key->color; } return RX_QUEUED; } @@ -2017,7 +2046,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) /* This is a fragment for a frame that should already be pending in * fragment cache. Add this fragment to the end of the pending entry. */ - entry = ieee80211_reassemble_find(rx->sdata, frag, seq, + entry = ieee80211_reassemble_find(cache, frag, seq, rx->seqno_idx, hdr); if (!entry) { I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); @@ -2032,25 +2061,39 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) if (entry->check_sequential_pn) { int i; u8 pn[IEEE80211_CCMP_PN_LEN], *rpn; - int queue; - if (!rx->key || - (rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP && - rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256 && - rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP && - rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP_256)) + if (!requires_sequential_pn(rx, fc)) return RX_DROP_UNUSABLE; + + /* Prevent mixed key and fragment cache attacks */ + if (entry->key_color != rx->key->color) + return RX_DROP_UNUSABLE; + memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN); for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) { pn[i]++; if (pn[i]) break; } - queue = rx->security_idx; - rpn = rx->key->u.ccmp.rx_pn[queue]; + + rpn = rx->ccm_gcm.pn; if (memcmp(pn, rpn, IEEE80211_CCMP_PN_LEN)) return RX_DROP_UNUSABLE; memcpy(entry->last_pn, pn, IEEE80211_CCMP_PN_LEN); + } else if (entry->is_protected && + (!rx->key || + (!ieee80211_has_protected(fc) && + !(status->flag & RX_FLAG_DECRYPTED)) || + rx->key->color != entry->key_color)) { + /* Drop this as a mixed key or fragment cache attack, even + * if for TKIP Michael MIC should protect us, and WEP is a + * lost cause anyway. + */ + return RX_DROP_UNUSABLE; + } else if (entry->is_protected && rx->key && + entry->key_color != rx->key->color && + (status->flag & RX_FLAG_DECRYPTED)) { + return RX_DROP_UNUSABLE; } skb_pull(rx->skb, ieee80211_hdrlen(fc)); @@ -2082,7 +2125,6 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) out: ieee80211_led_rx(rx->local); - out_no_led: if (rx->sta) rx->sta->rx_stats.packets++; return RX_CONTINUE; @@ -2239,13 +2281,13 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc) struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; /* - * Allow EAPOL frames to us/the PAE group address regardless - * of whether the frame was encrypted or not. + * Allow EAPOL frames to us/the PAE group address regardless of + * whether the frame was encrypted or not, and always disallow + * all other destination addresses for them. */ - if (ehdr->h_proto == rx->sdata->control_port_protocol && - (ether_addr_equal(ehdr->h_dest, rx->sdata->vif.addr) || - ether_addr_equal(ehdr->h_dest, pae_group_addr))) - return true; + if (unlikely(ehdr->h_proto == rx->sdata->control_port_protocol)) + return ether_addr_equal(ehdr->h_dest, rx->sdata->vif.addr) || + ether_addr_equal(ehdr->h_dest, pae_group_addr); if (ieee80211_802_1x_port_control(rx) || ieee80211_drop_unencrypted(rx, fc)) @@ -2285,6 +2327,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) if ((sdata->vif.type == NL80211_IFTYPE_AP || sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && + ehdr->h_proto != rx->sdata->control_port_protocol && (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) { if (is_multicast_ether_addr(ehdr->h_dest)) { /* @@ -2337,9 +2380,30 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) #endif if (skb) { + struct ethhdr *ehdr = (struct ethhdr *)skb->data; + /* deliver to local stack */ skb->protocol = eth_type_trans(skb, dev); memset(skb->cb, 0, sizeof(skb->cb)); + + /* + * 802.1X over 802.11 requires that the authenticator address + * be used for EAPOL frames. However, 802.1X allows the use of + * the PAE group address instead. If the interface is part of + * a bridge and we pass the frame with the PAE group address, + * then the bridge will forward it to the network (even if the + * client was not associated yet), which isn't supposed to + * happen. + * To avoid that, rewrite the destination address to our own + * address, so that the authenticator (e.g. hostapd) will see + * the frame, but bridge won't forward it anywhere else. Note + * that due to earlier filtering, the only other address can + * be the PAE group address. + */ + if (unlikely(skb->protocol == sdata->control_port_protocol && + !ether_addr_equal(ehdr->h_dest, sdata->vif.addr))) + ether_addr_copy(ehdr->h_dest, sdata->vif.addr); + if (rx->napi) napi_gro_receive(rx->napi, skb); else @@ -2421,9 +2485,27 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) if (ieee80211_data_to_8023_exthdr(skb, ðhdr, rx->sdata->vif.addr, - rx->sdata->vif.type)) + rx->sdata->vif.type, + true)) return RX_DROP_UNUSABLE; + if (rx->key) { + /* + * We should not receive A-MSDUs on pre-HT connections, + * and HT connections cannot use old ciphers. Thus drop + * them, as in those cases we couldn't even have SPP + * A-MSDUs or such. + */ + switch (rx->key->conf.cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + return RX_DROP_UNUSABLE; + default: + break; + } + } + ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, rx->sdata->vif.type, rx->local->hw.extra_tx_headroom, diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index bdcc6cb60b1c..ded1264cf8e4 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -366,6 +366,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, u64_stats_init(&sta->rx_stats.syncp); + ieee80211_init_frag_cache(&sta->frags); + sta->sta_state = IEEE80211_STA_NONE; /* Mark TID as unreserved */ @@ -999,6 +1001,8 @@ static void __sta_info_destroy_part2(struct sta_info *sta) rate_control_remove_sta_debugfs(sta); ieee80211_sta_debugfs_remove(sta); + ieee80211_destroy_frag_cache(&sta->frags); + cleanup_single_sta(sta); } diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index cc808ac783e5..fd31c4db1282 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -391,6 +391,34 @@ struct ieee80211_sta_rx_stats { u64 msdu[IEEE80211_NUM_TIDS + 1]; }; +/* + * IEEE 802.11-2016 (10.6 "Defragmentation") recommends support for "concurrent + * reception of at least one MSDU per access category per associated STA" + * on APs, or "at least one MSDU per access category" on other interface types. + * + * This limit can be increased by changing this define, at the cost of slower + * frame reassembly and increased memory use while fragments are pending. + */ +#define IEEE80211_FRAGMENT_MAX 4 + +struct ieee80211_fragment_entry { + struct sk_buff_head skb_list; + unsigned long first_frag_time; + u16 seq; + u16 extra_len; + u16 last_frag; + u8 rx_queue; + u8 check_sequential_pn:1, /* needed for CCMP/GCMP */ + is_protected:1; + u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ + unsigned int key_color; +}; + +struct ieee80211_fragment_cache { + struct ieee80211_fragment_entry entries[IEEE80211_FRAGMENT_MAX]; + unsigned int next; +}; + /** * struct sta_info - STA information * @@ -454,6 +482,7 @@ struct ieee80211_sta_rx_stats { * @pcpu_rx_stats: per-CPU RX statistics, assigned only if the driver needs * this (by advertising the USES_RSS hw flag) * @status_stats: TX status statistics + * @frags: fragment cache */ struct sta_info { /* General information, mostly static */ @@ -551,6 +580,8 @@ struct sta_info { struct cfg80211_chan_def tdls_chandef; + struct ieee80211_fragment_cache frags; + /* keep last! */ struct ieee80211_sta sta; }; diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index c0529c4b60f8..7819a2507d39 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -162,8 +162,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) update_iv: /* update IV in key information to be able to detect replays */ - rx->key->u.tkip.rx[rx->security_idx].iv32 = rx->tkip_iv32; - rx->key->u.tkip.rx[rx->security_idx].iv16 = rx->tkip_iv16; + rx->key->u.tkip.rx[rx->security_idx].iv32 = rx->tkip.iv32; + rx->key->u.tkip.rx[rx->security_idx].iv16 = rx->tkip.iv16; return RX_CONTINUE; @@ -289,8 +289,8 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) key, skb->data + hdrlen, skb->len - hdrlen, rx->sta->sta.addr, hdr->addr1, hwaccel, rx->security_idx, - &rx->tkip_iv32, - &rx->tkip_iv16); + &rx->tkip.iv32, + &rx->tkip.iv16); if (res != TKIP_DECRYPT_OK) return RX_DROP_UNUSABLE; @@ -548,6 +548,8 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx, } memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN); + if (unlikely(ieee80211_is_frag(hdr))) + memcpy(rx->ccm_gcm.pn, pn, IEEE80211_CCMP_PN_LEN); } /* Remove CCMP header and MIC */ @@ -777,6 +779,8 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx) } memcpy(key->u.gcmp.rx_pn[queue], pn, IEEE80211_GCMP_PN_LEN); + if (unlikely(ieee80211_is_frag(hdr))) + memcpy(rx->ccm_gcm.pn, pn, IEEE80211_CCMP_PN_LEN); } /* Remove GCMP header and MIC */ diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index ba9e711f7e3d..4e08305a55c4 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -1256,7 +1256,7 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u, ip_vs_addr_copy(svc->af, &svc->addr, &u->addr); svc->port = u->port; svc->fwmark = u->fwmark; - svc->flags = u->flags; + svc->flags = u->flags & ~IP_VS_SVC_F_HASHED; svc->timeout = u->timeout * HZ; svc->netmask = u->netmask; svc->ipvs = ipvs; diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c index c8a4a48bced9..8be604eb6961 100644 --- a/net/netfilter/nf_synproxy_core.c +++ b/net/netfilter/nf_synproxy_core.c @@ -34,6 +34,9 @@ synproxy_parse_options(const struct sk_buff *skb, unsigned int doff, int length = (th->doff * 4) - sizeof(*th); u8 buf[40], *ptr; + if (unlikely(length < 0)) + return false; + ptr = skb_header_pointer(skb, doff + sizeof(*th), length, buf); if (ptr == NULL) return false; @@ -50,6 +53,8 @@ synproxy_parse_options(const struct sk_buff *skb, unsigned int doff, length--; continue; default: + if (length < 2) + return true; opsize = *ptr++; if (opsize < 2) return true; diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c index 8396dc8ee247..babe42ff3eec 100644 --- a/net/netfilter/nfnetlink_cthelper.c +++ b/net/netfilter/nfnetlink_cthelper.c @@ -355,10 +355,14 @@ static int nfnl_cthelper_update(const struct nlattr * const tb[], struct nf_conntrack_helper *helper) { + u32 size; int ret; - if (tb[NFCTH_PRIV_DATA_LEN]) - return -EBUSY; + if (tb[NFCTH_PRIV_DATA_LEN]) { + size = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN])); + if (size != helper->data_len) + return -EBUSY; + } if (tb[NFCTH_POLICY]) { ret = nfnl_cthelper_update_policy(helper, tb[NFCTH_POLICY]); diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c index 47beb3abcc9d..e2c815ee06d0 100644 --- a/net/netfilter/nft_exthdr.c +++ b/net/netfilter/nft_exthdr.c @@ -34,6 +34,9 @@ static void nft_exthdr_eval(const struct nft_expr *expr, unsigned int offset = 0; int err; + if (pkt->skb->protocol != htons(ETH_P_IPV6)) + goto err; + err = ipv6_find_hdr(pkt->skb, &offset, priv->type, NULL, NULL); if (err < 0) goto err; diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index 9ef880917edf..2820fa6f399c 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -1227,6 +1227,9 @@ xt_replace_table(struct xt_table *table, smp_wmb(); table->private = newinfo; + /* make sure all cpus see new ->private value */ + smp_mb(); + /* * Even though table entries have now been swapped, other CPU's * may still be using the old entries. This is okay, because diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index f85d0e07af2d..9be851ce97c2 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c @@ -96,6 +96,7 @@ static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = { static int netlbl_mgmt_add_common(struct genl_info *info, struct netlbl_audit *audit_info) { + void *pmap = NULL; int ret_val = -EINVAL; struct netlbl_domaddr_map *addrmap = NULL; struct cipso_v4_doi *cipsov4 = NULL; @@ -195,6 +196,7 @@ static int netlbl_mgmt_add_common(struct genl_info *info, ret_val = -ENOMEM; goto add_free_addrmap; } + pmap = map; map->list.addr = addr->s_addr & mask->s_addr; map->list.mask = mask->s_addr; map->list.valid = 1; @@ -203,10 +205,8 @@ static int netlbl_mgmt_add_common(struct genl_info *info, map->def.cipso = cipsov4; ret_val = netlbl_af4list_add(&map->list, &addrmap->list4); - if (ret_val != 0) { - kfree(map); - goto add_free_addrmap; - } + if (ret_val != 0) + goto add_free_map; entry->family = AF_INET; entry->def.type = NETLBL_NLTYPE_ADDRSELECT; @@ -243,6 +243,7 @@ static int netlbl_mgmt_add_common(struct genl_info *info, ret_val = -ENOMEM; goto add_free_addrmap; } + pmap = map; map->list.addr = *addr; map->list.addr.s6_addr32[0] &= mask->s6_addr32[0]; map->list.addr.s6_addr32[1] &= mask->s6_addr32[1]; @@ -255,10 +256,8 @@ static int netlbl_mgmt_add_common(struct genl_info *info, map->def.calipso = calipso; ret_val = netlbl_af6list_add(&map->list, &addrmap->list6); - if (ret_val != 0) { - kfree(map); - goto add_free_addrmap; - } + if (ret_val != 0) + goto add_free_map; entry->family = AF_INET6; entry->def.type = NETLBL_NLTYPE_ADDRSELECT; @@ -268,10 +267,12 @@ static int netlbl_mgmt_add_common(struct genl_info *info, ret_val = netlbl_domhsh_add(entry, audit_info); if (ret_val != 0) - goto add_free_addrmap; + goto add_free_map; return 0; +add_free_map: + kfree(pmap); add_free_addrmap: kfree(addrmap); add_doi_put_def: diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 205865292ba3..541410f1c3b7 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -436,11 +436,13 @@ void netlink_table_ungrab(void) static inline void netlink_lock_table(void) { + unsigned long flags; + /* read_lock() synchronizes us to netlink_table_grab */ - read_lock(&nl_table_lock); + read_lock_irqsave(&nl_table_lock, flags); atomic_inc(&nl_table_users); - read_unlock(&nl_table_lock); + read_unlock_irqrestore(&nl_table_lock, flags); } static inline void diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c index 22e340a9049c..92c6fbfd51f7 100644 --- a/net/nfc/llcp_sock.c +++ b/net/nfc/llcp_sock.c @@ -121,6 +121,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) if (!llcp_sock->service_name) { nfc_llcp_local_put(llcp_sock->local); llcp_sock->local = NULL; + llcp_sock->dev = NULL; ret = -ENOMEM; goto put_dev; } @@ -130,6 +131,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) llcp_sock->local = NULL; kfree(llcp_sock->service_name); llcp_sock->service_name = NULL; + llcp_sock->dev = NULL; ret = -EADDRINUSE; goto put_dev; } diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 85a3d9ed4c29..bff6ba84d397 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c @@ -1188,6 +1188,7 @@ EXPORT_SYMBOL(nci_allocate_device); void nci_free_device(struct nci_dev *ndev) { nfc_free_device(ndev->nfc_dev); + nci_hci_deallocate(ndev); kfree(ndev); } EXPORT_SYMBOL(nci_free_device); diff --git a/net/nfc/nci/hci.c b/net/nfc/nci/hci.c index a0ab26d535dc..5fae3f064ad0 100644 --- a/net/nfc/nci/hci.c +++ b/net/nfc/nci/hci.c @@ -798,3 +798,8 @@ struct nci_hci_dev *nci_hci_allocate(struct nci_dev *ndev) return hdev; } + +void nci_hci_deallocate(struct nci_dev *ndev) +{ + kfree(ndev->hci_dev); +} diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c index 92a3cfae4de8..2fba626a0125 100644 --- a/net/nfc/rawsock.c +++ b/net/nfc/rawsock.c @@ -345,7 +345,7 @@ static int rawsock_create(struct net *net, struct socket *sock, return -ESOCKTNOSUPPORT; if (sock->type == SOCK_RAW) { - if (!capable(CAP_NET_RAW)) + if (!ns_capable(net->user_ns, CAP_NET_RAW)) return -EPERM; sock->ops = &rawsock_raw_ops; } else { diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index d3e364c6a320..3f23f021ff89 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2674,7 +2674,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) } if (likely(saddr == NULL)) { dev = packet_cached_dev_get(po); - proto = po->num; + proto = READ_ONCE(po->num); } else { err = -EINVAL; if (msg->msg_namelen < sizeof(struct sockaddr_ll)) @@ -2886,7 +2886,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) if (likely(saddr == NULL)) { dev = packet_cached_dev_get(po); - proto = po->num; + proto = READ_ONCE(po->num); } else { err = -EINVAL; if (msg->msg_namelen < sizeof(struct sockaddr_ll)) @@ -3157,7 +3157,7 @@ static int packet_do_bind(struct sock *sk, const char *name, int ifindex, /* prevents packet_notifier() from calling * register_prot_hook() */ - po->num = 0; + WRITE_ONCE(po->num, 0); __unregister_prot_hook(sk, true); rcu_read_lock(); dev_curr = po->prot_hook.dev; @@ -3167,17 +3167,17 @@ static int packet_do_bind(struct sock *sk, const char *name, int ifindex, } BUG_ON(po->running); - po->num = proto; + WRITE_ONCE(po->num, proto); po->prot_hook.type = proto; if (unlikely(unlisted)) { dev_put(dev); po->prot_hook.dev = NULL; - po->ifindex = -1; + WRITE_ONCE(po->ifindex, -1); packet_cached_dev_reset(po); } else { po->prot_hook.dev = dev; - po->ifindex = dev ? dev->ifindex : 0; + WRITE_ONCE(po->ifindex, dev ? dev->ifindex : 0); packet_cached_dev_assign(po, dev); } } @@ -3492,7 +3492,7 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, uaddr->sa_family = AF_PACKET; memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data)); rcu_read_lock(); - dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex); + dev = dev_get_by_index_rcu(sock_net(sk), READ_ONCE(pkt_sk(sk)->ifindex)); if (dev) strlcpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data)); rcu_read_unlock(); @@ -3508,16 +3508,18 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr, struct sock *sk = sock->sk; struct packet_sock *po = pkt_sk(sk); DECLARE_SOCKADDR(struct sockaddr_ll *, sll, uaddr); + int ifindex; if (peer) return -EOPNOTSUPP; + ifindex = READ_ONCE(po->ifindex); sll->sll_family = AF_PACKET; - sll->sll_ifindex = po->ifindex; - sll->sll_protocol = po->num; + sll->sll_ifindex = ifindex; + sll->sll_protocol = READ_ONCE(po->num); sll->sll_pkttype = 0; rcu_read_lock(); - dev = dev_get_by_index_rcu(sock_net(sk), po->ifindex); + dev = dev_get_by_index_rcu(sock_net(sk), ifindex); if (dev) { sll->sll_hatype = dev->type; sll->sll_halen = dev->addr_len; @@ -4097,7 +4099,7 @@ static int packet_notifier(struct notifier_block *this, } if (msg == NETDEV_UNREGISTER) { packet_cached_dev_reset(po); - po->ifindex = -1; + WRITE_ONCE(po->ifindex, -1); if (po->prot_hook.dev) dev_put(po->prot_hook.dev); po->prot_hook.dev = NULL; @@ -4400,7 +4402,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, was_running = po->running; num = po->num; if (was_running) { - po->num = 0; + WRITE_ONCE(po->num, 0); __unregister_prot_hook(sk, false); } spin_unlock(&po->bind_lock); @@ -4433,7 +4435,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, spin_lock(&po->bind_lock); if (was_running) { - po->num = num; + WRITE_ONCE(po->num, num); register_prot_hook(sk); } spin_unlock(&po->bind_lock); @@ -4602,8 +4604,8 @@ static int packet_seq_show(struct seq_file *seq, void *v) s, atomic_read(&s->sk_refcnt), s->sk_type, - ntohs(po->num), - po->ifindex, + ntohs(READ_ONCE(po->num)), + READ_ONCE(po->ifindex), po->running, atomic_read(&s->sk_rmem_alloc), from_kuid_munged(seq_user_ns(seq), sock_i_uid(s)), diff --git a/net/rds/recv.c b/net/rds/recv.c index 488a198be3e1..4bd307e31b40 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c @@ -596,7 +596,7 @@ int rds_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, if (rds_cmsg_recv(inc, msg, rs)) { ret = -EFAULT; - goto out; + break; } rds_stats_inc(s_recv_delivered); diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index 70ee78d8f8fb..7aafb402e5c7 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -247,7 +247,7 @@ static int tcindex_alloc_perfect_hash(struct tcindex_data *cp) int i, err = 0; cp->perfect = kcalloc(cp->hash, sizeof(struct tcindex_filter_result), - GFP_KERNEL); + GFP_KERNEL | __GFP_NOWARN); if (!cp->perfect) return -ENOMEM; diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index 551cf193649e..02ef78d2b3df 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c @@ -388,7 +388,8 @@ static void dsmark_reset(struct Qdisc *sch) struct dsmark_qdisc_data *p = qdisc_priv(sch); pr_debug("%s(sch %p,[qdisc %p])\n", __func__, sch, p); - qdisc_reset(p->q); + if (p->q) + qdisc_reset(p->q); sch->qstats.backlog = 0; sch->q.qlen = 0; } diff --git a/net/sctp/input.c b/net/sctp/input.c index 12d821ea8a1f..8f4574c4aa6c 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -1165,7 +1165,7 @@ static struct sctp_association *__sctp_rcv_walk_lookup(struct net *net, ch = (sctp_chunkhdr_t *) ch_end; chunk_num++; - } while (ch_end < skb_tail_pointer(skb)); + } while (ch_end + sizeof(*ch) < skb_tail_pointer(skb)); return asoc; } diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 0ef65822fdd3..00d95fefdc6f 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -486,11 +486,21 @@ static struct rpc_task *__rpc_find_next_queued_priority(struct rpc_wait_queue *q struct list_head *q; struct rpc_task *task; + /* + * Service the privileged queue. + */ + q = &queue->tasks[RPC_NR_PRIORITY - 1]; + if (queue->maxpriority > RPC_PRIORITY_PRIVILEGED && !list_empty(q)) { + task = list_first_entry(q, struct rpc_task, u.tk_wait.list); + goto out; + } + /* * Service a batch of tasks from a single owner. */ q = &queue->tasks[queue->priority]; - if (!list_empty(q) && --queue->nr) { + if (!list_empty(q) && queue->nr) { + queue->nr--; task = list_first_entry(q, struct rpc_task, u.tk_wait.list); goto out; } diff --git a/net/tipc/msg.c b/net/tipc/msg.c index aeb4554dfdda..c1ab2ff2f6ac 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -141,18 +141,13 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf) if (unlikely(head)) goto err; *buf = NULL; + if (skb_has_frag_list(frag) && __skb_linearize(frag)) + goto err; frag = skb_unshare(frag, GFP_ATOMIC); if (unlikely(!frag)) goto err; head = *headbuf = frag; TIPC_SKB_CB(head)->tail = NULL; - if (skb_is_nonlinear(head)) { - skb_walk_frags(head, tail) { - TIPC_SKB_CB(head)->tail = tail; - } - } else { - skb_frag_list_init(head); - } return 0; } diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 804cab8f9509..c1b9074f3325 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -741,7 +741,10 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, spin_lock_bh(&inputq->lock); if (skb_peek(arrvq) == skb) { skb_queue_splice_tail_init(&tmpq, inputq); - __skb_dequeue(arrvq); + /* Decrease the skb's refcnt as increasing in the + * function tipc_skb_peek + */ + kfree_skb(__skb_dequeue(arrvq)); } spin_unlock_bh(&inputq->lock); __skb_queue_purge(&tmpq); diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 3aaf209cf7a1..43a17fb9f290 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -534,12 +534,14 @@ static void unix_release_sock(struct sock *sk, int embrion) u->path.mnt = NULL; state = sk->sk_state; sk->sk_state = TCP_CLOSE; + + skpair = unix_peer(sk); + unix_peer(sk) = NULL; + unix_state_unlock(sk); wake_up_interruptible_all(&u->peer_wait); - skpair = unix_peer(sk); - if (skpair != NULL) { if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) { unix_state_lock(skpair); @@ -554,7 +556,6 @@ static void unix_release_sock(struct sock *sk, int embrion) unix_dgram_peer_wake_disconnect(sk, skpair); sock_put(skpair); /* It may now die */ - unix_peer(sk) = NULL; } /* Try to flush out this socket. Throw out buffers at least */ diff --git a/net/wireless/util.c b/net/wireless/util.c index dcdcfb8341e6..5e230d228b23 100755 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -429,7 +429,8 @@ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, - const u8 *addr, enum nl80211_iftype iftype) + const u8 *addr, enum nl80211_iftype iftype, + bool is_amsdu) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct { @@ -517,7 +518,7 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)); tmp.h_proto = payload.proto; - if (likely((ether_addr_equal(payload.hdr, rfc1042_header) && + if (likely((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) && tmp.h_proto != htons(ETH_P_AARP) && tmp.h_proto != htons(ETH_P_IPX)) || ether_addr_equal(payload.hdr, bridge_tunnel_header))) @@ -659,6 +660,9 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, remaining = skb->len - offset; if (subframe_len > remaining) goto purge; + /* mitigate A-MSDU aggregation injection attacks */ + if (ether_addr_equal(eth.h_dest, rfc1042_header)) + goto purge; offset += sizeof(struct ethhdr); last = remaining <= subframe_len + padding; @@ -929,6 +933,9 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, case NL80211_IFTYPE_MESH_POINT: /* mesh should be handled? */ break; + case NL80211_IFTYPE_OCB: + cfg80211_leave_ocb(rdev, dev); + break; default: break; } diff --git a/net/wireless/wext-spy.c b/net/wireless/wext-spy.c index 33bef22e44e9..b379a0371653 100644 --- a/net/wireless/wext-spy.c +++ b/net/wireless/wext-spy.c @@ -120,8 +120,8 @@ int iw_handler_set_thrspy(struct net_device * dev, return -EOPNOTSUPP; /* Just do it */ - memcpy(&(spydata->spy_thr_low), &(threshold->low), - 2 * sizeof(struct iw_quality)); + spydata->spy_thr_low = threshold->low; + spydata->spy_thr_high = threshold->high; /* Clear flag */ memset(spydata->spy_thr_under, '\0', sizeof(spydata->spy_thr_under)); @@ -147,8 +147,8 @@ int iw_handler_get_thrspy(struct net_device * dev, return -EOPNOTSUPP; /* Just do it */ - memcpy(&(threshold->low), &(spydata->spy_thr_low), - 2 * sizeof(struct iw_quality)); + threshold->low = spydata->spy_thr_low; + threshold->high = spydata->spy_thr_high; return 0; } @@ -173,10 +173,10 @@ static void iw_send_thrspy_event(struct net_device * dev, memcpy(threshold.addr.sa_data, address, ETH_ALEN); threshold.addr.sa_family = ARPHRD_ETHER; /* Copy stats */ - memcpy(&(threshold.qual), wstats, sizeof(struct iw_quality)); + threshold.qual = *wstats; /* Copy also thresholds */ - memcpy(&(threshold.low), &(spydata->spy_thr_low), - 2 * sizeof(struct iw_quality)); + threshold.low = spydata->spy_thr_low; + threshold.high = spydata->spy_thr_high; /* Send event to user space */ wireless_send_event(dev, SIOCGIWTHRSPY, &wrqu, (char *) &threshold); diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 9c3fbf4553cc..c23c04d38a82 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -550,7 +550,7 @@ static int x25_create(struct net *net, struct socket *sock, int protocol, if (protocol) goto out; - rc = -ENOBUFS; + rc = -ENOMEM; if ((sk = x25_alloc_socket(net, kern)) == NULL) goto out; diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index e72ef1b19efc..2ec3047cabd9 100755 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -579,6 +579,20 @@ static struct xfrm_state *xfrm_state_construct(struct net *net, copy_from_user_state(x, p); + if (attrs[XFRMA_ENCAP]) { + x->encap = kmemdup(nla_data(attrs[XFRMA_ENCAP]), + sizeof(*x->encap), GFP_KERNEL); + if (x->encap == NULL) + goto error; + } + + if (attrs[XFRMA_COADDR]) { + x->coaddr = kmemdup(nla_data(attrs[XFRMA_COADDR]), + sizeof(*x->coaddr), GFP_KERNEL); + if (x->coaddr == NULL) + goto error; + } + if (attrs[XFRMA_SA_EXTRA_FLAGS]) x->props.extra_flags = nla_get_u32(attrs[XFRMA_SA_EXTRA_FLAGS]); @@ -599,23 +613,9 @@ static struct xfrm_state *xfrm_state_construct(struct net *net, attrs[XFRMA_ALG_COMP]))) goto error; - if (attrs[XFRMA_ENCAP]) { - x->encap = kmemdup(nla_data(attrs[XFRMA_ENCAP]), - sizeof(*x->encap), GFP_KERNEL); - if (x->encap == NULL) - goto error; - } - if (attrs[XFRMA_TFCPAD]) x->tfcpad = nla_get_u32(attrs[XFRMA_TFCPAD]); - if (attrs[XFRMA_COADDR]) { - x->coaddr = kmemdup(nla_data(attrs[XFRMA_COADDR]), - sizeof(*x->coaddr), GFP_KERNEL); - if (x->coaddr == NULL) - goto error; - } - xfrm_mark_get(attrs, &x->mark); xfrm_smark_init(attrs, &x->props.smark); diff --git a/scripts/analyze_suspend.py b/scripts/analyze_suspend.py index a0ba48fa2c5e..edc4f1255f9b 100755 --- a/scripts/analyze_suspend.py +++ b/scripts/analyze_suspend.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Tool for analyzing suspend/resume timing # Copyright (c) 2013, Intel Corporation. diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter index d9ff038c1b28..a650bea5ccdd 100755 --- a/scripts/bloat-o-meter +++ b/scripts/bloat-o-meter @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # # Copyright 2004 Matt Mackall # diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl index 9ca667bcaee9..594c55541b16 100755 --- a/scripts/bootgraph.pl +++ b/scripts/bootgraph.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Copyright 2008, Intel Corporation # diff --git a/scripts/checkincludes.pl b/scripts/checkincludes.pl index 97b2c6143fe4..cfdfa02d4d92 100755 --- a/scripts/checkincludes.pl +++ b/scripts/checkincludes.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # # checkincludes: find/remove files included more than once # diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl index b8f616545277..32828fafcf5b 100755 --- a/scripts/checkstack.pl +++ b/scripts/checkstack.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Check the stack usage of functions # diff --git a/scripts/config b/scripts/config index 73de17d39698..06ac9882e1de 100755 --- a/scripts/config +++ b/scripts/config @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Manipulate options in a .config file from the command line myname=${0##*/} diff --git a/scripts/diffconfig b/scripts/diffconfig index 0db267d0adc9..19189f3c4a03 100755 --- a/scripts/diffconfig +++ b/scripts/diffconfig @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # # diffconfig - a tool to compare .config files. # diff --git a/scripts/dtc/dt_to_config b/scripts/dtc/dt_to_config index 9a248b505c58..5dfd1bff351f 100755 --- a/scripts/dtc/dt_to_config +++ b/scripts/dtc/dt_to_config @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Copyright 2016 by Frank Rowand # Copyright 2016 by Gaurav Minocha diff --git a/scripts/extract_xc3028.pl b/scripts/extract_xc3028.pl index 47877deae6d7..61d9b256c658 100755 --- a/scripts/extract_xc3028.pl +++ b/scripts/extract_xc3028.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Copyright (c) Mauro Carvalho Chehab # Released under GPLv2 diff --git a/scripts/get_dvb_firmware b/scripts/get_dvb_firmware index 1a0a04125f71..f3f230225aba 100755 --- a/scripts/get_dvb_firmware +++ b/scripts/get_dvb_firmware @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # DVB firmware extractor # # (c) 2004 Andrew de Quincey diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl index c21d16328d3f..70dcfb6b3de1 100755 --- a/scripts/markup_oops.pl +++ b/scripts/markup_oops.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl use File::Basename; use Math::BigInt; diff --git a/scripts/profile2linkerlist.pl b/scripts/profile2linkerlist.pl index 6943fa7cc95b..f23d7be94394 100755 --- a/scripts/profile2linkerlist.pl +++ b/scripts/profile2linkerlist.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # # Takes a (sorted) output of readprofile and turns it into a list suitable for diff --git a/scripts/show_delta b/scripts/show_delta index 5b365009e6a3..55c66dce6fc1 100755 --- a/scripts/show_delta +++ b/scripts/show_delta @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # show_deltas: Read list of printk messages instrumented with # time data, and format with time deltas. diff --git a/scripts/stackdelta b/scripts/stackdelta index 48eabf2f48f8..20a79f19a111 100755 --- a/scripts/stackdelta +++ b/scripts/stackdelta @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Read two files produced by the stackusage script, and show the # delta between them. diff --git a/scripts/tracing/draw_functrace.py b/scripts/tracing/draw_functrace.py index db40fa04cd51..30f117dfab43 100755 --- a/scripts/tracing/draw_functrace.py +++ b/scripts/tracing/draw_functrace.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python """ Copyright 2008 (c) Frederic Weisbecker diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 04a53cdb409f..966d30bf2e38 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -878,6 +878,8 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, if (format == SMK_FIXED24_FMT && (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX)) return -EINVAL; + if (count > PAGE_SIZE) + return -EINVAL; data = memdup_user_nul(buf, count); if (IS_ERR(data)) diff --git a/sound/core/timer.c b/sound/core/timer.c index be9e517e264c..4d57a7a7dd44 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -488,9 +488,10 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event) return; if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) return; + event += 10; /* convert to SNDRV_TIMER_EVENT_MXXX */ list_for_each_entry(ts, &ti->slave_active_head, active_list) if (ts->ccallback) - ts->ccallback(ts, event + 100, &tstamp, resolution); + ts->ccallback(ts, event, &tstamp, resolution); } /* start/continue a master timer */ diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig index 8557e54d2659..82894330cae1 100644 --- a/sound/firewire/Kconfig +++ b/sound/firewire/Kconfig @@ -36,7 +36,7 @@ config SND_OXFW * Mackie(Loud) Onyx-i series (former models) * Mackie(Loud) Onyx Satellite * Mackie(Loud) Tapco Link.Firewire - * Mackie(Loud) d.2 pro/d.4 pro + * Mackie(Loud) d.2 pro/d.4 pro (built-in FireWire card with OXFW971 ASIC) * Mackie(Loud) U.420/U.420d * TASCAM FireOne * Stanton Controllers & Systems 1 Deck/Mixer @@ -82,7 +82,7 @@ config SND_BEBOB * PreSonus FIREBOX/FIREPOD/FP10/Inspire1394 * BridgeCo RDAudio1/Audio5 * Mackie Onyx 1220/1620/1640 (FireWire I/O Card) - * Mackie d.2 (FireWire Option) + * Mackie d.2 (optional FireWire card with DM1000 ASIC) * Stanton FinalScratch 2 (ScratchAmp) * Tascam IF-FW/DM * Behringer XENIX UFX 1204/1604 @@ -108,6 +108,7 @@ config SND_BEBOB * M-Audio Ozonic/NRV10/ProfireLightBridge * M-Audio FireWire 1814/ProjectMix IO * Digidesign Mbox 2 Pro + * ToneWeal FW66 To compile this driver as a module, choose M here: the module will be called snd-bebob. diff --git a/sound/firewire/bebob/bebob.c b/sound/firewire/bebob/bebob.c index a205b93fd9ac..4bb2cbe73f20 100644 --- a/sound/firewire/bebob/bebob.c +++ b/sound/firewire/bebob/bebob.c @@ -60,6 +60,7 @@ static DECLARE_BITMAP(devices_used, SNDRV_CARDS); #define VEN_MAUDIO1 0x00000d6c #define VEN_MAUDIO2 0x000007f5 #define VEN_DIGIDESIGN 0x00a07e +#define OUI_SHOUYO 0x002327 #define MODEL_FOCUSRITE_SAFFIRE_BOTH 0x00000000 #define MODEL_MAUDIO_AUDIOPHILE_BOTH 0x00010060 @@ -414,7 +415,7 @@ static const struct ieee1394_device_id bebob_id_table[] = { SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010049, &spec_normal), /* Mackie, Onyx 1220/1620/1640 (Firewire I/O Card) */ SND_BEBOB_DEV_ENTRY(VEN_MACKIE2, 0x00010065, &spec_normal), - /* Mackie, d.2 (Firewire Option) */ + // Mackie, d.2 (optional Firewire card with DM1000). SND_BEBOB_DEV_ENTRY(VEN_MACKIE1, 0x00010067, &spec_normal), /* Stanton, ScratchAmp */ SND_BEBOB_DEV_ENTRY(VEN_STANTON, 0x00000001, &spec_normal), @@ -513,6 +514,8 @@ static const struct ieee1394_device_id bebob_id_table[] = { &maudio_special_spec), /* Digidesign Mbox 2 Pro */ SND_BEBOB_DEV_ENTRY(VEN_DIGIDESIGN, 0x0000a9, &spec_normal), + // Toneweal FW66. + SND_BEBOB_DEV_ENTRY(OUI_SHOUYO, 0x020002, &spec_normal), /* IDs are unknown but able to be supported */ /* Apogee, Mini-ME Firewire */ /* Apogee, Mini-DAC Firewire */ diff --git a/sound/firewire/oxfw/oxfw.c b/sound/firewire/oxfw/oxfw.c index a7ab34d5e7b0..e2932ac9d487 100644 --- a/sound/firewire/oxfw/oxfw.c +++ b/sound/firewire/oxfw/oxfw.c @@ -405,8 +405,7 @@ static const struct ieee1394_device_id oxfw_id_table[] = { * Onyx-i series (former models): 0x081216 * Mackie Onyx Satellite: 0x00200f * Tapco LINK.firewire 4x6: 0x000460 - * d.2 pro: Unknown - * d.4 pro: Unknown + * d.2 pro/d.4 pro (built-in card): Unknown * U.420: Unknown * U.420d: Unknown */ diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index dfedfd85f205..463906882b95 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c @@ -564,7 +564,7 @@ static int snd_cmi8330_probe(struct snd_card *card, int dev) } if (acard->sb->hardware != SB_HW_16) { snd_printk(KERN_ERR PFX "SB16 not found during probe\n"); - return err; + return -ENODEV; } snd_wss_out(acard->wss, CS4231_MISC_INFO, 0x40); /* switch on MODE2 */ diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c index 2cc068be7d3b..90fa57ad14c0 100644 --- a/sound/isa/sb/sb16_csp.c +++ b/sound/isa/sb/sb16_csp.c @@ -1086,10 +1086,14 @@ static void snd_sb_qsound_destroy(struct snd_sb_csp * p) card = p->chip->card; down_write(&card->controls_rwsem); - if (p->qsound_switch) + if (p->qsound_switch) { snd_ctl_remove(card, p->qsound_switch); - if (p->qsound_space) + p->qsound_switch = NULL; + } + if (p->qsound_space) { snd_ctl_remove(card, p->qsound_space); + p->qsound_space = NULL; + } up_write(&card->controls_rwsem); /* cancel pending transfer of QSound parameters */ diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c index e75bfc511e3e..ad42d2364199 100644 --- a/sound/isa/sb/sb8.c +++ b/sound/isa/sb/sb8.c @@ -111,10 +111,6 @@ static int snd_sb8_probe(struct device *pdev, unsigned int dev) /* block the 0x388 port to avoid PnP conflicts */ acard->fm_res = request_region(0x388, 4, "SoundBlaster FM"); - if (!acard->fm_res) { - err = -EBUSY; - goto _err; - } if (port[dev] != SNDRV_AUTO_PORT) { if ((err = snd_sbdsp_create(card, port[dev], irq[dev], diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c index e85fb04ec7be..b567c4bdae00 100644 --- a/sound/pci/hda/hda_tegra.c +++ b/sound/pci/hda/hda_tegra.c @@ -363,6 +363,9 @@ static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev) unsigned short gcap; int irq_id = platform_get_irq(pdev, 0); + if (irq_id < 0) + return irq_id; + err = hda_tegra_init_chip(chip, pdev); if (err) return err; diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c index 33c6be9fb388..7c70ba5e2540 100644 --- a/sound/ppc/powermac.c +++ b/sound/ppc/powermac.c @@ -90,7 +90,11 @@ static int snd_pmac_probe(struct platform_device *devptr) sprintf(card->shortname, "PowerMac %s", name_ext); sprintf(card->longname, "%s (Dev %d) Sub-frame %d", card->shortname, chip->device_id, chip->subframe); - if ( snd_pmac_tumbler_init(chip) < 0 || snd_pmac_tumbler_post_init() < 0) + err = snd_pmac_tumbler_init(chip); + if (err < 0) + goto __error; + err = snd_pmac_tumbler_post_init(); + if (err < 0) goto __error; break; case PMAC_AWACS: diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c index 6df29fa30fb9..9e449dd8da92 100644 --- a/sound/soc/codecs/cs35l33.c +++ b/sound/soc/codecs/cs35l33.c @@ -1209,6 +1209,7 @@ static int cs35l33_i2c_probe(struct i2c_client *i2c_client, dev_err(&i2c_client->dev, "CS35L33 Device ID (%X). Expected ID %X\n", devid, CS35L33_CHIP_ID); + ret = -EINVAL; goto err_enable; } diff --git a/sound/soc/codecs/sti-sas.c b/sound/soc/codecs/sti-sas.c index d6e00c77edcd..7cf76661c3cc 100644 --- a/sound/soc/codecs/sti-sas.c +++ b/sound/soc/codecs/sti-sas.c @@ -542,6 +542,7 @@ static const struct of_device_id sti_sas_dev_match[] = { }, {}, }; +MODULE_DEVICE_TABLE(of, sti_sas_dev_match); static int sti_sas_driver_probe(struct platform_device *pdev) { diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4f3d94ce0a98..d2cfebf4c01b 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3677,7 +3677,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, if (!routes) { dev_err(card->dev, "ASoC: Could not allocate DAPM route table\n"); - return -EINVAL; + return -ENOMEM; } for (i = 0; i < num_routes; i++) { diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index deb597f7c302..f40657da4db2 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c @@ -149,6 +149,7 @@ static struct snd_soc_dai_link tegra_alc5632_dai = { static struct snd_soc_card snd_soc_tegra_alc5632 = { .name = "tegra-alc5632", + .driver_name = "tegra", .owner = THIS_MODULE, .remove = tegra_alc5632_card_remove, .dai_link = &tegra_alc5632_dai, diff --git a/sound/soc/tegra/tegra_max98090.c b/sound/soc/tegra/tegra_max98090.c index 902da36581d1..f4f238924c76 100644 --- a/sound/soc/tegra/tegra_max98090.c +++ b/sound/soc/tegra/tegra_max98090.c @@ -205,6 +205,7 @@ static struct snd_soc_dai_link tegra_max98090_dai = { static struct snd_soc_card snd_soc_tegra_max98090 = { .name = "tegra-max98090", + .driver_name = "tegra", .owner = THIS_MODULE, .remove = tegra_max98090_card_remove, .dai_link = &tegra_max98090_dai, diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c index e5ef4e9c4ac5..3088c6f401e3 100644 --- a/sound/soc/tegra/tegra_rt5640.c +++ b/sound/soc/tegra/tegra_rt5640.c @@ -150,6 +150,7 @@ static struct snd_soc_dai_link tegra_rt5640_dai = { static struct snd_soc_card snd_soc_tegra_rt5640 = { .name = "tegra-rt5640", + .driver_name = "tegra", .owner = THIS_MODULE, .remove = tegra_rt5640_card_remove, .dai_link = &tegra_rt5640_dai, diff --git a/sound/soc/tegra/tegra_rt5677.c b/sound/soc/tegra/tegra_rt5677.c index 1470873ecde6..451e7254e87b 100644 --- a/sound/soc/tegra/tegra_rt5677.c +++ b/sound/soc/tegra/tegra_rt5677.c @@ -198,6 +198,7 @@ static struct snd_soc_dai_link tegra_rt5677_dai = { static struct snd_soc_card snd_soc_tegra_rt5677 = { .name = "tegra-rt5677", + .driver_name = "tegra", .owner = THIS_MODULE, .remove = tegra_rt5677_card_remove, .dai_link = &tegra_rt5677_dai, diff --git a/sound/soc/tegra/tegra_sgtl5000.c b/sound/soc/tegra/tegra_sgtl5000.c index 863e04809a6b..8755a9528d92 100644 --- a/sound/soc/tegra/tegra_sgtl5000.c +++ b/sound/soc/tegra/tegra_sgtl5000.c @@ -103,6 +103,7 @@ static struct snd_soc_dai_link tegra_sgtl5000_dai = { static struct snd_soc_card snd_soc_tegra_sgtl5000 = { .name = "tegra-sgtl5000", + .driver_name = "tegra", .owner = THIS_MODULE, .dai_link = &tegra_sgtl5000_dai, .num_links = 1, diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c index f0cd01dbfc38..633d26c4811b 100644 --- a/sound/soc/tegra/tegra_wm8753.c +++ b/sound/soc/tegra/tegra_wm8753.c @@ -110,6 +110,7 @@ static struct snd_soc_dai_link tegra_wm8753_dai = { static struct snd_soc_card snd_soc_tegra_wm8753 = { .name = "tegra-wm8753", + .driver_name = "tegra", .owner = THIS_MODULE, .dai_link = &tegra_wm8753_dai, .num_links = 1, diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index e485278e027a..20a3ca03ac30 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -228,6 +228,7 @@ static struct snd_soc_dai_link tegra_wm8903_dai = { static struct snd_soc_card snd_soc_tegra_wm8903 = { .name = "tegra-wm8903", + .driver_name = "tegra", .owner = THIS_MODULE, .dai_link = &tegra_wm8903_dai, .num_links = 1, diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c index 6492f8143ff1..e5bebb473d95 100644 --- a/sound/soc/tegra/tegra_wm9712.c +++ b/sound/soc/tegra/tegra_wm9712.c @@ -59,6 +59,7 @@ static struct snd_soc_dai_link tegra_wm9712_dai = { static struct snd_soc_card snd_soc_tegra_wm9712 = { .name = "tegra-wm9712", + .driver_name = "tegra", .owner = THIS_MODULE, .dai_link = &tegra_wm9712_dai, .num_links = 1, diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c index 2cea203c4f5f..90a770968f34 100644 --- a/sound/soc/tegra/trimslice.c +++ b/sound/soc/tegra/trimslice.c @@ -103,6 +103,7 @@ static struct snd_soc_dai_link trimslice_tlv320aic23_dai = { static struct snd_soc_card snd_soc_trimslice = { .name = "tegra-trimslice", + .driver_name = "tegra", .owner = THIS_MODULE, .dai_link = &trimslice_tlv320aic23_dai, .num_links = 1, diff --git a/sound/usb/format.c b/sound/usb/format.c index 90fe44897730..3e901405f55d 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c @@ -218,9 +218,11 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof continue; /* C-Media CM6501 mislabels its 96 kHz altsetting */ /* Terratec Aureon 7.1 USB C-Media 6206, too */ + /* Ozone Z90 USB C-Media, too */ if (rate == 48000 && nr_rates == 1 && (chip->usb_id == USB_ID(0x0d8c, 0x0201) || chip->usb_id == USB_ID(0x0d8c, 0x0102) || + chip->usb_id == USB_ID(0x0d8c, 0x0078) || chip->usb_id == USB_ID(0x0ccd, 0x00b1)) && fp->altsetting == 5 && fp->maxpacksize == 392) rate = 96000; diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index ea3a9bd05e68..0107bbfeb17d 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -687,6 +687,10 @@ static int line6_init_cap_control(struct usb_line6 *line6) line6->buffer_message = kmalloc(LINE6_MIDI_MESSAGE_MAXLEN, GFP_KERNEL); if (!line6->buffer_message) return -ENOMEM; + + ret = line6_init_midi(line6); + if (ret < 0) + return ret; } else { ret = line6_hwdep_init(line6); if (ret < 0) diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c index 17aa616e61f5..aaa192aee883 100644 --- a/sound/usb/line6/pod.c +++ b/sound/usb/line6/pod.c @@ -421,11 +421,6 @@ static int pod_init(struct usb_line6 *line6, if (err < 0) return err; - /* initialize MIDI subsystem: */ - err = line6_init_midi(line6); - if (err < 0) - return err; - /* initialize PCM subsystem: */ err = line6_init_pcm(line6, &pod_pcm_properties); if (err < 0) diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c index 0c4512d0382e..a911cff0cec8 100644 --- a/sound/usb/line6/variax.c +++ b/sound/usb/line6/variax.c @@ -217,7 +217,6 @@ static int variax_init(struct usb_line6 *line6, const struct usb_device_id *id) { struct usb_line6_variax *variax = (struct usb_line6_variax *) line6; - int err; line6->process_message = line6_variax_process_message; line6->disconnect = line6_variax_disconnect; @@ -233,11 +232,6 @@ static int variax_init(struct usb_line6 *line6, if (variax->buffer_activate == NULL) return -ENOMEM; - /* initialize MIDI subsystem: */ - err = line6_init_midi(&variax->line6); - if (err < 0) - return err; - /* initiate startup procedure: */ variax_startup1(variax); return 0; diff --git a/sound/usb/midi.c b/sound/usb/midi.c index ea264727fdf7..f0b41fee7130 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c @@ -1867,8 +1867,12 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi *umidi, ms_ep = find_usb_ms_endpoint_descriptor(hostep); if (!ms_ep) continue; + if (ms_ep->bLength <= sizeof(*ms_ep)) + continue; if (ms_ep->bNumEmbMIDIJack > 0x10) continue; + if (ms_ep->bLength < sizeof(*ms_ep) + ms_ep->bNumEmbMIDIJack) + continue; if (usb_endpoint_dir_out(ep)) { if (endpoints[epidx].out_ep) { if (++epidx >= MIDI_MAX_ENDPOINTS) { diff --git a/tools/kvm/kvm_stat/kvm_stat b/tools/kvm/kvm_stat/kvm_stat index 581278c58488..5e5797cc3757 100755 --- a/tools/kvm/kvm_stat/kvm_stat +++ b/tools/kvm/kvm_stat/kvm_stat @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # top-like utility for displaying kvm statistics # diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index 0619054bd7a0..61fe3ce5862d 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -603,7 +603,7 @@ static int get_maxfds(void) struct rlimit rlim; if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) - return min((int)rlim.rlim_max / 2, 512); + return min(rlim.rlim_max / 2, (rlim_t)512); return 512; } diff --git a/tools/perf/python/tracepoint.py b/tools/perf/python/tracepoint.py index eb4dbed57de7..ce273c8b512b 100755 --- a/tools/perf/python/tracepoint.py +++ b/tools/perf/python/tracepoint.py @@ -1,4 +1,4 @@ -#! /usr/bin/python +#! /usr/bin/env python # -*- python -*- # -*- coding: utf-8 -*- diff --git a/tools/perf/python/twatch.py b/tools/perf/python/twatch.py index c235c22b107a..5a55b25f0b8c 100755 --- a/tools/perf/python/twatch.py +++ b/tools/perf/python/twatch.py @@ -1,4 +1,4 @@ -#! /usr/bin/python +#! /usr/bin/env python # -*- python -*- # -*- coding: utf-8 -*- # twatch - Experimental use of the perf python interface diff --git a/tools/perf/scripts/python/sched-migration.py b/tools/perf/scripts/python/sched-migration.py index de66cb3b72c9..dd3e7ae2a1af 100644 --- a/tools/perf/scripts/python/sched-migration.py +++ b/tools/perf/scripts/python/sched-migration.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Cpu task migration overview toy # diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 89808ab008ad..9187d8119a75 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1427,6 +1427,7 @@ int perf_session__peek_event(struct perf_session *session, off_t file_offset, if (event->header.size < hdr_sz || event->header.size > buf_sz) return -1; + buf += hdr_sz; rest = event->header.size - hdr_sz; if (readn(fd, buf, rest) != (ssize_t)rest) diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py index c8680984d2d6..163f38fbd79c 100644 --- a/tools/perf/util/setup.py +++ b/tools/perf/util/setup.py @@ -1,4 +1,4 @@ -#!/usr/bin/python2 +#!/usr/bin/env python2 from distutils.core import setup, Extension from os import getenv diff --git a/tools/testing/ktest/compare-ktest-sample.pl b/tools/testing/ktest/compare-ktest-sample.pl index a373a5bfff68..c488e863d83f 100755 --- a/tools/testing/ktest/compare-ktest-sample.pl +++ b/tools/testing/ktest/compare-ktest-sample.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl open (IN,"ktest.pl"); while () { diff --git a/tools/testing/selftests/powerpc/pmu/ebb/no_handler_test.c b/tools/testing/selftests/powerpc/pmu/ebb/no_handler_test.c index 8341d7778d5e..87630d44fb4c 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/no_handler_test.c +++ b/tools/testing/selftests/powerpc/pmu/ebb/no_handler_test.c @@ -50,8 +50,6 @@ static int no_handler_test(void) event_close(&event); - dump_ebb_state(); - /* The real test is that we never took an EBB at 0x0 */ return 0; diff --git a/tools/testing/selftests/x86/protection_keys.c b/tools/testing/selftests/x86/protection_keys.c index 5338e668b5e6..d78736845b8e 100644 --- a/tools/testing/selftests/x86/protection_keys.c +++ b/tools/testing/selftests/x86/protection_keys.c @@ -609,7 +609,6 @@ int alloc_random_pkey(void) int nr_alloced = 0; int random_index; memset(alloced_pkeys, 0, sizeof(alloced_pkeys)); - srand((unsigned int)time(NULL)); /* allocate every possible key and make a note of which ones we got */ max_nr_pkey_allocs = NR_PKEYS; @@ -1387,6 +1386,8 @@ int main(void) { int nr_iterations = 22; + srand((unsigned int)time(NULL)); + setup_handlers(); printf("has pku: %d\n", cpu_has_pku());